Rust implementation of the Claude Agent SDK
Build AI agents that autonomously read files, run commands, search the web, edit code, and more. Rusty Claw gives you the same tools, agent loop, and context management that power Claude Code, programmable in Rust.
use rusty_claw::prelude::*;
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() -> Result<(), ClawError> {
let options = ClaudeAgentOptions::builder()
.allowed_tools(vec!["Read".into(), "Edit".into(), "Bash".into()])
.permission_mode(PermissionMode::AcceptEdits)
.build();
let mut stream = query("Find and fix the bug in auth.py", Some(options)).await?;
while let Some(message) = stream.next().await {
match message? {
Message::Assistant(msg) => {
for block in msg.message.content {
if let ContentBlock::Text { text } = block {
println!("{}", text);
}
}
}
Message::Result(ResultMessage::Success { result, .. }) => {
println!("Done: {}", result);
}
_ => {}
}
}
Ok(())
}Rusty Claw includes built-in tool support via the Claude CLI, so your agent can start working immediately without you implementing tool execution.
- Rust 1.70 or later
- Claude Code CLI v2.0.0 or later (install guide)
- Anthropic API key set as
ANTHROPIC_API_KEYenvironment variable
[dependencies]
rusty_claw = "0.1"
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1"export ANTHROPIC_API_KEY=your-api-keyCreate src/main.rs:
use rusty_claw::prelude::*;
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() -> Result<(), ClawError> {
let options = ClaudeAgentOptions::builder()
.allowed_tools(vec!["Bash".into(), "Glob".into()])
.permission_mode(PermissionMode::AcceptEdits)
.build();
let mut stream = query("What files are in this directory?", Some(options)).await?;
while let Some(message) = stream.next().await {
if let Ok(Message::Result(ResultMessage::Success { result, .. })) = message {
println!("{}", result);
}
}
Ok(())
}cargo runReady to build? Follow the Quickstart to create an agent that finds and fixes bugs.
One-shot queries with streaming responses via query():
let mut stream = query("Explain this codebase", Some(options)).await?;Persistent multi-turn sessions with ClaudeClient:
let mut client = ClaudeClient::new(options)?;
client.connect().await?;
let stream = client.send_message("Refactor the auth module").await?;
// ... later ...
let stream = client.send_message("Now add tests for it").await?;
client.close().await?;Define MCP tools with the #[claw_tool] procedural macro:
#[claw_tool(name = "lookup_user", description = "Look up a user by ID")]
async fn lookup_user(user_id: String) -> ToolResult {
ToolResult::text(format!("Found user: {user_id}"))
}Lifecycle event hooks for validation, monitoring, and security:
// Block dangerous shell commands
async fn guard_bash(
input: HookInput, _id: Option<&str>, _ctx: &HookContext,
) -> Result<HookResponse, ClawError> {
if let Some(tool_input) = &input.tool_input {
if let Some(cmd) = tool_input["command"].as_str() {
if cmd.contains("rm -rf") {
return Ok(HookResponse::deny("Dangerous command blocked"));
}
}
}
Ok(HookResponse::allow("OK"))
}Spawn specialized agents with dedicated prompts and tool restrictions:
let mut agents = HashMap::new();
agents.insert("code-reviewer".into(), AgentDefinition {
description: "Expert code reviewer for quality and security".into(),
prompt: "Analyze code quality and suggest improvements.".into(),
tools: vec!["Read".into(), "Grep".into(), "Glob".into()],
model: Some("sonnet".into()),
});Strongly-typed message structures with serde for all Claude protocol interactions:
match message? {
Message::System(SystemMessage::Init { session_id, tools, .. }) => { /* ... */ }
Message::Assistant(msg) => { /* text, tool_use, thinking blocks */ }
Message::Result(ResultMessage::Success { result, usage, .. }) => { /* ... */ }
_ => {}
}The examples/ directory contains runnable demonstrations:
| Example | Description |
|---|---|
| simple_query.rs | One-shot query with streaming responses |
| interactive_client.rs | Multi-turn sessions with ClaudeClient |
| custom_tool.rs | Custom MCP tools with #[claw_tool] macro |
| session_resume.rs | Resume, fork, and name sessions |
| system_prompts.rs | Custom, preset, and append system prompts |
| tool_permissions.rs | Allow/deny lists and CanUseToolHandler |
| partial_messages.rs | Stream incremental content blocks |
| advanced_tools.rs | Vec<T>, bool params, doc comments in #[claw_tool] |
| image_tool_results.rs | Text + image multi-content tool results |
| hook_callbacks.rs | HookCallback trait, input/context/response |
| hooks_guardrails.rs | HookHandler for validation and logging |
| agent_environment.rs | Working directory, env vars, CLI path |
| advanced_config.rs | Settings sources, output format, betas |
| rate_limit_handling.rs | RateLimitEvent and ClawError matching |
| transport_layer.rs | CliDiscovery and Transport trait |
| file_checkpointing.rs | File snapshots and rewind_files() |
| interrupt_and_status.rs | interrupt() and mcp_status() |
| external_mcp.rs | External MCP server config (stub) |
| subagent_usage.rs | Agent definitions and subagent hooks |
Run an example:
cargo run -p examples --example simple_querySee examples/README.md for details. All examples require the Claude CLI (>= 2.0.0) and a valid ANTHROPIC_API_KEY.
| Guide | Description |
|---|---|
| Quickstart | Build a bug-fixing agent step by step |
| Messages | Message types and parsing reference |
| Hooks | Intercept and control agent behavior |
| Sessions | Multi-turn sessions, resume, and fork |
| MCP | Model Context Protocol tool integration |
| Permissions | Control what your agent can do |
| Subagents | Spawn specialized sub-agents |
| Technical Spec | Detailed architecture and protocol docs |
Rusty Claw is an unofficial, community-driven Rust SDK that provides the same core capabilities as Anthropic's official Python and TypeScript SDKs.
| Rusty Claw (Rust) | Official (Python/TypeScript) | |
|---|---|---|
| API style | query() + ClaudeClient |
query() + streaming |
| Message types | Rust enums with serde | Dataclasses / interfaces |
| Tool definition | #[claw_tool] proc macro |
Decorators / helper functions |
| Hooks | HookCallback trait + closures |
Callback functions |
| Async runtime | tokio | asyncio / native async |
| Error handling | Result<T, ClawError> |
Exceptions / thrown errors |
| Performance | Zero-cost abstractions, no GC | Interpreted runtime |
When to use Rusty Claw:
- Building Rust CLI tools, services, or system-level agents
- Performance-critical agent workloads where Python/Node overhead matters
- Embedding agent capabilities in existing Rust applications
- Platform teams building internal tools with Rust backends
User Application
|
+-- query() / ClaudeClient
| |
+-- Control Protocol (JSON-RPC bidirectional)
| |
+-- Transport Layer (trait: connect/read/write/close)
| |
+-- SubprocessCLITransport (spawns claude CLI)
| |
+-- SDK MCP Server Bridge (in-process tool hosting)
|
v
Claude Code CLI (>= 2.0.0)
Key components:
- Transport Layer - Bidirectional NDJSON communication over stdio
- Control Protocol - Handles permission requests, tool queries, and session management
- MCP Integration - Model Context Protocol server for exposing custom tools
- Hook System - Intercept and respond to lifecycle events
- Type System - Strongly-typed messages, content blocks, and protocol structures
cargo build # Build
cargo test --workspace # Run tests
cargo clippy --workspace # Lint
cargo doc --open # Generate docsSee CONTRIBUTING.md for the full development guide.
Licensed under the MIT License. See LICENSE for details.
Architecturally inspired by Anthropic's Python SDK (claude-agent-sdk-python), licensed under MIT.