Skip to content

ZeroMcp/ZeroMCP.net

Repository files navigation

ZeroMCP.net

NuGet Version NuGet Downloads License: MIT GitHub Stars

Enterprise-grade MCP enablement for ASP.NET Core APIs.

ZeroMCP lets teams expose existing controller and minimal API endpoints as MCP (Model Context Protocol) tools, resources, templates, and prompts, without creating a second service or duplicating logic.

Executive Summary

  • What it solves: Connect LLM clients to established ASP.NET Core APIs safely and quickly.
  • How it works: Annotate endpoints ([Mcp], [McpResource], [McpTemplate], [McpPrompt]) or use minimal API metadata (.AsMcp, .AsResource, .AsTemplate, .AsPrompt), then map one MCP route.
  • Why enterprises adopt it: Keeps existing auth, policy, validation, observability, and release controls in place.

Core Capabilities

  • In-process dispatch through your real ASP.NET Core pipeline
  • Streamable HTTP MCP endpoint (GET and POST)
  • Optional stdio transport for local/desktop MCP clients
  • Streaming tool results via IAsyncEnumerable<T>
  • Tools, resources, templates, and prompts in one framework
  • Per-tool governance (roles, policies, filters)
  • Observability hooks (correlation, logs, metrics sink, OpenTelemetry tags)
  • Inspector endpoints for discovery and controlled testing
  • Versioned MCP routes for phased client migration

Architecture at a Glance

  1. API startup discovers MCP metadata from controllers and minimal APIs.
  2. ZeroMCP builds schemas and endpoint descriptors.
  3. MCP clients call /mcp using JSON-RPC methods.
  4. ZeroMCP dispatches in-process to your original endpoint.
  5. Response is normalized back into MCP-compatible output.

This model preserves middleware behavior and avoids "shadow implementations."

Quick Start

1) Install package

<PackageReference Include="ZeroMCP" Version="1.*" />

2) Register and map

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();

builder.Services.AddZeroMCP(options =>
{
    options.ServerName = "Orders Platform";
    options.ServerVersion = "1.0.0";
});

var app = builder.Build();

app.MapControllers();
app.MapZeroMCP(); // registers GET+POST /mcp

app.Run();

3) Expose endpoints as MCP

[HttpGet("{id:int}")]
[Mcp("get_order", Description = "Retrieves an order by ID.")]
public IActionResult GetOrder(int id) => Ok(new { id });

app.MapGet("/api/health", () => Results.Ok(new { status = "ok" }))
   .AsMcp("health_check", "Returns API health status.");

Enterprise Deployment Guidance

Security baseline

  • Protect MCP endpoint using existing authentication/authorization:
app.MapZeroMCP().RequireAuthorization("McpPolicy");
  • Enforce least privilege with Roles and Policy on tool metadata.
  • Keep inspector endpoints disabled or restricted outside trusted environments.
  • Forward only required security headers via ForwardHeaders.

Governance

  • ToolFilter: discovery-time exclusion by name/environment.
  • ToolVisibilityFilter: per-request dynamic visibility based on context.
  • Roles/policies are enforced at listing and invocation boundaries.
  • Use versioned routes to run controlled cutovers across client populations.

Observability and operations

  • Correlation IDs via configurable header propagation.
  • Structured logging around MCP request lifecycle and tool calls.
  • IMcpMetricsSink for custom telemetry export.
  • Optional OpenTelemetry enrichment for traces.
  • SSE-based keep-alive behavior for long-lived MCP connections.

Reliability recommendations

  • Set endpoint auth and rate limiting policies at the ASP.NET Core layer.
  • Treat /mcp as a production API surface with normal SLO/SLA controls.
  • Keep inspector UI behind environment checks or internal access controls.
  • Validate key tool flows with integration tests before client rollout.

Configuration Example

builder.Services.AddZeroMCP(options =>
{
    options.ServerName = "Orders Platform";
    options.ServerVersion = "2.3.0";
    options.RoutePrefix = "/mcp";

    // Core behavior
    options.IncludeInputSchemas = true;
    options.ForwardHeaders = ["Authorization"];

    // Governance
    options.ToolFilter = name => !name.StartsWith("internal_");
    options.ToolVisibilityFilter = (name, ctx) =>
        ctx.User.IsInRole("Admin") || !name.StartsWith("admin_");

    // Observability
    options.CorrelationIdHeader = "X-Correlation-ID";
    options.EnableOpenTelemetryEnrichment = true;

    // Optional MCP capabilities
    options.EnableResources = true;
    options.EnablePrompts = true;
    options.EnableToolInspector = false;
    options.EnableToolInspectorUI = false;
});

