Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions md/conductor.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ adapted to HTTP. Keeping the polyfill explicit prevents instrumentation or
orchestration from silently changing session MCP declarations. See [MCP
Bridge](./mcp-bridge.md).

The polyfill supports v1 by default. For a draft-v2 chain, enable
`unstable_protocol_v2` on both the conductor and polyfill crates; without the
polyfill feature, it rejects v2 initialization instead of interpreting v2
traffic as v1.

## Tracing

The conductor can record an idealized logical sequence of ACP and MCP messages.
Expand Down
54 changes: 40 additions & 14 deletions md/mcp-bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ Native MCP-over-ACP requires the core SDK's `unstable_mcp_over_acp` feature. The
polyfill enables that feature on its core dependency, so applications using the
polyfill receive it through Cargo feature unification.

The polyfill supports stable protocol v1 by default. To place it in a draft-v2
conductor chain, enable `unstable_protocol_v2` on both the conductor and
polyfill dependencies:

```toml
agent-client-protocol-conductor = { version = "...", features = ["unstable_protocol_v2"] }
agent-client-protocol-polyfill = { version = "...", features = ["unstable_protocol_v2"] }
```

The feature makes this concrete compatibility proxy recognize v2
initialization, capability, session setup, and `mcp/*` wire types. It does not
add high-level v2 global MCP attachment or proxy-session helpers to the core
SDK; those remain v1-only.

## Placement

Insert the polyfill immediately before the final agent that lacks native
Expand All @@ -37,17 +51,23 @@ ConductorImpl::new_agent("conductor", components)
.await?;
```

The application proxy can attach a high-level
`agent_client_protocol::mcp_server::McpServer`. The SDK advertises it in
session setup requests as `McpServer::Acp`; callers do not need to construct a
transport placeholder themselves.
For v1, the application proxy can attach a high-level
`agent_client_protocol::mcp_server::McpServer`. The SDK advertises it in session
setup requests as `McpServer::Acp`; callers do not need to construct a transport
placeholder themselves. In a v2 chain, a version-aware proxy currently supplies
the `schema::v2::McpServer::Acp` declaration directly because the high-level
global proxy attachment helpers remain v1-only.

During initialization, the polyfill forwards the request to its successor and
sets `agentCapabilities.mcpCapabilities.acp` in the response seen upstream when
the successor advertises HTTP MCP support. In this chain position that
capability means the chain can consume native MCP-over-ACP declarations through
the adapter; it does not imply that the final agent implements the transport
itself.
During initialization, the polyfill forwards the request to its successor. When
the successor advertises HTTP MCP support, the polyfill advertises native ACP
MCP support in the response seen upstream:

- v1 sets `agentCapabilities.mcpCapabilities.acp` to `true`.
- v2 adds the `capabilities.session.mcp.acp` marker.

In this chain position that capability means the chain can consume native
MCP-over-ACP declarations through the adapter; it does not imply that the final
agent implements the transport itself.

If the successor already advertises native ACP MCP support, the polyfill leaves
the capability, declarations, and `mcp/message` traffic unchanged. If it
Expand All @@ -56,8 +76,8 @@ support and rejects any native declaration that is nevertheless supplied.

## Transformation

For each `McpServer::Acp` entry in `session/new`, `session/load`,
`session/resume`, or feature-gated `session/fork`, the polyfill:
For each schema-selected `McpServer::Acp` entry in a session setup request, the
polyfill:

1. Creates or reuses a connection-scoped localhost bridge endpoint for the
`serverId` and replaces the declaration with the HTTP transport for the
Expand All @@ -72,11 +92,17 @@ For each `McpServer::Acp` entry in `session/new`, `session/load`,
the connection from the bridge.

Enable the polyfill crate's `unstable_session_fork` feature when adapting fork
requests.
requests. Stable v1 setup includes `session/new`, `session/load`, and
`session/resume`; draft v2 includes `session/new` and `session/resume`. Both
versions include `session/fork` when `unstable_session_fork` is enabled.

Declarations using another transport are left unchanged, including extension
transports represented by v2's `McpServer::Other`.

Endpoints are cached by `serverId` across session setup requests on the ACP
connection. The output declaration is rebuilt for each occurrence, preserving
that occurrence's `name` and `_meta` even when its endpoint is reused.
that occurrence's `name`, `_meta`, and other unmodified extension fields even
when its endpoint is reused.

The native wire envelopes are documented in the [SDK Protocol
Reference](./protocol.md#native-mcp-over-acp).
Expand Down
15 changes: 15 additions & 0 deletions md/protocol-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,21 @@ validates the final agent's initialize response against that selection.
The proxy connection also routes v2 `session/new` requests and responses
without interpreting them as v1 payloads.

### MCP compatibility polyfill

The concrete
`agent_client_protocol_polyfill::mcp_over_acp::McpOverAcpPolyfill` can
participate in a v2 conductor chain when its `unstable_protocol_v2` feature is
enabled. It selects v1 or v2 from `_proxy/initialize`, uses that version's MCP
capability and wire types, and adapts native `McpServer::Acp` declarations in
v2 `session/new`, `session/resume`, and feature-gated `session/fork` requests.
Other declarations and unrelated request fields remain unchanged. See
[MCP-over-ACP Compatibility Bridge](./mcp-bridge.md) for placement and feature
configuration.

This feature extends the concrete compatibility proxy only. Global MCP
attachment and proxy-session helpers in the core SDK remain v1-only.

The SDK handles the `initialize` negotiation at the JSON-RPC boundary:

- A v2 client advertises protocol v2 as its latest supported version.
Expand Down
10 changes: 8 additions & 2 deletions src/agent-client-protocol-conductor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,15 @@ agent-client-protocol-test.workspace = true
yopo.workspace = true
expect-test.workspace = true
regex.workspace = true
rmcp = { workspace = true, features = ["client", "server", "transport-io", "transport-child-process"] }
rmcp = { workspace = true, features = [
"client",
"server",
"transport-io",
"transport-child-process",
"transport-streamable-http-client-reqwest",
] }
schemars.workspace = true
agent-client-protocol-polyfill.workspace = true
agent-client-protocol-polyfill = { workspace = true, features = ["unstable_protocol_v2"] }

[lints]
workspace = true
Loading