Skip to content

feat(mcp): deferred MCP tool loading — name-only stubs + tool_search activation (#119)#173

Merged
OGtwelve merged 3 commits into
mainfrom
feat/deferred-mcp-tools-119
Jul 13, 2026
Merged

feat(mcp): deferred MCP tool loading — name-only stubs + tool_search activation (#119)#173
OGtwelve merged 3 commits into
mainfrom
feat/deferred-mcp-tools-119

Conversation

@OGtwelve

@OGtwelve OGtwelve commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What & why

Closes #119. McpClientManager fetches every configured server's tool schemas, but the adapter then narrows the union to fixed slots (readFile, bash, …) — so every other MCP tool a server exposes was silently dropped. Spreading the whole registry into each agent instead would serialize every tool's JSON schema into every request, on every step. This mounts the surplus behind deferred loading: name-only until fetched, so a large MCP registry becomes viable without the context-window tax.

How

Three layers (one commit each):

  1. Threshold + surface splitmcpDeferToolsOver config key (int ≥ 0, default 20, 0 = always defer; project > global, pick honors a configured 0). McpClientManager.toolSurfaceForRole(role) returns { direct, deferred }: at/below the threshold the whole surplus is direct (byte-identical to plain mounting), above it the whole surplus is deferred.
  2. tool_search mechanism (src/mcp/tool-search.ts) — toolSearch(deferred) builds the tool + a per-invocation activation Set + a name-only index block. select:name1,name2 fetches exact names; any other query is keyword-ranked over names + descriptions (capped by max_results, default 5); each match returns its full schema and activates. guardDeferred wraps a deferred tool so a pre-activation call returns a typed "fetch it via tool_search first" result (never a throw / provider validation error). deferredToolIndexBlock renders the always-visible tier.
  3. Adapter integration (src/loop/run-loop-adapter.ts) — mountDeferredTools splits the role's surplus (excluding fixed-slot-named MCP tools, which stay partial-filled), mounts direct surplus in full and deferred surplus guard-wrapped + tool_search, and appends the index block to the system prompt. withActiveTools composes activeTools onto the feat(subagents): wire Compactor into subagent loops via prepareStep — summarize-and-continue #102 compaction prepareStep — one function returns both activeTools (recomputed each step as activations accumulate) and the compaction messages override. Wired for Worker + Reviewer; the Planner (read-only survey) and CI-fix session (fixed record) are untouched per the issue.

Scope boundaries (from the issue)

Deferred names use the mcp__<server>__<tool> namespacing from #115. Activation is scoped to one subagent invocation (a fresh invocation starts fully deferred). submit and fixed local slots are never deferred. Below the threshold there is no tool_search, no index block, and the role keeps its plain compaction prepareStep. Extending activation to the Planner / ci-fix is a separate follow-up.

SDK notes

Tests / gate

  • mcp-client.test.ts: toolSurfaceForRole split at/above/0 threshold + allowlist interaction.
  • tool-search.test.ts: select:/keyword/no-hit, schema rendering, index first-sentence, guard pre/post activation.
  • config-loader.test.ts: default 20 + project-over-global + configured 0 honored.
  • run-loop-adapter.test.ts: mountDeferredTools split + fixed-slot exclusion, activeToolNames gating, and an over-threshold end-to-end (surplus reaches the Worker name-only + tool_search, deferred schemas absent from active tools; regression: tools beyond the fixed slots now reach the Worker).
  • Green: typecheck (both) + typecheck:tests (compat) + test:node (aitm 902 / compat 250) + biome all clean.

Part of #100.

Summary by CodeRabbit

  • New Features

    • Added configurable deferred loading for MCP tools.
    • Excess tools are listed by name and can be discovered and activated through tool_search.
    • Prevented calls to unavailable tools until they are fetched, with clear guidance instead of provider errors.
    • Applied deferred loading consistently across Worker and Reviewer workflows.
    • Added role-specific tool filtering and support for explicit threshold configuration, including zero.
  • Documentation

    • Documented deferred MCP tool loading, configuration, and invocation behavior.

marshall added 3 commits July 13, 2026 10:40
… activation (#119)

Adapter integration for deferred loading. resolveWorkerTools/resolveReviewerTools
only fill fixed slots, so every other MCP tool was silently dropped; now the surplus
is mounted:
- mountDeferredTools splits the role's surplus (McpClientManager.toolSurfaceForRole)
  into directly-mounted (full schema, at/below threshold) vs. deferred (name-only +
  guard, above it), plus tool_search and a prompt index block when anything defers.
- withActiveTools composes activeTools onto the #102 compaction prepareStep — one
  function returns both activeTools (every step, recomputed as activations accumulate)
  and the compaction messages override. Below threshold the plain compaction step is
  kept, so the surface is byte-identical for that role.
- Worker + Reviewer wired; Planner (read-only) and ci-fix (fixed record) untouched per
  the issue. Fixed-slot-named MCP tools stay partial-filled, never deferred.

Tests: mountDeferredTools split + fixed-slot exclusion, activeToolNames gating, and an
over-threshold end-to-end (surplus reaches the Worker name-only + tool_search, deferred
schemas absent from active tools). docs/mcp.md documents mcpDeferToolsOver.

Closes #119.
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 50c40b17-15c7-4578-ac90-09d4ec2a3963

📥 Commits

Reviewing files that changed from the base of the PR and between 2dbb187 and 9aedc5b.

📒 Files selected for processing (10)
  • packages/aitm/docs/mcp.md
  • packages/aitm/src/config/config-loader.test.ts
  • packages/aitm/src/config/config-loader.ts
  • packages/aitm/src/config/schema.ts
  • packages/aitm/src/loop/run-loop-adapter.test.ts
  • packages/aitm/src/loop/run-loop-adapter.ts
  • packages/aitm/src/mcp/mcp-client.test.ts
  • packages/aitm/src/mcp/mcp-client.ts
  • packages/aitm/src/mcp/tool-search.test.ts
  • packages/aitm/src/mcp/tool-search.ts

📝 Walkthrough

Walkthrough

Adds configurable deferred MCP tool loading. Surplus tools are exposed through a searchable index, activated per subagent invocation, guarded before activation, and integrated into Worker and Reviewer tool preparation with configuration and test coverage.

Changes

Deferred MCP tool loading

Layer / File(s) Summary
MCP deferral configuration
packages/aitm/src/config/schema.ts, packages/aitm/src/config/config-loader.ts, packages/aitm/src/config/config-loader.test.ts
Adds the validated mcpDeferToolsOver setting, default value, project/global precedence, and explicit 0 handling.
Role-level MCP tool surfaces
packages/aitm/src/mcp/mcp-client.ts, packages/aitm/src/mcp/mcp-client.test.ts
Splits role tools into direct and deferred sets according to the threshold and role allowlist.
Deferred search and guards
packages/aitm/src/mcp/tool-search.ts, packages/aitm/src/mcp/tool-search.test.ts
Adds tool_search, deferred-tool indexing, activation tracking, schema rendering, keyword matching, and fetch-first guards.
Worker and Reviewer activation wiring
packages/aitm/src/loop/run-loop-adapter.ts, packages/aitm/src/loop/run-loop-adapter.test.ts, packages/aitm/docs/mcp.md
Mounts surplus MCP tools, appends prompt indexes, updates active tools across steps, preserves compaction wiring, and documents the behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Worker
  participant McpClientManager
  participant tool_search
  participant DeferredMCPTool
  Worker->>McpClientManager: request role tool surface
  McpClientManager-->>Worker: direct tools and deferred tools
  Worker->>tool_search: search or select deferred tool
  tool_search-->>Worker: schema and activation
  Worker->>DeferredMCPTool: call activated tool
  DeferredMCPTool-->>Worker: tool result
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: deferred MCP tool loading with tool_search activation.
Linked Issues check ✅ Passed The changes implement threshold-based MCP deferral, tool_search activation, typed pre-activation guards, prompt indexing, and Worker/Reviewer integration as requested.
Out of Scope Changes check ✅ Passed The diff stays focused on deferred MCP loading, config, tests, and docs; no unrelated feature work is introduced.
Docstring Coverage ✅ Passed Docstring coverage is 34.78% which is sufficient. The required threshold is 30.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/deferred-mcp-tools-119

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

@OGtwelve

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@OGtwelve OGtwelve merged commit 58f7ba0 into main Jul 13, 2026
4 checks passed
@OGtwelve OGtwelve deleted the feat/deferred-mcp-tools-119 branch July 13, 2026 11:53
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.

feat(mcp): deferred MCP tool loading — name-only stubs + tool_search activation

1 participant