Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gunpal5/claude-agent-sdk-dotnet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

20 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Claude Agent SDK for .NET (Unofficial)

NuGet .NET License

Unofficial .NET SDK for Claude Code. Build production-ready AI applications with Claude's advanced code generation, analysis, and agentic capabilities.

🎯 Status: Production Ready | πŸ“– Docs: Complete

Note: This is an unofficial community SDK. For official Anthropic SDKs, visit anthropic.com.

✨ Features

  • πŸš€ Simple Query API - One-shot queries with ClaudeAgent.QueryAsync()
  • πŸ’¬ Interactive Client - Multi-turn conversations with ClaudeSdkClient
  • πŸ“‘ Streaming Responses - Real-time partial message updates
  • πŸ› οΈ Tool Support - File operations (Read, Write, Edit), Bash commands, Web fetching
  • πŸ”’ Type-Safe - Strongly-typed messages and content blocks
  • ⚑ Async/Await - Built on modern C# async patterns with IAsyncEnumerable<T>
  • 🎯 Error Handling - Comprehensive exception hierarchy
  • 🧹 Resource Management - Automatic cleanup with IAsyncDisposable
  • βœ… Battle-Tested - 117 comprehensive tests covering edge cases
  • πŸ“Š Todo & Token Tracking - Monitor Claude's task progress and API usage
  • πŸ“š Well-Documented - Complete guides and interactive examples

πŸ“¦ Installation

Via NuGet Package Manager

dotnet add package ClaudeAgentSdk

Prerequisites

  1. .NET 8.0 or higher

    dotnet --version  # Should be 8.0+
  2. Claude Code CLI

    npm install -g @anthropic-ai/claude-code
  3. Anthropic API Key - Set as environment variable:

    # Windows (PowerShell)
    $env:ANTHROPIC_API_KEY = "your-api-key-here"
    
    # Linux/macOS
    export ANTHROPIC_API_KEY="your-api-key-here"

πŸš€ Quick Start

Simple Query

using ClaudeAgentSdk;

await foreach (var message in ClaudeAgent.QueryAsync("What is 2 + 2?"))
{
    if (message is AssistantMessage assistantMsg)
    {
        foreach (var block in assistantMsg.Content)
        {
            if (block is TextBlock textBlock)
            {
                Console.WriteLine(textBlock.Text);
            }
        }
    }
    else if (message is ResultMessage resultMsg)
    {
        Console.WriteLine($"βœ“ Completed in {resultMsg.DurationMs}ms");
    }
}

Interactive Multi-Turn Conversation

using ClaudeAgentSdk;

var options = new ClaudeAgentOptions { MaxTurns = 50 };

await using var client = new ClaudeSdkClient(options);
await client.ConnectAsync();

// First query
await client.QueryAsync("Create a Python web server");
await foreach (var msg in client.ReceiveResponseAsync())
{
    // Handle response...
}

// Follow-up query in same session
await client.QueryAsync("Now add authentication to it");
await foreach (var msg in client.ReceiveResponseAsync())
{
    // Handle response...
}

With Tool Support

var options = new ClaudeAgentOptions
{
    AllowedTools = new List<string> { "Read", "Write", "Edit", "Bash" },
    PermissionMode = PermissionMode.Default
};

await foreach (var message in ClaudeAgent.QueryAsync(
    "Create a file called hello.txt with 'Hello World'", options))
{
    if (message is AssistantMessage assistantMsg)
    {
        foreach (var block in assistantMsg.Content)
        {
            if (block is ToolUseBlock toolUse)
            {
                Console.WriteLine($"πŸ”§ Using tool: {toolUse.Name}");
            }
        }
    }
}

Tracking Todo Tasks and Token Usage

