Repository navigation
docs(058): implementation plan for the MCP 2026-07-28 upgrade - #1202
Merged
Merged
Conversation
Related #532 Phase 0 + Phase 1 artifacts for spec 058, written from a verified probe of mark3labs/mcp-go v1.0.0 stable rather than from the beta-era spec text. ## What the probe established - Production code compiles unchanged on both editions. The only break is a test symbol: NewTestStreamableHTTPServer moved to server/servertest (32 call sites, 6 files). - The full internal/server suite under v1.0.0 fails on exactly the two known profile tests and nothing else, which closes the SC-008 question for that package. - Two statements in the spec's Dependency Gate are now stale: the v1.0.0 client is modern-first, not capped at 2025-11-25, and "zero compile errors" no longer holds for stable. ## Decisions recorded - Spec-057 conflict: Option A (the /mcp/p/<slug> URL path is already request-carried identity) plus two mandatory grafts — gate resolver tier 3 on the era, because stdio session ids are the constant "stdio" and the empty-id guard alone would let modern stdio requests persist a selection; and a list-only resolver, which also fixes a pre-existing FR-012 violation where prompts/list varies by connection after set_profile. - The library bump alone flips the upstream-facing default to 2026-07-28, so the plan pins both directions in the bump PR and lifts them separately. - FR-015/FR-016 cannot be satisfied through the v1.0.0 public client API: CallTool hard-wires the multi-round-trip loop and the single-shot entry points are unexported. The plan proposes detect-and-frame plus a spec amendment, and stops for ratification rather than implementing around it. - FR-018/SC-005 are vacuous today: mcpproxy proxies no resources. ## Two findings worth separate attention - Security: mcp-go keys in-flight cancellations as "<sessionID>:<requestID>", and every modern request has an empty session id, so two clients using the same JSON-RPC id can cancel each other's calls. Masked by the FR-028 pin; must be resolved before that pin lifts. - Spec-032 tool hashes are computed from the library-decoded schema, so a decoder change can re-flag unchanged tools as rug-pulls. Measured against a real 1096-tool database: zero exposure. Mitigation is a normalizer fix plus a guard test, not a migration.
Deploying mcpproxy-docs with
|
| Latest commit: |
56bbe22
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://fd589cf0.mcpproxy-docs.pages.dev |
| Branch Preview URL: | https://058-mcp-2026-upgrade.mcpproxy-docs.pages.dev |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 33781692949 --repo smart-mcp-proxy/mcpproxy-go
|
… breakdown Related #532 Applies the spec amendments the v1.0.0 probe made necessary, and turns the plan into 79 dependency-ordered tasks. ## Amendments (decided under the zero-interruption policy, rationale inline) - FR-015/FR-016: detect-and-frame. MRTR relay cannot be built on the v1.0.0 public client API — CallTool hard-wires the round-trip loop and the single-shot entry points are unexported — so the original text had no satisfying implementation. True relay becomes FR-016a, gated on upstream library changes, with a sealed-envelope design of record. - FR-016b (new): stop copying the upstream result envelope wholesale, or an upstream input_required marker reaches clients as mcpproxy's own. - FR-007: scoped to requests. No header path exists for notifications and mcpproxy originates none, so the original wording was untestable. - FR-018/SC-005: vacuous today; mcpproxy proxies no resources. Kept for future resource proxying rather than implemented as dead code. - FR-027: now names both hops. Under the original single-default reading the library bump alone would have violated it. - SC-006: the fetch-reduction clause is withdrawn as unmeasurable from mcpproxy's side; the hints-present half stands. - Dependency Gate: corrected the two claims the stable probe falsified. ## Task ordering Two constraints override raw priority. Both hops are pinned in Phase 2 before anything else, and US3 (stateless readiness) fully lands before US1 lifts the client-facing pin — lifting first would expose the cross-client cancellation collision to real users rather than to tests. The MVP is Phases 1-2: library current, wire provably unchanged, and two latent defects fixed. Increment 2 (US3) pays down FR-012/FR-013 debt that exists on main today, independent of ever serving the new protocol.
…jected Related #532 The amendments were cross-reviewed as the repo convention requires. The review confirmed two and rejected the reasoning behind three, plus one factual detail. Corrected here with the original claim and its withdrawal both left visible, so a later reader can see what was believed and why it was wrong. - FR-015/FR-016: the claim that MRTR relay "cannot be built on the public client API" was WRONG. SendRequest is exported on the transport interface, mcpproxy constructs that transport itself, and GetTransport returns it, so relay is buildable today. The decision to defer stands, but on cost — a second dispatch path bypassing everything internal/upstream/core layers on CallTool — not on impossibility. FR-016a now names the concrete starting point instead of a nonexistent blocker. - FR-007: both stated reasons were wrong. Static and func headers DO reach notifications through sendHTTP, and mcpproxy does originate one (notifications/initialized, sent by the library during the handshake). Only the per-method half is genuinely out of reach, because WithHTTPHeaderFunc takes a context and cannot know the method it is stamping. - SC-006: "unmeasurable from mcpproxy's side" was overstated. The existing AddBeforeAny hook sees every method and resolves a session, so a per-client tools/list counter would measure it. The counter and a baseline are missing, not the possibility. - FR-018: there are two AddResource call sites, not one. Both are schema compiler registrations, so the conclusion is unchanged. Confirmed unchanged: FR-027 (the constant really was redefined) and the FR-016b design (an empty ResultType is filled with "complete" by the decorator). Also recorded, because it cost a full review cycle: the first cross-review returned a FALSE CLEAN. It exited having auto-rejected its own reads of the module cache, so it verified nothing and its silence was indistinguishable from approval. Evidence had to be staged inside the repo before it could see anything. A cross-review that produced no verdict text has not run.
Related #532 The Phase 1-2 implementation review confirmed four findings. Two were fixed in the code; the other two are real but out of scope for a wire-inert bump, so they become US3 tasks rather than claims that they are "tracked" somewhere. - T036a: the era pin covers Streamable HTTP only. mcp-go has no stdio equivalent and the era is chosen per request by the shared handler, so a stdio client can opt into 2026-07-28 today. Not reachable by default, since config validation rewrites an empty listen address to the HTTP default. - T036b: nothing asserts the direct-mode handler calls proxyResultEnvelope, so FR-016b on /mcp/all rests on the call site staying as written. Reaching that handler needs the wired-proxy harness US3 builds. research.md gains D10 with the full outcome, including two things worth remembering about the review itself: the stdio gap was raised by four of six lenses at "major" before verification settled it at minor, and three verify agents died on API errors, so the confirmed set is a floor rather than a ceiling.
2 of 3 tasks
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.
Related #532
Phase 0 and Phase 1 artifacts for spec 058, written from a verified probe of
mark3labs/mcp-gov1.0.0 stable rather than from the beta-era spec text. Docs only, no code change.What the probe established
NewTestStreamableHTTPServermoved toserver/servertest(32 call sites, 6 files).internal/serversuite under v1.0.0 fails on exactly the two known profile tests and nothing else, which closes the SC-008 question for that package.2025-11-25, and "zero compile errors" no longer holds.Decisions recorded
Spec-057 conflict → Option A, plus two mandatory grafts. The
/mcp/p/<slug>URL path is already request-carried identity, so it survives the stateless era with no routing changes. The grafts: gate resolver tier 3 on the era, because stdio session ids are the constant"stdio"and the empty-id guard alone would let modern stdio requests persist a selection; and add a list-only resolver, which also fixes a pre-existing FR-012 violation whereprompts/listvaries by connection afterset_profile.The bump alone flips the upstream-facing default.
connection_lifecycle.go:19sendsmcp.LATEST_PROTOCOL_VERSION, now2026-07-28, so bumping the library makes mcpproxy speak the new protocol to every capable upstream before any of this work lands. The plan pins both directions in the bump PR and lifts them separately.FR-015/FR-016 cannot be satisfied through the v1.0.0 public client API.
CallToolhard-wires the multi-round-trip loop and the single-shot entry points are unexported, so a proxy cannot relay MRTR at all. The plan proposes detect-and-frame plus a spec amendment and stops for your ratification rather than implementing around an unratified MUST. FR-018/SC-005 are separately vacuous: mcpproxy proxies no resources.Two findings worth separate attention
"<sessionID>:<requestID>", and every modern request has an empty session id, so two clients that pick the same JSON-RPC id can cancel each other's calls. The FR-028 pin masks this today; it must be resolved before the pin lifts, and reported upstream.What I need from you
Ratify (or reject) the FR-015/FR-016 and FR-018 amendments.
speckit.tasksis blocked on that decision.