SwaggerMcp 1.0.0
Package name changed
See the version list below for details.
dotnet add package SwaggerMcp --version 1.0.0
NuGet\Install-Package SwaggerMcp -Version 1.0.0
<PackageReference Include="SwaggerMcp" Version="1.0.0" />
<PackageVersion Include="SwaggerMcp" Version="1.0.0" />
<PackageReference Include="SwaggerMcp" />
paket add SwaggerMcp --version 1.0.0
#r "nuget: SwaggerMcp, 1.0.0"
#:package SwaggerMcp@1.0.0
#addin nuget:?package=SwaggerMcp&version=1.0.0
#tool nuget:?package=SwaggerMcp&version=1.0.0
SwaggerMcp
Expose your existing ASP.NET Core API as an MCP (Model Context Protocol) server with a single attribute and two lines of setup. No separate process. No code duplication.
How It Works
Tag any controller action with [McpTool] and SwaggerMcp will:
- Discover it at startup via ASP.NET Core's
IApiDescriptionGroupCollectionProvider(same source as Swagger) - Generate a JSON Schema for its inputs by merging route params, query params, and body properties
- Expose it via a
POST /mcpendpoint that speaks the MCP Streamable HTTP transport - Dispatch calls in-process through your real action pipeline — filters, validation, and authorization all run normally
MCP Client (Claude Desktop, Claude.ai, etc.)
│
│ POST /mcp (JSON-RPC 2.0, MCP protocol)
▼
SwaggerMcp Endpoint
│
│ in-process dispatch
▼
Your Controller Action ← [McpTool] tagged
│
│ real response
▼
MCP Client gets structured result
Quick Start
1. Install
<PackageReference Include="SwaggerMcp" Version="1.0.0" />
2. Register services
// Program.cs
builder.Services.AddSwaggerMcp(options =>
{
options.ServerName = "My Orders API";
options.ServerVersion = "1.0.0";
});
3. Map the endpoint
app.MapSwaggerMcp(); // registers POST /mcp
4. Tag your actions
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
[HttpGet("{id}")]
[McpTool("get_order", Description = "Retrieves a single order by ID.")]
public ActionResult<Order> GetOrder(int id) { ... }
[HttpPost]
[McpTool("create_order", Description = "Creates a new order. Returns the created order.")]
public ActionResult<Order> CreateOrder([FromBody] CreateOrderRequest request) { ... }
[HttpDelete("{id}")]
// No [McpTool] — invisible to MCP clients
public IActionResult Delete(int id) { ... }
}
That's it. Point any MCP client at POST /mcp and it will see your tagged endpoints as tools.
Configuration
builder.Services.AddSwaggerMcp(options =>
{
options.ServerName = "My API"; // shown during MCP handshake
options.ServerVersion = "2.0.0"; // shown during MCP handshake
options.RoutePrefix = "/mcp"; // where the endpoint is mounted
options.IncludeInputSchemas = true; // attach JSON Schema to tools (helps LLM)
// Optional: filter which tagged tools are exposed at runtime
options.ToolFilter = name => !name.StartsWith("admin_");
});
Custom route
app.MapSwaggerMcp("/api/mcp"); // overrides options.RoutePrefix
The [McpTool] Attribute
[McpTool(
name: "create_order", // Required. Snake_case tool name for the LLM.
Description = "Creates an order.", // Shown to the LLM. Be descriptive.
Tags = ["write", "orders"] // Optional. For grouping/filtering.
)]
Placement rules
- Per-action only —
[McpTool]goes on individual action methods, not controllers - One name per application — duplicate names are logged as warnings and skipped
- Any HTTP method — GET, POST, PATCH, DELETE all work
How Parameters Are Mapped
SwaggerMcp merges all parameter sources into a single flat JSON Schema object that the LLM fills in:
| Parameter source | MCP mapping |
|---|---|
Route params ({id}) |
Always required properties |
Query params (?status=) |
Optional (or required if [Required]) |
[FromBody] object |
Properties expanded inline from JSON Schema |
Example:
[HttpPatch("{id}/status")]
[McpTool("update_order_status", Description = "Updates an order's status.")]
public IActionResult UpdateStatus(int id, [FromBody] UpdateStatusRequest req) { ... }
public class UpdateStatusRequest
{
[Required] public string Status { get; set; }
public string? Reason { get; set; }
}
Produces this MCP input schema:
{
"type": "object",
"properties": {
"id": { "type": "integer" },
"status": { "type": "string" },
"reason": { "type": "string" }
},
"required": ["id", "status"]
}
In-Process Dispatch
When the MCP client calls a tool, SwaggerMcp:
- Creates a fresh DI scope (same as a real request)
- Builds a synthetic
HttpContextwith route values, query string, and body stream populated from the JSON arguments - Invokes the action via
IActionInvokerFactory— your full filter pipeline runs - Captures the response body and forwards it as the MCP result
This means:
[Authorize]works — set up auth on the MCP endpoint and your action filters enforce it[ValidateModel]/ModelStateworks — validation errors return as MCP error results- Exception filters work — unhandled exceptions are caught and returned gracefully
- Your existing DI services, repositories, and business logic are called as-is
Connecting MCP Clients
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"my-api": {
"type": "http",
"url": "http://localhost:5000/mcp"
}
}
}
Claude.ai (remote MCP)
Point at your deployed API's /mcp endpoint. For production, add authentication — SwaggerMcp doesn't impose any auth on the /mcp route itself, so you can apply standard ASP.NET Core auth middleware or .RequireAuthorization() as needed:
app.MapSwaggerMcp().RequireAuthorization("McpPolicy");
Contributing
PRs welcome. The most impactful next additions would be:
- Minimal API endpoint support (read from
IEndpointDataSourcein addition toIApiDescriptionGroupCollectionProvider) - SSE transport support
- XML doc comment extraction for auto-populating descriptions
- Auth token forwarding from MCP client to dispatched action
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- NJsonSchema (>= 11.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.