feat: add MCP routing modes (direct, code_execution, retrieve_tools)#327
Merged
feat: add MCP routing modes (direct, code_execution, retrieve_tools)#327
Conversation
Add RoutingMode field to Config struct supporting three modes: - retrieve_tools (default): BM25 search via retrieve_tools + call_tool variants - direct: All upstream tools exposed with serverName__toolName naming - code_execution: JS orchestration via code_execution tool Includes validation, default application, JSON serialization, and tests.
…c 031) Create mcp_routing.go with: - ParseDirectToolName/FormatDirectToolName for serverName__toolName convention - buildDirectModeTools: discovers upstream tools and creates direct handlers - buildCodeExecModeTools: creates code_execution + retrieve_tools tool set - makeDirectModeHandler: handles auth, permissions, upstream calls, activity logging - buildToolCatalogDescription: generates tool catalog for code_execution description
Add directServer and codeExecServer fields to MCPProxyServer struct. Initialize separate MCP server instances during proxy creation: - server (existing): retrieve_tools mode tools - directServer: direct mode with serverName__toolName tools - codeExecServer: code_execution + retrieve_tools tools Add GetMCPServerForMode() to select the correct instance by mode. Add RefreshDirectModeTools() for rebuilding tools on server changes.
Register per-mode MCP endpoints in startCustomHTTPServer: - /mcp/all -> direct mode (all upstream tools with serverName__toolName) - /mcp/code -> code_execution mode (JS orchestration + retrieve_tools) - /mcp/call -> retrieve_tools mode (explicit, same as /mcp default) - /mcp -> configured routing_mode (backward compatible default) Add listenForRoutingModeRefresh goroutine to rebuild direct and code_execution mode tools when servers.changed events fire.
Test cases for makeDirectModeHandler: - Permission denied when agent lacks required permission tier - Server access denied for restricted agent tokens - Agent with correct permissions passes auth checks - Destructive tools require destructive permission specifically - No auth context (backward compatible) passes auth checks
Add AuthInfo and ToolAnnotationLookup to ExecutionOptions for permission enforcement during code_execution. Each call_tool() invocation now: - Checks server access against auth context AllowedServers - Looks up tool annotations to determine required permission tier - Validates agent has the required permission (read/write/destructive) - Tracks max_permission_level across all calls in the execution Wire up auth context from MCP handler to jsruntime via handleCodeExecution. Add lookupToolPermission helper to resolve tool permission from index.
- Add routing_mode field to StatusInfo struct (table and JSON output) - Display routing mode in printStatusTable with "Routing:" label - Default to retrieve_tools when routing_mode is empty - Show routing mode description and endpoints in doctor output - Add tests for routing mode in table, JSON, and config-fallback
- Add GET /api/v1/routing endpoint returning mode, description, endpoints, available_modes - Add routing_mode field to GET /api/v1/status response - Default to retrieve_tools when routing_mode is not configured - Add tests for routing endpoint and status routing_mode field
- Add RoutingInfo type and routing_mode to StatusUpdate in api.ts - Add getRouting() API method for /api/v1/routing endpoint - Add routing state, routingMode computed, and fetchRouting action to system store - Display routing mode badge in TopHeader.vue - Fetch routing info on app initialization
- Add routing_mode to config schema in swagger.yaml - Add GET /api/v1/routing endpoint to OpenAPI spec - Rebuild frontend dist with routing mode UI changes
GetConfig() can return nil config (e.g., in tests with mock controllers). Add nil guard before accessing cfg.RoutingMode to prevent panic.
C1: Default /mcp endpoint now respects routing_mode config by using GetMCPServerForMode() instead of always using retrieve_tools server. C2: lookupToolPermission now uses exact match via lookupToolAnnotations (StateView) as primary lookup, with BM25 index search (limit 20) as fallback. Prevents wrong permission tier from fuzzy search results. I1: When code execution is disabled in config, the /mcp/code endpoint returns a clear error message instead of confusing runtime failure.
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 22897560537 --repo smart-mcp-proxy/mcpproxy-go
|
Resolves staticcheck QF1003 lint error by converting if/else chain to a tagged switch on routingMode. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
retrieve_tools(current default/BM25 search),direct(all tools exposed withserverName__toolNamenaming), andcode_execution(JS orchestration with tool catalog)/mcp/all(direct),/mcp/code(code_execution),/mcp/call(retrieve_tools)/mcpendpoint respectsrouting_modeconfig settingcall_tool()invocationsmcpproxy statusandmcpproxy doctoroutputGET /api/v1/routingendpoint with mode info and available endpointsRelated #279
Test plan
serverName__toolNameround-trip (format/parse) with edge cases-race