Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d1a299e
chore: update vulnerable packages (#1229)
keegancsmith Dec 8, 2025
2e48170
remove tool metion from help text (#1230)
burmudar Dec 8, 2025
4de2c09
add script to dump mcp tool list
burmudar Nov 27, 2025
bd20984
parse mcp tool json
burmudar Nov 27, 2025
6d269dd
fix parsing for when items: true
burmudar Nov 27, 2025
4cf4889
use lib/errors
burmudar Nov 28, 2025
e479290
temporarily ignore embedded json
burmudar Nov 28, 2025
1164172
move mcp files to internal/mcp
burmudar Dec 2, 2025
5fab60f
unexport and remove unused structs
burmudar Dec 2, 2025
72974c4
rename MCPToolDef to ToolDef and move around structs
burmudar Dec 2, 2025
58bbc3c
rename parser + method to decoder + decode*
burmudar Dec 5, 2025
505a7b0
simplify types fold: Schema into SchemaObject
burmudar Dec 8, 2025
d01f5ea
add mcp list-tools to list available tool calls
burmudar Nov 27, 2025
c4306cb
set variable name for embedded json
burmudar Nov 28, 2025
bfdfe06
fix usage of fmt.Errorf
burmudar Nov 28, 2025
6297121
fix test
burmudar Nov 28, 2025
bc4a87d
fix lint error
burmudar Nov 28, 2025
6603541
make default LoadToolDefinitions and unexported loadToolDefinitions
burmudar Dec 2, 2025
14b9832
use internal/mcp
burmudar Dec 2, 2025
07f9d05
fixup after refactor
burmudar Dec 2, 2025
312a810
improve list-tools output
burmudar Dec 4, 2025
89d742e
change name to RawName and have method for Name() that is normalized
burmudar Nov 27, 2025
cf08d88
remove Name() method and use method name field
burmudar Dec 2, 2025
3cb9b00
fix test
burmudar Dec 2, 2025
5840064
fixup
burmudar Dec 5, 2025
6160b49
fixup
burmudar Dec 8, 2025
49af84d
build flagset from inputschema to parse args
burmudar Nov 27, 2025
169b5e6
initial handleMcpTool method
burmudar Nov 28, 2025
9f4c7e3
export LoadToolDefinitions and add LoadDefaultToolDefinitions
burmudar Dec 2, 2025
45368db
move mcp args to internal/mcp
burmudar Dec 2, 2025
b236f16
guard against nil tool definitions when building flagsets
burmudar Dec 2, 2025
1cc1c27
use github.com/sourcegraph/sourcegraphh/lib/errors
burmudar Dec 2, 2025
8d0b3f6
fixup old Kind usage
burmudar Dec 8, 2025
3815a50
add todo
burmudar Dec 8, 2025
4839034
feat(mcp): do mcp tool call from cli args (#1216)
burmudar Dec 9, 2025
700a6cb
add todo
burmudar Dec 8, 2025
897aae6
Merge branch 'wb/mcp-list-tools' into wb/mcp-flagset-inputschema
burmudar Dec 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cmd/src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ The commands are:
search search for results on Sourcegraph
search-jobs manages search jobs
serve-git serves your local git repositories over HTTP for Sourcegraph to pull
tool exposes tools for AI agents to interact with Sourcegraph (EXPERIMENTAL)
users,user manages users
codeowners manages code ownership information
version display and compare the src-cli version against the recommended version for your instance
Expand Down
69 changes: 66 additions & 3 deletions cmd/src/mcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
}
func mcpMain(args []string) error {
fmt.Println("NOTE: This command is still experimental")
tools, err := mcp.LoadToolDefinitions()

Check failure on line 19 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: mcp.LoadToolDefinitions

Check failure on line 19 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: mcp.LoadToolDefinitions

Check failure on line 19 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: mcp.LoadToolDefinitions
if err != nil {
return err
}
Expand All @@ -43,10 +43,73 @@
if !ok {
return fmt.Errorf("tool definition for %q not found - run src mcp list-tools to see a list of available tools", subcmd)
}
return handleMcpTool(tool, args[1:])

flagArgs := args[1:] // skip subcommand name
if len(args) > 1 && args[1] == "schema" {
return printSchemas(tool)
}

flags, vars, err := mcp.BuildArgFlagSet(tool)
if err != nil {
return err
}
if err := flags.Parse(flagArgs); err != nil {
return err
}
mcp.DerefFlagValues(vars)

if err := validateToolArgs(tool.InputSchema, args, vars); err != nil {
return err
}

apiClient := cfg.apiClient(nil, flags.Output())
return handleMcpTool(context.Background(), apiClient, tool, vars)

Check failure on line 66 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: context

Check failure on line 66 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: context

Check failure on line 66 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: context
}

func handleMcpTool(tool *mcp.ToolDef, args []string) error {
fmt.Printf("handling tool %q args: %+v", tool.Name, args)
func printSchemas(tool *mcp.ToolDef) error {
input, err := json.MarshalIndent(tool.InputSchema, "", " ")

Check failure on line 70 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: json

Check failure on line 70 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: json

Check failure on line 70 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: json
if err != nil {
return err
}
output, err := json.MarshalIndent(tool.OutputSchema, "", " ")

Check failure on line 74 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: json

Check failure on line 74 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: json

Check failure on line 74 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: json
if err != nil {
return err
}

fmt.Printf("Input:\n%v\nOutput:\n%v\n", string(input), string(output))
return nil
}

func validateToolArgs(inputSchema mcp.SchemaObject, args []string, vars map[string]any) error {
for _, reqName := range inputSchema.Required {
if vars[reqName] == nil {
return errors.Newf("no value provided for required flag --%s", reqName)

Check failure on line 86 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: errors

Check failure on line 86 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: errors

Check failure on line 86 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: errors
}
}

if len(args) < len(inputSchema.Required) {
return errors.Newf("not enough arguments provided - the following flags are required:\n%s", strings.Join(inputSchema.Required, "\n"))

Check failure on line 91 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: strings

Check failure on line 91 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: errors

Check failure on line 91 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: strings

Check failure on line 91 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: errors

Check failure on line 91 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: strings

Check failure on line 91 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: errors
}

return nil
}

func handleMcpTool(ctx context.Context, client api.Client, tool *mcp.ToolDef, vars map[string]any) error {

Check failure on line 97 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: api

Check failure on line 97 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: context

Check failure on line 97 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: api

Check failure on line 97 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: context

Check failure on line 97 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: api

Check failure on line 97 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: context
resp, err := mcp.DoToolRequest(ctx, client, tool, vars)
if err != nil {
return err
}

result, err := mcp.DecodeToolResponse(resp)
if err != nil {
return err
}
defer resp.Body.Close()

output, err := json.MarshalIndent(result, "", " ")

Check failure on line 109 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-test (macos-latest)

undefined: json

Check failure on line 109 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / scip-go

undefined: json

Check failure on line 109 in cmd/src/mcp.go

View workflow job for this annotation

GitHub Actions / go-lint

undefined: json
if err != nil {
return err
}
fmt.Println(string(output))
return nil
}
19 changes: 10 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ require (
github.com/sourcegraph/scip v0.6.1
github.com/sourcegraph/sourcegraph/lib v0.0.0-20240709083501-1af563b61442
github.com/stretchr/testify v1.11.1
golang.org/x/net v0.46.0
golang.org/x/net v0.47.0
golang.org/x/sync v0.18.0
google.golang.org/api v0.256.0
google.golang.org/protobuf v1.36.10
Expand Down Expand Up @@ -67,15 +67,15 @@ require (
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/cli v24.0.4+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v25.0.6+incompatible // indirect
github.com/docker/docker v28.0.0+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
github.com/felixge/fgprof v0.9.3 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-chi/chi/v5 v5.0.10 // indirect
github.com/go-chi/chi/v5 v5.2.2 // indirect
github.com/go-jose/go-jose/v4 v4.1.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gofrs/uuid/v5 v5.0.0 // indirect
Expand All @@ -91,11 +91,12 @@ require (
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc4 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/rs/cors v1.9.0 // indirect
github.com/rs/cors v1.11.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/beaut v0.0.0-20240611013027-627e4c25335a // indirect
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
Expand All @@ -116,7 +117,7 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
go.opentelemetry.io/otel/trace v1.38.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
Expand Down Expand Up @@ -216,14 +217,14 @@ require (
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/oauth2 v0.33.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/term v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/tools v0.37.0 // indirect
golang.org/x/tools v0.38.0 // indirect
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.76.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect; direct
Expand Down
38 changes: 20 additions & 18 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ github.com/docker/cli v24.0.4+incompatible h1:Y3bYF9ekNTm2VFz5U/0BlMdJy73D+Y1iAA
github.com/docker/cli v24.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg=
github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v28.0.0+incompatible h1:Olh0KS820sJ7nPsBKChVhk5pzqcwDR15fumfAd/p9hM=
github.com/docker/docker v28.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=
github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
Expand Down Expand Up @@ -188,8 +188,8 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI=
Expand Down Expand Up @@ -344,6 +344,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down Expand Up @@ -402,8 +404,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
Expand Down Expand Up @@ -513,25 +515,25 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w=
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -563,8 +565,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8=
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE=
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU=
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
Expand All @@ -574,8 +576,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand All @@ -586,8 +588,8 @@ golang.org/x/tools v0.0.0-20200624163319-25775e59acb7/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
94 changes: 94 additions & 0 deletions internal/mcp/mcp_args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package mcp

import (
"flag"
"fmt"
"reflect"
"strings"

"github.com/sourcegraph/sourcegraph/lib/errors"
)

var _ flag.Value = (*strSliceFlag)(nil)

type strSliceFlag struct {
vals []string
}

func (s *strSliceFlag) Set(v string) error {
s.vals = append(s.vals, v)
return nil
}

func (s *strSliceFlag) String() string {
return strings.Join(s.vals, ",")
}

func DerefFlagValues(vars map[string]any) {
for k, v := range vars {
rfl := reflect.ValueOf(v)
if rfl.Kind() == reflect.Pointer {
vv := rfl.Elem().Interface()
if slice, ok := vv.(strSliceFlag); ok {
vv = slice.vals
}
if isNil(vv) {
delete(vars, k)
} else {
vars[k] = vv
}
}
}
}

func isNil(v any) bool {
if v == nil {
return true
}
rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.Slice, reflect.Map, reflect.Pointer, reflect.Interface:
return rv.IsNil()
default:
return false
}
}

func BuildArgFlagSet(tool *ToolDef) (*flag.FlagSet, map[string]any, error) {
if tool == nil {
return nil, nil, errors.New("cannot build flagset on nil Tool Definition")
}
fs := flag.NewFlagSet(tool.Name, flag.ContinueOnError)
flagVars := map[string]any{}

for name, pVal := range tool.InputSchema.Properties {
switch pv := pVal.(type) {
case *SchemaPrimitive:
switch pv.Type {
case "integer":
dst := fs.Int(name, 0, pv.Description)
flagVars[name] = dst

case "boolean":
dst := fs.Bool(name, false, pv.Description)
flagVars[name] = dst
case "string":
dst := fs.String(name, "", pv.Description)
flagVars[name] = dst
default:
return nil, nil, fmt.Errorf("unknown schema primitive kind %q", pv.Type)

}
case *SchemaArray:
strSlice := new(strSliceFlag)
fs.Var(strSlice, name, pv.Description)
flagVars[name] = strSlice
case *SchemaObject:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have nay uses of that in our tools?

// TODO(burmudar): we can support SchemaObject as part of stdin echo '{ stuff }' | sg mcp commit-search
// not supported yet
// Also support sg mcp commit-search --json '{ stuff }'
}
}

return fs, flagVars, nil
}
Loading
Loading