Skip to content

feat(rmcp)!: move the rmcp integration behind a versioned rmcp_3 feature - #471

Merged
benbrandt merged 1 commit into
mainfrom
rmcp-versioned-features
Oct 30, 2026
Merged

benbrandt merged 1 commit into
mainfrom
rmcp-versioned-features

Conversation

@benbrandt

Copy link
Copy Markdown
Member

Summary

agent-client-protocol-rmcp now has one module per supported rmcp major version, each behind a matching Cargo feature, so future rmcp majors can land as minor releases instead of forcing an ACP major.

  • rmcp is now an optional dependency renamed to rmcp_3 (package = "rmcp", 3.4.0, server + schemars, same as the workspace entry). Feature rmcp_3 = ["dep:rmcp_3"]. No rmcp feature is on by default.
  • The whole integration (McpServerExt, McpServerBuilder, re-exports of McpTool, EnabledTools, tool_fn!, tool_fn_mut!) moves to agent_client_protocol_rmcp::rmcp_3. The crate root only holds docs, and nothing there depends on which rmcp features are on. Enabling a future rmcp_4 would only add an rmcp_4 module.
  • With no rmcp feature, the crate compiles as an empty crate, and its root docs say which feature to enable. There is no compile_error!.
  • The unstable_protocol_v2 and unstable_mcp_over_acp passthrough features are unchanged and apply to every rmcp module.
  • docs.rs: all-features = true plus --cfg docsrs, and a doc(cfg) badge on the module, the same setup as the core crate.

Naming: rmcp_3 for the feature, module and dependency

The crate's existing features are snake_case (unstable_mcp_over_acp, unstable_protocol_v2), so a hyphenated rmcp-3 would be the odd one out. Using one identifier for the feature, the module and the renamed dependency means cfg(feature = "rmcp_3"), rmcp_3::McpServerExt and dep:rmcp_3 all read the same and grep together. Inside the crate, each module file imports use ::rmcp_3 as rmcp;, so the existing rmcp:: paths are unchanged.

Tests and examples use a dev-dependency also named rmcp_3 (with macros), because Cargo rejects the same package under two names. Each one does extern crate rmcp_3 as rmcp; so rmcp's macros keep resolving.

Dependents

  • Conductor and cookbook dev-deps enable rmcp_3 and import from rmcp_3::. Their own direct rmcp dependencies are unchanged. Testy (agent-client-protocol-test) uses rmcp directly and not the integration crate, so it needs no change.
  • The ignore doctests in the core crate that mention the integration now use the new path.

Docs

  • The rmcp README has a feature/module table, a rewritten "Versioning" section (one module per rmcp major, no default, a new rmcp major is a minor release, dropping one is breaking and waits for an ACP major), and an adjusted "Why a Separate Crate?".
  • md/migration-v4.md has a new section on enabling rmcp_3, with the before/after import table.
  • design.md, features.md, transport-architecture.md and mcp-over-acp.md mention the feature, and the example commands include rmcp_3.
  • The .release-plz.toml comment now says rmcp majors arrive as features in minor releases.

CI

  • The default WASI check of the rmcp crate now passes --features rmcp_3; otherwise it would only check an empty crate.
  • The docs.rs build check also covers agent-client-protocol-rmcp.
  • just test also runs cargo test -p agent-client-protocol-rmcp --features rmcp_3, which covers the integration without the unstable passthrough features.

Test plan

  • cargo fmt -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings, plain cargo clippy -- -D warnings, and -p agent-client-protocol-rmcp --no-default-features (lib and all targets)
  • cargo hack check --workspace --feature-powerset --depth 2 --exclude-features default,unstable,wasm_js --no-dev-deps
  • cargo test --workspace --all-features --locked --no-fail-fast (only agent-client-protocol-derive --lib fails, a local dyld/runner issue that also happens on main)
  • cargo test -p agent-client-protocol-rmcp --features rmcp_3 --locked, and with no features
  • RUSTDOCFLAGS="-D warnings" cargo doc -p agent-client-protocol-rmcp, with all features and with none; nightly --cfg docsrs docs build
  • cargo check -p agent-client-protocol-rmcp --lib --target wasm32-wasip2 --features rmcp_3
  • mdbook build

agent-client-protocol-rmcp now exposes one module per supported rmcp major
version, each behind a matching Cargo feature. The rmcp 3.x integration
moves to the `rmcp_3` module, enabled by the `rmcp_3` feature, and rmcp
becomes an optional dependency renamed to `rmcp_3`. No rmcp feature is
enabled by default; without one the crate compiles as an empty crate.

The features are purely additive, so support for a future rmcp major
version can arrive as a new `rmcp_N` feature and module in a minor release.
The `unstable_protocol_v2` and `unstable_mcp_over_acp` passthrough features
apply to every rmcp module. docs.rs builds with all features and shows
feature badges.

The conductor and cookbook enable `rmcp_3`; CI checks the rmcp crate on WASI
with `rmcp_3`, checks its docs.rs build, and tests it without the unstable
passthrough features.

BREAKING CHANGE: enable the `rmcp_3` feature of agent-client-protocol-rmcp
and import its items from `agent_client_protocol_rmcp::rmcp_3` instead of the
crate root (`McpServerExt`, `McpServerBuilder`, `McpTool`, `EnabledTools`,
`tool_fn!`, `tool_fn_mut!`).

Co-Authored-By: Claude <noreply@anthropic.com>
@benbrandt
benbrandt merged commit 6b4d298 into main Oct 30, 2026
14 checks passed
@benbrandt
benbrandt deleted the rmcp-versioned-features branch October 30, 2026 22:30
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