MCPify 0.0.11-preview
dotnet add package MCPify --version 0.0.11-preview
NuGet\Install-Package MCPify -Version 0.0.11-preview
<PackageReference Include="MCPify" Version="0.0.11-preview" />
<PackageVersion Include="MCPify" Version="0.0.11-preview" />
<PackageReference Include="MCPify" />
paket add MCPify --version 0.0.11-preview
#r "nuget: MCPify, 0.0.11-preview"
#:package MCPify@0.0.11-preview
#addin nuget:?package=MCPify&version=0.0.11-preview&prerelease
#tool nuget:?package=MCPify&version=0.0.11-preview&prerelease
MCPify
MCPify is a .NET library that bridges the gap between your existing ASP.NET Core APIs (or external OpenAPI/Swagger specs) and the Model Context Protocol (MCP). It allows you to expose API operations as MCP tools that can be consumed by AI assistants like Claude Desktop, ensuring seamless integration with your existing services.
Features
- Automatic Tool Generation: Dynamically converts OpenAPI (Swagger) v2/v3 definitions into MCP tools.
- Hybrid Support: Expose your local ASP.NET Core endpoints and external public APIs simultaneously.
- Seamless Authentication: Built-in support for OAuth 2.0 Authorization Code Flow with PKCE.
- Includes a
login_auth_code_pkcetool that handles the browser-based login flow automatically. - Securely stores tokens per session using encrypted local storage.
- Automatically refreshes tokens when they expire.
- Includes a
- MCP Authorization Spec Compliant: Full compliance with the MCP Authorization Specification.
- Protected Resource Metadata (
/.well-known/oauth-protected-resource) - RFC 8707 Resource Parameter support
- JWT token validation (expiration, audience, scopes)
- 403 Forbidden with
insufficient_scopeerror
- Protected Resource Metadata (
- Dual Transport: Supports both
Stdio(for local desktop apps like Claude) andHttp(SSE) transports. - Production Ready: Robust logging, error handling, and configurable options.
Supported Frameworks
- .NET 8, .NET 9, .NET 10
Quick Start
1. Installation
Install the package into your ASP.NET Core project:
dotnet add package MCPify
2. Configuration
Add MCPify to your Program.cs:
using MCPify.Hosting;
var builder = WebApplication.CreateBuilder(args);
// ... Add other services ...
// 1. Add MCPify services
builder.Services.AddMcpify(options =>
{
// Choose Transport (Stdio for local tools, Http for remote)
options.Transport = McpTransportType.Stdio;
// Option A: Expose Local Endpoints
options.LocalEndpoints = new LocalEndpointsOptions
{
Enabled = true,
ToolPrefix = "myapp_",
// Optional: Filter which endpoints to expose
Filter = op => op.Route.StartsWith("/api")
};
// Option B: Expose External APIs via Swagger
options.ExternalApis.Add(new ExternalApiOptions
{
ApiBaseUrl = "https://petstore.swagger.io/v2",
OpenApiUrl = "https://petstore.swagger.io/v2/swagger.json",
ToolPrefix = "petstore_"
});
});
var app = builder.Build();
// 2. Add Middleware
app.UseMcpifyContext();
app.UseMcpifyOAuth(); // If using Authentication
// ... Map your endpoints ...
// 3. Map the MCP endpoint (required for Http transport, optional for Stdio)
app.MapMcpifyEndpoint();
app.Run();
3. Usage with Claude Desktop
To use your MCPify app with Claude Desktop, edit your config file (%APPDATA%\Claude\claude_desktop_config.json on Windows or ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"my-app": {
"command": "dotnet",
"args": [
"run",
"--project",
"/absolute/path/to/YourProject.csproj",
"--",
"--Mcpify:Transport=Stdio"
]
}
}
}
Note: When using
dotnet run, ensure your application does not print build logs to stdout, as this corrupts the MCP JSON-RPC protocol. You can suppress logs or publish your app as a single-file executable for a cleaner setup.
Authentication
MCPify provides a first-class experience for APIs secured with OAuth 2.0.
Enabling OAuth
Register the authentication provider in your Program.cs:
services.AddScoped<OAuthAuthorizationCodeAuthentication>(sp => {
return new OAuthAuthorizationCodeAuthentication(
clientId: "your-client-id",
authorizationEndpoint: "https://auth.example.com/authorize",
tokenEndpoint: "https://auth.example.com/token",
scope: "api_access",
secureTokenStore: sp.GetRequiredService<ISecureTokenStore>(),
mcpContextAccessor: sp.GetRequiredService<IMcpContextAccessor>(),
redirectUri: "http://localhost:5000/auth/callback" // Your app must handle this
);
});
// Register the Login Tool
services.AddLoginTool(sp => new LoginTool());
The Login Flow
- The user asks Claude: "Please login" or uses a tool that requires auth.
- Claude calls the
login_auth_code_pkcetool. - MCPify automatically opens the system browser to the login page (in interactive environments).
- The user logs in and approves the request.
- The browser redirects back to your application (e.g.,
/auth/callback). - Your app saves the token and displays a success message.
- The
login_auth_code_pkcetool detects the successful login and reports back to Claude. - Claude can now invoke authenticated tools!
Headless / Remote Environments
When running MCPify on headless servers, containers, or remote environments where a browser cannot be opened, you can configure the login behavior to skip browser launch attempts and immediately return the authorization URL:
builder.Services.AddMcpify(options =>
{
// For headless/remote environments - return URL immediately without browser launch
options.LoginBrowserBehavior = BrowserLaunchBehavior.Never;
});
Available options for LoginBrowserBehavior:
| Value | Description |
|---|---|
Auto (default) |
Automatically detects headless environments (no DISPLAY on Linux, SSH sessions, containers) and skips browser launch when appropriate. |
Always |
Always attempt to open the browser, regardless of environment. |
Never |
Never attempt to open the browser. Returns the authorization URL immediately for manual authentication. Ideal for headless servers and containers. |
With Auto mode, MCPify detects headless environments by checking:
- Linux: Missing
DISPLAYorWAYLAND_DISPLAYenvironment variables, SSH sessions without X forwarding, Docker containers - Windows: Container environments (Kubernetes, Docker)
- macOS: SSH sessions
Token Validation
MCPify supports JWT token validation for enhanced security. Token validation is opt-in for backward compatibility.
builder.Services.AddMcpify(options =>
{
// Set the resource URL for audience validation
options.ResourceUrlOverride = "https://api.example.com";
// Configure OAuth (scopes defined here can be auto-required)
options.OAuthConfigurations.Add(new OAuth2Configuration
{
AuthorizationUrl = "https://auth.example.com/authorize",
TokenUrl = "https://auth.example.com/token",
Scopes = new Dictionary<string, string>
{
{ "read", "Read access" },
{ "write", "Write access" }
}
});
// Enable token validation (opt-in)
options.TokenValidation = new TokenValidationOptions
{
EnableJwtValidation = true, // Enable JWT parsing and validation
ValidateAudience = true, // Validate 'aud' claim matches resource URL
ValidateScopes = true, // Validate token has required scopes
RequireOAuthConfiguredScopes = true, // Require scopes from OAuth2Configuration
ClockSkew = TimeSpan.FromMinutes(5) // Allowed clock skew for expiration
};
});
Scope Configuration Options:
| Option | Description |
|---|---|
RequireOAuthConfiguredScopes = true |
Automatically require all scopes from OAuth configurations. This includes scopes defined in OAuthConfigurations and scopes discovered from OpenAPI security schemes. |
DefaultRequiredScopes |
Explicitly list required scopes (use when you want different scopes than what's advertised in OAuth config). |
Automatic Integration with OpenAPI: When MCPify loads an external API from an OpenAPI spec that includes OAuth2 security schemes (like those configured for Swagger UI), the scopes are automatically parsed and added to the OAuth configuration store. With RequireOAuthConfiguredScopes = true, these scopes are automatically enforced during token validation - no duplicate configuration needed.
When validation fails, MCPify returns appropriate HTTP responses:
| Scenario | Status Code | WWW-Authenticate |
|---|---|---|
| No token provided | 401 Unauthorized | Bearer resource_metadata="..." |
| Token expired | 401 Unauthorized | Bearer error="invalid_token", error_description="Token has expired" |
| Wrong audience | 401 Unauthorized | Bearer error="invalid_token", error_description="Token audience does not match..." |
| Missing scopes | 403 Forbidden | Bearer error="insufficient_scope", scope="required_scope" |
Per-Tool Scope Requirements
Define granular scope requirements for specific tools using pattern matching:
builder.Services.AddMcpify(options =>
{
options.TokenValidation = new TokenValidationOptions
{
EnableJwtValidation = true,
ValidateScopes = true,
DefaultRequiredScopes = new List<string> { "mcp.access" }
};
// Define per-tool scope requirements
options.ScopeRequirements = new List<ScopeRequirement>
{
// All admin_* tools require 'admin' scope
new ScopeRequirement
{
Pattern = "admin_*",
RequiredScopes = new List<string> { "admin" }
},
// Write operations require 'write' scope
new ScopeRequirement
{
Pattern = "*_create",
RequiredScopes = new List<string> { "write" }
},
new ScopeRequirement
{
Pattern = "*_update",
RequiredScopes = new List<string> { "write" }
},
new ScopeRequirement
{
Pattern = "*_delete",
RequiredScopes = new List<string> { "write" }
},
// Read-only tools need at least 'read' OR 'write' scope
new ScopeRequirement
{
Pattern = "*_get",
AnyOfScopes = new List<string> { "read", "write" }
}
};
});
Pattern matching supports:
*- matches any sequence of characters?- matches any single character- Exact match -
tool_name
RFC 8707 Resource Parameter
MCPify automatically includes the RFC 8707 resource parameter in OAuth requests when ResourceUrlOverride is configured. This helps authorization servers issue tokens scoped to specific resources:
builder.Services.AddMcpify(options =>
{
options.ResourceUrlOverride = "https://api.example.com";
// ...
});
The resource parameter is added to:
- Authorization URL (
/authorize?resource=...) - Token exchange requests (
POST /tokenwithresource=...) - Token refresh requests
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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
- Microsoft.OpenApi.Readers (>= 1.6.28)
- ModelContextProtocol (>= 0.6.0-preview.1)
- ModelContextProtocol.AspNetCore (>= 0.6.0-preview.1)
- System.Security.Cryptography.ProtectedData (>= 8.0.0)
-
net8.0
- Microsoft.OpenApi.Readers (>= 1.6.28)
- ModelContextProtocol (>= 0.6.0-preview.1)
- ModelContextProtocol.AspNetCore (>= 0.6.0-preview.1)
- System.Security.Cryptography.ProtectedData (>= 8.0.0)
-
net9.0
- Microsoft.OpenApi.Readers (>= 1.6.28)
- ModelContextProtocol (>= 0.6.0-preview.1)
- ModelContextProtocol.AspNetCore (>= 0.6.0-preview.1)
- System.Security.Cryptography.ProtectedData (>= 8.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.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.11-preview | 43 | 1/18/2026 |
| 0.0.10-preview | 33 | 1/18/2026 |
| 0.0.9-preview | 46 | 1/16/2026 |
| 0.0.8 | 57 | 1/16/2026 |
| 0.0.8-preview | 115 | 12/26/2025 |
| 0.0.7 | 170 | 12/23/2025 |
| 0.0.7-preview | 78 | 12/20/2025 |
| 0.0.6-preview | 114 | 12/13/2025 |
| 0.0.5-preview | 161 | 12/7/2025 |
| 0.0.4 | 626 | 12/3/2025 |
| 0.0.4-preview | 612 | 12/2/2025 |
| 0.0.3 | 619 | 12/3/2025 |
| 0.0.3-preview | 134 | 11/24/2025 |
| 0.0.2 | 618 | 12/2/2025 |
| 0.0.2-preview | 110 | 11/23/2025 |
| 0.0.1 | 116 | 11/23/2025 |
| 0.0.1-preview | 103 | 11/23/2025 |