Repository navigation
fix(sse): recognize MCP-gateway-namespaced CCR retrieve tool names (#13781, #13897) - #14028
Merged
Merged
Conversation
…13781, #13897) callerSupportsCcrRetrieve() matched the omniroute_ccr_retrieve tool by exact string equality. MCP aggregators/gateways (Docker MCP Toolkit, Claude Code) rename re-exposed tools with a namespace prefix (e.g. mcp__docker__omniroute__omniroute_ccr_retrieve, or a dotted/slashed prefix), so a fully MCP-capable caller reachable only under such a name was treated as unable to retrieve at all -- skipping both the protocol-instruction injection and, per the #7746 safety guarantee, the entire CCR compression engine for that request. Add matchesCcrRetrieveToolName(), a separator-bounded trailing-segment match (__, ., /, :) that accepts a namespaced form of the tool name while still rejecting a near-miss like omniroute_ccr_retrieve_v2 -- never a bare substring/endsWith check.
Collaborator
Author
|
Validated in local merge-train /tmp/mt-train3b.log on 192.168.0.113 @ train tip 408e2128791696a18966681953136fc96aeb99b0 (32 PRs boarded): static gates green; full test:unit 40694 tests, 17 failing — every one reproduces on the pure release tip (base-red sweep list), zero new reds. Merged --admin per merge-gates §4/§7. |
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…heaper-inference#13781, cheaper-inference#13897) (cheaper-inference#14028) callerSupportsCcrRetrieve() matched the omniroute_ccr_retrieve tool by exact string equality. MCP aggregators/gateways (Docker MCP Toolkit, Claude Code) rename re-exposed tools with a namespace prefix (e.g. mcp__docker__omniroute__omniroute_ccr_retrieve, or a dotted/slashed prefix), so a fully MCP-capable caller reachable only under such a name was treated as unable to retrieve at all -- skipping both the protocol-instruction injection and, per the cheaper-inference#7746 safety guarantee, the entire CCR compression engine for that request. Add matchesCcrRetrieveToolName(), a separator-bounded trailing-segment match (__, ., /, :) that accepts a namespaced form of the tool name while still rejecting a near-miss like omniroute_ccr_retrieve_v2 -- never a bare substring/endsWith check.
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.
Root cause
callerSupportsCcrRetrieve()(open-sse/services/compression/engines/ccr/protocolInstruction.ts)matched the CCR retrieve tool by exact string equality against
omniroute_ccr_retrieve. MCPaggregators/gateways (Docker MCP Toolkit, Claude Code, and similar) rename tools when re-exposing
them to the model to avoid cross-server name collisions — typically as
mcp__<gateway>__<server>__omniroute_ccr_retrieve, or with a dotted/slashed namespace prefix(
omniroute.omniroute_ccr_retrieve). Because the match was exact, a caller that is fullyMCP-capable — it CAN and WILL call the tool, just under a gateway-assigned namespaced name — was
treated as if it had no access at all. Per the #7746 safety guarantee this check gates
apply()itself, not just the injected instruction, so the entire CCR compression engine wassilently skipped for such callers.
Fixes both #13781 and #13897, which report the same root cause from two angles (tool-matching
too strict for MCP environments / protocol instruction never injected when the MCP gateway
namespaces tools).
Fix
Added
matchesCcrRetrieveToolName(): true on an exact match, or when the name ends with one ofthe separators
__,.,/,:immediately followed byomniroute_ccr_retrieve— aseparator-bounded trailing-segment match, never a bare substring/
.endsWith()test, so anear-miss like
omniroute_ccr_retrieve_v2still correctly does not match. Wired into both theflat and nested (
{type:"function",function:{name}}) branches ofcallerSupportsCcrRetrieve().Regression test — RED → GREEN
tests/unit/ccr-protocol-instruction.test.tsRED (confirmed against
origin/release/v3.8.51, unfixedprotocolInstruction.tsswapped back invia
git checkout -- <file>, never a branch switch — new test cases only):GREEN (fix restored):
Also re-ran the existing suite in full (all 11 cases, including the pre-existing
some_other_tool → NO instructionandno tools → NO instructioncases) and the relatedtests/unit/compression/ccr-non-mcp-full-prompt-loss-7746.test.ts(8/8) — both green, noregression to the #7746 safety guarantee.
Gates run
node --import tsx/esm --test tests/unit/ccr-protocol-instruction.test.ts— 11/11 passnode --import tsx/esm --test tests/unit/compression/ccr-non-mcp-full-prompt-loss-7746.test.ts— 8/8 passnode scripts/check/check-file-size.mjs— no violation on touched filesnode scripts/check/check-complexity.mjs— OK (2850 violations vs baseline 3218)node scripts/check/check-cognitive-complexity.mjs— OK (1289 violations vs baseline 1437)npm run typecheck:core— exit 0npm run check:open-sse-typecheck— OK, 0 pre-existing errorsnpx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files>— cleannode scripts/check/check-changelog-integrity.mjs— OKVerified the commit message and this PR body carry no AI-generation footer / Co-authored-by trailer.
Closes #13781
Closes #13897