This chapter documents shared schema features, the proxy extension implemented
by the Rust SDK's conductor, and the opt-in native MCP-over-ACP transport.
The proxy methods are provisional SDK extensions. MCP-over-ACP is also
unstable and is available only with the unstable_mcp_over_acp feature.
Schema 1.12 exposes draft client-authored instructions with the
unstable_session_system_prompt feature. In v1, check
agentCapabilities.sessionCapabilities.systemPrompt; in v2, check
capabilities.session.systemPrompt. Omitted or null means unsupported.
An object advertises support for text content in append mode. Only request
override if the agent also advertises systemPrompt.mode.override.
Use the version's SystemPrompt::new builder and pass the complete request
through the SDK's _from session helpers:
use agent_client_protocol::schema::v1;
let instructions = v1::SystemPrompt::new(vec![
"Review changes without modifying files.".into(),
]);
let request = v1::NewSessionRequest::new("/workspace/project")
.system_prompt(instructions);
// After checking the agent's advertised capability:
// connection.build_session_from(request).block_task().start_session().await?;
# let _ = request;This snippet requires unstable_session_system_prompt; v2 additionally
requires unstable_protocol_v2 and uses the equivalent v2 types.
SystemPrompt::new defaults to append in Rust, but both mode and content
are required on the wire. Omitted or null systemPrompt supplies no client
instructions. Malformed values fail typed request decoding with -32602;
unknown modes are preserved for forwarding, not treated as append.
Clients should re-send the prompt on load (v1), resume, and fork. Agents that advertise support must apply a supplied prompt or reject the lifecycle operation, not silently create or restore a session without it. Override replaces agent-authored default instructions, not tools, permissions, or workspace instructions. Only supply content trusted at system-instruction precedence. Enabling the local Cargo feature does not advertise peer support.
| Method | JSON-RPC shape | Purpose |
|---|---|---|
_proxy/initialize |
request | Initialize a component as a proxy |
_proxy/successor |
request or notification | Forward one inner ACP message to the next component |
mcp/message |
request or notification | Invoke one MCP operation or carry its notification |
There are no separate request and notification method names for successor or
MCP message forwarding. The presence of an outer JSON-RPC id distinguishes a
request from a notification.
Transport frames carry protocol-neutral RawJsonRpcResponse values. Their
boxed RawJsonRpcError preserves numeric error codes, distinguishes omitted
data from explicit null, and retains error extension fields. Raw relays
should forward these values without ACP interpretation.
Typed ACP dispatch converts raw errors to Error explicitly using
RawJsonRpcError::into_acp_error; ACP error codes are interpreted at that
boundary and error extension fields are discarded. RawJsonRpcMessage::response
still accepts an ACP Result<Value, Error> and converts its error to the raw
representation. Other protocols should construct RawJsonRpcResponse directly.
The conductor sends _proxy/initialize to a component that has a successor.
Its parameters are the same fields as the normal InitializeRequest for the
selected ACP version. Receiving this method, rather than initialize, tells the
component that it is running as a proxy and may forward messages with
_proxy/successor.
The response is the matching version's normal InitializeResponse result. The
stable flat schema::InitializeProxyRequest type uses v1; with
unstable_protocol_v2, schema::v2::InitializeProxyRequest preserves the v2
request and response types. The final agent receives the ordinary initialize
method and does not need to understand the proxy extension.
_proxy/successor wraps one inner ACP method and its parameters. The inner
message is flattened into the outer parameters:
{
"jsonrpc": "2.0",
"id": 12,
"method": "_proxy/successor",
"params": {
"method": "session/prompt",
"params": {
"sessionId": "session-1",
"prompt": []
}
}
}The conductor unwraps the message and sends the inner request to the next
component. The outer response carries the inner request's result or error. To
forward an inner notification, omit the outer id; no response is produced.
Optional extension metadata may be included as _meta alongside the flattened
inner message.
Enable unstable_mcp_over_acp to use the draft native transport. A component
providing an MCP server adds McpServer::Acp to session setup requests
(session/new, session/load, session/resume, and the opt-in session/fork).
Its wire shape contains a human-readable name and an opaque server identifier:
{
"type": "acp",
"name": "project-tools",
"serverId": "mcp-server:01"
}serverId identifies the declared server and is used to route mcp/message
back to the component that provided it. A provider must not reuse one server ID
for multiple visible servers on the same ACP connection. The high-level
agent_client_protocol::mcp_server::McpServer APIs create this declaration
automatically.
An agent that consumes this transport advertises
agentCapabilities.mcpCapabilities.acp. If the final agent supports HTTP but
not ACP-transport MCP servers, place the MCP-over-ACP compatibility
bridge immediately before it.
An agent-to-provider request invokes one MCP operation. A provider-to-agent
notification belongs to that active operation. This is an ACP envelope choice,
not an MCP method-name convention: the outer id distinguishes message kind,
and inner methods such as tools/call and notifications/progress stay distinct.
Reverse requests are not part of this binding.
{
"jsonrpc": "2.0",
"id": 21,
"method": "mcp/message",
"params": {
"serverId": "mcp-server:01",
"requestId": "logical-request:01",
"method": "tools/call",
"params": {
"name": "example",
"arguments": {},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
}The logical ID stays stable through proxies; the outer ACP ID is hop-local.
Each inner request declares its version and capabilities. This binding exposes
MCP 2026-07-28 only, without initialize or a discovery prerequisite.
{
"jsonrpc": "2.0",
"id": 21,
"result": {
"result": { "content": [] }
}
}Successful ACP responses carry exactly one inner result or error.
An MCP error's code, omitted/null data, and extensions retain MCP meaning.
Outer ACP errors describe binding failures. MRTR's input_required remains an
inner result; subscriptions remain active requests with scoped notifications.
Cancellation uses ACP's existing best-effort mechanism. The Rust SDK supervises owned cleanup, but that stronger implementation behavior is not an extra requirement for advertising the transport capability.
See the native guide and migration guide. The previous connection IDs and connect/disconnect methods are removed.