| docs | ||
| samples/CodexMcpGateway | ||
| src | ||
| tests | ||
| .gitignore | ||
| AGENT-PRIMER.md | ||
| LICENSE | ||
| README.md | ||
| Svrnty.MCP.Gateway.sln | ||
Svrnty.MCP.Gateway
A modular, scalable, secure .NET library for routing and managing Model Context Protocol (MCP) traffic
What is Svrnty.MCP.Gateway?
Svrnty.MCP.Gateway is a standalone, reusable .NET library that provides proxy and routing infrastructure for Model Context Protocol (MCP) traffic, enabling centralized management, authentication, monitoring, and load balancing between MCP clients and servers.
Model Context Protocol (MCP) is an industry-standard protocol backed by Anthropic that defines how AI agents communicate with external tools and data sources. The Gateway acts as an intelligent intermediary that enhances security, observability, and reliability.
Key Features
- Centralized Routing: Single point of entry for all MCP traffic
- Clean Architecture: Core abstractions, infrastructure implementation, ASP.NET Core integration
- Security-First: Authentication, authorization, rate limiting, audit logging
- HTTP Transport: Production-ready HTTP communication with MCP servers
- AI-Automated Setup: AGENT-PRIMER.md guides AI assistants to configure your integration automatically
- TDD Foundation: Built with test-driven development, comprehensive test coverage
- Production-Ready: Observability, health checks, circuit breakers, load balancing
Why Svrnty.MCP.Gateway?
Problem: Managing multiple MCP clients connecting to multiple MCP servers becomes complex, with duplicated authentication, monitoring, and routing logic scattered across components.
Solution: Svrnty.MCP.Gateway provides a centralized proxy that handles routing, authentication, rate limiting, and monitoring in one place, simplifying architecture and enhancing security.
Use Cases:
- Route multiple AI agents to appropriate backend MCP servers
- Centralize authentication and authorization for all MCP traffic
- Monitor and log all tool calls across your infrastructure
- Implement rate limiting and circuit breakers
- Load balance requests across multiple server instances
- A/B test different MCP server implementations
- Provide unified observability dashboard
Quick Start
Prerequisites
- .NET 8.0 SDK or higher
- Access to MCP servers (backends to route to)
- MCP clients (frontends that will connect through gateway)
Option 1: AI-Automated Setup (Recommended)
If you have access to Claude or another AI assistant:
- Copy this entire folder to your project directory
- Open your AI assistant and say: "Read AGENT-PRIMER.md and set up Svrnty.MCP.Gateway for my project"
- The AI will analyze your system, generate configuration, and create routing rules automatically
Option 2: Manual Setup
Step 1: Add Package Reference
# Via project reference (development)
dotnet add reference /path/to/Svrnty.MCP.Gateway/src/Svrnty.MCP.Gateway.AspNetCore/Svrnty.MCP.Gateway.AspNetCore.csproj
# OR via NuGet (when published)
# dotnet add package Svrnty.MCP.Gateway.AspNetCore
Step 2: Configure appsettings.json
Add Gateway configuration:
{
"Mcp": {
"Gateway": {
"Name": "MyMcpGateway",
"Version": "1.0.0",
"Description": "MCP Gateway for routing and management",
"ListenAddress": "http://localhost:8080"
},
"Servers": [
{
"Id": "codex-server-1",
"Name": "CODEX MCP Server 1",
"Transport": {
"Type": "Http",
"BaseUrl": "http://localhost:5050"
},
"Enabled": true
},
{
"Id": "codex-server-2",
"Name": "CODEX MCP Server 2",
"Transport": {
"Type": "Http",
"BaseUrl": "http://localhost:5051"
},
"Enabled": true
},
{
"Id": "remote-api",
"Name": "Remote API Server",
"Transport": {
"Type": "Http",
"BaseUrl": "https://api.example.com/mcp"
},
"Enabled": true
}
],
"Routing": {
"Strategy": "RoundRobin",
"HealthCheckInterval": "00:00:30"
},
"Security": {
"EnableAuthentication": true,
"ApiKeyHeader": "X-MCP-API-Key",
"RateLimit": {
"RequestsPerMinute": 100,
"BurstSize": 20
}
},
"Monitoring": {
"EnableMetrics": true,
"EnableTracing": true,
"EnableAuditLog": true
}
}
}
Step 3: Update Program.cs
using Svrnty.MCP.Gateway.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
// Add MCP Gateway
builder.Services.AddMcpGateway(builder.Configuration.GetSection("Mcp"));
// Add health checks
builder.Services.AddHealthChecks()
.AddCheck<McpServerHealthCheck>("mcp-servers");
var app = builder.Build();
// Map Gateway endpoints
app.MapMcpGateway();
app.MapHealthChecks("/health");
app.Run();
Step 4: Configure Routing Rules
using Svrnty.MCP.Gateway.Core.Routing;
public class CustomRoutingStrategy : IRoutingStrategy
{
public string SelectServer(
RoutingContext context,
IEnumerable<ServerInfo> availableServers)
{
// Route based on tool name pattern
if (context.ToolName.StartsWith("search_"))
{
return "codex-server-1";
}
// Route based on client identity
if (context.ClientId == "admin-client")
{
return "codex-server-2";
}
// Default: round-robin
return availableServers.First().Id;
}
}
Step 5: Run and Test
# Run the gateway
dotnet run
# Ensure MCP servers are running
# Terminal 1: dotnet run --project /path/to/CodexMcpServer (port 5050)
# Terminal 2: dotnet run --project /path/to/CodexMcpServer2 (port 5051)
# Test gateway health
curl http://localhost:8080/health
# Test request routing through gateway
curl -X POST http://localhost:8080/mcp/invoke \
-H "Content-Type: application/json" \
-H "X-Client-Id: demo-client" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":"1"}'
Architecture
Svrnty.MCP.Gateway follows Clean Architecture principles:
┌─────────────────────────────────────────────────┐
│ Svrnty.MCP.Gateway.Cli (Executable) │
│ ┌───────────────────────────────────────────┐ │
│ │ Svrnty.MCP.Gateway.AspNetCore (HTTP)│ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Svrnty.MCP.Gateway.Infrastructure│ │ │
│ │ │ ┌───────────────────────────────┐ │ │ │
│ │ │ │ Svrnty.MCP.Gateway.Core │ │ │ │
│ │ │ │ - IGatewayRouter │ │ │ │
│ │ │ │ - IRoutingStrategy │ │ │ │
│ │ │ │ - IAuthProvider │ │ │ │
│ │ │ │ - ICircuitBreaker │ │ │ │
│ │ │ │ - Models (no dependencies) │ │ │ │
│ │ │ └───────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
Projects
| Project | Purpose | Dependencies |
|---|---|---|
| Svrnty.MCP.Gateway.Core | Abstractions, interfaces, models | None |
| Svrnty.MCP.Gateway.Infrastructure | Router, auth, circuit breakers, load balancing | Core, System.Text.Json |
| Svrnty.MCP.Gateway.AspNetCore | ASP.NET Core integration, HTTP endpoints | Core, Infrastructure, ASP.NET Core |
| Svrnty.MCP.Gateway.Cli | Management CLI for gateway | All above |
See Architecture Documentation for detailed design.
Examples
1. CodexMcpGateway (Multi-Server Router)
Sample gateway configuration routing to multiple backends:
samples/CodexMcpGateway/
├── Routing/
│ ├── ToolBasedRouter.cs # Route by tool name
│ ├── ClientBasedRouter.cs # Route by client identity
│ └── LoadBalancedRouter.cs # Round-robin load balancing
├── Middleware/
│ ├── AuthenticationMiddleware.cs
│ ├── RateLimitingMiddleware.cs
│ └── AuditLoggingMiddleware.cs
├── Program.cs
└── appsettings.json
Running the sample:
cd samples/CodexMcpGateway
dotnet run
# Gateway listens on http://localhost:8080
# Configure clients to connect to gateway instead of servers directly
2. Simple Routing Strategy
Route based on tool name patterns:
public class ToolBasedRouter : IRoutingStrategy
{
public string SelectServer(
RoutingContext context,
IEnumerable<ServerInfo> servers)
{
return context.ToolName switch
{
var t when t.StartsWith("search_") => "codex-server",
var t when t.StartsWith("db_") => "database-server",
var t when t.StartsWith("api_") => "remote-api",
_ => servers.First().Id // Default
};
}
}
3. Load Balancing
Distribute load across multiple server instances:
public class LoadBalancedRouter : IRoutingStrategy
{
private int _currentIndex = 0;
public string SelectServer(
RoutingContext context,
IEnumerable<ServerInfo> servers)
{
var serverList = servers.Where(s => s.IsHealthy).ToList();
if (serverList.Count == 0)
{
throw new NoHealthyServersException();
}
var index = Interlocked.Increment(ref _currentIndex) % serverList.Count;
return serverList[index].Id;
}
}
4. Circuit Breaker Pattern
Prevent cascading failures:
public class CircuitBreakerRouter : IRoutingStrategy
{
private readonly ICircuitBreaker _circuitBreaker;
public string SelectServer(
RoutingContext context,
IEnumerable<ServerInfo> servers)
{
var healthyServers = servers.Where(s =>
s.IsHealthy && !_circuitBreaker.IsOpen(s.Id)
);
if (!healthyServers.Any())
{
throw new AllServersUnavailableException();
}
return healthyServers.First().Id;
}
}
Security
Authentication
Support for multiple auth strategies:
{
"Security": {
"EnableAuthentication": true,
"Strategies": [
{
"Type": "ApiKey",
"HeaderName": "X-MCP-API-Key"
},
{
"Type": "JWT",
"Issuer": "https://auth.example.com",
"Audience": "mcp-gateway"
}
]
}
}
Authorization
Role-based access control:
[Authorize(Roles = "MCP.Admin")]
public class GatewayManagementController : Controller
{
[HttpPost("servers/{serverId}/enable")]
public async Task EnableServer(string serverId)
{
// Only admins can enable/disable servers
}
}
Rate Limiting
Per-client rate limiting:
{
"RateLimit": {
"Global": {
"RequestsPerMinute": 1000
},
"PerClient": {
"RequestsPerMinute": 100,
"BurstSize": 20
},
"PerServer": {
"RequestsPerMinute": 500
}
}
}
Monitoring
Metrics
OpenTelemetry metrics exposed:
mcp_gateway_requests_total- Total requests processedmcp_gateway_request_duration_ms- Request latencymcp_gateway_errors_total- Error count by typemcp_gateway_server_health- Server health statusmcp_gateway_circuit_breaker_state- Circuit breaker state
Audit Logging
All tool calls logged:
{
"timestamp": "2025-10-19T17:40:00Z",
"clientId": "web-client-123",
"serverId": "codex-server",
"toolName": "search_codex",
"arguments": { "query": "architecture" },
"responseTime": "45ms",
"status": "success"
}
Health Checks
Gateway health dashboard:
curl http://localhost:8080/health
{
"status": "Healthy",
"totalServers": 3,
"healthyServers": 3,
"degradedServers": 0,
"unhealthyServers": 0,
"servers": [
{
"id": "codex-server",
"status": "Healthy",
"lastCheck": "2025-10-19T17:40:00Z",
"responseTime": "12ms"
}
]
}
Testing
Integration Tests
# Run all tests
dotnet test
# Run specific test project
dotnet test tests/Svrnty.MCP.Gateway.Tests/
# Run with coverage
dotnet test /p:CollectCoverage=true
Load Testing
Included load testing tools:
# Simulate 100 concurrent clients
cd tests/LoadTests
dotnet run -- --clients 100 --duration 60s
# Output:
# Requests: 45,000
# Success: 44,950 (99.9%)
# Avg Latency: 22ms
# p95 Latency: 45ms
# p99 Latency: 78ms
Test Coverage
Svrnty.MCP.Gateway maintains 76.99% average line coverage and 57.45% average branch coverage with 192 tests passing (100%).
Coverage Breakdown by Project:
-
Svrnty.MCP.Gateway.Core.Tests: 68 tests
- Line Coverage: 76.99%
- Branch Coverage: 57.45%
- Domain models, routing strategies, connection management
-
Svrnty.MCP.Gateway.Infrastructure.Tests: 118 tests
- Line Coverage: 84.16% (excellent)
- Branch Coverage: 67.39%
- HTTP client pooling, circuit breakers, health checks
-
Svrnty.MCP.Gateway.AspNetCore.Tests: 6 tests
- Line Coverage: 4.62% (low - expected)
- Branch Coverage: 3.87%
- ASP.NET Core middleware and configuration
- Note: Low coverage normal for thin ASP.NET Core layers
Analysis:
- Core and Infrastructure: Excellent coverage (77-84%)
- AspNetCore: Low coverage expected (minimal logic, mostly wiring)
- Routing strategies comprehensively tested (3 strategies × multiple scenarios)
- Load balancing and failover well-covered
Coverage Reports:
# Generate coverage report
dotnet test --collect:"XPlat Code Coverage" --results-directory ./TestResults
# View detailed coverage
# See: /home/svrnty/codex/COVERAGE-SUMMARY.md for complete analysis
Status: ✅ Excellent - Core business logic excellently tested, production-ready
Documentation
| Document | Description |
|---|---|
| API Reference | Complete API documentation (IGatewayRouter, Routing Strategies, Models) |
| Module Design | Architecture and design decisions |
| Implementation Plan | Development roadmap |
| AGENT-PRIMER.md | AI-assisted setup guide |
| Routing Strategies | Routing configuration guide |
| Security Guide | Authentication and authorization |
| HTTPS Setup Guide | Production TLS/HTTPS configuration |
Related Modules
Svrnty.MCP is a family of three complementary modules:
- Svrnty.MCP.Server - Server library (expose tools TO AI agents)
- Svrnty.MCP.Client - Client library (call tools FROM servers)
- Svrnty.MCP.Gateway - Gateway/proxy (route between clients and servers) ← You are here
All three modules share:
- Same Clean Architecture pattern
- Same documentation structure
- Same security principles
- Compatible .NET 8 SDKs
Contributing
We welcome contributions! See CONTRIBUTING.md for:
- Development setup
- Code standards
- Testing requirements
- Pull request process
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Issues: GitHub Issues
- Email: info@svrnty.io
- Documentation: docs/
Built with love by Svrnty
Creating sovereign tools to democratize technology for humanity.