claude_code_agent_sdk/
lib.rs

1//! # Claude Agent SDK for Rust
2//!
3//! Rust SDK for interacting with Claude Code CLI, enabling programmatic access to Claude's
4//! capabilities with full bidirectional streaming support and 100% feature parity with the
5//! official Python SDK.
6//!
7//! ## Features
8//!
9//! - **Simple Query API**: One-shot queries with both collecting ([`query`]) and streaming ([`query_stream`]) modes
10//! - **Bidirectional Streaming**: Real-time streaming communication with [`ClaudeClient`]
11//! - **Dynamic Control**: Interrupt, change permissions, switch models mid-execution
12//! - **Hooks System**: Intercept and control Claude's behavior at runtime with 6 hook types
13//! - **Custom Tools**: In-process MCP servers with ergonomic [`tool!`](crate::tool) macro
14//! - **Plugin System**: Load custom plugins to extend Claude's capabilities
15//! - **Permission Management**: Fine-grained control over tool execution
16//! - **Cost Control**: Budget limits and fallback models for production reliability
17//! - **Extended Thinking**: Configure maximum thinking tokens for complex reasoning
18//! - **Session Management**: Resume, fork, and manage conversation sessions
19//! - **Multimodal Input**: Send images alongside text using base64 or URLs
20//!
21//! ## Quick Start
22//!
23//! ### Simple Query
24//!
25//! ```no_run
26//! use claude_agent_sdk_rs::{query, Message, ContentBlock};
27//!
28//! #[tokio::main]
29//! async fn main() -> anyhow::Result<()> {
30//!     // One-shot query that collects all messages
31//!     let messages = query("What is 2 + 2?", None).await?;
32//!
33//!     for message in messages {
34//!         if let Message::Assistant(msg) = message {
35//!             for block in &msg.message.content {
36//!                 if let ContentBlock::Text(text) = block {
37//!                     println!("Claude: {}", text.text);
38//!                 }
39//!             }
40//!         }
41//!     }
42//!
43//!     Ok(())
44//! }
45//! ```
46//!
47//! ### Streaming Query
48//!
49//! ```no_run
50//! use claude_agent_sdk_rs::{query_stream, Message, ContentBlock};
51//! use futures::StreamExt;
52//!
53//! #[tokio::main]
54//! async fn main() -> anyhow::Result<()> {
55//!     // Streaming query for memory-efficient processing
56//!     let mut stream = query_stream("Explain Rust ownership", None).await?;
57//!
58//!     while let Some(result) = stream.next().await {
59//!         let message = result?;
60//!         if let Message::Assistant(msg) = message {
61//!             for block in &msg.message.content {
62//!                 if let ContentBlock::Text(text) = block {
63//!                     println!("Claude: {}", text.text);
64//!                 }
65//!             }
66//!         }
67//!     }
68//!
69//!     Ok(())
70//! }
71//! ```
72//!
73//! ### Bidirectional Client
74//!
75//! ```no_run
76//! use claude_agent_sdk_rs::{ClaudeClient, ClaudeAgentOptions, Message, PermissionMode};
77//! use futures::StreamExt;
78//!
79//! #[tokio::main]
80//! async fn main() -> anyhow::Result<()> {
81//!     let options = ClaudeAgentOptions::builder()
82//!         .permission_mode(PermissionMode::BypassPermissions)
83//!         .max_turns(5)
84//!         .build();
85//!
86//!     let mut client = ClaudeClient::new(options);
87//!     client.connect().await?;
88//!
89//!     // Send query
90//!     client.query("What is Rust?").await?;
91//!
92//!     // Receive responses
93//!     {
94//!         let mut stream = client.receive_response();
95//!         while let Some(result) = stream.next().await {
96//!             match result? {
97//!                 Message::Assistant(msg) => {
98//!                     println!("Got assistant message");
99//!                 }
100//!                 Message::Result(_) => break,
101//!                 _ => {}
102//!             }
103//!         }
104//!     } // stream is dropped here
105//!
106//!     client.disconnect().await?;
107//!     Ok(())
108//! }
109//! ```
110//!
111//! ## Multimodal Input (Images)
112//!
113//! The SDK supports sending images alongside text in your prompts using structured content blocks.
114//! Both base64-encoded images and URL references are supported.
115//!
116//! ### Supported Formats
117//!
118//! - JPEG (`image/jpeg`)
119//! - PNG (`image/png`)
120//! - GIF (`image/gif`)
121//! - WebP (`image/webp`)
122//!
123//! ### Size Limits
124//!
125//! - Maximum base64 data size: 15MB (results in ~20MB decoded)
126//! - Large images may timeout or fail - resize before encoding
127//!
128//! ### Example: Query with Image
129//!
130//! ```no_run
131//! use claude_agent_sdk_rs::{query_with_content, UserContentBlock, Message, ContentBlock};
132//!
133//! #[tokio::main]
134//! async fn main() -> anyhow::Result<()> {
135//!     // For real usage, load and base64-encode an image file
136//!     // This example uses a pre-encoded 1x1 red PNG pixel
137//!     let base64_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
138//!
139//!     // Query with text and image
140//!     let messages = query_with_content(vec![
141//!         UserContentBlock::text("What color is this image?"),
142//!         UserContentBlock::image_base64("image/png", base64_data)?,
143//!     ], None).await?;
144//!
145//!     for message in messages {
146//!         if let Message::Assistant(msg) = message {
147//!             for block in &msg.message.content {
148//!                 if let ContentBlock::Text(text) = block {
149//!                     println!("Claude: {}", text.text);
150//!                 }
151//!             }
152//!         }
153//!     }
154//!
155//!     Ok(())
156//! }
157//! ```
158//!
159//! ### Example: Using Image URLs
160//!
161//! ```no_run
162//! use claude_agent_sdk_rs::{query_with_content, UserContentBlock};
163//!
164//! #[tokio::main]
165//! async fn main() -> anyhow::Result<()> {
166//!     let messages = query_with_content(vec![
167//!         UserContentBlock::text("Describe this architecture diagram"),
168//!         UserContentBlock::image_url("https://example.com/diagram.png"),
169//!     ], None).await?;
170//!
171//!     Ok(())
172//! }
173//! ```
174//!
175//! ### Example: Streaming with Images
176//!
177//! ```no_run
178//! use claude_agent_sdk_rs::{query_stream_with_content, UserContentBlock, Message, ContentBlock};
179//! use futures::StreamExt;
180//!
181//! #[tokio::main]
182//! async fn main() -> anyhow::Result<()> {
183//!     // Minimal 1x1 PNG for example purposes
184//!     let png_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
185//!
186//!     let mut stream = query_stream_with_content(vec![
187//!         UserContentBlock::image_base64("image/png", png_base64)?,
188//!         UserContentBlock::text("What's in this image?"),
189//!     ], None).await?;
190//!
191//!     while let Some(result) = stream.next().await {
192//!         let message = result?;
193//!         if let Message::Assistant(msg) = message {
194//!             for block in &msg.message.content {
195//!                 if let ContentBlock::Text(text) = block {
196//!                     print!("{}", text.text);
197//!                 }
198//!             }
199//!         }
200//!     }
201//!
202//!     Ok(())
203//! }
204//! ```
205//!
206//! ## Configuration
207//!
208//! The SDK provides extensive configuration through [`ClaudeAgentOptions`]:
209//!
210//! ```no_run
211//! use claude_agent_sdk_rs::{ClaudeAgentOptions, PermissionMode, SdkPluginConfig};
212//!
213//! let options = ClaudeAgentOptions::builder()
214//!     .model("claude-opus-4")
215//!     .fallback_model("claude-sonnet-4")
216//!     .max_budget_usd(10.0)
217//!     .max_thinking_tokens(2000)
218//!     .max_turns(10)
219//!     .permission_mode(PermissionMode::Default)
220//!     .plugins(vec![SdkPluginConfig::local("./my-plugin")])
221//!     .build();
222//! ```
223//!
224//! ## Examples
225//!
226//! The SDK includes 22 comprehensive examples covering all features. See the
227//! [examples directory](https://github.com/yourusername/claude-agent-sdk-rs/tree/master/examples)
228//! for detailed usage patterns.
229//!
230//! ## Documentation
231//!
232//! - [README](https://github.com/yourusername/claude-agent-sdk-rs/blob/master/README.md) - Getting started
233//! - [Plugin Guide](https://github.com/yourusername/claude-agent-sdk-rs/blob/master/PLUGIN_GUIDE.md) - Plugin development
234//! - [Examples](https://github.com/yourusername/claude-agent-sdk-rs/tree/master/examples) - 22 working examples
235
236pub mod client;
237pub mod errors;
238mod internal;
239pub mod query;
240pub mod types;
241pub mod version;
242
243// Re-export commonly used types
244pub use errors::{ClaudeError, ImageValidationError, Result};
245pub use types::{
246    config::*,
247    hooks::*,
248    mcp::{
249        McpServerConfig, McpServers, SdkMcpServer, SdkMcpTool, ToolDefinition, ToolHandler, ToolResult,
250        ToolResultContent as McpToolResultContent, create_sdk_mcp_server,
251        // ACP tool name prefix support
252        ACP_TOOL_PREFIX, acp_tool_name, is_acp_tool, strip_acp_prefix,
253    },
254    messages::*,
255    permissions::*,
256    plugin::*,
257};
258
259// Re-export public API
260pub use client::ClaudeClient;
261pub use query::{query, query_stream, query_stream_with_content, query_with_content};