Install
$ agentstack add mcp-ajgit-claude-agentsdk ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
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.mdor.claude/CLAUDE.mdin your working directory - User-level:
~/.claude/CLAUDE.mdfor global instructions across all projects - Local-level:
CLAUDE.local.mdor.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.
Write a review
Versions
- v0.1.0 Imported from the upstream source.