Crate claude_agent_sdk

Crate claude_agent_sdk 

Source
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::{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::{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::{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::{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::{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::{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::{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

Re-exports§

pub use errors::ClaudeError;
pub use errors::ImageValidationError;
pub use errors::Result;
pub use mcp::TaskHandle;
pub use mcp::TaskHint;
pub use mcp::TaskId;
pub use mcp::TaskManager;
pub use mcp::TaskPriority;
pub use mcp::TaskProgress;
pub use mcp::TaskRequest;
pub use mcp::TaskResult;
pub use mcp::TaskState;
pub use mcp::TaskStatus;
pub use mcp::TaskUri;
pub use observability::Histogram;
pub use observability::HistogramBuckets;
pub use observability::LogLevel;
pub use observability::LogObserver;
pub use observability::Logger;
pub use observability::MetricsCollector;
pub use orchestration::Agent;
pub use orchestration::AgentFilter;
pub use orchestration::AgentInput;
pub use orchestration::AgentMetadata;
pub use orchestration::AgentOutput;
pub use orchestration::AgentRegistry;
pub use orchestration::ExecutionConfig;
pub use orchestration::ExecutionContext;
pub use orchestration::ExecutionTrace;
pub use orchestration::Orchestrator;
pub use orchestration::OrchestratorInput;
pub use orchestration::OrchestratorOutput;
pub use orchestration::ParallelOrchestrator;
pub use orchestration::SequentialOrchestrator;
pub use skills::Skill;
pub use skills::SkillError;
pub use skills::SkillInput;
pub use skills::SkillOutput;
pub use skills::SkillPackage;
pub use skills::SkillRegistry;
pub use skills::SkillResources;
pub use subagents::DelegationStrategy;
pub use subagents::Subagent;
pub use subagents::SubagentCall;
pub use subagents::SubagentConfig;
pub use subagents::SubagentError;
pub use subagents::SubagentExecutor;
pub use subagents::SubagentOutput;
pub use todos::TodoError;
pub use todos::TodoItem;
pub use todos::TodoList;
pub use todos::TodoStatus;
pub use commands::CommandError;
pub use commands::CommandHandler;
pub use commands::CommandRegistry;
pub use commands::SlashCommand;
pub use types::mcp::McpServerConfig;
pub use types::mcp::McpServers;
pub use types::mcp::SdkMcpServer;
pub use types::mcp::SdkMcpTool;
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 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 v2::create_session;
pub use v2::prompt;
pub use v2::resume_session;
pub use v2::Message as V2Message;
pub use v2::PermissionMode as V2PermissionMode;
pub use v2::PromptResult;
pub use v2::Session;
pub use v2::SessionOptions;
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
commands
Slash Commands system for Claude Agent SDK
errors
Error types for the Claude Agent SDK
mcp
MCP (Model Context Protocol) 2025-11-25 Implementation
observability
Observability Module
orchestration
Multi-Agent Orchestration Framework
query
Simple query function for one-shot interactions
skills
Agent Skills System for Claude Agent SDK
subagents
Subagent system for Claude Agent SDK
todos
Todo List management for Claude Agent SDK
types
Type definitions for the Claude Agent SDK
v2
Claude Agent SDK V2 API
version
Version information for the Claude Agent SDK

Macros§

tool
Macro to create a tool