AgentStack
MCP verified MIT Self-run

Claude AgentSdk

mcp-ajgit-claude-agentsdk · by AJGit

A C# SDK for building intelligent agents with Claude Code CLI

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add mcp-ajgit-claude-agentsdk

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Claude AgentSdk? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Claude.AgentSdk

A C# SDK for building agents with the Claude Code CLI. This SDK provides a .NET interface to the same agent capabilities that power Claude Code.

Requirements

  • .NET 8.0, 9.0, or 10.0
  • Claude Code CLI installed and available in PATH

Installation

Install Claude Code CLI

npm install -g @anthropic-ai/claude-code

Verify installation:

claude --version

Add SDK to Your Project

dotnet add package AJGit.Claude.AgentSdk

For ASP.NET Core dependency injection support:

dotnet add package AJGit.Claude.AgentSdk.Extensions.DependencyInjection

Or reference the project directly:

Quick Start

Simple Query

using Claude.AgentSdk;
using Claude.AgentSdk.Messages;

var client = new ClaudeAgentClient();

await foreach (var message in client.QueryAsync("What is the capital of France?"))
{
    if (message is AssistantMessage assistant)
    {
        foreach (var block in assistant.MessageContent.Content)
        {
            if (block is TextBlock text)
            {
                Console.Write(text.Text);
            }
        }
    }
}

With Options

var options = new ClaudeAgentOptions
{
    Model = "sonnet",                              // Model to use (string)
    MaxTurns = 10,                                 // Limit conversation turns
    SystemPrompt = "You are a helpful assistant.", // Custom system prompt (string)
    AllowedTools = ["Read", "Glob", "Grep"],       // Tools Claude can use
    WorkingDirectory = "/path/to/project"          // Working directory
};

var client = new ClaudeAgentClient(options);

Strongly-Typed Model Selection

Use ModelIdentifier for type-safe model selection with IntelliSense support:

using Claude.AgentSdk.Types;

var options = new ClaudeAgentOptions
{
    // New: Strongly-typed model selection
    ModelId = ModelIdentifier.Sonnet,              // Use predefined model aliases
    FallbackModelId = ModelIdentifier.Haiku,       // Type-safe fallback

    // Specific versions also available
    // ModelId = ModelIdentifier.ClaudeOpus45,     // claude-opus-4-5-20251101
    // ModelId = ModelIdentifier.ClaudeSonnet4,    // claude-sonnet-4-20250514

    // Custom models supported
    // ModelId = ModelIdentifier.Custom("my-fine-tuned-model"),

    MaxTurns = 10,
    AllowedTools = ["Read", "Glob", "Grep"]
};

// Backward compatible: string Model property still works
var legacyOptions = new ClaudeAgentOptions { Model = "sonnet" };
Available Model Identifiers

| Identifier | Value | |------------|-------| | ModelIdentifier.Sonnet | "sonnet" | | ModelIdentifier.Opus | "opus" | | ModelIdentifier.Haiku | "haiku" | | ModelIdentifier.ClaudeSonnet4 | "claude-sonnet-4-20250514" | | ModelIdentifier.ClaudeOpus45 | "claude-opus-4-5-20251101" | | ModelIdentifier.ClaudeHaiku35 | "claude-3-5-haiku-20241022" |

Strongly-Typed Tool Names

Use ToolName for type-safe tool references with IntelliSense support:

using Claude.AgentSdk.Types;

var options = new ClaudeAgentOptions
{
    // Strongly-typed tool names
    AllowedTools = [ToolName.Read, ToolName.Write, ToolName.Bash, ToolName.Grep],
    DisallowedTools = [ToolName.WebSearch, ToolName.WebFetch],

    // MCP tool names use factory method
    // AllowedTools = [ToolName.Mcp("email-tools", "search_inbox")]
};

// Backward compatible: string arrays still work
var legacyOptions = new ClaudeAgentOptions
{
    AllowedTools = ["Read", "Write", "Bash"]
};
Available Built-in Tools

