ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework 1.1.0-rc4

Prefix Reserved
This is a prerelease version of ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework.
dotnet add package ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework --version 1.1.0-rc4
                    
NuGet\Install-Package ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework -Version 1.1.0-rc4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework" Version="1.1.0-rc4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework" Version="1.1.0-rc4" />
                    
Directory.Packages.props
<PackageReference Include="ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework --version 1.1.0-rc4
                    
#r "nuget: ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework, 1.1.0-rc4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework@1.1.0-rc4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework&version=1.1.0-rc4&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework&version=1.1.0-rc4&prerelease
                    
Install as a Cake Tool

ManagedCode.ClaudeCodeSharpSDK

CI Release CodeQL NuGet License: MIT

ManagedCode.ClaudeCodeSharpSDK is a .NET SDK for driving the Claude Code CLI from C#.

It is intentionally CLI-first. The library does not reimplement Anthropic APIs or invent its own transport. It wraps the local claude binary, runs Claude Code in print mode, and maps the emitted protocol into typed C# models.

What You Get

  • ClaudeClient / ClaudeThread API for start, resume, run, and stream workflows
  • real Claude Code print-mode transport via claude -p
  • typed parsing for stream-json events
  • structured output with StructuredOutputSchema
  • optional Microsoft.Extensions.AI adapter package
  • optional Microsoft Agent Framework adapter package
  • repository automation that tracks upstream changes in anthropics/claude-code

Source Of Truth

This SDK follows the real Claude Code CLI contract in print mode:

  • claude -p --output-format json
  • claude -p --output-format stream-json --verbose
  • upstream reference repository: anthropics/claude-code

If the docs in this repository and the observed CLI behavior ever diverge, the observed CLI behavior wins and the SDK should be updated to match.

Upstream tracking is built into the repo:

Packages

Core SDK:

dotnet add package ManagedCode.ClaudeCodeSharpSDK

Optional Microsoft.Extensions.AI adapter:

dotnet add package ManagedCode.ClaudeCodeSharpSDK.Extensions.AI

Optional Microsoft Agent Framework adapter:

dotnet add package ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework --prerelease

Prerequisites

Before using the SDK, you need:

  • claude installed and available in PATH, or configured via ClaudeOptions.ClaudeExecutablePath
  • an authenticated local Claude Code session for real runs

Quick sanity check:

claude --version
claude --help
claude -p --output-format json --dangerously-skip-permissions --no-session-persistence "Reply with ok only."

Quickstart

using ManagedCode.ClaudeCodeSharpSDK.Client;

using var client = new ClaudeClient();
using var thread = client.StartThread();

var result = await thread.RunAsync("Diagnose failing tests and propose a fix.");

Console.WriteLine(result.FinalResponse);
Console.WriteLine($"Items: {result.Items.Count}");

ClaudeClient auto-starts by default. If you want explicit lifecycle control, create it with AutoStart = false and call StartAsync() yourself.

Core Concepts

Client

ClaudeClient owns executable discovery, lifecycle, and metadata queries:

  • StartThread()
  • ResumeThread(sessionId)
  • GetCliMetadata()
  • GetCliUpdateStatus()

Thread

ClaudeThread represents one Claude Code conversation/session:

  • turns are serialized per thread instance
  • RunAsync(...) returns the final response plus collected items
  • RunStreamedAsync(...) exposes the parsed event stream

Transport

At runtime the SDK executes Claude Code in print mode and parses stream-json output. It does not maintain a separate protocol implementation.

Streaming

using ManagedCode.ClaudeCodeSharpSDK.Client;
using ManagedCode.ClaudeCodeSharpSDK.Models;

using var client = new ClaudeClient();
using var thread = client.StartThread();

var streamed = await thread.RunStreamedAsync("Implement the fix.");

await foreach (var evt in streamed.Events)
{
    switch (evt)
    {
        case ItemCompletedEvent completed:
            Console.WriteLine($"Item: {completed.Item.Type}");
            break;

        case TurnCompletedEvent done:
            Console.WriteLine(done.Result);
            Console.WriteLine($"Output tokens: {done.Usage.OutputTokens}");
            break;
    }
}

Structured Output

using System.Text.Json.Serialization;
using ManagedCode.ClaudeCodeSharpSDK.Client;
using ManagedCode.ClaudeCodeSharpSDK.Models;

public sealed record RepositorySummary(string Summary, string Status);

