Emissary
Production-grade Claude agents for .NET — compile-time verified, provably safe, Native AOT.
Emissary is a Claude-native agent framework for modern C#. Tool schemas and dispatchers are generated by the compiler, agent behavior is constrained by enforceable contracts, and every run is recordable, replayable, and assertable in CI.
var options = new AgentOptions
{
SystemPrompt = "You are a support agent. Verify identity before refunding.",
Tools = { SupportTools.VerifyIdentityTool, SupportTools.RefundPaymentTool },
};
options.Rules.Require("refund_payment", prerequisite: "verify_identity");
var agent = new ClaudeAgent(options);
var result = await agent.RunAsync("Refund order A-1001, it arrived broken.");
Start here
| Guide | What it covers |
|---|---|
| Getting started | Install, first tool, first agent, streaming |
| Tools and schemas | [ClaudeTool], parameters, structured outputs, diagnostics |
| Safety and contracts | Tool contracts, taint tracking, RBAC, shadow mode, compensation |
| Testing agents | Record/replay, behavioral assertions, canarying, LLM-judge evaluation |
| Production | Hosting, human-in-the-loop, sessions, resilience, caching, cost, telemetry |
The API reference is generated from the source XML documentation, and benchmarks has the measured numbers behind the performance claims.
Packages
| Package | What it adds |
|---|---|
Emissary |
Agent runtime + the [ClaudeTool]/[ClaudeSchema] source generator and analyzer |
Emissary.Testing |
Behavioral assertions, canarying, and LLM-judge evaluation |
Emissary.AspNetCore |
SSE streaming endpoints and the human-approval webhook |
Emissary.Mcp |
Expose tools or whole agents as an MCP stdio server |
Emissary.Sqlite |
Durable suspended-run and conversation persistence |
Emissary.Extensions.AI |
IChatClient adapter for Microsoft.Extensions.AI pipelines |
Design decisions
Emissary's architecture decisions are recorded as ADRs. The ones that explain the most about how it behaves:
| ADR | Decision |
|---|---|
| 0001 | Claude-native, not provider-agnostic |
| 0003 | 100% coverage, and what may be baselined |
| 0005 | Tag-driven, lockstep versioning |
| 0006 | Compaction runs client-side, so compacted runs still replay |
| 0007 | A failed tool tells the model less than it tells the caller |
| 0008 | Tests at the SDK boundary must use SDK-produced values |