Skip to content

feat(mcp): upgrade MCP infrastructure to rmcp 3.1.2 (MCP 2026-07-28) - #62

Merged
runyourempire merged 2 commits into
mainfrom
feat/rmcp-3-upgrade
Aug 11, 2026
Merged

feat(mcp): upgrade MCP infrastructure to rmcp 3.1.2 (MCP 2026-07-28)#62
runyourempire merged 2 commits into
mainfrom
feat/rmcp-3-upgrade

Conversation

@runyourempire

Copy link
Copy Markdown
Collaborator

Summary

Upgrades the entire MCP infrastructure two SDK major versions: rmcp 1.5.0 → 3.1.2. The embedded server now speaks the sessionless MCP 2026-07-28 protocol revision natively while remaining fully backward compatible with every legacy protocol version (2024-11-052025-06-18).

What changed

  • Transportwith_stateful_mode(false)with_legacy_session_mode(false) (rename, semantics preserved). Per SEP-2567, 2026-07-28 clients are always served statelessly — the 422 session-wedge class is now removed at the protocol level itself. stateless_protocol_metadata_required stays false, so header-less legacy clients are still treated as 2025-03-26. The Mcp-Session-Id: stateless backfill for old strict CLIs is unchanged.
  • Handler — MRTR-aware returns (call_toolCallToolResponse, read_resourceReadResourceResponse); centralized redaction applies to the Complete variant. subscribe/unsubscribe kept for legacy clients under #[allow(deprecated)] (capability still not advertised).
  • Content modelContent/RawContent → flat ContentBlock; RawResourceResource builder.
  • Optimization (SEP-2549)tools/list / resources/list stamp ttlMs: 300000 + cacheScope: "private" (both lists are static for the process lifetime). A new regression test pins the exact legacy-peer wire behavior: resultType stripped by rmcp, cache hints ride along as ignored extra fields.
  • Gate tooling fix (separate commit)tools/test-install-gate.sh failed closed on every push from a linked worktree: its git rev-parse --show-toplevel ROOT lookup dies under WSL-style bash because a Windows-created worktree's .git file points at a Windows-native D:/... gitdir. ROOT now derives from the script's own location + hook-exported git env is scrubbed. Verified in WSL bash (with/without hook env) and Git Bash.

Compatibility

  • cargo semver-checks vs the published 0.8.7 baseline: no semver update required → stays in ^0.8; consumers (4DA) pick it up automatically. The 0.8.0 decision to make MCP param types pub(crate) is exactly why this two-major SDK jump is invisible to consumers.
  • All 0.8.4 stateless-422 + backfill guard tests pass unchanged; legacy stateful sessions (build_app_stateful) still work; REST /api/tools, auth/rate-limit/origin/DNS-rebinding middleware, CLI bridge, and victauri-test client untouched.

Gate (local, all green)

cargo fmt --check · clippy --all-targets zero warnings (default / no-default-features / release) · 1,634 workspace tests + 1 new, 0 failures (incl. bridge e2e) · cargo doc -D warnings · scripts/preflight.ps1 PASSED · cargo semver-checks

⚠ Post-merge note for maintainers

tools/test-install-gate.sh is integrity-pinned: after merging, re-run bash tools/install-gate.sh once to re-pin the updated file (the gate will fail closed until then — by design).

🤖 Generated with Claude Code

https://claude.ai/code/session_01KSa8Fdy8xgexFYYx47DkAg

audit and others added 2 commits August 11, 2026 13:17
Two-SDK-major jump (rmcp 1.5.0 -> 3.1.2). The embedded server now speaks
the sessionless MCP 2026-07-28 revision natively while staying fully
backward compatible with every legacy protocol version:

- Transport: with_stateful_mode(false) -> with_legacy_session_mode(false)
  (rename, semantics preserved). Per SEP-2567, 2026-07-28 clients are
  ALWAYS served statelessly - the 422 session-wedge class is now removed
  at the protocol level itself. stateless_protocol_metadata_required stays
  false so header-less legacy clients are still treated as 2025-03-26.
  The Mcp-Session-Id "stateless" backfill for old strict CLIs is unchanged.
- Handler: MRTR-aware returns (call_tool -> CallToolResponse, read_resource
  -> ReadResourceResponse); redaction applies to the Complete variant.
  subscribe/unsubscribe kept for legacy clients under allow(deprecated).
- Content model: Content/RawContent -> ContentBlock, RawResource ->
  Resource builder (annotation wrapper dropped).
- Optimization (SEP-2549): tools/list + resources/list stamp
  ttlMs=300000 + cacheScope=private (both lists are static for the
  process lifetime). New regression test pins the legacy-peer wire
  behavior: resultType stripped, cache hints ride along as ignored
  extra fields.

