Skip to content

Switch to upstream rmcp.#10754

Open
vorporeal wants to merge 4 commits into
masterfrom
david/switch-to-upstream-rmcp
Open

Switch to upstream rmcp.#10754
vorporeal wants to merge 4 commits into
masterfrom
david/switch-to-upstream-rmcp

Conversation

@vorporeal
Copy link
Copy Markdown
Contributor

@vorporeal vorporeal commented May 12, 2026

Description

Switches Warp from our fork of rmcp back to the upstream crates.io release so we no longer have to carry and maintain a fork just for Warp-specific compatibility.

Our fork primarily existed because older upstream rmcp supported the legacy SSE client transport that some MCP servers still rely on, but current upstream releases no longer include that transport. To preserve compatibility while using upstream rmcp, this PR adds a small local mcp workspace crate that contains the old upstream SSE transport implementation (SseClientTransport, reconnect handling, reqwest integration, and auth integration), copied from an earlier version of upstream rmcp under its Apache-2.0 license with attribution in the copied files.

This also updates Warp's MCP integration for the newer upstream APIs and related dependency changes:

  • Replace the forked rmcp git dependency with upstream rmcp = "1.6".
  • Add crates/mcp to host the legacy SSE transport shim used by Warp.
  • Update MCP tool/resource call sites and capability builders for upstream rmcp API changes.
  • Update the reqwest integration for the newer reqwest API.
  • Persist the full upstream StoredCredentials shape for MCP OAuth so refreshed tokens, token_received_at, and DCR client secrets survive restarts.
  • Preserve existing refresh tokens when an OAuth refresh response omits a replacement refresh token.

Testing

  • cargo check -p warp passes.

  • Added/updated unit coverage for MCP OAuth credential deserialization, token timestamp persistence, skipped empty-token persistence, and refresh-token carry-forward behavior.

  • Updated MCP capability helper tests for the upstream builder-style APIs.

  • Manually tested MCP server connections using the legacy SSE transport with a local build.

  • I have manually tested my changes locally with ./script/run

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Co-Authored-By: Oz oz-agent@warp.dev

@cla-bot cla-bot Bot added the cla-signed label May 12, 2026
Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@vorporeal vorporeal force-pushed the david/switch-to-upstream-rmcp branch from 9b73bb4 to 6f53c6d Compare May 12, 2026 23:37
@vorporeal vorporeal marked this pull request as ready for review May 12, 2026 23:44
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 12, 2026

@vorporeal

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR switches Warp to upstream rmcp and restores legacy SSE support in a new mcp crate.

Concerns

  • Clean SSE stream termination currently ends the transport instead of reconnecting, so normal idle timeouts or server restarts can leave MCP connections dead.
  • The new stream-error log includes the full SSE URI, which may contain query-string credentials or session tokens.

Security

  • Redact or omit the logged SSE URI before writing stream errors to logs.

Verdict

Found: 0 critical, 2 important, 1 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

retrying,
}
}
None => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] A clean EOF from the SSE response terminates the transport instead of using the retry policy; servers and proxies commonly close SSE connections normally during idle timeouts or restarts, leaving Warp permanently disconnected until the server is recreated.

last_event_id: Option<&str>,
) {
tracing::warn!(
uri = %self.uri,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] [SECURITY] This logs the full SSE URL on stream errors; MCP configs can carry tokens or session IDs in query parameters, so redact the query/userinfo or omit the URI before logging.

matches!(sse.event.as_deref(), None | Some("") | Some("message"));
if !is_message_event {
match this.connector.handle_control_event(&sse) {
Ok(()) => return self.poll_next(cx),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [SUGGESTION] [SECURITY] A server can keep this poll recursive by sending buffered control or malformed events; replace the self.poll_next(cx) recursion paths with a loop so untrusted SSE input cannot grow the stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant