anthropic_agent_sdk/lib.rs
1//! # Claude Agent SDK for Rust
2//!
3//! Rust SDK for building AI agents powered by Claude Code.
4//! Async/await, strong typing, tokio-based.
5//!
6//! ## Quick Start
7//!
8//! Basic usage with [`query()`]:
9//!
10//! ```no_run
11//! use anthropic_agent_sdk::query;
12//! use futures::StreamExt;
13//!
14//! #[tokio::main]
15//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
16//! let stream = query("What is 2 + 2?", None).await?;
17//! let mut stream = Box::pin(stream);
18//!
19//! while let Some(message) = stream.next().await {
20//! match message? {
21//! anthropic_agent_sdk::Message::Assistant { message, .. } => {
22//! println!("Claude: {:?}", message);
23//! }
24//! _ => {}
25//! }
26//! }
27//! Ok(())
28//! }
29//! ```
30//!
31//! ## Core Features
32//!
33//! ### 1. Simple Queries with [`query()`]
34//!
35//! For one-shot interactions where you don't need bidirectional communication:
36//!
37//! ```no_run
38//! # use anthropic_agent_sdk::{query, ClaudeAgentOptions};
39//! # use futures::StreamExt;
40//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
41//! let options = ClaudeAgentOptions::builder()
42//! .system_prompt("You are a helpful coding assistant")
43//! .max_turns(5)
44//! .build();
45//!
46//! let stream = query("Explain async/await in Rust", Some(options)).await?;
47//! # Ok(())
48//! # }
49//! ```
50//!
51//! ### 2. Interactive Client with [`ClaudeSDKClient`]
52//!
53//! For stateful conversations with bidirectional communication:
54//!
55//! ```no_run
56//! # use anthropic_agent_sdk::{ClaudeSDKClient, ClaudeAgentOptions};
57//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
58//! let options = ClaudeAgentOptions::builder()
59//! .max_turns(10)
60//! .build();
61//!
62//! let mut client = ClaudeSDKClient::new(options, None).await?;
63//! client.send_message("Hello, Claude!").await?;
64//!
65//! while let Some(message) = client.next_message().await {
66//! // Process messages...
67//! }
68//!
69//! client.close().await?;
70//! # Ok(())
71//! # }
72//! ```
73//!
74//! ### 3. MCP Tools with rmcp
75//!
76//! Create custom MCP tools that Claude can discover and use. Enable the `rmcp` feature
77//! to use the official [rmcp](https://crates.io/crates/rmcp) crate:
78//!
79//! ```ignore
80//! use anthropic_agent_sdk::mcp::{
81//! tool, tool_router, tool_handler, Parameters, ServerCapabilities, ServerHandler,
82//! ServerInfo, ToolRouter,
83//! };
84//! use schemars::JsonSchema;
85//! use serde::Deserialize;
86//!
87//! #[derive(Deserialize, JsonSchema)]
88//! struct AddParams {
89//! /// First number
90//! a: f64,
91//! /// Second number
92//! b: f64,
93//! }
94//!
95//! #[derive(Clone)]
96//! struct Calculator { tool_router: ToolRouter<Self> }
97//!
98//! #[tool_router]
99//! impl Calculator {
100//! fn new() -> Self { Self { tool_router: Self::tool_router() } }
101//!
102//! #[tool(description = "Add two numbers")]
103//! fn add(&self, Parameters(params): Parameters<AddParams>) -> String {
104//! format!("{} + {} = {}", params.a, params.b, params.a + params.b)
105//! }
106//! }
107//!
108//! #[tool_handler]
109//! impl ServerHandler for Calculator {
110//! fn get_info(&self) -> ServerInfo {
111//! ServerInfo {
112//! capabilities: ServerCapabilities::builder().enable_tools().build(),
113//! ..Default::default()
114//! }
115//! }
116//! }
117//! ```
118//!
119//! See `examples/mcp_server.rs` for a complete demo.
120//!
121//! ### 4. Hooks for Custom Behavior
122//!
123//! Intercept and modify tool execution:
124//!
125//! ```no_run
126//! # use anthropic_agent_sdk::{ClaudeAgentOptions, HookManager, HookEvent, HookOutput};
127//! # use anthropic_agent_sdk::hooks::HookMatcherBuilder;
128//! # use std::collections::HashMap;
129//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
130//! let hook = HookManager::callback(|event_data, tool_name, _context| async move {
131//! println!("Tool used: {:?}", tool_name);
132//! Ok(HookOutput::default())
133//! });
134//!
135//! let matcher = HookMatcherBuilder::new(Some("*"))
136//! .add_hook(hook)
137//! .build();
138//!
139//! let mut hooks = HashMap::new();
140//! hooks.insert(HookEvent::PreToolUse, vec![matcher]);
141//!
142//! let options = ClaudeAgentOptions::builder()
143//! .hooks(hooks)
144//! .build();
145//! # Ok(())
146//! # }
147//! ```
148//!
149//! See the [`hooks`] module for more details.
150//!
151//! ### 5. Permission Control
152//!
153//! Control which tools Claude can use and how:
154//!
155//! ```no_run
156//! # use anthropic_agent_sdk::{ClaudeAgentOptions, PermissionManager};
157//! # use anthropic_agent_sdk::types::{PermissionResult, PermissionResultAllow, PermissionResultDeny};
158//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
159//! let permission_callback = PermissionManager::callback(
160//! |tool_name, _tool_input, _context| async move {
161//! match tool_name.as_str() {
162//! "Read" | "Glob" => Ok(PermissionResult::Allow(PermissionResultAllow {
163//! updated_input: None,
164//! updated_permissions: None,
165//! })),
166//! _ => Ok(PermissionResult::Deny(PermissionResultDeny {
167//! message: "Tool not allowed".to_string(),
168//! interrupt: false,
169//! }))
170//! }
171//! }
172//! );
173//!
174//! let options = ClaudeAgentOptions::builder()
175//! .can_use_tool(permission_callback)
176//! .build();
177//! # Ok(())
178//! # }
179//! ```
180//!
181//! See the [`permissions`] module for more details.
182//!
183//! ## Architecture
184//!
185//! The SDK is organized into several key modules:
186//!
187//! - [`types`]: Core type definitions, identifiers, and builders
188//! - [`query()`]: Simple one-shot query function
189//! - [`client`]: Interactive bidirectional client
190//! - [`mcp`]: SDK MCP server for custom tools
191//! - [`hooks`]: Hook system for intercepting events
192//! - [`permissions`]: Permission control for tool usage
193//! - [`transport`]: Communication layer with Claude Code CLI
194//! - [`control`]: Control protocol handler
195//! - [`message`]: Message parsing and types
196//! - [`error`]: Error types and handling
197//!
198//! ## Feature Flags
199//!
200//! This crate supports the following feature flags:
201//!
202//! - `rmcp` - Enables SDK MCP server support via the official rmcp crate
203//!
204//! ## Logging
205//!
206//! This crate uses [`tracing`](https://crates.io/crates/tracing) for structured logging.
207//! Tracing events are always emitted but are zero-cost when no subscriber is attached.
208//! To see logs, attach a tracing subscriber in your application:
209//!
210//! ```rust,ignore
211//! tracing_subscriber::fmt::init();
212//! ```
213//!
214//! ## Examples
215//!
216//! - `simple_query.rs` - Basic query usage
217//! - `interactive_client.rs` - Interactive REPL conversation
218//! - `bidirectional_demo.rs` - Concurrent operations
219//! - `hooks_demo.rs` - Hook system for tool interception
220//! - `permissions_demo.rs` - Permission control for tools
221//! - `mcp_server.rs` - MCP server with custom tools (requires `--features rmcp`)
222//! - `mcp_integration.rs` - Full E2E with Claude using MCP tools
223//! - `introspection_demo.rs` - Session info, models, commands, MCP status
224//! - `plan_mode_demo.rs` - Plan mode with approval workflow
225//! - `oauth_demo.rs` - OAuth authentication with PKCE
226//!
227//! Run examples with:
228//! ```bash
229//! cargo run --example simple_query
230//! cargo run --example oauth_demo
231//! cargo run --example mcp_server --features rmcp
232//! ```
233//!
234//! ## Requirements
235//!
236//! - Rust 1.85.0 or later
237//! - Node.js (for Claude Code CLI)
238//! - Claude Code: `npm install -g @anthropic-ai/claude-code`
239//!
240//! ## Error Handling
241//!
242//! All fallible operations return [`Result<T, ClaudeError>`](Result):
243//!
244//! ```no_run
245//! # use anthropic_agent_sdk::{query, ClaudeError};
246//! # async fn example() {
247//! match query("Hello", None).await {
248//! Ok(stream) => { /* ... */ }
249//! Err(ClaudeError::CliNotFound(msg)) => {
250//! eprintln!("Claude Code not installed: {}", msg);
251//! }
252//! Err(e) => {
253//! eprintln!("Error: {}", e);
254//! }
255//! }
256//! # }
257//! ```
258//!
259//! ## Safety and Best Practices
260//!
261//! - **No unsafe code** - The SDK is 100% safe Rust
262//! - **Type safety** - Newtypes prevent mixing incompatible values
263//! - **Async/await** - Built on tokio for efficient concurrency
264//! - **Resource management** - Proper cleanup via RAII and Drop
265//! - **Error handling** - Typed errors with context
266//!
267//! ## Security
268//!
269//! - **Environment variable filtering** - Dangerous variables like `LD_PRELOAD`, `PATH`, `NODE_OPTIONS` are blocked
270//! - **Callback timeouts** - Hook and permission callbacks have configurable timeouts (default 60 seconds)
271//! - **Buffer limits** - Configurable max buffer size (default 1MB) prevents memory exhaustion
272//! - **Cancellation support** - Callbacks receive cancellation tokens for graceful abort
273//!
274//! For complete security details, see `SECURITY.md` in the repository.
275//!
276//! ## Version History
277//!
278//! - **0.2.0** (Current) - TypeScript SDK parity release
279//! - MCP integration via official rmcp crate
280//! - Hooks, introspection, runtime setters
281//! - Plan mode, slash commands, skills support
282//! - Model usage tracking, permission denials
283//!
284//! - **0.1.0** - Initial release
285//! - `query()` function for simple queries
286//! - `ClaudeSDKClient` for bidirectional communication
287//! - Hook system for event interception
288//! - Permission control for tool usage
289
290#![warn(missing_docs)]
291#![warn(clippy::all)]
292
293pub mod auth;
294pub mod callbacks;
295pub mod client;
296pub mod control;
297pub mod error;
298pub mod hooks;
299pub mod mcp;
300pub mod message;
301pub mod permissions;
302pub mod query;
303pub mod transport;
304pub mod types;
305pub mod utils;
306
307// Re-export commonly used types
308pub use callbacks::{
309 FnHookCallback, FnPermissionCallback, HookCallback, PermissionCallback, SharedHookCallback,
310 SharedPermissionCallback,
311};
312pub use client::ClaudeSDKClient;
313pub use error::{ClaudeError, Result};
314pub use futures::StreamExt;
315pub use hooks::{HookManager, HookMatcherBuilder};
316pub use message::parse_message;
317pub use permissions::{PermissionManager, PermissionManagerBuilder};
318pub use query::query;
319pub use transport::{
320 MIN_CLI_VERSION, PromptInput, SubprocessTransport, Transport, check_claude_version,
321};
322pub use types::{
323 AgentDefinition, CanUseToolCallback, ClaudeAgentOptions, ClaudeAgentOptionsBuilder,
324 ContentBlock, ContentValue, HookContext, HookDecision, HookEvent, HookMatcher, HookOutput,
325 McpHttpServerConfig, McpServerConfig, McpServers, McpSseServerConfig, McpStdioServerConfig,
326 Message, OutputFormat, PermissionBehavior, PermissionMode, PermissionRequest, PermissionResult,
327 PermissionResultAllow, PermissionResultDeny, PermissionRuleValue, PermissionUpdate,
328 PermissionUpdateDestination, RequestId, SdkMcpServerConfig, SessionId, SettingSource,
329 SystemPrompt, SystemPromptPreset, ToolName, ToolPermissionContext, UsageData, UsageLimit,
330 UserContent,
331};
332
333/// Version of the SDK
334pub const VERSION: &str = env!("CARGO_PKG_VERSION");