Skip to content

fix!: narrow transport and MCP APIs and fix rmcp integration issues - #476

Open
benbrandt wants to merge 7 commits into
mainfrom
cleanup-transports-mcp
Open

benbrandt wants to merge 7 commits into
mainfrom
cleanup-transports-mcp

Conversation

@benbrandt

@benbrandt benbrandt commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

Part of the 5.0.0 public-API cleanup. This PR covers the HTTP crate, mcp_server, the rmcp crate, AcpAgent, and some cookbook/docs nits. Breaking changes are listed in md/migration-v5.md.

Addressed

  • F11 HttpClientError: now #[non_exhaustive] with rustdoc. Its causes use #[source] instead of #[from], and Display no longer repeats the source.
  • F76 CorsOptions: now an opaque struct built through its constructors. The Vec<HeaderValue> payload is no longer public. md/migration-config-api.md describes the 3.x enum and the v5 struct separately.
  • F43 The HTTP crate re-exports axum (server) and reqwest/url (client).
  • F14 Crate docs for the HTTP crate, plus AcpHttpServer rustdoc with a v1+v2 AgentProtocolRouter example and a # Panics section on into_router (covered by tests).
  • F17 EnabledTools is crate-private.
  • F77 enable_tool/disable_tool return a local UnknownToolError instead of a -32600 Error. ? still converts it.
  • F78 McpServerExt is sealed.
  • F47 McpConnectionContext::Acp is #[non_exhaustive].
  • F36 Builder-built servers report the builder name and a new McpServerBuilder::version (default 0.0.0) as serverInfo. The trace snapshot is updated.
  • F37 Builder tool errors, including bad arguments, become isError: true results. Unknown or disabled tools still get -32602. RegisteredMcpTool::call_tool reports bad arguments as -32602 instead of -32603, covered by a unit test.
  • F35 rmcp now picks the native MCP-over-ACP path from the core crate's feature, using a hidden __if_mcp_over_acp! macro. Its rustdoc says it is a stable cross-crate contract for 5.x, so renaming it is breaking. Fully un-gating the constructor isn't possible because McpService uses schema types that are only available behind unstable_mcp_over_acp.
  • F24 Dropped rmcp's no-op unstable_protocol_v2 feature. The v2 example gets the core feature through a dev-dependency.
  • F55 The tool_fn/tool_fn_mut builder examples compile, including the macro argument.
  • F09 AcpAgent::spawn_process is pub(crate).
  • F61 Removed the AcpAgent::claude_agent()/codex() presets, which ran unpinned @latest npx packages. The migration guide shows from_str with a pinned version.
  • F28 MatchDispatch::otherwise_ignore now answers unmatched requests with -32601. The examples use method_not_found(). Fixed the stale "no effect" and handle_if docs. The migration guide covers the change and its effect on v1::ActiveSession::read_to_string, where requests routed to the session that it does not handle now get -32601.
  • F56 The v1 permission recipe sends session/cancel before answering cancelled. It now compiles as a doctest.
  • F54 The custom handler recipe now says it parses a raw Dispatch as v1 types.
  • G84 The WebAssembly docs explain the Send requirement and how to keep !Send host values outside the connection.
  • Flaky test graceful_shutdown_sigkills_child_ignoring_sigterm: the scripts install the TERM trap before writing the PID file that starts shutdown, and the terminate window is now 1s (the test takes about 1.1s). 16 parallel runs under extra CPU load all passed.

Skipped

  • F66 (HTTP client constructor naming): the names already pair up consistently (new/builder for a base URL, with_endpoint/builder_with_endpoint for an exact URL, from_http_client for a prebuilt client). Renaming them would churn the docs and callers for little gain.

benbrandt and others added 7 commits October 31, 2026 10:55
…rate

- HttpClientError is #[non_exhaustive] with rustdoc on every variant. Its
  url and reqwest causes are #[source] instead of #[from], and Display no
  longer repeats the source.
