claude-agent-sdk-rust 1.0.0

Rust SDK for Claude Agent - Build production-ready AI agents with Claude
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
# Claude Agent SDK for Rust - API Guide

## Table of Contents

- [Overview]#overview
- [Quick Start]#quick-start
- [Core Concepts]#core-concepts
- [Simple Query API]#simple-query-api
- [Interactive Client API]#interactive-client-api
- [Hook System]#hook-system
- [Permission Callbacks]#permission-callbacks
- [Thinking and Effort]#thinking-and-effort
- [Structured Output]#structured-output
- [Budget and Cost Control]#budget-and-cost-control
- [Configuration Options]#configuration-options
- [Message Types]#message-types
- [Error Handling]#error-handling
- [Examples]#examples

## Overview

The Claude Agent SDK for Rust provides a production-ready interface to Claude Code CLI, enabling you to build AI agents with full control over permissions, hooks, and agent behavior.

### Key Features

- **Simple Query API** - One-shot queries with streaming responses
- **Interactive Client** - Multi-turn conversations with bidirectional communication
- **Hook System** - Intercept and control agent behavior at key points
- **Permission Callbacks** - Fine-grained control over tool usage
- **Type-Safe** - Fully typed API with compile-time safety
- **Async/Await** - Built on Tokio for efficient async operations

## Quick Start

```rust
use claude_agent_sdk_rust::{query, Message};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Simple one-shot query
    let mut messages = query("What is 2 + 2?", None).await?;

    while let Some(msg) = messages.next().await {
        match msg? {
            Message::Assistant(assistant) => {
                println!("Claude: {:?}", assistant);
            }
            Message::Result(result) => {
                println!("Cost: ${:.4}", result.total_cost_usd.unwrap_or(0.0));
            }
            _ => {}
        }
    }

    Ok(())
}
```

## Core Concepts

### 1. Query vs Client

**`query()`** - For simple, one-shot queries:
- Spawns CLI, sends prompt, returns stream of messages
- Automatically cleans up after result
- Best for single questions or tasks

**`ClaudeSDKClient`** - For interactive sessions:
- Maintains persistent connection
- Supports multiple queries in sequence
- Dynamic configuration changes
- Full control protocol access

### 2. Message Stream

All interactions return a stream of `Message` enum variants:

```rust
pub enum Message {
    User(UserMessage),        // User input
    Assistant(AssistantMessage), // Claude's response
    System(SystemMessage),    // System metadata
    Result(ResultMessage),    // Final metrics
    StreamEvent(StreamEvent), // Partial messages
}
```

### 3. Content Blocks

Assistant messages contain content blocks:

```rust
pub enum ContentBlock {
    Text(TextBlock),           // Text output
    Thinking(ThinkingBlock),   // Extended thinking
    ToolUse(ToolUseBlock),     // Tool invocation
    ToolResult(ToolResultBlock), // Tool output
}
```

## Simple Query API

### Basic Usage

```rust
use claude_agent_sdk_rust::query;
use futures::StreamExt;

let messages = query("Explain async/await in Rust", None).await?;
let mut messages = Box::pin(messages);

while let Some(msg) = messages.next().await {
    // Handle message
}
```

### With Options

```rust
use claude_agent_sdk_rust::{query, ClaudeAgentOptions, PermissionMode};

let options = ClaudeAgentOptions::builder()
    .permission_mode(PermissionMode::AcceptEdits)
    .max_turns(5)
    .allowed_tools(vec!["Read".to_string(), "Write".to_string()])
    .build();

let messages = query("Help me refactor this code", Some(options)).await?;
```

## Interactive Client API

### Connection Lifecycle

```rust
use claude_agent_sdk_rust::{ClaudeSDKClient, ClaudeAgentOptions};

// Create client
let mut client = ClaudeSDKClient::new(ClaudeAgentOptions::default());

// Connect (starts CLI process)
client.connect(Some("Hello!".to_string())).await?;

// Use client for multiple queries...

// Disconnect (cleans up)
client.disconnect().await?;
```

### Sending Queries

```rust
// Send a query
client.query("What files are in this directory?").await?;

// Receive response
let messages = client.receive_response()?;
let mut messages = Box::pin(messages);

while let Some(msg) = messages.next().await {
    match msg? {
        Message::Assistant(a) => { /* handle */ }
        Message::Result(r) => break, // Auto-terminates
        _ => {}
    }
}
```

