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.
Latest Release: v0.0.12 - Now with enhanced OAuth middleware and improved testing infrastructure!
- Enhanced OAuth Middleware: Improved OAuth authentication middleware with better error handling and token management (#17)
- JWT Token Validation: Full support for JWT access token validation including expiration, audience, and scope verification (#15)
- Per-Tool Scope Requirements: Define granular scope requirements for specific tools using pattern matching (#15)
- Automatic Scope Discovery: Scopes are automatically extracted from OpenAPI security schemes and enforced during validation (#15)
- WWW-Authenticate Header: Improved WWW-Authenticate header to include scope parameter per MCP spec
- LoginBrowserBehavior: Control browser launch behavior for OAuth login in headless environments
- OAuth2Configuration List: Support for multiple OAuth providers with AuthorizationServers exposure (#13)
- 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.
- .NET 8, .NET 9, .NET 10
Install the package into your ASP.NET Core project:
dotnet add package MCPifyAdd MCPify to your Program.cs:
using MCPify.Hosting;
var builder = WebApplication.CreateBuilder(args);
// ... Add other services ...
// Add MCPify services
builder.Services.AddMcpify(options =>
{
// Stdio for local tools (Claude Desktop), Http for remote servers
options.Transport = McpTransportType.Stdio;
// Option A: Expose Local Endpoints
options.LocalEndpoints = new LocalEndpointsOptions
{
Enabled = true,
ToolPrefix = "myapp_",
BaseUrlOverride = "https://localhost:5001", // Optional: override base URL
Filter = op => op.Route.StartsWith("/api"), // Optional: filter endpoints
AuthenticationFactory = sp => sp.GetRequiredService<OAuthAuthorizationCodeAuthentication>() // Optional
};
// Option B: Expose External APIs from URL
options.ExternalApis.Add(new ExternalApiOptions
{
ApiBaseUrl = "https://petstore.swagger.io/v2",
OpenApiUrl = "https://petstore.swagger.io/v2/swagger.json",
ToolPrefix = "petstore_"
});
// Option C: Expose External APIs from Local File
options.ExternalApis.Add(new ExternalApiOptions
{
ApiBaseUrl = "https://api.example.com",
OpenApiFilePath = "path/to/openapi-spec.json", // or .yaml
ToolPrefix = "myapi_"
});
});
var app = builder.Build();
// Add Middleware (order matters!)
app.UseAuthentication();
app.UseAuthorization();
// ... Map your endpoints ...
// Map the MCP endpoint (required for Http transport)
app.MapMcpifyEndpoint();
app.Run();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.
MCPify provides comprehensive OAuth 2.0 authentication support with automatic token management, validation, and scope enforcement.
Register the authentication provider in your Program.cs (ensure this is done before calling AddMcpify):
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 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!
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
MCPify now relies on the official ModelContextProtocol.AspNetCore authentication handler for OAuth 2.0. When you call AddMcpify, the MCP authentication scheme is registered automatically and the handler issues WWW-Authenticate challenges that point back to the protected resource metadata endpoint.
builder.Services.AddMcpify(options =>
{
// Set the resource URL for audience validation
options.ResourceUrlOverride = "https://api.example.com";
// Configure OAuth provider(s)
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 for backward compatibility)
options.TokenValidation = new TokenValidationOptions
{
EnableJwtValidation = true,
ValidateAudience = true,
ValidateScopes = true,
RequireOAuthConfiguredScopes = true, // Auto-require scopes from OAuth config
ClockSkew = TimeSpan.FromMinutes(5)
};
});If you need to customize the advertised metadata—for example to add documentation links or override the detected resource URL—you can configure McpAuthenticationOptions:
builder.Services.PostConfigure<McpAuthenticationOptions>(options =>
{
options.ResourceMetadata ??= new ProtectedResourceMetadata();
options.ResourceMetadata.Documentation = new Uri("https://docs.example.com/mcp");
});Ensure your middleware pipeline includes app.UseAuthentication(); and app.UseAuthorization(); so that the handler can participate in requests. Challenges no longer run through a custom middleware; the standard ASP.NET Core authentication flow handles everything.
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
We welcome contributions! Please see our Contributing Guide for details.
MIT