[JsonSerializable(typeof(RepositorySummary))]
internal sealed partial class AppJsonContext : JsonSerializerContext;

var schema = StructuredOutputSchema.Map<RepositorySummary>(
    additionalProperties: false,
    (response => response.Summary, StructuredOutputSchema.PlainText()),
    (response => response.Status, StructuredOutputSchema.PlainText()));

using var client = new ClaudeClient();
using var thread = client.StartThread();

var result = await thread.RunAsync(
    "Summarize the repository status as JSON.",
    schema,
    AppJsonContext.Default.RepositorySummary);

Console.WriteLine(result.TypedResponse.Status);
Console.WriteLine(result.TypedResponse.Summary);

If you want full turn control, use TurnOptions:

using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(30));

var result = await thread.RunAsync(
    "Summarize the repository status as JSON.",
    AppJsonContext.Default.RepositorySummary,
    new TurnOptions
    {
        OutputSchema = schema,
        CancellationToken = timeout.Token,
    });

Notes:

  • typed runs require TurnOptions.OutputSchema or a direct outputSchema overload
  • the JsonTypeInfo<T> overloads are the AOT-safe path
  • reflection-based typed overloads are intentionally marked as AOT-unsafe

Resume An Existing Session

using ManagedCode.ClaudeCodeSharpSDK.Client;

using var client = new ClaudeClient();
using var thread = client.ResumeThread("existing-session-id");

var result = await thread.RunAsync("Continue from the previous plan.");
Console.WriteLine(result.FinalResponse);

Microsoft Agent Framework

ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework is a thin Microsoft Agent Framework package over the existing ClaudeChatClient. It is currently published as a prerelease package because the upstream Microsoft.Agents.AI dependency is still prerelease.

using ManagedCode.ClaudeCodeSharpSDK.Extensions.AI;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

IChatClient chatClient = new ClaudeChatClient();

AIAgent agent = chatClient.AsAIAgent(
    name: "ClaudeAssistant",
    instructions: "You are a concise coding assistant.");

var response = await agent.RunAsync("What changed in this repository?");
Console.WriteLine(response.Text);

DI registration:

using ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework.Extensions;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

builder.Services.AddClaudeCodeAgent(
    configureAgent: options =>
    {
        options.Name = "ClaudeAssistant";
        options.ChatOptions = new ChatOptions
        {
            Instructions = "You are a concise coding assistant."
        };
    });

app.MapGet("/agent", async (AIAgent agent) =>
{
    var response = await agent.RunAsync("Summarize the repository");
    return response.ToString();
});

Keyed DI registration:

using ManagedCode.ClaudeCodeSharpSDK.Extensions.AgentFramework.Extensions;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddKeyedClaudeCodeAgent(
    "claude-main",
    configureAgent: options =>
    {
        options.Name = "ClaudeAssistant";
        options.ChatOptions = new ChatOptions
        {
            Instructions = "You are a concise coding assistant."
        };
    });

using var provider = services.BuildServiceProvider();
var keyedAgent = provider.GetRequiredKeyedService<AIAgent>("claude-main");

This package builds on the existing IChatClient adapter, so the canonical MAF path remains IChatClient.AsAIAgent(...); the Claude-specific package adds a supported package boundary and DI convenience methods.

Current limitations are the same as the underlying ClaudeChatClient adapter:

  • message input is text-first in the current runtime surface
  • Claude CLI-managed tools are not exposed as provider-specific MAF callbacks by this SDK
  • streaming behavior follows ClaudeChatClient updates rather than token-level deltas

Thread Options

ThreadOptions maps the Claude Code flags currently supported by this SDK.

using ManagedCode.ClaudeCodeSharpSDK.Client;
using ManagedCode.ClaudeCodeSharpSDK.Models;

var options = new ThreadOptions
{
    Model = ClaudeModels.ClaudeOpus45,
    PermissionMode = PermissionMode.AcceptEdits,
    AllowedTools = ["Read", "Write", "Edit"],
    DisallowedTools = ["Bash"],
    AdditionalDirectories = ["/workspace", "/tmp"],
    SystemPrompt = "Be concise and explicit about risk.",
    AppendSystemPrompt = "Prefer concrete file paths in explanations.",
    MaxBudgetUsd = 0.50m,
    NoSessionPersistence = true,
    AdditionalCliArguments = ["--some-future-flag", "custom-value"],
};

using var thread = client.StartThread(options);