### Dynamic Configuration

```rust
// Change permission mode mid-session
client.set_permission_mode(PermissionMode::AcceptAll).await?;

// Change AI model
client.set_model(Some("claude-opus-4-20250514".to_string())).await?;

// Interrupt current processing
client.interrupt().await?;
```

## Hook System

Hooks allow you to intercept and control agent behavior at specific points.

### Hook Events

- `PreToolUse` - Before tool execution
- `PostToolUse` - After tool execution
- `PostToolUseFailure` - After a tool execution fails
- `UserPromptSubmit` - When user submits a prompt
- `Notification` - When the agent sends a notification
- `Stop` - When agent loop stops
- `SubagentStart` - When a subagent starts
- `SubagentStop` - When a subagent stops
- `PreCompact` - Before context compaction
- `PermissionRequest` - When a permission decision is needed

### Implementing a Hook

```rust
use claude_agent_sdk_rust::callbacks::{HookCallback, hooks};
use claude_agent_sdk_rust::types::{HookInput, HookOutput, HookContext};
use async_trait::async_trait;

struct LoggingHook;

#[async_trait]
impl HookCallback for LoggingHook {
    async fn call(
        &self,
        input: HookInput,
        tool_use_id: Option<String>,
        _context: HookContext,
    ) -> claude_agent_sdk_rust::Result<HookOutput> {
        // Match on hook input type
        if let HookInput::PreToolUse(pre_tool) = input {
            println!("Tool: {}", pre_tool.tool_name);
            println!("Input: {:?}", pre_tool.tool_input);
        }

        // Allow execution to continue
        Ok(hooks::allow())
    }
}
```

### Registering Hooks

```rust
use claude_agent_sdk_rust::types::HookEvent;

let mut client = ClaudeSDKClient::new(options);

// Register hook for all tools
let hook_id = client.register_hook(
    HookEvent::PreToolUse,
    None,  // Match all tools
    LoggingHook,
);

// Register hook for specific tools
let hook_id = client.register_hook(
    HookEvent::PreToolUse,
    Some("Bash|Edit"),  // Match Bash or Edit
    SecurityHook,
);
```

### Hook Responses

```rust
use claude_agent_sdk_rust::callbacks::hooks;

// Allow execution
Ok(hooks::allow())

// Block execution
Ok(hooks::block("Reason for blocking"))

// Allow with message to user
Ok(hooks::allow_with_message("Custom message"))

// Defer (async execution)
Ok(hooks::defer(Some(5000))) // 5 second timeout
```

## Permission Callbacks

Permission callbacks control which tools Claude can use and how.

### Implementing a Permission Callback

```rust
use claude_agent_sdk_rust::callbacks::{PermissionCallback, permissions};
use claude_agent_sdk_rust::types::{PermissionResult, ToolPermissionContext};
use async_trait::async_trait;
use serde_json::Value;

struct SafetyChecker;

#[async_trait]
impl PermissionCallback for SafetyChecker {
    async fn call(
        &self,
        tool_name: String,
        input: Value,
        _context: ToolPermissionContext,
    ) -> claude_agent_sdk_rust::Result<PermissionResult> {
        // Block dangerous commands
        if tool_name == "Bash" {
            if let Some(cmd) = input.get("command").and_then(|v| v.as_str()) {
                if cmd.contains("rm -rf") {
                    return Ok(permissions::deny("Dangerous command blocked"));
                }
            }
        }

        // Allow by default
        Ok(permissions::allow())
    }
}
```

### Registering Permission Callback

```rust
let mut client = ClaudeSDKClient::new(options);

// Set permission callback (only one active at a time)
client.set_permission_callback(SafetyChecker);
```

### Permission Responses

```rust
use claude_agent_sdk_rust::callbacks::permissions;

// Allow tool use
Ok(permissions::allow())

// Allow with modified input
Ok(permissions::allow_with_input(modified_input))

// Deny tool use
Ok(permissions::deny("Not allowed"))

// Deny and stop session
Ok(permissions::deny_and_interrupt("Critical violation"))
```

## Thinking and Effort

Control Claude's reasoning depth with thinking configuration and effort levels.