await foreach (var message in ClaudeAgent.QueryAsync("Build a REST API with auth"))
{
    switch (message)
    {
        case SystemMessage { Subtype: "todo" } sysMsg:
            // Display Claude's todo list
            break;

        case AssistantMessage { Content: var content }:
            foreach (var block in content)
            {
                if (block is ToolUseBlock { Name: "TodoWrite" } toolUse)
                {
                    // Parse and display todos from toolUse.Input
                }
            }
            break;

        case ResultMessage resultMsg:
            // Display token usage and cost
            var inputTokens = resultMsg.Usage["input_tokens"];
            var outputTokens = resultMsg.Usage["output_tokens"];
            Console.WriteLine($"Tokens: {inputTokens + outputTokens:N0}");
            Console.WriteLine($"Cost: ${resultMsg.TotalCostUsd:F6}");
            break;
    }
}

πŸ“š Documentation

Guides

Examples

  • ClaudeChat - Full-featured interactive CLI application
    • Simple query mode
    • Interactive conversation mode
    • Streaming mode
    • Tools demo mode
    • Todo and usage tracking mode

API Reference

Core Types

  • ClaudeAgent - Static class for simple queries

    • QueryAsync(prompt, options) - Execute a one-shot query
  • ClaudeSdkClient - Interactive client for multi-turn conversations

    • ConnectAsync(prompt?) - Connect to Claude
    • QueryAsync(prompt) - Send a query
    • ReceiveResponseAsync() - Receive messages until ResultMessage
    • ReceiveMessagesAsync() - Receive all messages continuously

Message Types

  • Message - Base class for all messages
  • AssistantMessage - Messages from Claude
  • UserMessage - Messages from user
  • SystemMessage - System notifications (including todos)
  • ResultMessage - Query completion with metrics
  • StreamEvent - Streaming progress updates

Content Blocks

  • TextBlock - Text content
  • ThinkingBlock - Claude's internal reasoning
  • ToolUseBlock - Tool invocation
  • ToolResultBlock - Tool execution result

Options

public class ClaudeAgentOptions
{
    public List<string> AllowedTools { get; set; }       // ["Read", "Write", "Bash"]
    public List<string> DisallowedTools { get; set; }
    public string? SystemPrompt { get; set; }
    public PermissionMode? PermissionMode { get; set; }  // Default, AllowAll, Deny
    public int? MaxTurns { get; set; }                   // Default: 25
    public string? Model { get; set; }                   // Default: claude-sonnet-4
    public bool IncludePartialMessages { get; set; }     // Enable streaming
    public string? Cwd { get; set; }                     // Working directory
    public Dictionary<string, string> Env { get; set; }  // Environment variables
    // ... and more
}

🎯 Use Cases

Code Generation

await foreach (var msg in ClaudeAgent.QueryAsync(
    "Create a REST API for a blog with CRUD operations in C#"))
{
    // Claude will generate the code with proper structure
}

Code Analysis

var options = new ClaudeAgentOptions
{
    AllowedTools = new List<string> { "Read", "Grep" }
};

await foreach (var msg in ClaudeAgent.QueryAsync(
    "Analyze the code in src/ directory for potential bugs", options))
{
    // Claude will read and analyze your code
}

File Operations

var options = new ClaudeAgentOptions
{
    AllowedTools = new List<string> { "Read", "Write", "Edit" }
};

await foreach (var msg in ClaudeAgent.QueryAsync(
    "Refactor all .cs files to use nullable reference types", options))
{
    // Claude will read, analyze, and modify files
}

Testing and QA

var options = new ClaudeAgentOptions
{
    AllowedTools = new List<string> { "Read", "Write", "Bash" }
};

await foreach (var msg in ClaudeAgent.QueryAsync(
    "Create unit tests for MyService.cs and run them", options))
{
    // Claude will write tests and execute them
}

πŸ”§ Advanced Features

Custom Transport

public class MyCustomTransport : ITransport
{
    public bool IsReady => true;

    public async Task ConnectAsync(CancellationToken ct) { /* ... */ }