| Tool Name | Description | |-----------|-------------| | ToolName.Read | Read files from filesystem | | ToolName.Write | Write files to filesystem | | ToolName.Edit | Edit existing files | | ToolName.MultiEdit | Multiple edits in one operation | | ToolName.Bash | Execute bash commands | | ToolName.Grep | Search file contents | | ToolName.Glob | Find files by pattern | | ToolName.Task | Spawn subagents | | ToolName.WebFetch | Fetch web content | | ToolName.WebSearch | Search the web | | ToolName.TodoRead | Read todo list | | ToolName.TodoWrite | Update todo list | | ToolName.NotebookEdit | Edit Jupyter notebooks | | ToolName.AskUserQuestion | Ask user questions | | ToolName.Skill | Invoke skills | | ToolName.TaskOutput | Get background task output | | ToolName.KillShell | Terminate background shell |

MCP Tool Names

Create MCP tool names using the factory method:

// Format: mcp____
var mcpTool = ToolName.Mcp("email-tools", "search_inbox");
// Result: "mcp__email-tools__search_inbox"

// Or use McpServerName for even more type safety
var server = McpServerName.Sdk("email-tools");
var tool = server.Tool("search_inbox");  // Returns ToolName

Strongly-Typed MCP Server Names

Use McpServerName for type-safe MCP server references:

using Claude.AgentSdk.Types;

// Create server name
var server = McpServerName.Sdk("my-tools");

// Get tool names from server
var searchTool = server.Tool("search");       // ToolName: "mcp__my-tools__search"
var readTool = server.Tool("read_file");      // ToolName: "mcp__my-tools__read_file"

// Use with AllowedTools
var options = new ClaudeAgentOptions
{
    AllowedTools = [
        server.Tool("search"),
        server.Tool("read_file"),
        server.Tool("write_file")
    ]
};

Using CLAUDE.md Files

CLAUDE.md files provide project-specific context and instructions. To load them, you must explicitly specify SettingSources:

var options = new ClaudeAgentOptions
{
    // Use Claude Code's system prompt (includes tool instructions, code guidelines, etc.)
    SystemPrompt = SystemPromptConfig.ClaudeCode(),

    // IMPORTANT: You must specify SettingSources to load CLAUDE.md files
    // The claude_code preset alone does NOT load CLAUDE.md automatically
    SettingSources = [SettingSource.Project],  // Load project-level CLAUDE.md

    WorkingDirectory = "/path/to/project"
};

var client = new ClaudeAgentClient(options);

await foreach (var message in client.QueryAsync("Help me refactor this code"))
{
    // Claude now has access to your project guidelines from CLAUDE.md
}
System Prompt Options
// Option 1: Custom string prompt (replaces default entirely)
SystemPrompt = "You are a Python specialist."

// Option 2: Use Claude Code's preset (includes tools, code guidelines, safety)
SystemPrompt = SystemPromptConfig.ClaudeCode()

// Option 3: Use preset with appended instructions
SystemPrompt = SystemPromptConfig.ClaudeCode(append: "Always use TypeScript strict mode.")

// Option 4: Explicit preset configuration
SystemPrompt = new PresetSystemPrompt
{
    Preset = "claude_code",
    Append = "Focus on performance optimization."
}
Setting Sources
// Load only project-level CLAUDE.md (./CLAUDE.md or ./.claude/CLAUDE.md)
SettingSources = [SettingSource.Project]

// Load only user-level CLAUDE.md (~/.claude/CLAUDE.md)
SettingSources = [SettingSource.User]

// Load both project and user-level CLAUDE.md
SettingSources = [SettingSource.Project, SettingSource.User]

// Load project, user, and local settings (CLAUDE.local.md - gitignored)
SettingSources = [SettingSource.Project, SettingSource.User, SettingSource.Local]

CLAUDE.md locations:

  • Project-level: CLAUDE.md or .claude/CLAUDE.md in your working directory
  • User-level: ~/.claude/CLAUDE.md for global instructions across all projects
  • Local-level: CLAUDE.local.md or .claude/CLAUDE.local.md (typically gitignored)