### ThinkingConfig

```rust
use claude_agent_sdk_rust::{ClaudeAgentOptions, ThinkingConfig};

// Adaptive: Claude decides when to use extended thinking
let options = ClaudeAgentOptions::builder()
    .thinking(Some(ThinkingConfig::Adaptive))
    .build();

// Enabled with explicit token budget
let options = ClaudeAgentOptions::builder()
    .thinking(Some(ThinkingConfig::Enabled { budget_tokens: 10000 }))
    .build();

// Disabled
let options = ClaudeAgentOptions::builder()
    .thinking(Some(ThinkingConfig::Disabled))
    .build();
```

Maps to the `--max-thinking-tokens` CLI flag. `Adaptive` passes `0`, `Enabled` passes the budget, `Disabled` omits the flag.

### Effort

```rust
use claude_agent_sdk_rust::{ClaudeAgentOptions, Effort};

let options = ClaudeAgentOptions::builder()
    .effort(Some(Effort::High))
    .build();
```

**Levels:** `Low`, `Medium`, `High`, `Max`. Maps to the `--effort` CLI flag.

## Structured Output

Get Claude's response as validated JSON conforming to a schema. The `output_format` option accepts a JSON value with `type: "json_schema"` and a `schema` field containing a standard JSON Schema.

> **Important:** Structured output typically requires more than 1 turn. Set `max_turns` to at least 2-3 or omit it entirely. Using `max_turns(1)` will likely produce `error_max_turns` with no structured output.

```rust
use claude_agent_sdk_rust::{query, ClaudeAgentOptions, Message};
use futures::StreamExt;

let schema = serde_json::json!({
    "type": "json_schema",
    "schema": {
        "type": "object",
        "properties": {
            "summary": { "type": "string" },
            "language": { "type": "string" },
            "line_count": { "type": "number" }
        },
        "required": ["summary", "language", "line_count"]
    }
});

let options = ClaudeAgentOptions::builder()
    .output_format(Some(schema))
    .build();

let mut messages = query("Analyze src/main.rs", Some(options)).await?;
let mut messages = Box::pin(messages);

while let Some(msg) = messages.next().await {
    if let Ok(Message::Result(result)) = msg {
        if let Some(output) = &result.structured_output {
            // output is a serde_json::Value matching your schema
            println!("{}", serde_json::to_string_pretty(output)?);
        }
    }
}
```

The structured output is available on `ResultMessage.structured_output` when the query completes with `subtype: "success"`.

## Budget and Cost Control

### max_budget_usd

Set a per-query spending limit:

```rust
let options = ClaudeAgentOptions::builder()
    .max_budget_usd(Some(0.10))
    .build();
```

> **Important:** This is a **soft cap**. The budget is checked between turns — the current turn always completes before the limit is evaluated. Actual spend may slightly exceed the configured value.

### Fallback Model

Specify a model to fall back to if the primary model is unavailable:

```rust
let options = ClaudeAgentOptions::builder()
    .model(Some("claude-opus-4-20250514".into()))
    .fallback_model(Some("claude-sonnet-4-5-20250929".into()))
    .build();
```

## Configuration Options

### ClaudeAgentOptions

```rust
use claude_agent_sdk_rust::{
    ClaudeAgentOptions, PermissionMode, SystemPrompt, SettingSource,
    ThinkingConfig, Effort,
};

let options = ClaudeAgentOptions::builder()
    // Permission mode
    .permission_mode(PermissionMode::AcceptEdits)

    // Allowed tools (whitelist)
    .allowed_tools(vec!["Read".into(), "Write".into()])

    // Blocked tools (blacklist)
    .blocked_tools(vec!["Bash".into()])

    // System prompt
    .system_prompt(SystemPrompt::Text(
        "You are a Rust expert assistant".into()
    ))

    // Model selection
    .model(Some("claude-sonnet-4-5-20250929".into()))
    .fallback_model(Some("claude-haiku-4-5-20251001".into()))

    // Conversation limits
    .max_turns(10u32)
    .max_budget_usd(Some(0.50))

    // Thinking and effort
    .thinking(Some(ThinkingConfig::Adaptive))
    .effort(Some(Effort::High))

    // Structured output
    .output_format(Some(serde_json::json!({
        "type": "json_schema",
        "schema": { "type": "object", "properties": {} }
    })))

    // CLI path (auto-detected if not set)
    .cli_path(Some("/path/to/claude".into()))

    // Settings sources
    .setting_sources(Some(vec![
        SettingSource::User,
        SettingSource::Project,
    ]))

    .build();
```

