Skip to content

Commit 8496eed

Browse files
authored
docs: update conductor and RMCP usage examples (#287)
1 parent 1616f70 commit 8496eed

5 files changed

Lines changed: 52 additions & 41 deletions

File tree

src/agent-client-protocol-conductor/src/conductor.rs

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -63,52 +63,50 @@
6363
//! Components are instantiated lazily when the first `initialize` request is received
6464
//! from the editor. This enables dynamic proxy chain construction based on client capabilities.
6565
//!
66-
//! ### Simple Usage
66+
//! ### Fixed Chains
6767
//!
68-
//! Pass a Vec of components that implement `Component`:
68+
//! Use [`ProxiesAndAgent`] to assemble a conductor that presents as an agent:
6969
//!
7070
//! ```ignore
71-
//! let conductor = Conductor::new(
71+
//! use agent_client_protocol_conductor::{ConductorImpl, ProxiesAndAgent};
72+
//!
73+
//! let conductor = ConductorImpl::new_agent(
7274
//! "my-conductor",
73-
//! vec![proxy1, proxy2, agent],
74-
//! None,
75+
//! ProxiesAndAgent::new(agent)
76+
//! .proxy(proxy1)
77+
//! .proxy(proxy2),
7578
//! );
7679
//! ```
7780
//!
78-
//! All components are spawned in order when the editor sends the first `initialize` request.
81+
//! A conductor that presents as a proxy takes only its internal proxies; its
82+
//! final successor is supplied when the conductor is connected:
7983
//!
80-
//! ### Dynamic Component Selection
84+
//! ```ignore
85+
//! use agent_client_protocol_conductor::ConductorImpl;
8186
//!
82-
//! Pass a closure to examine the `InitializeRequest` and dynamically construct the chain:
87+
//! let conductor = ConductorImpl::new_proxy("my-proxy-conductor", vec![proxy]);
88+
//! ```
8389
//!
84-
//! ```ignore
85-
//! let conductor = Conductor::new(
86-
//! "my-conductor",
87-
//! |cx, conductor_tx, init_req| async move {
88-
//! // Examine capabilities
89-
//! let needs_auth = has_auth_capability(&init_req);
90+
//! ### Dynamic Chain Selection
9091
//!
91-
//! let mut components = Vec::new();
92-
//! if needs_auth {
93-
//! components.push(spawn_auth_proxy(&cx, &conductor_tx)?);
94-
//! }
95-
//! components.push(spawn_agent(&cx, &conductor_tx)?);
92+
//! Both constructors also accept an instantiator closure. The closure receives
93+
//! the `InitializeRequest` and returns the possibly modified request together
94+
//! with type-erased connectors for the selected chain:
9695
//!
97-
//! // Return (potentially modified) request and component list
98-
//! Ok((init_req, components))
99-
//! },
100-
//! None,
101-
//! );
102-
//! ```
96+
//! ```ignore
97+
//! use agent_client_protocol::{Client, Conductor, DynConnectTo};
98+
//! use agent_client_protocol_conductor::ConductorImpl;
10399
//!
104-
//! The closure receives:
105-
//! - `cx: &ConnectionTo` - Connection context for spawning components
106-
//! - `conductor_tx: &mpsc::Sender<ConductorMessage>` - Channel for message routing
107-
//! - `init_req: InitializeRequest` - The Initialize request from the editor
100+
//! let conductor = ConductorImpl::new_agent("my-conductor", |init_req| async move {
101+
//! let mut proxies: Vec<DynConnectTo<Conductor>> = Vec::new();
102+
//! if has_auth_capability(&init_req) {
103+
//! proxies.push(DynConnectTo::new(make_auth_proxy()));
104+
//! }
108105
//!
109-
//! And returns:
110-
//! - Modified `InitializeRequest` to forward downstream
111-
//! - `Vec<ConnectionTo>` of spawned components
106+
//! let agent: DynConnectTo<Client> = DynConnectTo::new(make_agent());
107+
//! Ok((init_req, proxies, agent))
108+
//! });
109+
//! ```
112110
113111
use std::sync::Arc;
114112

src/agent-client-protocol-conductor/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitEx
8686
/// Wrapper for command-line component lists that can serve as either
8787
/// proxies-only (for proxy mode) or proxies+agent (for agent mode).
8888
///
89-
/// This exists because `AcpAgent` implements `Component<L>` for all `L`,
90-
/// so a `Vec<AcpAgent>` can be used as either a list of proxies or as
91-
/// proxies + final agent depending on the conductor mode.
89+
/// This exists because `AcpAgent` implements `ConnectTo<Client>` and
90+
/// `ConnectTo<Conductor>`, so a `Vec<AcpAgent>` can be used as either a list
91+
/// of proxies or as proxies + final agent depending on the conductor mode.
9292
#[derive(Debug)]
9393
pub struct CommandLineComponents(pub Vec<AcpAgent>);
9494

src/agent-client-protocol-rmcp/README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,20 @@ ACP-transport MCP servers.
2121
Use the `McpServerExt` trait to build an MCP server with tools:
2222

2323
```rust
24-
use agent_client_protocol::mcp_server::McpServer;
24+
use agent_client_protocol::{ConnectTo, mcp_server::McpServer, role::mcp};
2525
use agent_client_protocol_rmcp::McpServerExt;
2626

27-
let server = McpServer::builder("my-tools").build();
27+
async fn serve(
28+
client_transport: impl ConnectTo<mcp::Server>,
29+
) -> agent_client_protocol::Result<()> {
30+
let server = McpServer::<mcp::Client>::builder("my-tools").build();
31+
server.connect_to(client_transport).await
32+
}
2833
```
2934

35+
Choosing `mcp::Client` as the counterpart makes this a standalone MCP server
36+
that implements `ConnectTo<mcp::Client>`.
37+
3038
Or create an MCP server from an rmcp service:
3139

3240
```rust

src/agent-client-protocol-rmcp/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@
1111
//!
1212
//! Build an MCP server with tools using the extension trait:
1313
//!
14-
//! ```ignore
15-
//! use agent_client_protocol::mcp_server::McpServer;
14+
//! ```no_run
15+
//! use agent_client_protocol::{ConnectTo, mcp_server::McpServer, role::mcp};
1616
//! use agent_client_protocol_rmcp::McpServerExt;
1717
//!
18-
//! let server = McpServer::builder("my-tools").build();
18+
//! # async fn serve(
19+
//! # client_transport: impl ConnectTo<mcp::Server>,
20+
//! # ) -> agent_client_protocol::Result<()> {
21+
//! let server = McpServer::<mcp::Client>::builder("my-tools").build();
22+
//! server.connect_to(client_transport).await
23+
//! # }
1924
//! ```
2025
//!
2126
//! Or create an MCP server from an rmcp service:

src/agent-client-protocol/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub mod __private {
123123
pub use serde_json;
124124
}
125125

126-
// Re-export BoxFuture for implementing Component traits
126+
// Re-export BoxFuture for implementing SDK traits that return boxed futures.
127127
pub use futures::future::BoxFuture;
128128

129129
// Re-export commonly used infrastructure types for convenience

0 commit comments

Comments
 (0)