agent_client_protocol/lib.rs
1#![deny(missing_docs)]
2
3//! # agent-client-protocol -- the Agent Client Protocol (ACP) SDK
4//!
5//! **agent-client-protocol** is a Rust SDK for building [Agent-Client Protocol (ACP)][acp] applications.
6//! ACP is a protocol for communication between AI agents and their clients (IDEs, CLIs, etc.),
7//! enabling features like tool use, permission requests, and streaming responses.
8//!
9//! [acp]: https://agentclientprotocol.com/
10//!
11//! ## What can you build with agent-client-protocol?
12//!
13//! - **Clients** that talk to ACP agents (like building your own Claude Code interface)
14//! - **Proxies** that add capabilities to existing agents (like adding custom tools via MCP)
15//! - **Agents** that respond to prompts with AI-powered responses
16//!
17//! ## Quick Start: Connecting to an Agent
18//!
19//! The most common use case is connecting to an existing ACP agent as a client.
20//! Here's a minimal example that initializes a connection, creates a session,
21//! and sends a prompt:
22//!
23//! ```no_run
24//! use agent_client_protocol::Client;
25//! use agent_client_protocol::schema::{InitializeRequest, ProtocolVersion};
26//!
27//! # async fn run(transport: impl agent_client_protocol::ConnectTo<agent_client_protocol::Client>) -> agent_client_protocol::Result<()> {
28//! Client.builder()
29//! .name("my-client")
30//! .connect_with(transport, async |cx| {
31//! // Step 1: Initialize the connection
32//! cx.send_request(InitializeRequest::new(ProtocolVersion::V1))
33//! .block_task().await?;
34//!
35//! // Step 2: Create a session and send a prompt
36//! cx.build_session_cwd()?
37//! .block_task()
38//! .run_until(async |mut session| {
39//! session.send_prompt("What is 2 + 2?")?;
40//! let response = session.read_to_string().await?;
41//! println!("{}", response);
42//! Ok(())
43//! })
44//! .await
45//! })
46//! .await
47//! # }
48//! ```
49//!
50//! For a complete working example, see [`yolo_one_shot_client.rs`][yolo].
51//!
52//! [yolo]: https://github.com/agentclientprotocol/rust-sdk/blob/main/src/agent-client-protocol/examples/yolo_one_shot_client.rs
53//!
54//! ## Cookbook
55//!
56//! The [`agent_client_protocol_cookbook`] crate contains practical guides and examples:
57//!
58//! - Connecting as a client
59//! - Global MCP server
60//! - Per-session MCP server with workspace context
61//! - Building agents and reusable components
62//! - Running proxies with the conductor
63//!
64//! [`agent_client_protocol_cookbook`]: https://docs.rs/agent-client-protocol-cookbook
65//!
66//! ## Core Concepts
67//!
68//! The [`concepts`] module provides detailed explanations of how agent-client-protocol works,
69//! including connections, sessions, callbacks, ordering guarantees, and more.
70//!
71//! ## Related Crates
72//!
73//! - [`agent-client-protocol-conductor`] - Binary for running proxy chains
74//!
75//! [`agent-client-protocol-conductor`]: https://crates.io/crates/agent-client-protocol-conductor
76
77/// Capability management for the `_meta.symposium` object
78mod capabilities;
79/// Component abstraction for agents and proxies
80pub mod component;
81/// Core concepts for understanding and using agent-client-protocol
82pub mod concepts;
83/// Cookbook of common patterns for building ACP components
84pub mod cookbook;
85/// JSON-RPC handler types for building custom message handlers
86pub mod handler;
87/// JSON-RPC connection and handler infrastructure
88mod jsonrpc;
89/// MCP server support for providing MCP tools over ACP
90pub mod mcp_server;
91/// Role types for ACP connections
92pub mod role;
93/// ACP protocol schema types - all message types, requests, responses, and supporting types
94pub mod schema;
95/// Utility functions and types
96pub mod util;
97
98pub use capabilities::*;
99
100/// JSON-RPC message types.
101///
102/// This module re-exports types from the `jsonrpcmsg` crate that are transitively
103/// reachable through the public API (e.g., via [`Channel`]).
104///
105/// Users of the `agent-client-protocol` crate can use these types without adding a direct dependency
106/// on `jsonrpcmsg`.
107pub mod jsonrpcmsg {
108 pub use jsonrpcmsg::{Error, Id, Message, Params, Request, Response};
109}
110
111pub use jsonrpc::{
112 Builder, ByteStreams, Channel, ConnectionTo, Dispatch, HandleDispatchFrom, Handled,
113 IntoHandled, JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse, Lines,
114 NullHandler, Responder, ResponseRouter, SentRequest, UntypedMessage,
115 run::{ChainRun, NullRun, RunWithConnectionTo},
116};
117
118pub use role::{
119 Role, RoleId, UntypedRole,
120 acp::{Agent, Client, Conductor, Proxy},
121};
122
123pub use component::{ConnectTo, DynConnectTo};
124
125// Re-export BoxFuture for implementing Component traits
126pub use futures::future::BoxFuture;
127
128// Re-export the six primary message enum types at the root
129pub use schema::{
130 AgentNotification, AgentRequest, AgentResponse, ClientNotification, ClientRequest,
131 ClientResponse,
132};
133
134// Re-export commonly used infrastructure types for convenience
135pub use schema::{Error, ErrorCode, Result};
136
137// Re-export derive macros for custom JSON-RPC types
138pub use agent_client_protocol_derive::{JsonRpcNotification, JsonRpcRequest, JsonRpcResponse};
139
140mod session;
141pub use session::*;
142
143mod acp_agent;
144pub use acp_agent::{AcpAgent, LineDirection};
145
146mod stdio;
147pub use stdio::Stdio;
148
149/// This is a hack that must be given as the final argument of
150/// [`McpServerBuilder::tool_fn`](`crate::mcp_server::McpServerBuilder::tool_fn`) when defining tools.
151/// Look away, lest ye be blinded by its vileness!
152///
153/// Fine, if you MUST know, it's a horrific workaround for not having
154/// [return-type notation](https://github.com/rust-lang/rust/issues/109417)
155/// and for [this !@$#!%! bug](https://github.com/rust-lang/rust/issues/110338).
156/// Trust me, the need for it hurts me more than it hurts you. --nikomatsakis
157#[macro_export]
158macro_rules! tool_fn_mut {
159 () => {
160 |func, params, context| Box::pin(func(params, context))
161 };
162}
163
164/// This is a hack that must be given as the final argument of
165/// [`McpServerBuilder::tool_fn`](`crate::mcp_server::McpServerBuilder::tool_fn`) when defining stateless concurrent tools.
166/// See [`tool_fn_mut!`] for the gory details.
167#[macro_export]
168macro_rules! tool_fn {
169 () => {
170 |func, params, context| Box::pin(func(params, context))
171 };
172}
173
174/// This macro is used for the value of the `to_future_hack` parameter of
175/// [`Builder::on_receive_request`] and [`Builder::on_receive_request_from`].
176///
177/// It expands to `|f, req, responder, cx| Box::pin(f(req, responder, cx))`.
178///
179/// This is needed until [return-type notation](https://github.com/rust-lang/rust/issues/109417)
180/// is stabilized.
181#[macro_export]
182macro_rules! on_receive_request {
183 () => {
184 |f: &mut _, req, responder, cx| Box::pin(f(req, responder, cx))
185 };
186}
187
188/// This macro is used for the value of the `to_future_hack` parameter of
189/// [`Builder::on_receive_notification`] and [`Builder::on_receive_notification_from`].
190///
191/// It expands to `|f, notif, cx| Box::pin(f(notif, cx))`.
192///
193/// This is needed until [return-type notation](https://github.com/rust-lang/rust/issues/109417)
194/// is stabilized.
195#[macro_export]
196macro_rules! on_receive_notification {
197 () => {
198 |f: &mut _, notif, cx| Box::pin(f(notif, cx))
199 };
200}
201
202/// This macro is used for the value of the `to_future_hack` parameter of
203/// [`Builder::on_receive_dispatch`] and [`Builder::on_receive_dispatch_from`].
204///
205/// It expands to `|f, dispatch, cx| Box::pin(f(dispatch, cx))`.
206///
207/// This is needed until [return-type notation](https://github.com/rust-lang/rust/issues/109417)
208/// is stabilized.
209#[macro_export]
210macro_rules! on_receive_dispatch {
211 () => {
212 |f: &mut _, dispatch, cx| Box::pin(f(dispatch, cx))
213 };
214}