DevNitro.ClaudeAgentSdk 1.0.0

Claude Agent SDK for .NET (Unofficial)

.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.

Origin: Based on gunpal5/claude-agent-sdk-dotnet, cloned and modified for DevNitro. Published only to a local NuGet feed as DevNitro.ClaudeAgentSdk.

โœจ 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

From the local NuGet feed

This package is not on nuget.org. Pack it into _local-nuget (see Building the NuGet Package), then add that folder as a package source and reference it:

dotnet add package DevNitro.ClaudeAgentSdk --source <path-to-repo>/_local-nuget

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

Use pack-all.cs (requires the .NET 10 SDK). It builds, audits dependencies, runs tests, then packs into _local-nuget and tags the commit v<version>:

dotnet pack-all.cs                  # main/master: next stable patch (first pack is 1.0.0)
dotnet pack-all.cs -- --minor       # 1.0.x -> 1.1.0
dotnet pack-all.cs -- --help        # all options (script arguments go after --)

On other branches it produces a prerelease like 1.0.1-<branch>.<timestamp>.

๐Ÿค 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/HowdyChad/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.

๐Ÿ’ก 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 logging by default. Set CLAUDE_SDK_DEBUG=1 to write debug logs to the console and ~/.claudesdk/. Debug logs can include full prompts, so enable only for troubleshooting.
  • 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.

No packages depend on DevNitro.ClaudeAgentSdk.

v0.1.0 - Initial Release - Simple query API with ClaudeAgent.QueryAsync() - Interactive multi-turn conversations with ClaudeSdkClient - Streaming response support - Comprehensive tool support (Read, Write, Edit, Bash, etc.) - Type-safe message and content block handling - Full async/await support - 117 comprehensive tests with 100% pass rate - Complete documentation and examples

Version Downloads Last updated
1.0.0 1 09/24/2026