Tool Permission Callback

Control which tools Claude can use:

var options = new ClaudeAgentOptions
{
    AllowedTools = ["Read", "Write", "Bash"],
    CanUseTool = async (request, ct) =>
    {
        Console.WriteLine($"Claude wants to use: {request.ToolName}");
        Console.WriteLine($"Input: {request.Input}");

        // Auto-allow read operations
        if (request.ToolName == "Read")
            return new PermissionResultAllow();

        // Deny dangerous operations
        if (request.ToolName == "Bash")
            return new PermissionResultDeny { Message = "Bash not allowed" };

        // Allow with modifications
        return new PermissionResultAllow();
    }
};

MCP Servers

Model Context Protocol (MCP) servers extend Claude with custom tools and capabilities. The SDK supports four transport types.

Transport Types

| Transport | Config Type | Description | | --------- | ---------------------- | --------------------------------- | | stdio | McpStdioServerConfig | External process via stdin/stdout | | SSE | McpSseServerConfig | Server-Sent Events over HTTP | | HTTP | McpHttpServerConfig | HTTP request/response | | SDK | McpSdkServerConfig | In-process C# tools |

stdio Server (External Process)
var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        ["filesystem"] = new McpStdioServerConfig
        {
            Command = "npx",
            Args = ["@modelcontextprotocol/server-filesystem"],
            Env = new Dictionary
            {
                ["ALLOWED_PATHS"] = "/Users/me/projects"
            }
        }
    },
    AllowedTools = ["mcp__filesystem__list_files", "mcp__filesystem__read_file"]
};
SSE Server (Remote)
var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        ["remote-api"] = new McpSseServerConfig
        {
            Url = "https://api.example.com/mcp/sse",
            Headers = new Dictionary
            {
                ["Authorization"] = "Bearer your-token"
            }
        }
    }
};
HTTP Server (Remote)
var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        ["http-service"] = new McpHttpServerConfig
        {
            Url = "https://api.example.com/mcp",
            Headers = new Dictionary
            {
                ["X-API-Key"] = "your-api-key"
            }
        }
    }
};
SDK Server (In-Process C# Tools)

Define tools directly in C# that Claude can call:

using Claude.AgentSdk.Attributes;
using Claude.AgentSdk.Tools;

// Create a tool server
var toolServer = new McpToolServer("my-tools", "1.0.0");

// Register a tool with typed input
toolServer.RegisterTool(
    "calculate",
    "Perform arithmetic operations",
    async (input, ct) =>
    {
        var result = input.Operation switch
        {
            "add" => input.A + input.B,
            "multiply" => input.A * input.B,
            _ => throw new ArgumentException("Unknown operation")
        };
        return ToolResult.Text($"Result: {result}");
    });

// Or use attributes with compile-time registration (recommended)
[GenerateToolRegistration]  // Generates RegisterToolsCompiled() extension
public class MyTools
{
    [ClaudeTool("get_weather", "Get weather for a location",
        Categories = ["weather"],
        TimeoutSeconds = 5)]
    public string GetWeather(
        [ToolParameter(Description = "City name", Example = "Tokyo")] string location,
        [ToolParameter(Description = "Unit: celsius or fahrenheit",
                       AllowedValues = ["celsius", "fahrenheit"])] string unit = "celsius")
    {
        return $"Weather in {location}: 72°F, sunny";
    }
}

var myTools = new MyTools();
toolServer.RegisterToolsCompiled(myTools);  // No reflection!

// Use with client
var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        ["my-tools"] = new McpSdkServerConfig
        {
            Name = "my-tools",
            Instance = toolServer
        }
    }
};

record CalculatorInput(double A, double B, string Operation);
Compile-Time Tool Registration (Recommended)

Use source generators to register tools without reflection:

// Add generator reference to your project:
// 