Supported MCP Surface

  • initialize
  • tools/list, tools/call
  • resources/list, resources/templates/list, resources/read
  • resources/subscribe, resources/unsubscribe (when enabled)
  • prompts/list, prompts/get
  • notification flows such as list-changed updates (when enabled)

Transport Options

Streamable HTTP (default)

  • GET /mcp for metadata and SSE scenarios
  • POST /mcp for JSON-RPC methods

stdio (optional)

if (args.Contains("--mcp-stdio"))
{
    await app.RunMcpStdioAsync();
    return;
}

Useful for local-first MCP clients that spawn your service process directly.

Claude Desktop stdio example

{
  "mcpServers": {
    "orders-api": {
      "command": "dotnet",
      "args": ["run", "--project", "ZeroMCP.Sample", "--", "--mcp-stdio"]
    }
  }
}

For full client setup options (stdio and HTTP), see wiki/Connecting-Clients.md.

Inspector Endpoints

  • GET /mcp/tools: JSON inventory of tools and schemas
  • GET /mcp/ui: browser-based invocation UI

Recommended usage: enable in development and internal test environments only.

Versioning and Compatibility

  • Semantic versioning policy is defined in VERSIONING.md.
  • MCP protocol behavior is implemented with explicit compatibility tests.
  • Versioned endpoint support allows non-breaking migration paths for clients.

Solution Layout

  • ZeroMCP/: core framework package (NuGet artifact source)
  • ZeroMCP.Sample/: reference host with practical patterns
  • ZeroMCP.Tests/: integration and schema/compatibility tests
  • examples/: focused scenario samples:
    • Minimal
    • WithAuth
    • WithEnrichment
    • WithStdio
    • WithRateLimiting
    • Enterprise
  • wiki/: implementation and operations documentation
  • progress.md: persistent engineering change log

[Mcp] Attribute Quick Reference

[Mcp] supports a required tool name plus optional metadata used for discoverability and governance.

[Mcp(
    "create_order",
    Description = "Creates an order.",
    Tags = new[] { "orders", "write" },
    Category = "orders",
    Examples = new[] { "Create order for Alice, quantity 2" },
    Hints = new[] { "idempotent", "cost=low" },
    Roles = new[] { "Admin" },
    Policy = "RequireEditor",
    Version = 2
)]

Full details: wiki/The-Mcp-Attribute.md.

Other Attribute Quick Reference

Use these when exposing MCP resources and prompts from controller actions:

[McpResource("catalog://info", "catalog_info",
    Description = "Returns catalog metadata.",
    MimeType = "application/json")]

[McpTemplate("catalog://products/{id}", "product_resource",
    Description = "Returns a product by ID.",
    MimeType = "application/json")]

[McpPrompt("restock_recommendation_prompt",
    Description = "Generates a restock recommendation prompt.")]

Minimal API equivalents:

app.MapGet("/api/catalog/info", () => Results.Ok(...))
   .AsResource("catalog://info", "catalog_info", "Returns catalog metadata.", mimeType: "application/json");

app.MapGet("/api/catalog/products/{id:int}", (int id) => Results.Ok(...))
   .AsTemplate("catalog://products/{id}", "product_resource", "Returns a product by ID.", mimeType: "application/json");

app.MapGet("/api/catalog/prompts/restock/{productId:int}", (int productId) => Results.Ok(...))
   .AsPrompt("restock_recommendation_prompt", "Generates a restock recommendation prompt.");

Full details: wiki/Resources-and-Prompts.md.

Build and Test

dotnet build ZeroMCP.slnx -v detailed
dotnet test ZeroMCP.Tests/ZeroMCP.Tests.csproj -v detailed

Integration tests include MCP streamable HTTP behaviour (e.g. GET /mcp with Accept: text/event-stream and Mcp-Session-Id, resources/subscribe with session header, and notifications/resources/updated on the SSE channel). See McpResourceSubscriptionTests and McpClientCompatibilityTests in ZeroMCP.Tests/.

Documentation Map

  • Package README: ZeroMCP/README.md
  • Configuration: wiki/Configuration.md
  • Security model: wiki/Security-Model.md
  • Enterprise usage: wiki/Enterprise-Usage.md
  • Tool versioning: wiki/Tool-Versioning.md
  • Resources and prompts: wiki/Resources-and-Prompts.md

Contributing

Contributions are welcome, especially around protocol compatibility hardening, minimal API binding parity, and production-focused samples. Please include integration tests and documentation updates with each functional change.

About

Turn your API into a MCP Server, Zero Effort, Zero Friction, Zero Duplication

Topics

Resources

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors

Languages