Gate: fmt clean; clippy --all-targets zero warnings (default,
no-default-features, release); 1,634 workspace tests + new test, 0
failures (incl. all 0.8.4 stateless-422/backfill guards, legacy stateful
sessions, bridge e2e); cargo doc -D warnings; preflight.ps1 PASSED;
cargo semver-checks vs published 0.8.7: no semver update required ->
stays in ^0.8, consumers pick it up automatically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KSa8Fdy8xgexFYYx47DkAg
The pre-push gate failed closed on every push from a linked worktree while
passing in the main tree. Root cause (traced, not guessed): the script
derived ROOT via `git rev-parse --show-toplevel`, but a Windows-created
linked worktree's `.git` FILE points at a Windows-native `D:/...` gitdir
that WSL git treats as a relative path -> exit 128 "not a git repository".
Same Windows-native-path class the 0.8.7 audit fixed in install-gate.sh.

- ROOT now derives from the script's own location (it is only a source
  tree / scratch anchor, never a git repo) - no git needed, works in main
  tree and linked worktrees under WSL bash and Git Bash alike.
- Also scrub hook-exported git env (GIT_DIR & friends) so scratch-repo
  git calls can never be poisoned by the invoking hook's repo context.

Verified: exit 0 under WSL bash with hook-style GIT_DIR (was 128), WSL
bash plain, and Git Bash; the R7 symlink case now runs under WSL instead
of being skipped, and correctly refuses.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KSa8Fdy8xgexFYYx47DkAg
@runyourempire
runyourempire merged commit 5fa1445 into main Aug 11, 2026
40 of 42 checks passed
@runyourempire
runyourempire deleted the feat/rmcp-3-upgrade branch August 11, 2026 04:08
runyourempire added a commit that referenced this pull request Aug 11, 2026
Lockfile-only freshening (requirement stays "2"; no manifest change, so
consumers are unaffected). Brings ~4 months of upstream fixes to the CI
and dev builds, including tauri 2.11.3's IPC channel mutex-locking
adjustments - relevant because PR #62's CI surfaced one intermittent
firing of the known upstream Rc<Webview> reload race on WebKitGTK
(webview_reload_during_introspection_is_safe, 1-in-2 on that PR, 0-in-10
on recent main; green on rerun of the same SHA). The E2E matrix guards
this change on all three platforms.

Gate: build + clippy --all-targets zero warnings + full workspace tests
0 failures + fmt clean against 2.11.5 (tao 0.35, wry 0.55).


Claude-Session: https://claude.ai/code/session_01KSa8Fdy8xgexFYYx47DkAg

Co-authored-by: audit <audit@example.test>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
runyourempire added a commit that referenced this pull request Aug 11, 2026
…ive-verified (#65)

Version bump 0.8.7 -> 0.8.8 across the workspace (bump script + manual:
server.json, which the script does not cover and which was still at 0.8.6
- missed by the 0.8.7 release; vscode extension to 0.8.8).

Release-prep adversarial sweep applied on top of the merged train
(#62 rmcp 3.1.2, #63 tauri 2.11.5 lock, #64 checkpoint fix):
- Fixed stale session-era claims in faq/testing/architecture/
  getting-started docs, victauri-test rustdoc, and the CLI init template
  (the transport is stateless by default; 2026-07-28 removes sessions).
- Fixed two stale "31 tools" counts (plugin README, agent-session
  example) and the "subscribable resources" claim (subscribe was never
  advertised and is legacy-only); documented the new SEP-2549 cache
  hints; refreshed stale sample versions.
- build_app_stateful doc notes 2026-07-28 clients are always sessionless.

Adversarial verification before this release: zero stale rmcp-1.5 API
refs in code; tools_fallback.json verified at 35 entries; JS log
timestamps verified integer Date.now() everywhere (checkpoint-fix
soundness); privacy config verified init-only (list-TTL soundness);
REAL stdio bridge e2e vs the new server for BOTH the shipped 0.8.6 CLI
and this tree's CLI (initialize/tools-list/tool-calls + identity
selection across two live apps) - all pass.

Gate: fmt clean; clippy --all-targets 0 warnings (default, no-default,
release); full workspace tests 0 failures; cargo doc -D warnings clean;
cargo semver-checks: no semver update required (x3 crates);
cargo package OK for all leaf crates (dependents blocked only on the
not-yet-published 0.8.8 core - expected pre-publish ordering).


Claude-Session: https://claude.ai/code/session_01KSa8Fdy8xgexFYYx47DkAg

Co-authored-by: audit <audit@example.test>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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