Claude Seekho

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

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

StatusException
400AnthropicBadRequestException
401AnthropicUnauthorizedException
403AnthropicForbiddenException
404AnthropicNotFoundException
429AnthropicRateLimitException
5xxAnthropic5xxException
Mid-streamAnthropicSseException
NetworkAnthropicIOException
Base classesAnthropicApiException, 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?" }],
});