### Permission Modes

```rust
pub enum PermissionMode {
    AcceptAll,    // Auto-approve all tools
    AcceptEdits,  // Auto-approve file edits only
    Ask,          // Prompt for each tool (default)
    Callback,     // Use permission callback
}
```

## Message Types

### AssistantMessage

```rust
pub struct AssistantMessage {
    pub message: AssistantMessageInner,
    pub parent_tool_use_id: Option<String>,
}

pub struct AssistantMessageInner {
    pub role: String,  // "assistant"
    pub content: Vec<ContentBlock>,
}
```

### ResultMessage

```rust
pub struct ResultMessage {
    pub subtype: String,                        // "success" | "error_max_turns" | ...
    pub duration_ms: u64,
    pub duration_api_ms: u64,
    pub is_error: bool,
    pub num_turns: u32,
    pub session_id: String,
    pub total_cost_usd: Option<f64>,
    pub usage: Option<Value>,
    pub result: Option<String>,                 // Result text (if any)
    pub structured_output: Option<Value>,       // JSON output when output_format is set
}
```

### SystemMessage

```rust
pub struct SystemMessage {
    pub subtype: String,
    pub content: Option<Value>,
}
```

## Error Handling

### Error Types

```rust
pub enum ClaudeSDKError {
    CLINotFound(String),
    TransportError(String),
    MessageParse(String),
    NotConnected,
    AlreadyConnected,
    HookNotFound(String),
    PermissionCallbackNotSet,
    ControlTimeout { timeout_seconds: u64, request: String },
    Other(String),
}
```

### Handling Errors

```rust
use claude_agent_sdk_rust::ClaudeSDKError;

match query("prompt", None).await {
    Ok(stream) => { /* handle stream */ }
    Err(ClaudeSDKError::CLINotFound(msg)) => {
        eprintln!("Claude CLI not found: {}", msg);
        eprintln!("Install from: https://claude.com/claude-code");
    }
    Err(e) => eprintln!("Error: {}", e),
}
```

## Examples

### Example 1: Simple Code Review

```rust
use claude_agent_sdk_rust::{query, Message, ClaudeAgentOptions};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let options = ClaudeAgentOptions::builder()
        .allowed_tools(vec!["Read".into()])
        .system_prompt(SystemPrompt::Text(
            "You are a code reviewer. Focus on best practices.".into()
        ))
        .build();

    let messages = query(
        "Review the code in src/main.rs",
        Some(options)
    ).await?;

    let mut messages = Box::pin(messages);

    while let Some(msg) = messages.next().await {
        if let Message::Assistant(a) = msg? {
            for block in &a.message.content {
                if let Some(text) = block.as_text() {
                    println!("{}", text.text);
                }
            }
        }
    }

    Ok(())
}
```

### Example 2: Interactive Refactoring

```rust
use claude_agent_sdk_rust::{ClaudeSDKClient, ClaudeAgentOptions, Message};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let options = ClaudeAgentOptions::builder()
        .permission_mode(PermissionMode::AcceptEdits)
        .build();

    let mut client = ClaudeSDKClient::new(options);
    client.connect(None).await?;

    // First query
    client.query("Refactor src/utils.rs to use modern Rust patterns").await?;
    let messages = client.receive_response()?;
    let mut messages = Box::pin(messages);

    while let Some(msg) = messages.next().await {
        if let Message::Result(_) = msg? { break; }
    }
    drop(messages);

    // Follow-up query
    client.query("Add tests for the refactored code").await?;
    let messages = client.receive_response()?;
    let mut messages = Box::pin(messages);

    while let Some(msg) = messages.next().await {
        if let Message::Result(_) = msg? { break; }
    }
    drop(messages);

    client.disconnect().await?;
    Ok(())
}
```

### Example 3: Safety-Enhanced Agent

