Skip to content

fix: preserve compact MCP tool routing guidance - #1668

Merged
Dumbris merged 6 commits into
smart-mcp-proxy:mainfrom
copystring:fix/compact-tool-routing-guidance
Oct 20, 2026
Merged

Dumbris merged 6 commits into
smart-mcp-proxy:mainfrom
copystring:fix/compact-tool-routing-guidance

Conversation

@copystring

@copystring copystring commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Compact retrieve_tools entries omit call_with, while agents are told to select a call variant using tool-name heuristics. This can route tools such as windows:PowerShell through the wrong variant even though the proxy already has an authoritative upstream classification.

This change includes the same call_with route in each compact entry as full mode, including the existing call_tool_read fallback when tier annotations are unavailable. Tool descriptions and usage instructions make that route authoritative over names, descriptions, command text, and apparent intent; security tiers and dispatch behavior are unchanged. The compact contract and REST API documentation include the field.

Response and tools/list goldens now pin the intended routing fields and guidance. Historical pre099/pre105 captures remain unchanged; enumerated compatibility checks permit only the deliberate description deltas and continue checking all other fields. A structural comparison of the twelve updated JSON fixtures confirmed that ranking, schemas, tool membership, and unrelated data are unchanged.

Validation:

  • Fifteen focused top-level tests passed in both personal and server editions (-tags server,nogui), without golden-update environment variables. Includes compact routing parity for read/write/destructive/unannotated tools, Full/Stats/ProfileV3/Spec094 response goldens, tools/list snapshots, read-only profiles, enumerated surface deltas, and historical pre105 compatibility.
  • Exact test selection:
    go test ./internal/server -run '^(TestBuildToolEntry_Compact.*|TestCallToolVariantDescriptionsHonorRouteAnnotations|TestRetrieveToolsInstructions_RetrieveToolsMode|TestRetrieveToolsFullMode_GoldenByteIdentity|TestRetrieveToolsProfileV3_GoldenByteIdentity|TestSpec094Goldens|TestToolsListSnapshot_MatchesMergeBaseGoldens|TestToolsList_ProfilesPresentUnderReadOnlyMode|TestToolsListSnapshot_DeltaIsEnumerated|TestCodeExecutionDescriptions_EnumerationIsAdminOnly|TestMenuSurface_ExactDeltaFromPreFeature)$' -count=1 -v
  • The same selection passed with -tags server,nogui.
  • gofmt on changed Go files and git diff --check.

Tests used go1.26.9 from the official Windows archive, verified against its official SHA256 manifest. The full Go suite was not run locally; Linux and cross-platform build verification runs in CI.

Additional regression coverage: route parity now covers canonical IDs with and without an explicit server, and bare tool names with an explicit server, across read/write/destructive/unannotated tools. Missing result/tool/identity and unknown-server cases preserve the read fallback. These focused tests pass in personal and server editions. Local Go coverage reports 100% statement coverage for compactToolCallWith; the rest of the package was not used to infer a patch coverage percentage.

@copystring copystring changed the title Preserve compact MCP tool routing guidance fix: preserve compact MCP tool routing guidance Oct 18, 2026
@codecov-commenter

codecov-commenter commented Oct 18, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@copystring

Copy link
Copy Markdown
Contributor Author

The remaining failing check is FR-011's merge-base latency comparison on head c0bf49d6235c9ccd62e5731107463c7e8c64f34d.

In the head run, read_cache measured about 50 ms p95 for both interleaved caller arms, versus about 1.54 ms on the base; the other operations passed. This has not yet been established as runner noise or as a code regression.

Could a maintainer rerun the failed FR-011 job on this same head to check whether it reproduces? My current repository permissions do not allow workflow reruns. If it reproduces, I will investigate the latency before marking this ready for review.

The Codecov comment reports that all modified coverable lines are covered; there is no failed Codecov check in the current rollup. A Codecov rerun would not rerun FR-011.

@Dumbris

Dumbris commented Oct 20, 2026

Copy link
Copy Markdown
Member

Thanks @copystring, this is a real fix and a clean one. Compact call_with plus the authoritative-route wording in the tool descriptions is the right shape.

What I did on your branch (your three commits untouched, authorship preserved):

  • Merged current main into the branch (ab82e3ead). Your base was stale and the merge was conflict-free.
  • Re-ran the frozen goldens (TestToolsListSnapshot_*, TestMenuSurface_*, TestDirectFullMode_ByteStable*), your compact/call_with tests, go build ./..., and scripts/test-api-e2e.sh locally: green (the only e2e miss was the server-edition-binary presence check, which is my local build setup, not your change).
  • golangci-lint v2 (bare and --build-tags server): no findings in any file this PR touches.

On the FR-011 failure: it is runner noise, not your change. Your diff does not touch read_cache, and locally read_cache p95 swings between ~14 and ~22 ms on plain main and on this branch alike, with no systematic gap. The workflow is also advisory (continue-on-error: true), so it never blocked merging. I've pushed a new head, so FR-011 re-runs from scratch on it.

Next step is to confirm CI on the new head; then this is ready to flip out of draft whenever you like.

…dance; align docs and comments

Review follow-ups to smart-mcp-proxy#1668:
- toolslist_snapshot_test pins the retrieve_tools and call_tool_* deltas
  against the frozen pre-105 capture with test-owned sentences instead of
  substituting the live description after a prefix check.
- The code_execution-mode isolation test asserts the live selection-guide
  heading is absent, and the retrieve_tools-mode test asserts it present,
  so neither can pass vacuously.
- DeriveCallWith's doc comment no longer tells agents to override the read
  default from descriptions; call_with is authoritative, and the server
  tier gate plus the profile unannotated policy decide admission.
- docs/features/search-discovery.md, docs/configuration.md and the mcp.go
  entry-builder comment list call_with in the compact shape and drop the
  'byte-identical' claim for full mode.
@Dumbris
Dumbris marked this pull request as ready for review October 20, 2026 15:50
@Dumbris
Dumbris enabled auto-merge (squash) October 20, 2026 15:50
@Dumbris

Dumbris commented Oct 20, 2026

Copy link
Copy Markdown
Member

Thanks @copystring, good catch and a clean fix. The live check (compact and full mode, with annotated, destructive and unannotated tools) matched, and the change is a net token saving on every golden. I pushed one commit on top of your branch: the pre-105 snapshot test now pins the exact description delta with test-owned sentences, the code_execution isolation assertion checks the live heading so it cannot pass vacuously, and the docs plus the DeriveCallWith comment say call_with is authoritative. I marked the PR ready and armed auto-merge; it lands when CI is green.

@Dumbris
Dumbris merged commit 9b8271f into smart-mcp-proxy:main Oct 20, 2026
48 checks passed
@copystring
copystring deleted the fix/compact-tool-routing-guidance branch October 20, 2026 21:48
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.

3 participants