crimson-crab v0.1 MIT OR Apache-2.0 MSRV 1.75
The production-grade Rust SDK for Claude.
The definitive Rust client for Anthropic's Claude API, engineered to first-party SDK standards: the complete API surface, identical retry semantics, and same-week support for every Claude release. Streaming, tool use, thinking, prompt caching and batches are first-class, not adapted.
cargo add crimson-crab
Spec fidelity, not surface area
The complete Claude API. Nothing lost in translation.
Streaming, tool use, adaptive thinking, prompt caching, batches — every Claude capability is a first-class Rust type that mirrors the wire exactly. And when Anthropic ships something new, you’re covered from day one: new models, new features, and new content types flow through without breaking a single build.
Streaming SSE
A hand-rolled SSE parser yields fine-grained StreamEvents and accumulates a final Message for you — no eventsource dependency.
Tool use
Define tools with raw JSON schemas, drive the agentic loop yourself, and pass any server-tool through ToolUnion::Raw.
Adaptive thinking
ThinkingConfig covers adaptive, budgeted and disabled modes, with effort and display controls surfaced directly.
Prompt caching
Attach CacheControl to any block with an optional 5m/1h TTL, and read cache hits back off Usage.
Message Batches
Create, poll and cancel batches, then stream results back with a JSONL-decoding Stream<BatchResult>.
Token counting
Turn any request into a count request and get exact input_tokens before you spend on generation.
Typed errors & retries
Every non-2xx maps to a precise Error variant with request_id. Backoff with jitter honors retry-after automatically.
Forward compatible
Unknown block types, stream events and stop reasons deserialize into Unknown catch-alls — new API surface never breaks a build.
Runtime-light & WASM-ready
The public API exposes futures_core::Stream, not tokio types. reqwest underneath means it also checks on wasm32-unknown-unknown.
From zero to streaming in one screen
Ergonomic, but nothing hidden.
A builder for every request, helpers for the common paths, and full command of stop_reason. Here it is end to end.
use crimson_crab::{Client, MessagesRequest, MessageParam, models_ids};
// Reads ANTHROPIC_API_KEY from the environment.
let client = Client::from_env()?;
let req = MessagesRequest::builder()
.model(models_ids::CLAUDE_OPUS_4_8)
.max_tokens(1024)
.system("You are terse.")
.messages(vec![MessageParam::user("Hello, Claude")])
.build()?; // validates required fields
let msg = client.messages().create(&req).await?;
if msg.stop_reason == Some(StopReason::Refusal) {
// handle a declined response
}
println!("{}", msg.text()); // concat of all text blocks
use futures_util::StreamExt;
use crimson_crab::{StreamEvent, ContentDelta};
let mut stream = client.messages().stream(&req).await?;
while let Some(event) = stream.next().await {
if let StreamEvent::ContentBlockDelta { delta, .. } = event? {
if let ContentDelta::TextDelta { text } = delta {
print!("{text}"); // tokens as they arrive
}
}
}
let final_msg = stream.final_message(); // fully accumulated Message
// ...or collapse the whole stream into a single line:
let msg = client.messages().stream(&req).await?.collect_final().await?;
use crimson_crab::{Tool, MessagesRequest, StopReason, models_ids};
let weather = Tool::new(
"get_weather",
"Look up the current weather for a city",
serde_json::json!({
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"],
}),
);
let req = MessagesRequest::builder()
.model(models_ids::CLAUDE_SONNET_5)
.max_tokens(1024)
.tools(vec![weather.into()])
.messages(messages.clone())
.build()?;
let msg = client.messages().create(&req).await?;
if msg.stop_reason == Some(StopReason::ToolUse) {
// dispatch each ToolUse block, append its ToolResult, and loop
}
Depth beats breadth
Why a dedicated client?
Multi-provider frameworks like rig and genai are genuinely great — if you need one interface across many model vendors, use them. crimson-crab makes the winning bet for Claude builders: go deep on one API and track it relentlessly — so every new Claude capability lands here first, typed and tested.
Straight talk: if your app talks to several model vendors, a framework will serve you better. crimson-crab is for teams who have chosen Claude and want the whole surface, exactly as Anthropic ships it.