C# (.NET) and TypeScript SDKs
Besides Python, Anthropic's official SDKs exist for C#, TypeScript, Java, Go, Ruby and PHP. For a .NET developer the C# SDK (NuGet package Anthropic) matters most — it also includes the Microsoft.Extensions.AI IChatClient integration.
10.1 C# SDK setup
dotnet new console -n ClaudeDemo
cd ClaudeDemo
dotnet add package Anthropic # official SDK (.NET Standard 2.0+)
# Separate packages for platforms: Anthropic.Bedrock, Anthropic.Vertex, Anthropic.Foundry, Anthropic.Aws10.2 Basic request and reading the response
using Anthropic;
using Anthropic.Models.Messages;
AnthropicClient client = new(); // reads ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL from the environment
var message = await client.Messages.Create(new MessageCreateParams
{
Model = "claude-opus-5-5",
MaxTokens = 1024,
System = "You are a .NET expert.",
Messages = [ new UserMessageParam { Content = "When should I implement IDisposable?" } ],
});
foreach (var block in message.Content) // Content is a discriminated union
{
if (block.TryPickText(out var textBlock)) // narrow the type with TryPick*
Console.WriteLine(textBlock.Text);
}
Console.WriteLine($"{message.StopReason} | in={message.Usage.InputTokens} out={message.Usage.OutputTokens}");10.3 Streaming and thinking (C#)
var parameters = new MessageCreateParams
{
Model = "claude-opus-5-5",
MaxTokens = 64000,
Thinking = new ThinkingConfigAdaptive { Display = Display.Summarized },
Messages = [ new UserMessageParam { Content = "Explain the CQRS pattern" } ],
};
// Streaming methods have the "Streaming" suffix and return IAsyncEnumerable
await foreach (RawMessageStreamEvent ev in client.Messages.CreateStreaming(parameters))
{
if (ev.TryPickContentBlockDelta(out var delta) && delta.Delta.TryPickText(out var text))
Console.Write(text.Text);
}10.4 Tool definition (C#)
using System.Text.Json;
var p = new MessageCreateParams
{
Model = "claude-opus-5-5",
MaxTokens = 16000,
Tools = [
new Tool {
Name = "get_weather",
Description = "Returns the current weather of a city",
InputSchema = new() {
Properties = new Dictionary<string, JsonElement> {
["location"] = JsonSerializer.SerializeToElement(
new { type = "string", description = "Name of the city" }),
},
Required = ["location"],
},
},
],
Messages = [ new UserMessageParam { Content = "Weather in Pune?" } ],
};
// If the response has a ToolUseBlock, run the function and send back a ToolResultBlockParam.
// Do not want to write the loop yourself? Use the beta BetaToolRunner (Anthropic.Helpers.Beta).10.5 IChatClient integration (Microsoft.Extensions.AI)
You can expose AnthropicClient as an IChatClient. The benefit: middleware from the Semantic Kernel / Microsoft.Extensions.AI ecosystem (function invocation, logging, caching) and tools from the MCP C# SDK work directly with Claude — switching providers is easy.
using Anthropic;
using Microsoft.Extensions.AI;
using ModelContextProtocol.Client;
AnthropicClient client = new();
IChatClient chatClient = client.AsIChatClient("claude-opus-5-5")
.AsBuilder()
.UseFunctionInvocation() // tool calls will run automatically
.Build();
// Tools from a remote MCP server via the MCP C# SDK
McpClient learningServer = await McpClient.CreateAsync(
new HttpClientTransport(new() { Endpoint = new("https://learn.microsoft.com/api/mcp") }));
ChatOptions options = new() { Tools = [.. await learningServer.ListToolsAsync()] };
Console.WriteLine(await chatClient.GetResponseAsync("Tell me about IChatClient", options));10.6 C# errors, retries, timeouts
| Status | Exception |
|---|---|
| 400 | AnthropicBadRequestException |
| 401 | AnthropicUnauthorizedException |
| 403 | AnthropicForbiddenException |
| 404 | AnthropicNotFoundException |
| 429 | AnthropicRateLimitException |
| 5xx | Anthropic5xxException |
| Mid-stream | AnthropicSseException |
| Network | AnthropicIOException |
| Base classes | AnthropicApiException, Anthropic4xxException, AnthropicException |
AnthropicClient client = new() { MaxRetries = 3, Timeout = TimeSpan.FromSeconds(60) };
// Different options for one call (does not change the original client)
var msg = await client
.WithOptions(o => o with { MaxRetries = 5 })
.Messages.Create(parameters);
// Need the raw HTTP response (headers, status)?
var raw = await client.WithRawResponse.Messages.Create(parameters);
Console.WriteLine(raw.StatusCode);10.7 TypeScript SDK
// npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // reads ANTHROPIC_API_KEY from the environment
const response = await client.messages.create({
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: "What is useEffect cleanup in React?" }],
});
for (const block of response.content) {
if (block.type === "text") console.log(block.text); // narrow by type
}
// Streaming
const stream = client.messages.stream({
model: "claude-opus-5-5", max_tokens: 64000,
messages: [{ role: "user", content: "Explain the Next.js app router" }],
});
stream.on("text", (t) => process.stdout.write(t));
const finalMsg = await stream.finalMessage();// Tool Runner + Zod (the SDK runs the loop)
import { betaZodTool } from "@anthropic-ai/sdk/helpers/beta/zod";
import { z } from "zod";
const getWeather = betaZodTool({
name: "get_weather",
description: "Weather of a city",
inputSchema: z.object({ location: z.string().describe("City") }),
run: async (input) => `${input.location}: 31°C`,
});
const finalMessage = await client.beta.messages.toolRunner({
model: "claude-opus-5-5", max_tokens: 16000,
tools: [getWeather],
messages: [{ role: "user", content: "Weather in Delhi?" }],
});