Expand description
§Claude Agent SDK for Rust
Rust SDK for interacting with Claude Code CLI, enabling programmatic access to Claude’s capabilities with full bidirectional streaming support and 100% feature parity with the official Python SDK.
§Features
- Simple Query API: One-shot queries with both collecting ([
query]) and streaming (query_stream) modes - Bidirectional Streaming: Real-time streaming communication with
ClaudeClient - Dynamic Control: Interrupt, change permissions, switch models mid-execution
- Hooks System: Intercept and control Claude’s behavior at runtime with 6 hook types
- Custom Tools: In-process MCP servers with ergonomic
tool!macro - Plugin System: Load custom plugins to extend Claude’s capabilities
- Permission Management: Fine-grained control over tool execution
- Cost Control: Budget limits and fallback models for production reliability
- Extended Thinking: Configure maximum thinking tokens for complex reasoning
- Session Management: Resume, fork, and manage conversation sessions
- Multimodal Input: Send images alongside text using base64 or URLs
§Quick Start
§Simple Query
use claude_agent_sdk_rs::{query, Message, ContentBlock};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// One-shot query that collects all messages
let messages = query("What is 2 + 2?", None).await?;
for message in messages {
if let Message::Assistant(msg) = message {
for block in &msg.message.content {
if let ContentBlock::Text(text) = block {
println!("Claude: {}", text.text);
}
}
}
}
Ok(())
}§Streaming Query
use claude_agent_sdk_rs::{query_stream, Message, ContentBlock};
use futures::StreamExt;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Streaming query for memory-efficient processing
let mut stream = query_stream("Explain Rust ownership", None).await?;
while let Some(result) = stream.next().await {
let message = result?;
if let Message::Assistant(msg) = message {
for block in &msg.message.content {
if let ContentBlock::Text(text) = block {
println!("Claude: {}", text.text);
}
}
}
}
Ok(())
}§Bidirectional Client
use claude_agent_sdk_rs::{ClaudeClient, ClaudeAgentOptions, Message, PermissionMode};
use futures::StreamExt;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let options = ClaudeAgentOptions::builder()
.permission_mode(PermissionMode::BypassPermissions)
.max_turns(5)
.build();
let mut client = ClaudeClient::new(options);
client.connect().await?;
// Send query
client.query("What is Rust?").await?;
// Receive responses
{
let mut stream = client.receive_response();
while let Some(result) = stream.next().await {
match result? {
Message::Assistant(msg) => {
println!("Got assistant message");
}
Message::Result(_) => break,
_ => {}
}
}
} // stream is dropped here
client.disconnect().await?;
Ok(())
}§Multimodal Input (Images)
The SDK supports sending images alongside text in your prompts using structured content blocks. Both base64-encoded images and URL references are supported.
§Supported Formats
- JPEG (
image/jpeg) - PNG (
image/png) - GIF (
image/gif) - WebP (
image/webp)
§Size Limits
- Maximum base64 data size: 15MB (results in ~20MB decoded)
- Large images may timeout or fail - resize before encoding
§Example: Query with Image
use claude_agent_sdk_rs::{query_with_content, UserContentBlock, Message, ContentBlock};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// For real usage, load and base64-encode an image file
// This example uses a pre-encoded 1x1 red PNG pixel
let base64_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
// Query with text and image
let messages = query_with_content(vec![
UserContentBlock::text("What color is this image?"),
UserContentBlock::image_base64("image/png", base64_data)?,
], None).await?;
for message in messages {
if let Message::Assistant(msg) = message {
for block in &msg.message.content {
if let ContentBlock::Text(text) = block {
println!("Claude: {}", text.text);
}
}
}
}
Ok(())
}§Example: Using Image URLs
use claude_agent_sdk_rs::{query_with_content, UserContentBlock};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let messages = query_with_content(vec![
UserContentBlock::text("Describe this architecture diagram"),
UserContentBlock::image_url("https://example.com/diagram.png"),
], None).await?;
Ok(())
}§Example: Streaming with Images
use claude_agent_sdk_rs::{query_stream_with_content, UserContentBlock, Message, ContentBlock};
use futures::StreamExt;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Minimal 1x1 PNG for example purposes
let png_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
let mut stream = query_stream_with_content(vec![
UserContentBlock::image_base64("image/png", png_base64)?,
UserContentBlock::text("What's in this image?"),
], None).await?;
while let Some(result) = stream.next().await {
let message = result?;
if let Message::Assistant(msg) = message {
for block in &msg.message.content {
if let ContentBlock::Text(text) = block {
print!("{}", text.text);
}
}
}
}
Ok(())
}§Configuration
The SDK provides extensive configuration through ClaudeAgentOptions:
use claude_agent_sdk_rs::{ClaudeAgentOptions, PermissionMode, SdkPluginConfig};
let options = ClaudeAgentOptions::builder()
.model("claude-opus-4")
.fallback_model("claude-sonnet-4")
.max_budget_usd(10.0)
.max_thinking_tokens(2000)
.max_turns(10)
.permission_mode(PermissionMode::Default)
.plugins(vec![SdkPluginConfig::local("./my-plugin")])
.build();§Examples
The SDK includes 22 comprehensive examples covering all features. See the examples directory for detailed usage patterns.
§Documentation
- README - Getting started
- Plugin Guide - Plugin development
- Examples - 22 working examples
Re-exports§
pub use errors::ClaudeError;pub use errors::ImageValidationError;pub use errors::Result;pub use types::mcp::McpServerConfig;pub use types::mcp::McpServers;pub use types::mcp::SdkMcpServer;pub use types::mcp::SdkMcpTool;pub use types::mcp::ToolDefinition;pub use types::mcp::ToolHandler;pub use types::mcp::ToolResult;pub use types::mcp::ToolResultContent as McpToolResultContent;pub use types::mcp::create_sdk_mcp_server;pub use types::mcp::ACP_TOOL_PREFIX;pub use types::mcp::acp_tool_name;pub use types::mcp::is_acp_tool;pub use types::mcp::strip_acp_prefix;pub use client::ClaudeClient;pub use query::query;pub use query::query_stream;pub use query::query_stream_with_content;pub use query::query_with_content;pub use types::config::*;pub use types::hooks::*;pub use types::messages::*;pub use types::permissions::*;pub use types::plugin::*;
Modules§
- client
- ClaudeClient for bidirectional streaming interactions with hook support
- errors
- Error types for the Claude Agent SDK
- query
- Simple query function for one-shot interactions
- types
- Type definitions for the Claude Agent SDK
- version
- Version information for the Claude Agent SDK
Macros§
- tool
- Macro to create a tool