Universal.Anthropic.ClaudeAgentSdk
2.0.3
dotnet add package Universal.Anthropic.ClaudeAgentSdk --version 2.0.3
NuGet\Install-Package Universal.Anthropic.ClaudeAgentSdk -Version 2.0.3
<PackageReference Include="Universal.Anthropic.ClaudeAgentSdk" Version="2.0.3" />
<PackageVersion Include="Universal.Anthropic.ClaudeAgentSdk" Version="2.0.3" />
<PackageReference Include="Universal.Anthropic.ClaudeAgentSdk" />
paket add Universal.Anthropic.ClaudeAgentSdk --version 2.0.3
#r "nuget: Universal.Anthropic.ClaudeAgentSdk, 2.0.3"
#:package Universal.Anthropic.ClaudeAgentSdk@2.0.3
#addin nuget:?package=Universal.Anthropic.ClaudeAgentSdk&version=2.0.3
#tool nuget:?package=Universal.Anthropic.ClaudeAgentSdk&version=2.0.3
Universal.Anthropic.ClaudeAgentSdk
⚠️ Unofficial. This is an independent, third-party wrapper — not published, maintained, endorsed, or supported by Anthropic.
- "Claude", "Claude Code", and "Anthropic" are trademarks of Anthropic PBC, referenced here only to describe compatibility.
- Provided as-is, with no warranty. Parts of the underlying CLI wire protocol aren't officially documented and may change without notice; review the source and test against your own use case before relying on this in production.
- You need your own Anthropic API key or Claude subscription — this package doesn't provide access, credentials, or billing of any kind.
Universal.Anthropic.ClaudeAgentSdk is a C# library for running the Claude Code CLI as a subprocess and consuming its stream-json output, in the same spirit as Anthropic's official TypeScript/Python Claude Agent SDKs.
It does not bundle the claude executable inside the NuGet package, but it can find one for you in three ways:
ClaudeCodeExecutableSource.SystemPath(default) — resolvesclaude/claude.exefromPATH. Install it separately withnpm install -g @anthropic-ai/claude-codeor a platform installer.ClaudeCodeExecutableSource.Download— downloads the official native binary for your OS/architecture directly fromdownloads.claude.ai(the same source the official install scripts use), verifies its SHA-256 checksum against the published release manifest, and caches it under your local application data folder. No Node.js, npm, or shell installer required — this works the same way on Windows, macOS, and Linux.ClaudeCodeExecutableSource.SystemPathThenDownload— triesPATHfirst (so a machine that already has Claude Code installed keeps using that installation), and only downloads a cached copy if nothing is found. This is resolved lazily on each query, not at startup, so it always reflects whatever's onPATHat execution time.ClaudeCodeQuery.Options.Executable.ClaudeCodePath— set this to use aclaudebinary you already have (e.g. one your application bundles itself). It always wins overSourcewhen set.
Executable is its own ClaudeCodeExecutableOptions type (ClaudeCodePath, Source, DownloadVersion, DownloadCacheDirectory) rather than living directly on ClaudeCodeQuery.Options, because ClaudeCodeDownloader only ever needs those four settings — not the rest of ClaudeCodeQuery.Options (Model, SystemPrompt, AllowedTools, etc.), which are query-only concerns. Call ClaudeCodeDownloader directly with just a ClaudeCodeExecutableOptions if you want to manage the binary independently of running any query.
Updating a downloaded binary
Once ClaudeCodeDownloader has cached a binary for a platform, EnsureDownloadedAsync (and therefore ExecutableSource.Download/SystemPathThenDownload) never checks the network again on its own, even with DownloadVersion left at the default "latest" — it just keeps using what's cached. Call these explicitly on whatever schedule suits your application:
// Check without downloading anything.
var check = await ClaudeCodeDownloader.CheckForUpdateAsync(options.Executable);
if (check.IsUpdateAvailable)
{
Console.WriteLine($"{check.InstalledVersion ?? "(none)"} -> {check.LatestVersion} available");
}
// Fetch and cache whatever's currently latest, regardless of what's cached.
string updatedPath = await ClaudeCodeDownloader.UpdateAsync(options.Executable);
Old cached versions aren't deleted automatically; prune ClaudeCodeExecutableOptions.DownloadCacheDirectory yourself if that matters for your deployment.
Using a Claude Pro/Max/Team subscription instead of API billing
This SDK never touches authentication itself — it just spawns claude, which reads whatever credentials it's already configured with:
- If
claudehas already been logged into interactively on the machine (claude→ browser login), the subprocess reuses that cached credential (OS keychain on macOS,~/.claude/.credentials.jsonon Linux,%USERPROFILE%\.claude\.credentials.jsonon Windows) automatically. Nothing to configure. - For headless machines (CI, servers, containers), run
claude setup-tokenonce to mint a one-year OAuth token tied to the Pro/Max/Team/Enterprise subscription, then pass it through:
This bills against the subscription's quota rather than pay-per-token API usage.options.EnvironmentVariables = new Dictionary<string, string> { ["CLAUDE_CODE_OAUTH_TOKEN"] = "..." };
Two gotchas: CLAUDE_CODE_OAUTH_TOKEN is ignored when ClaudeCodeQuery.Options.Bare is true; and if ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN is also present in the subprocess's inherited environment, it takes precedence over both the OAuth token and any interactive subscription login, so a stray API key env var will silently switch you to pay-per-token billing.
Logging in from code, including across devices
For a machine with no browser of its own (a remote box, a container), ClaudeCodeQuery.AuthenticateAsync drives the same OAuth login the CLI's own claude/claude setup-token commands use, but over the control channel instead of an interactive TUI:
var query = await ClaudeCodeClient.StartAsync(options);
OAuthAuthenticationUrls urls = await query.AuthenticateAsync();
// urls.AutomaticUrl only completes if opened on this same machine (localhost redirect).
// urls.ManualUrl works from literally any device/browser -- open it anywhere, log in,
// and its success page displays a code instead of redirecting.
Console.WriteLine($"Open this URL on any device to log in: {urls.ManualUrl}");
string pastedCode = Console.ReadLine(); // paste the "authorizationCode#state" shown on that page
AccountInfo account = await query.SubmitOAuthCallbackAsync(pastedCode);
If a browser is available on the same machine instead, open urls.AutomaticUrl there and call WaitForOAuthCompletionAsync() instead of SubmitOAuthCallbackAsync — it blocks until the CLI's own localhost redirect listener resolves the flow, with no code to paste. Either way, once the flow completes the same session picks up the new credentials immediately; no respawn needed. Both completion calls are genuine network round trips (token exchange), so pass a generous timeout rather than the default.
Usage
var options = new ClaudeCodeQuery.Options
{
WorkingDirectory = @"C:\my\project",
AllowedTools = new[] { "Read", "Grep" },
};
// `await using` is required: a plain `await foreach` alone does not stop the subprocess when the loop
// ends -- this class supports resuming the same conversation with further turns after a bare `await foreach`
// completes, so only an explicit Dispose/CloseAsync (not "the loop finished") means "I'm done with this query."
var query = ClaudeCodeClient.Query("What does this repo do?", options);
await using (query)
{
await foreach (var message in query)
{
switch (message)
{
case AssistantMessage assistant:
Console.WriteLine(assistant.Message.Content);
break;
case ResultMessage result:
Console.WriteLine($"Cost: ${result.TotalCostUsd}");
break;
}
}
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.10)
- Newtonsoft.Json (>= 13.0.4)
- System.Threading.Channels (>= 10.0.10)
- Universal.Anthropic.Client (>= 3.0.5)
- Universal.Common.Json (>= 1.9.0)
- Universal.Common.Serialization (>= 2.4.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Universal.Anthropic.ClaudeAgentSdk:
| Package | Downloads |
|---|---|
|
Universal.Operative.Sdk.Anthropic.ClaudeAgentSdk
Experimental IModel adapter that runs the Claude Code CLI (via Universal.Anthropic.ClaudeAgentSdk) as an Operative model provider. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Updated Universal.Common.Json dependency to 1.9.0.