- CorsOptions is an opaque struct built through its constructors, so
  the Vec<HeaderValue> payload is no longer public.
- Re-export axum, reqwest, and url, which appear in public signatures.
- Add crate docs and AcpHttpServer rustdoc, including a v1+v2
  AgentProtocolRouter example and a # Panics section on into_router,
  covered by tests.

BREAKING CHANGE: HttpClientError is non-exhaustive and no longer implements
From<url::ParseError> or From<reqwest::Error>. CorsOptions variants are no
longer public; use CorsOptions::disabled(), allow_origins(..), and
allow_any_origin().

Co-Authored-By: Claude <noreply@anthropic.com>
- Builder-built MCP servers report the builder name and a new
  McpServerBuilder::version (default 0.0.0) as serverInfo instead of rmcp.
- Tool errors, including arguments that do not match the input schema,
  become tools/call results with isError: true. Unknown or disabled tools
  still get -32602. RegisteredMcpTool::call_tool reports bad arguments as
  -32602 instead of -32603.
- The native MCP-over-ACP path follows the core crate's
  unstable_mcp_over_acp feature through a hidden __if_mcp_over_acp! macro,
  so enabling it only on agent-client-protocol no longer makes each request
  bridge a fresh rmcp service.
- EnabledTools is crate-private. enable_tool/disable_tool return
  UnknownToolError, a local error, instead of a -32600 Error.
- McpServerExt is sealed and McpConnectionContext::Acp is non_exhaustive.
- Drop rmcp's no-op unstable_protocol_v2 passthrough feature.
- Make the tool_fn/tool_fn_mut builder examples compile with their macro
  argument.

BREAKING CHANGE: EnabledTools is no longer exported. enable_tool and
disable_tool return UnknownToolError. McpServerExt is sealed.
McpConnectionContext::Acp is non_exhaustive. agent-client-protocol-rmcp no
longer has an unstable_protocol_v2 feature. Builder tool errors are now
isError results rather than JSON-RPC errors.

Co-Authored-By: Claude <noreply@anthropic.com>
- AcpAgent::spawn_process is pub(crate). It exposed async_process types
  from a private optional dependency and skipped the process-group guard.
- Remove AcpAgent::claude_agent() and AcpAgent::codex(), which ran
  unpinned npx @latest adapters. Use AcpAgent::from_str with a version.
- Shutdown test scripts install their TERM trap before writing the PID
  file that starts shutdown, and the SIGKILL test gives the trap a 1s
  terminate window, so a loaded machine still records SIGTERM.

BREAKING CHANGE: AcpAgent::spawn_process, AcpAgent::claude_agent, and
AcpAgent::codex are no longer public.

Co-Authored-By: Claude <noreply@anthropic.com>
MatchDispatch::otherwise_ignore dropped an unmatched request, which now
answers -32603. It answers -32601 instead, and still ignores unmatched
notifications and responses. The MatchDispatch and MatchDispatchFrom
examples use Error::method_not_found(), and the if_request /
if_notification docs describe what happens when params fail to parse
instead of saying the call has no effect or naming handle_if.

Co-Authored-By: Claude <noreply@anthropic.com>
…Send bounds

- The v1 permission recipe sends session/cancel before answering
  cancelled, like the v2 recipe, and now compiles as a doctest.
- The custom handler recipe says that it parses a raw Dispatch as v1
  types and only belongs on a v1 connection.
- The WebAssembly docs say that handlers, transports, and connection
  futures must be Send on every target and how to keep !Send host values
  outside the connection.

Co-Authored-By: Claude <noreply@anthropic.com>
Add a migration-v5 entry for MatchDispatch::otherwise_ignore answering
unmatched requests with -32601 and its effect on
v1::ActiveSession::read_to_string. Rewrite the CORS section of the config
migration guide so it no longer says the variants are still available.
Document __if_mcp_over_acp! as a stable cross-crate contract for 5.x, and
test that RegisteredMcpTool::call_tool reports bad arguments as -32602.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>

This branch has not been deployed

No deployments
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