diff --git a/cmd/src/mcp.go b/cmd/src/mcp.go index 4a3eba10fc..3878fe24b6 100644 --- a/cmd/src/mcp.go +++ b/cmd/src/mcp.go @@ -5,6 +5,7 @@ import ( "encoding/json" "flag" "fmt" + "maps" "strings" "github.com/sourcegraph/src-cli/internal/mcp" @@ -29,6 +30,12 @@ func mcpUsage() { fmt.Println(" src mcp schema View the input/output schema of a tool") fmt.Println(" src mcp Invoke a tool with the given flags") fmt.Println(" src mcp -h List the available flags of a tool") + fmt.Println("\nCOMMON FLAGS:") + fmt.Println(" --json '{...}' Provide all tool arguments as a JSON object (recommended for agents)") + fmt.Println("\nNOTE:") + fmt.Println(" When both --json and explicit flags are provided, values from --json take precedence.") + fmt.Println("\nEXAMPLE:") + fmt.Println(" src mcp --json '{\"arg1\": \"value1\", \"arg2\": \"value2\"}'") } func mcpMain(args []string) error { @@ -76,6 +83,20 @@ func mcpMain(args []string) error { } mcp.DerefFlagValues(flags, vars) + // arguments provided via a JSON object take precedence over explicit values provided from flags + if val, ok := vars["json"]; ok { + if jsonVal, ok := val.(string); ok && len(jsonVal) > 0 { + m := make(map[string]any) + if err := json.Unmarshal([]byte(jsonVal), &m); err != nil { + return err + } + // copy overrides existing keys + maps.Copy(vars, m) + } + // we delete "json" from vars, otherwise it will be sent as a argument to the tool call + delete(vars, "json") + } + if err := validateToolArgs(tool.InputSchema, args, vars); err != nil { return err } diff --git a/internal/mcp/mcp_args.go b/internal/mcp/mcp_args.go index bdd7af6ef7..e492a645ef 100644 --- a/internal/mcp/mcp_args.go +++ b/internal/mcp/mcp_args.go @@ -93,5 +93,7 @@ func BuildArgFlagSet(tool *ToolDef) (*flag.FlagSet, map[string]any, error) { } } + flagVars["json"] = fs.String("json", "", "provide all arguments as a JSON object") + return fs, flagVars, nil }