Not every flag in the upstream CLI is necessarily surfaced yet, but unsupported future non-transport flags can still be passed through AdditionalCliArguments. SDK-managed transport flags such as --print, --output-format, --input-format, and --json-schema are reserved and rejected if passed through manually.

Metadata And Update Checks

using System.Linq;
using ManagedCode.ClaudeCodeSharpSDK.Client;

using var client = new ClaudeClient();

var metadata = client.GetCliMetadata();
Console.WriteLine($"Installed Claude Code: {metadata.InstalledVersion}");
Console.WriteLine($"Default model: {metadata.DefaultModel}");

foreach (var model in metadata.Models.Where(model => model.IsListed))
{
    Console.WriteLine(model.Slug);
}

var update = client.GetCliUpdateStatus();
if (update.IsUpdateAvailable)
{
    Console.WriteLine(update.UpdateMessage);
    Console.WriteLine(update.UpdateCommand);
}

Current metadata support includes:

  • installed CLI version from claude --version
  • default model discovery from Claude settings files with SDK fallback to sonnet
  • SDK-known model aliases/constants
  • upstream tag comparison against anthropics/claude-code

Logging

using ManagedCode.ClaudeCodeSharpSDK.Client;
using ManagedCode.ClaudeCodeSharpSDK.Configuration;
using Microsoft.Extensions.Logging;

public sealed class ConsoleClaudeLogger : ILogger
{
    public IDisposable BeginScope<TState>(TState state) where TState : notnull => NullScope.Instance;
    public bool IsEnabled(LogLevel logLevel) => true;

    public void Log<TState>(
        LogLevel logLevel,
        EventId eventId,
        TState state,
        Exception? exception,
        Func<TState, Exception?, string> formatter)
    {
        Console.WriteLine($"[{logLevel}] {formatter(state, exception)}");
        if (exception is not null)
        {
            Console.WriteLine(exception);
        }
    }

    private sealed class NullScope : IDisposable
    {
        public static NullScope Instance { get; } = new();
        public void Dispose() { }
    }
}

using var client = new ClaudeClient(new ClaudeOptions
{
    Logger = new ConsoleClaudeLogger(),
});

Current Limitations

  • the current SDK transport is print-mode only
  • LocalImageInput exists in the model layer but is rejected in the current Claude print-mode implementation
  • TurnOptions.ReplayUserMessages is reserved for future stream-json input support and currently throws
  • the Microsoft.Extensions.AI adapter is text-first and does not expose custom Claude internal item types
  • ChatOptions.Tools is ignored because Claude Code manages tools internally
  • authenticated end-to-end behavior depends on the local Claude Code session available on the machine

Microsoft.Extensions.AI Adapter

using Microsoft.Extensions.AI;
using ManagedCode.ClaudeCodeSharpSDK.Extensions.AI;

IChatClient client = new ClaudeChatClient();

var response = await client.GetResponseAsync(
[
    new ChatMessage(ChatRole.User, "Summarize the repository."),
]);

Console.WriteLine(response.Text);

Streaming:

await foreach (var update in client.GetStreamingResponseAsync(
[
    new ChatMessage(ChatRole.User, "Implement the fix."),
]))
{
    Console.Write(update.Text);
}

Claude-specific options flow through ChatOptions.AdditionalProperties:

using ManagedCode.ClaudeCodeSharpSDK.Client;
using Microsoft.Extensions.AI;

var options = new ChatOptions
{
    AdditionalProperties = new AdditionalPropertiesDictionary
    {
        ["claude:working_directory"] = "/workspace",
        ["claude:permission_mode"] = PermissionMode.AcceptEdits,
        ["claude:allowed_tools"] = new[] { "Read", "Write" },
        ["claude:max_budget_usd"] = 0.25m,
    },
};

See:

Development

Clone with submodules:

git clone https://github.com/managedcode/ClaudeCodeSharpSDK.git
cd ClaudeCodeSharpSDK
git submodule update --init --recursive

Build and test:

dotnet build ManagedCode.ClaudeCodeSharpSDK.slnx -c Release -warnaserror
dotnet test --solution ManagedCode.ClaudeCodeSharpSDK.slnx -c Release

Smoke-only subset:

dotnet test --project ClaudeCodeSharpSDK.Tests/ClaudeCodeSharpSDK.Tests.csproj -c Release --no-build -- --treenode-filter "/*/*/*/ClaudeCli_Smoke_*"

Documentation Map

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0-rc4 18 3/16/2026