```rust
use claude_agent_sdk_rust::{
    ClaudeSDKClient, ClaudeAgentOptions, Message,
    callbacks::{PermissionCallback, permissions, HookCallback, hooks},
    types::{HookEvent, HookInput, HookOutput, HookContext,
            PermissionResult, ToolPermissionContext},
};
use async_trait::async_trait;
use serde_json::Value;

struct CommandValidator;

#[async_trait]
impl PermissionCallback for CommandValidator {
    async fn call(
        &self,
        tool_name: String,
        input: Value,
        _ctx: ToolPermissionContext,
    ) -> claude_agent_sdk_rust::Result<PermissionResult> {
        if tool_name == "Bash" {
            if let Some(cmd) = input.get("command").and_then(|v| v.as_str()) {
                // Block network access
                if cmd.contains("curl") || cmd.contains("wget") {
                    return Ok(permissions::deny("Network access blocked"));
                }
            }
        }
        Ok(permissions::allow())
    }
}

struct AuditLogger;

#[async_trait]
impl HookCallback for AuditLogger {
    async fn call(
        &self,
        input: HookInput,
        _tool_use_id: Option<String>,
        _ctx: HookContext,
    ) -> claude_agent_sdk_rust::Result<HookOutput> {
        if let HookInput::PreToolUse(pre_tool) = input {
            // Log to audit file
            println!("[AUDIT] {} - {:?}", pre_tool.tool_name, pre_tool.tool_input);
        }
        Ok(hooks::allow())
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = ClaudeSDKClient::new(ClaudeAgentOptions::default());

    // Register security controls
    client.set_permission_callback(CommandValidator);
    client.register_hook(HookEvent::PreToolUse, None, AuditLogger);

    client.connect(None).await?;
    client.query("Analyze system logs").await?;

    // Process messages...

    client.disconnect().await?;
    Ok(())
}
```

## Best Practices

### 1. Stream Handling

Always pin streams before iterating:

```rust
let messages = client.receive_response()?;
let mut messages = Box::pin(messages);  // Pin the stream

while let Some(msg) = messages.next().await {
    // Handle messages
}
```

### 2. Resource Cleanup

Drop streams before reusing client:

```rust
let messages = client.receive_response()?;
let mut messages = Box::pin(messages);

// Process messages...

drop(messages);  // Drop stream before next query

client.query("Next question").await?;
```

### 3. Error Handling

Handle specific error types:

```rust
match client.connect(None).await {
    Ok(_) => { /* connected */ }
    Err(ClaudeSDKError::CLINotFound(_)) => {
        // Provide installation instructions
    }
    Err(ClaudeSDKError::AlreadyConnected) => {
        // Client is already connected
    }
    Err(e) => eprintln!("Connection error: {}", e),
}
```

### 4. Permission Callbacks

Always return a result - never panic:

```rust
#[async_trait]
impl PermissionCallback for MyChecker {
    async fn call(...) -> Result<PermissionResult> {
        // Validate inputs
        // Return allow/deny
        // Never panic!
        Ok(permissions::allow())
    }
}
```

### 5. Hook Callbacks

Keep hooks fast - avoid blocking operations:

```rust
#[async_trait]
impl HookCallback for FastHook {
    async fn call(...) -> Result<HookOutput> {
        // Quick validation/logging only
        // Defer heavy operations to async hooks
        Ok(hooks::allow())
    }
}
```

## Troubleshooting

### CLI Not Found

```bash
# Install Claude Code CLI (native installer, recommended)
curl -fsSL https://claude.ai/install.sh | bash

# Or via npm
npm install -g @anthropic-ai/claude-code

# Or set custom path in your options
# .cli_path(Some("/path/to/claude".into()))
```

### Authentication Required

```bash
# Run claude and follow the browser login prompt
claude

# Or set an API key
export ANTHROPIC_API_KEY="sk-ant-..."
```

### Version Mismatch

```bash
# Check CLI version (requires 2.0.0+)
claude --version
```

## Further Reading

- [README.md]../README.md - Installation and setup
- [examples/]../examples/ - Complete working examples
- [Rust API Documentation]https://docs.rs/claude-agent-sdk - Full API reference (once published)
- [Claude Code Documentation]https://code.claude.com/docs - CLI documentation

## Support

- GitHub Issues: https://github.com/Wally869/claude-agent-sdk-rust/issues
- Claude Code: https://code.claude.com