feat: MCP SDK v2 migration with dual-era (2026-07-28 + legacy) support - #255
Conversation
|
Codex review: needs changes before merge. Reviewed August 2, 2026, 4:48 PM ET / 20:48 UTC. ClawSweeper reviewWhat this changesMigrates mcporter’s runtime and serving bridge to MCP SDK v2, adding automatic modern/legacy protocol negotiation, a per-server protocol-version override, and dual-era record/replay support. Merge readinessKeep open. This collaborator-authored PR remains necessary because current Priority: P2 Review scores
Verification
How this fits togetherMCPorter turns configured stdio, HTTP, and SSE MCP servers into CLI and TypeScript runtime calls, then can expose daemon-managed tools through its own MCP serve bridge. This change sits at the transport boundary where configuration selects a client protocol path before tool calls, OAuth, recording, replay, and served responses continue downstream. flowchart TD
Config[Configured MCP server] --> Mode[Protocol mode selection]
Mode --> Client[SDK v2 MCP client]
Client --> Probe[Modern discovery or legacy fallback]
Probe --> Remote[Remote MCP server]
Remote --> Runtime[Tool and resource runtime]
Runtime --> Bridge[CLI output and serve bridge]
Before merge
Findings
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Copy recommended automerge instructionTechnical reviewBest possible solution: Keep the v2 migration as the compatibility path, but correct all user-facing SDK-upstream tracking so it names the v2 package split and no longer directs debugging users to deleted local shims. Do we have a high-confidence way to reproduce the issue? Yes for the documentation defect: on the PR head, Is this the best way to solve the issue? No, not as submitted. The SDK v2 migration is aligned with MCPorter’s compatibility goal and has focused coverage, but the accompanying upstream-tracking documentation must describe the actual v2 dependency and debugging boundary. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 817843c5a4c0. LabelsLabel changes:
Label justifications:
EvidenceAcceptance criteria:
What I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cc78f5b93d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| let response = await client.request( | ||
| { method: 'resources/list', params: requestParams }, | ||
| specTypeSchemas.ListResourcesResult |
There was a problem hiding this comment.
Preserve empty resource lists for tool-only servers
When a server does not advertise the resources capability, v2 Client.listResources() intentionally returns { resources: [] }, but this new no-cursor path skips that wrapper and sends resources/list through client.request(). That request is still capability-checked, so mcporter resource <server>/runtime.listResources(server) now errors on tool-only servers instead of reporting no resources. Please keep the first page on client.listResources(requestParams) or explicitly return an empty list when resources are unsupported, then only use the low-level request loop after a real first page with nextCursor.
Useful? React with 👍 / 👎.
Migrates mcporter from
@modelcontextprotocol/sdkv1 to the SDK v2 packages (@modelcontextprotocol/client/@modelcontextprotocol/server2.0.0), bringing full dual-era protocol support: the new stateless MCP revision 2026-07-28 and every legacy era the v2 SDK negotiates (2024-10-07 through 2025-11-25).Highlights:
server/discoverprobe with byte-identical legacy fallback. New per-server config fieldprotocolVersion: "auto" | "legacy" | "2026-07-28"(schema regenerated).src/sdk-patches.tsis gone. The prototype monkey-patches (child reaping, stderr capture, tracing) are replaced by aMcporterStdioTransportsubclass built on v2's publicstderr/pid/teardown APIs. As a subclass, the negotiation probe runs in place on the live connection — no disposable sibling spawn per stdio connect (3s probe timeout).createMcpHandler: one HTTP endpoint serves 2026-07-28 clients and 2025-era clients side by side (stateless legacy fallback), stdio mode preserved,server__toolnaming/escaping unchanged. New test drives the bridge with a client pinned to2026-07-28.initialize) automatically force legacy negotiation on replay, so all existing recordings keep working.input_requiredresults surface as a clear "requires interactive input" error (interactive fulfilment lands in the next PR).list --verboseshows the negotiated protocol version/era. SDK v1 remains as a devDependency for legacy test fixtures only.Proof:
pnpm checkclean; full suite 917 passed / 3 skipped; autoreview clean (0.96). Rebased over the repo tooling cleanup on main.Part 2 of the MCP 2.0 series (after #254). Next: interactive elicitation/MRTR + OAuth hardening.
🤖 Generated with Claude Code