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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ when both `unstable_protocol_v2` and `unstable_mcp_over_acp` are enabled:
supported session setup request, while
`V2SessionBuilder::with_mcp_server(...)` attaches a server to one new session
and `V2ResumeSessionBuilder::with_mcp_server(...)` attaches one while resuming.
Successful v2 attachments remain active for the connection lifetime, and both
builders expose `on_proxy_session_start` to forward proxied setup without
coupling later session events to that response.
With `unstable_session_fork`, `V2ForkSessionBuilder::with_mcp_server(...)`
attaches one while forking. Successful v2 attachments remain active for the
connection lifetime, and all three builders expose `on_proxy_session_start` to
forward proxied setup without coupling later session events to that response.

**Proxy orchestration**

Expand All @@ -50,8 +51,9 @@ coupling later session events to that response.
- **API reference** for individual crates is on [docs.rs/agent-client-protocol](https://docs.rs/agent-client-protocol).
- **Design and architecture documentation** lives in the mdbook at [agentclientprotocol.github.io/rust-sdk](https://agentclientprotocol.github.io/rust-sdk/). Source is in [`md/`](./md/).
- **Draft protocol v2** setup, version-typed connections, and high-level
session usage are covered in
[Protocol V2](./md/protocol-v2.md).
session usage are covered in [Protocol V2](./md/protocol-v2.md). To run a
complete v2 agent/client pair first, use the
[Runnable V2 Quickstart](./md/protocol-v2-quickstart.md).

`Client.builder()`, `Agent.builder()`, and `Proxy.builder()` remain stable-v1
entry points; their `.v2()` counterparts select the draft-v2 API. With
Expand All @@ -66,7 +68,7 @@ infrastructure can use `without_acp_version_guard`.
- [Clients](https://agentclientprotocol.com/overview/clients)
- Official Libraries
- **Kotlin**: [`acp-kotlin`](https://github.com/agentclientprotocol/kotlin-sdk) – supports JVM, other targets are in progress
- **Rust**: [`agent-client-protocol`](https://crates.io/crates/agent-client-protocol) - See the [agent](./src/agent-client-protocol/examples/simple_agent.rs) and [client](./src/agent-client-protocol/examples/yolo_one_shot_client.rs) examples
- **Rust**: [`agent-client-protocol`](https://crates.io/crates/agent-client-protocol) - See the stable-v1 [agent](./src/agent-client-protocol/examples/simple_agent.rs) and [client](./src/agent-client-protocol/examples/yolo_one_shot_client.rs), or the draft-v2 [agent](./src/agent-client-protocol/examples/simple_agent_v2.rs) and [client](./src/agent-client-protocol/examples/v2_one_shot_client.rs) examples
- **TypeScript**: [`@agentclientprotocol/sdk`](https://www.npmjs.com/package/@agentclientprotocol/sdk) - See [examples/](https://github.com/agentclientprotocol/typescript-sdk/tree/main/src/examples)
- [Community Libraries](https://agentclientprotocol.com/libraries/community)

Expand Down
1 change: 1 addition & 0 deletions md/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [Request Cancellation](./request-cancellation.md)
- [Configurable LLM Providers](./llm-providers.md)
- [Protocol V2](./protocol-v2.md)
- [Runnable V2 Quickstart](./protocol-v2-quickstart.md)

# Transports

Expand Down
12 changes: 8 additions & 4 deletions md/mcp-bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ initialization, capability, session setup, and `mcp/*` wire types. It does not
change the core attachment API. `Proxy.v2().with_mcp_server(...)` provides
connection-global attachment. `V2SessionBuilder::with_mcp_server(...)` and
`V2ResumeSessionBuilder::with_mcp_server(...)` provide per-session attachment
for new and resumed sessions respectively. The polyfill adapts their native
declarations when the final agent supports only HTTP MCP.
for new and resumed sessions respectively. With `unstable_session_fork`,
`V2ForkSessionBuilder::with_mcp_server(...)` provides per-session fork
attachment. The polyfill adapts their native declarations when the final agent
supports only HTTP MCP.

## Placement

Expand All @@ -60,8 +62,10 @@ setup requests as `McpServer::Acp`; callers do not need to construct a transport
placeholder themselves. In v2, `Proxy.v2().with_mcp_server(...)` provides
connection-global attachment. `V2SessionBuilder::with_mcp_server(...)` and
`V2ResumeSessionBuilder::with_mcp_server(...)` provide per-session attachment
for new and resumed sessions respectively. The polyfill translates those
native declarations at the final compatibility boundary.
for new and resumed sessions respectively. With `unstable_session_fork`,
`V2ForkSessionBuilder::with_mcp_server(...)` provides per-session fork
attachment. The polyfill translates those native declarations at the final
compatibility boundary.

During initialization, the polyfill forwards the request to its successor. When
the successor advertises HTTP MCP support, the polyfill advertises native ACP
Expand Down
9 changes: 5 additions & 4 deletions md/migration_v2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,11 @@ high-level server in the same place; the emitted declaration and wire methods ch
builder attachment advertises the same server ID on `session/new`, `session/load`,
`session/resume`, and feature-gated `session/fork`. Stable v1 per-session attachment remains
specific to `session/new`; draft v2 additionally supports per-session resume attachment through
`V2ResumeSessionBuilder::with_mcp_server`. Do not construct an HTTP server with an `acp:` URL. If
the final agent accepts HTTP but not native ACP MCP servers, insert `McpOverAcpPolyfill`
immediately before it. The polyfill now consumes native `McpServer::Acp` declarations and adapts
only its final-agent-facing side.
`V2ResumeSessionBuilder::with_mcp_server` and feature-gated fork attachment through
`V2ForkSessionBuilder::with_mcp_server`. Do not construct an HTTP server with an `acp:` URL. If the
final agent accepts HTTP but not native ACP MCP servers, insert `McpOverAcpPolyfill` immediately
before it. The polyfill now consumes native `McpServer::Acp` declarations and adapts only its
final-agent-facing side.

The polyfill's public `BridgeMode` enum and `McpOverAcpPolyfill::stdio` were removed because the
required conductor `mcp` helper subcommand no longer exists. The polyfill has one supported mode;
Expand Down
93 changes: 93 additions & 0 deletions md/protocol-v2-quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Runnable Protocol V2 Quickstart

The core crate includes a small ACP v2 agent and client that run together over
stdio. Both are compiled examples behind the `unstable_protocol_v2` feature:

- [`simple_agent_v2.rs`](https://github.com/agentclientprotocol/rust-sdk/blob/main/src/agent-client-protocol/examples/simple_agent_v2.rs)
implements initialization and the complete baseline session lifecycle.
- [`v2_one_shot_client.rs`](https://github.com/agentclientprotocol/rust-sdk/blob/main/src/agent-client-protocol/examples/v2_one_shot_client.rs)
initializes the agent, creates a session, sends one prompt, renders text
output, waits for the matching session to become idle, and closes it.

## Run the pair

Build both examples from the repository root:

```bash
cargo build -p agent-client-protocol \
--features unstable_protocol_v2 \
--examples
```

Then point the client at the agent executable:

```bash
./target/debug/examples/v2_one_shot_client \
--command ./target/debug/examples/simple_agent_v2 \
"Hello from ACP v2"
```

The result shows the two independent parts of a v2 prompt:

```text
Prompt accepted; waiting for session output and completion...
Echo: Hello from ACP v2
Session is idle: Some(EndTurn)
```

The agent writes only JSON-RPC to stdout because ACP uses stdout as the wire.
Write logs and diagnostics to stderr when extending it.

## Client lifecycle

The client installs its `session/update` and `session/request_permission`
handlers before it opens a session. Permission requests are part of the
baseline client surface and have no capability marker; this non-interactive
example cancels them explicitly. It then follows this sequence:

1. Send `initialize` and verify that the agent advertised session support.
2. Send `session/new` and retain the returned command handle and session ID.
3. Send `session/prompt` and await its response. This only confirms acceptance.
4. Ignore queued updates for that new session until its foreground state becomes
`running`. The running update may already be queued when prompt acceptance
arrives.
5. Project subsequent message updates, and treat the next matching
`state_update` with `idle` as completion of foreground work. An idle update
queued before running is only the session's earlier ready state. Background
updates may still arrive afterward.
6. Send `session/close` when the client no longer needs the active session.

Real clients normally maintain one shared update projection for every session.
Do not install a temporary handler after sending a prompt: updates can arrive
before the prompt response and are not scoped to a prompt or turn ID.
Within that projection, message chunks append by `messageId`; a later message
snapshot with concrete content replaces the accumulated chunks, `null` clears
them, and omitted content preserves them. Rendering chunks and then rendering a
snapshot again would duplicate output.

## Agent lifecycle

Advertising `AgentCapabilities::session(SessionCapabilities::new())` commits an
agent to the baseline session surface. The example handles:

- `session/new`
- `session/list`
- `session/resume`
- `session/close`
- `session/prompt`
- `session/cancel`
- `session/update` notifications sent to the client

The prompt handler validates and marks the session busy, responds to
`session/prompt` immediately, and moves the actual work into a spawned task so
the connection can continue dispatching cancellation and other traffic. That
task sends the accepted user message, a running update, output, and finally an
idle update with a stop reason.

The example keeps history in memory and supports replay from the start before
the `session/resume` response. A production agent should replace this with
durable session storage, define its supported replay cursors, and make resource
cleanup and cancellation robust across process failure.

For the connection APIs, proxy routing, and compatibility details surrounding
these examples, continue with [Protocol V2](./protocol-v2.md).
Loading