Initial layout for an async Rust port of the Python claude-agent-sdk. Sets up Cargo.toml on 2024 edition, MIT LICENSE matching the upstream Python SDK's text with the Sulkta Coop copyright appended, a workspace .gitignore, and a README laying out the v0.1 scope and the Python -> Rust mapping table. No source modules yet — those land in the following commits. |
||
|---|---|---|
| .gitignore | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
claude-agent-sdk (Rust)
Async Rust SDK for the Claude Agent CLI — a faithful port of the official
Python claude-agent-sdk.
This crate wraps the claude CLI as a subprocess and exposes its
newline-delimited JSON stream as ergonomic Rust types. The Python SDK's
two entry points map directly:
query()for fire-and-forget one-shot prompts.ClaudeSDKClient→claude_agent_sdk::Clientfor bidirectional multi-turn sessions.
Status
v0.0.1 — initial port. Core feature parity for the subprocess wire protocol; advanced features (control protocol, hooks, in-process MCP servers, session_store, sandbox, plugins, agents) are deferred to v0.2. See v0.1 scope below.
Install
[dependencies]
claude-agent-sdk = { git = "https://gitea.sulkta.com/Sulkta-Coop/claude-agent-sdk-rust" }
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1"
Prerequisites: the claude CLI on PATH (or supply
ClaudeAgentOptions::with_cli_path()), and an authenticated Claude
session. The SDK does not bundle the CLI binary.
Quick start
use claude_agent_sdk::{query, ClaudeAgentOptions, Message, ContentBlock};
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() -> claude_agent_sdk::Result<()> {
let opts = ClaudeAgentOptions::new()
.with_system_prompt("You are a helpful assistant.")
.with_max_turns(1);
let mut stream = query("What is 2 + 2?", opts).await?;
while let Some(msg) = stream.next().await {
match msg? {
Message::Assistant(a) => {
for block in a.message.content {
if let ContentBlock::Text(t) = block {
println!("Claude: {}", t.text);
}
}
}
Message::Result(r) => {
if let Some(usd) = r.total_cost_usd {
println!("Cost: ${:.4}", usd);
}
break;
}
_ => {}
}
}
Ok(())
}
Multi-turn sessions
use claude_agent_sdk::{Client, ClaudeAgentOptions, Message, ContentBlock};
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() -> claude_agent_sdk::Result<()> {
let mut client = Client::new(ClaudeAgentOptions::new()).await?;
client.connect().await?;
let mut messages = client.messages();
client.send("What's the capital of France?").await?;
// ...consume messages until a Result frame, then ask a follow-up...
client.send("And of Germany?").await?;
// Drain until next Result, then disconnect.
while let Some(msg) = messages.next().await {
if let Message::Result(_) = msg? {
break;
}
}
client.disconnect().await?;
Ok(())
}
See the examples/ directory for runnable variants.
Mapping the Python SDK
| Python | Rust |
|---|---|
query(prompt=...) |
query(prompt, opts).await? |
ClaudeSDKClient |
Client |
ClaudeAgentOptions |
ClaudeAgentOptions |
AssistantMessage |
Message::Assistant(_) |
UserMessage |
Message::User(_) |
SystemMessage |
Message::System(_) |
ResultMessage |
Message::Result(_) |
TextBlock / ToolUseBlock |
ContentBlock::Text/ToolUse(_) |
CLINotFoundError |
Error::CliNotFound |
CLIConnectionError |
Error::CliConnection |
ProcessError |
Error::Process { .. } |
CLIJSONDecodeError |
Error::JsonDecode { .. } |
MessageParseError |
Error::MessageParse { .. } |
v0.1 scope and known limitations
The v0.1 port covers the core path. The following are deferred:
- Control protocol —
interrupt(),set_permission_mode(),set_model(),get_mcp_status(), etc. The Python SDK sends a JSON-RPCinitializerequest before the first user message and handles control requests/responses over the same stdio pair. The RustClientcurrently speaks only the bare user / assistant / result frames. Adding the control protocol unlocks the rest of the API. can_use_toolpermission callback — requires the control protocol.- In-process MCP servers (
@tool/create_sdk_mcp_server) — the Python decorator wraps amcp.server.Serverinstance. The Rust shape for this (likely a derive macro on aTooltrait + a runtime that multiplexes over the control protocol) is not yet drafted. HookMatcher— wire format is supported on the CLI side but the Rust callback surface is not designed.SessionStoremirroring adapter.Sandboxsettings, plugins, agents dataclass.
Each of these degrades gracefully — a v0.1 caller using a newer CLI sees fewer features, not breakage.
License
MIT. See LICENSE.
This is an independent port; the upstream Python SDK is © Anthropic, PBC.