[GenerateToolRegistration]  // Marker attribute for source generator
public class EmailTools
{
    [ClaudeTool("search_inbox", "Search emails with Gmail-like syntax",
        Categories = ["email"],
        TimeoutSeconds = 10)]
    public string SearchInbox(
        [ToolParameter(Description = "Gmail-style search query")] string query,
        [ToolParameter(Description = "Max results (1-100)", MinValue = 1, MaxValue = 100)] int? limit = 20)
    {
        // Implementation
    }

    [ClaudeTool("delete_email", "Delete an email by ID",
        Categories = ["email"],
        Dangerous = true)]  // Mark destructive operations
    public string DeleteEmail([ToolParameter(Description = "Email ID")] string id)
    {
        // Implementation
    }
}

// Generated extension method (no reflection)
var emailTools = new EmailTools();
toolServer.RegisterToolsCompiled(emailTools);

// Get tool names for AllowedTools configuration
var toolNames = emailTools.GetToolNamesCompiled();
// Returns: ["search_inbox", "delete_email", ...]

// Get MCP-prefixed tool names for a server
var mcpToolNames = emailTools.GetMcpToolNamesCompiled("email-tools");
// Returns: ["mcp__email-tools__search_inbox", "mcp__email-tools__delete_email", ...]

// Get AllowedTools array directly
var options = new ClaudeAgentOptions
{
    AllowedTools = emailTools.GetAllowedToolsCompiled("email-tools")
};

Generated Tool Name Methods:

| Method | Description | |--------|-------------| | GetToolNamesCompiled() | Returns IReadOnlyList of tool names | | GetMcpToolNamesCompiled(serverName) | Returns MCP-prefixed tool names | | GetAllowedToolsCompiled(serverName) | Returns string[] for AllowedTools |

Compile-Time Schema Generation

Generate JSON schemas at compile-time for input types:

[GenerateSchema]  // Generates static schema string
public record SearchInboxInput
{
    [ToolParameter(Description = "Gmail-style search query")]
    public required string Query { get; init; }

    [ToolParameter(Description = "Max results", MinValue = 1, MaxValue = 100)]
    public int? Limit { get; init; }
}

// Access generated schema
var schema = SearchInboxInputSchemaExtensions.GetSchema();
Combining Multiple MCP Servers
var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        // External filesystem server
        ["filesystem"] = new McpStdioServerConfig
        {
            Command = "npx",
            Args = ["@modelcontextprotocol/server-filesystem"]
        },
        // Remote API via SSE
        ["remote-api"] = new McpSseServerConfig
        {
            Url = "https://api.example.com/mcp/sse"
        },
        // In-process custom tools
        ["custom"] = new McpSdkServerConfig
        {
            Name = "custom",
            Instance = myToolServer
        }
    },
    // Allow specific MCP tools (format: mcp____)
    AllowedTools = [
        "mcp__filesystem__list_files",
        "mcp__remote-api__query",
        "mcp__custom__calculate"
    ]
};
Fluent MCP Server Builder

Use McpServerBuilder for a more ergonomic configuration experience:

using Claude.AgentSdk.Builders;

var servers = new McpServerBuilder()
    // Add stdio server with environment variables
    .AddStdio("file-tools", "python", "file_tools.py")
        .WithEnvironment("DEBUG", "true")
        .WithEnvironment("MAX_FILES", "100")

    // Add SSE server with authentication headers
    .AddSse("remote-api", "https://api.example.com/mcp/sse")
        .WithHeaders("Authorization", "Bearer your-token")
        .WithHeaders("X-API-Version", "2")

    // Add HTTP server
    .AddHttp("http-service", "https://api.example.com/mcp")
        .WithHeaders("X-API-Key", "your-api-key")

    // Add in-process SDK server
    .AddSdk("excel-tools", excelToolServer)

    .Build();

var options = new ClaudeAgentOptions
{
    McpServers = servers,
    Allo

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [AJGit](https://github.com/AJGit)
- **Source:** [AJGit/Claude.AgentSdk](https://github.com/AJGit/Claude.AgentSdk)
- **License:** MIT
- **Homepage:** https://www.nuget.org/packages/AJGit.Claude.AgentSdk

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.