    public async IAsyncEnumerable<Dictionary<string, object>> ReadMessagesAsync(
        CancellationToken ct)
    {
        // Custom message reading logic
        yield return message;
    }

    public async Task WriteAsync(string data, CancellationToken ct) { /* ... */ }
}

var client = new ClaudeSdkClient(options, new MyCustomTransport());

Permission Callbacks

var options = new ClaudeAgentOptions
{
    CanUseTool = (toolName, toolInput) =>
    {
        Console.WriteLine($"Allow tool {toolName}?");
        var response = Console.ReadLine();
        return response?.ToLower() == "yes"
            ? PermissionBehavior.Allow
            : PermissionBehavior.Deny;
    }
};

Error Handling

try
{
    await foreach (var msg in ClaudeAgent.QueryAsync("Your query"))
    {
        // Process messages
    }
}
catch (CliNotFoundException ex)
{
    Console.WriteLine("Claude Code CLI not found. Install with:");
    Console.WriteLine("  npm install -g @anthropic-ai/claude-code");
}
catch (CliConnectionException ex)
{
    Console.WriteLine($"Connection error: {ex}");
}
catch (ProcessException ex)
{
    Console.WriteLine($"Process failed: {ex.ExitCode}");
}

πŸ“¦ Building NuGet Package

cd src/ClaudeAgentSdk
dotnet pack --configuration Release

The package will be created in bin/Release/ClaudeAgentSdk.0.1.0.nupkg

Publishing to NuGet

dotnet nuget push bin/Release/ClaudeAgentSdk.0.1.0.nupkg \
  --api-key YOUR_API_KEY \
  --source https://api.nuget.org/v3/index.json

🀝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone repository
git clone https://github.com/gunpal5/claude-agent-sdk-dotnet.git
cd claude-agent-sdk-dotnet

# Restore dependencies
dotnet restore

# Build
dotnet build

# Run example
cd examples/ClaudeChat
dotnet run

πŸ“„ License

MIT License - see LICENSE file for details.

πŸ”— Links

πŸ’‘ Support

πŸŽ“ Example Projects

Check out the examples/ directory for complete working examples:

  • ClaudeChat - Interactive CLI with 5 modes (simple, interactive, streaming, tools, stats)
  • TodoAndUsageExample - Real-time tracking of todos and token usage

⚑ Performance

  • Streaming responses with minimal latency
  • Efficient JSON parsing with System.Text.Json
  • Async/await throughout for non-blocking I/O
  • Automatic resource cleanup
  • Subprocess communication optimized for large outputs (1MB buffer)

πŸ” Security

  • API keys handled securely via environment variables
  • Permission modes for tool usage control
  • Custom tool approval callbacks
  • No sensitive data logged by default
  • Process isolation for CLI execution

πŸ“Š Metrics & Monitoring

Track your usage:

if (message is ResultMessage result)
{
    // Token usage
    var tokens = result.Usage["input_tokens"] + result.Usage["output_tokens"];

    // Cost in USD
    var cost = result.TotalCostUsd;

    // Performance
    var duration = result.DurationMs;
    var apiTime = result.DurationApiMs;

    // Conversation
    var turns = result.NumTurns;
}

🌟 Why This SDK?

  • Production-Ready: Complete port of the official Python SDK
  • Idiomatic C#: Async/await, IAsyncEnumerable, IAsyncDisposable patterns
  • Type-Safe: Strong typing throughout with nullable reference types
  • Well-Tested: 117 comprehensive tests ensure reliability
  • Community-Driven: Open source and community maintained
  • Great Documentation: Multiple guides and working examples

This is an unofficial community SDK. For official Anthropic SDKs, visit anthropic.com.

About

Unofficial .NET SDK for Claude Code. Build production-ready AI applications with Claude's code generation and analysis capabilities. Supports streaming responses, multi-turn conversations, tool use, and comprehensive error handling. Complete port of the Python SDK with idiomatic C# async/await patterns.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages