| Crates.io | cc-sdk |
| lib.rs | cc-sdk |
| version | 0.1.11 |
| created_at | 2025-07-22 19:26:36.592419+00 |
| updated_at | 2025-09-09 07:50:57.894042+00 |
| description | Rust SDK for Claude Code CLI with full interactive capabilities |
| homepage | |
| repository | https://github.com/ZhangHanDong/claude-code-api-rs |
| max_upload_size | |
| id | 1763866 |
| size | 278,581 |
A Rust SDK for interacting with Claude Code CLI, providing both simple query interfaces and full interactive client capabilities.
query() functionThis Rust SDK provides comprehensive functionality for Claude Code interactions:
query(), send_message(), receive_response(), interrupt()Add this to your Cargo.toml:
[dependencies]
cc-sdk = "0.1.11"
tokio = { version = "1.0", features = ["full"] }
futures = "0.3"
Install Claude Code CLI:
npm install -g @anthropic-ai/claude-code
The SDK supports the latest Claude models available in 2025:
Opus 4.1 - Most capable model
"claude-opus-4-1-20250805""opus" (recommended - uses latest Opus)Sonnet 4 - Balanced performance
"claude-sonnet-4-20250514""sonnet" (recommended - uses latest Sonnet)"claude-3-5-sonnet-20241022""claude-3-5-haiku-20241022" (fastest)use cc_sdk::{query, ClaudeCodeOptions, Result};
// Using Opus 4.1 (recommended: use alias)
let options = ClaudeCodeOptions::builder()
.model("opus") // or "claude-opus-4-1-20250805" for specific version
.build();
// Using Sonnet 4 (recommended: use alias)
let options = ClaudeCodeOptions::builder()
.model("sonnet") // or "claude-sonnet-4-20250514" for specific version
.build();
let mut messages = query("Your prompt", Some(options)).await?;
use cc_sdk::{query, Result};
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<()> {
let mut messages = query("What is 2 + 2?", None).await?;
while let Some(msg) = messages.next().await {
println!("{:?}", msg?);
}
Ok(())
}
use cc_sdk::{InteractiveClient, ClaudeCodeOptions, Result};
#[tokio::main]
async fn main() -> Result<()> {
let mut client = InteractiveClient::new(ClaudeCodeOptions::default())?;
client.connect().await?;
// Send a message and receive response
let messages = client.send_and_receive(
"Help me write a Python web server".to_string()
).await?;
// Process responses
for msg in &messages {
match msg {
cc_sdk::Message::Assistant { message } => {
println!("Claude: {:?}", message);
}
_ => {}
}
}
// Send follow-up
let messages = client.send_and_receive(
"Make it use async/await".to_string()
).await?;
client.disconnect().await?;
Ok(())
}
use cc_sdk::{InteractiveClient, ClaudeCodeOptions, Result};
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<()> {
let mut client = InteractiveClient::new(ClaudeCodeOptions::default())?;
client.connect().await?;
// Send a message
client.send_message("Explain quantum computing".to_string()).await?;
// Receive messages as a stream
let mut stream = client.receive_messages_stream().await;
while let Some(result) = stream.next().await {
match result {
Ok(message) => {
println!("Received: {:?}", message);
if matches!(message, cc_sdk::Message::Result { .. }) {
break;
}
}
Err(e) => eprintln!("Error: {}", e),
}
}
// Or use the convenience method that stops at Result message
client.send_message("What's 2 + 2?".to_string()).await?;
let mut stream = client.receive_response_stream().await;
while let Some(result) = stream.next().await {
match result {
Ok(message) => println!("Message: {:?}", message),
Err(e) => eprintln!("Error: {}", e),
}
}
client.disconnect().await?;
Ok(())
}
use cc_sdk::{InteractiveClient, ClaudeCodeOptions, Result};
#[tokio::main]
async fn main() -> Result<()> {
let mut client = InteractiveClient::new(ClaudeCodeOptions::default())?;
client.connect().await?;
// Send message without waiting for response
client.send_message("Calculate pi to 100 digits".to_string()).await?;
// Do other work...
// Receive response when ready (stops at Result message)
let messages = client.receive_response().await?;
// Cancel long-running operations
client.send_message("Write a 10,000 word essay".to_string()).await?;
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
client.interrupt().await?;
client.disconnect().await?;
Ok(())
}
use cc_sdk::{ClaudeCodeOptions, PermissionMode, ControlProtocolFormat};
let options = ClaudeCodeOptions::builder()
.system_prompt("You are a helpful coding assistant")
.model("claude-3-5-sonnet-20241022")
.permission_mode(PermissionMode::AcceptEdits)
.max_turns(10)
.max_thinking_tokens(10000)
.allowed_tools(vec!["read_file".to_string(), "write_file".to_string()])
.cwd("/path/to/project")
// New in v0.1.6
.settings("claude-settings.json") // Use custom settings file
.add_dir("/path/to/related/project") // Add additional working directories
.add_dirs(vec![PathBuf::from("/dir1"), PathBuf::from("/dir2")]) // Add multiple dirs
// New in v0.1.11: Control protocol format configuration
.control_protocol_format(ControlProtocolFormat::Legacy) // Default: maximum compatibility
.build();
The SDK supports configurable control protocol formats for CLI compatibility:
sdk_control_request/response format - works with all CLI versionstype=control format - for newer CLI versions// Use environment variable to override (useful for testing)
// export CLAUDE_CODE_CONTROL_FORMAT=legacy # or "control"
// Or configure programmatically
let options = ClaudeCodeOptions::builder()
.control_protocol_format(ControlProtocolFormat::Legacy)
.build();
See CONTROL_PROTOCOL_COMPATIBILITY.md for detailed information.
query()Simple, stateless query function for one-shot interactions.
pub async fn query(
prompt: impl Into<String>,
options: Option<ClaudeCodeOptions>
) -> Result<impl Stream<Item = Result<Message>>>
InteractiveClientMain client for stateful, interactive conversations.
new(options: ClaudeCodeOptions) -> Result<Self> - Create a new clientconnect() -> Result<()> - Connect to Claude CLIsend_and_receive(prompt: String) -> Result<Vec<Message>> - Send message and wait for complete responsesend_message(prompt: String) -> Result<()> - Send message without waitingreceive_response() -> Result<Vec<Message>> - Receive messages until Result messageinterrupt() -> Result<()> - Cancel ongoing operationdisconnect() -> Result<()> - Disconnect from Claude CLIUserMessage - User input messagesAssistantMessage - Claude's responsesSystemMessage - System notificationsResultMessage - Operation results with timing and cost infoThe SDK provides comprehensive error types:
CLINotFoundError - Claude Code CLI not installedCLIConnectionError - Connection failuresProcessError - CLI process errorsInvalidState - Invalid operation stateCheck the examples/ directory for more usage examples:
interactive_demo.rs - Interactive conversation demoquery_simple.rs - Simple query examplefile_operations.rs - File manipulation exampleTest the latest features with these examples:
test_settings.rs - Using custom settings filestest_settings_safe.rs - Safe settings file handling with path detectiontest_add_dirs.rs - Adding multiple working directoriestest_combined_features.rs - Combining settings and add_dirstest_new_options.rs - Testing the new builder methodsExample settings files are provided:
examples/claude-settings.json - Basic settings configurationexamples/custom-claude-settings.json - Advanced settings with MCP serversNote: When running examples from the project root, use:
cargo run --example test_settings
The settings files use relative paths from the project root (e.g., examples/claude-settings.json)
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.