Skip to content

feat/mcp-tool-modes - #7016

Draft
kohlivrinda wants to merge 1 commit into
devfrom
09-09-feat_mcp-tool-modes
Draft

feat/mcp-tool-modes#7016
kohlivrinda wants to merge 1 commit into
devfrom
09-09-feat_mcp-tool-modes

Conversation

@kohlivrinda

@kohlivrinda kohlivrinda commented Sep 9, 2026

Copy link
Copy Markdown
Member

Summary

Introduces a tool_mode field for MCP clients that replaces the binary is_code_mode_client flag with a five-way enum: direct, code, compact, compact_names, and search. The new modes address context bloat without requiring a Starlark sandbox: compact strips all descriptions from tool definitions, compact_names exposes only tool names plus an on-demand getToolDetails meta-tool, and search hides tools entirely behind three meta-tools (searchTools, getToolDetails, executeTool) backed by a BM25 index. The legacy is_code_mode_client flag is kept in sync on every read and write so rolled-back binaries continue to work.

Changes

  • schemas.MCPToolMode — new string enum (direct, code, compact, compact_names, search) with ResolvedToolMode() (explicit field wins, then legacy flag, then direct) and NormalizeToolMode() (writes both fields into agreement).
  • core/mcp/toolmodes.go — new file implementing:
    • compactToolDefinition: strips function and parameter descriptions while preserving the JSON schema skeleton.
    • nameOnlyToolDefinition: replaces the parameter schema with an open, empty object.
    • BM25F index (newBM25Index, search) with camelCase-aware tokenization, plural normalization, and per-field weights that prevent long descriptions from burying exact name hits.
    • searchModeTools: returns the three meta-tool definitions with catalog size and server list baked into the searchTools description.
    • handleSearchTools, handleGetToolDetails, handleExecuteTool: dispatch logic for the meta-tools, including allow-list enforcement, request-context client filtering, nested request ID propagation, and plugin pipeline pass-through.
  • GetAvailableTools — routes each client through ResolvedToolMode() and appends compact/name-only definitions or records search-mode tools for the meta-tool catalog; injects meta-tools exactly once.
  • executeAgentsearchTools and getToolDetails are always auto-executable; executeTool is auto-executable iff the inner tool would be if called directly.
  • buildAllowedAutoExecutionTools — switched from IsCodeModeClient boolean to ResolvedToolMode() == MCPToolModeCode.
  • resolveExecuteToolTarget — new helper that parses an executeTool call's tool argument and resolves it to the owning client.
  • prepareToolExecution — skips client lookup for search-mode meta-tools, mirroring the existing code-mode skip.
  • Databasetool_mode VARCHAR(20) column added to config_mcp_clients; migration backfills code from is_code_mode_client = true and direct for everything else; rollback drops the column.
  • Config store / HTTP handlers / config loaderToolMode threaded through all read, write, create, and update paths; addMCPClient and updateMCPClient validate and normalize the field before persisting.
  • Config schematool_mode enum added; is_code_mode_client marked deprecated.
  • UI — the Code Mode toggle switch is replaced by a five-option Select in both the create form and the edit sheet; the clients table "Code Mode" column becomes "Tool Mode" with human-readable labels; resolveToolMode and MCP_TOOL_MODE_LABELS added to the MCP type module; optimistic cache update handles tool_mode.
  • Teststoolmodes_test.go covers compact stripping, BM25 ranking, the full mode matrix in GetAvailableTools, all three search meta-tool handlers (including refusals, stringified arguments, inner error propagation), and resolveExecuteToolTarget.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

# Core/Transports
go test ./core/mcp/... ./framework/configstore/... ./transports/bifrost-http/...

# UI
cd ui
pnpm i
pnpm build

To exercise search mode end-to-end:

  1. Create or update an MCP client with tool_mode: "search".
  2. Start an agent session; verify only searchTools, getToolDetails, and executeTool appear in the tool list.
  3. Call searchTools with a relevant query and confirm ranked results are returned.
  4. Call getToolDetails on a result and confirm full parameter docs including an example executeTool call.
  5. Call executeTool and confirm the inner tool executes and its result is re-enveloped under the outer call ID.

For compact and compact_names, verify that tool descriptions and parameter descriptions are absent from the request payload while the schema skeleton (types, required, enums) is preserved.

Breaking changes

  • Yes
  • No

is_code_mode_client continues to be read and written correctly. The database migration is additive and includes a rollback. Existing code-mode clients are automatically backfilled to tool_mode = "code".

Security considerations

executeTool enforces the same allow-list checks (ToolsToExecute, ToolsToAutoExecute, request-context include_clients) as a direct tool call. It also refuses to proxy tools whose client is not in search mode, preventing the meta-tool from being used as a bypass for direct or compact clients. The inner call goes through the full plugin pipeline.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant