From 5da613f131a9232997676eeca2505e2f5d6f7dcf Mon Sep 17 00:00:00 2001 From: William Bezuidenhout Date: Mon, 12 Jan 2026 16:16:41 +0200 Subject: [PATCH] try primary and legacy mcp urls before returning an error - latest url `.api/mcp` - legacy url `.api/mcp/v1` If neither work, we just return an error that the mcp endpoint is not available --- internal/mcp/mcp_request.go | 15 ++++++++++++++- internal/mcp/registry.go | 16 ++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/internal/mcp/mcp_request.go b/internal/mcp/mcp_request.go index e1b8d69c3d..db8b7bb8f8 100644 --- a/internal/mcp/mcp_request.go +++ b/internal/mcp/mcp_request.go @@ -13,7 +13,20 @@ import ( "github.com/sourcegraph/sourcegraph/lib/errors" ) -const MCPURLPath = ".api/mcp/v1" +const ( + MCPURLPath = ".api/mcp" + MCPURLPathLegacy = ".api/mcp/v1" +) + +func resolveMCPEndpoint(ctx context.Context, client api.Client) (string, error) { + for _, endpoint := range []string{MCPURLPath, MCPURLPathLegacy} { + _, err := doJSONRPC(ctx, client, endpoint, "tools/list", nil) + if err == nil { + return endpoint, nil + } + } + return "", errors.Newf("MCP endpoint not available: tried %s and %s", MCPURLPath, MCPURLPathLegacy) +} func fetchToolDefinitions(ctx context.Context, client api.Client, endpoint string) (map[string]*ToolDef, error) { resp, err := doJSONRPC(ctx, client, endpoint, "tools/list", nil) diff --git a/internal/mcp/registry.go b/internal/mcp/registry.go index 6797c3e829..342d530c35 100644 --- a/internal/mcp/registry.go +++ b/internal/mcp/registry.go @@ -12,7 +12,8 @@ import ( // ToolRegistry keeps track of tools and the endpoints they originated from type ToolRegistry struct { - tools map[string]*ToolDef + tools map[string]*ToolDef + endpoint string } func NewToolRegistry() *ToolRegistry { @@ -21,9 +22,16 @@ func NewToolRegistry() *ToolRegistry { } } -// LoadTools loads the tool definitions from the Mcp tool endpoints constants McpURLPath +// LoadTools loads the tool definitions from the MCP endpoint. +// It tries the new endpoint first (.api/mcp), then falls back to legacy (.api/mcp/v1). func (r *ToolRegistry) LoadTools(ctx context.Context, client api.Client) error { - tools, err := fetchToolDefinitions(ctx, client, MCPURLPath) + endpoint, err := resolveMCPEndpoint(ctx, client) + if err != nil { + return err + } + r.endpoint = endpoint + + tools, err := fetchToolDefinitions(ctx, client, endpoint) if err != nil { return err } @@ -40,7 +48,7 @@ func (r *ToolRegistry) Get(name string) (*ToolDef, bool) { // CallTool calls the given tool with the given arguments. It constructs the Tool request and decodes the Tool response func (r *ToolRegistry) CallTool(ctx context.Context, client api.Client, name string, args map[string]any) (map[string]json.RawMessage, error) { tool := r.tools[name] - resp, err := doToolCall(ctx, client, MCPURLPath, tool.RawName, args) + resp, err := doToolCall(ctx, client, r.endpoint, tool.RawName, args) if err != nil { return nil, err }