svrnty-mcp-gateway/samples/CodexMcpGateway/README.md
Svrnty a4a1dd2e38 docs: comprehensive AI coding assistant research and MCP-first implementation plan
Research conducted on modern AI coding assistants (Cursor, GitHub Copilot, Cline,
Aider, Windsurf, Replit Agent) to understand architecture patterns, context management,
code editing workflows, and tool use protocols.

Key Decision: Pivoted from building full CLI (40-50h) to validation-driven MCP-first
approach (10-15h). Build 5 core CODEX MCP tools that work with ANY coding assistant,
validate adoption over 2-4 weeks, then decide on full CLI if demand proven.

Files:
- research/ai-systems/modern-coding-assistants-architecture.md (comprehensive research)
- research/ai-systems/codex-coding-assistant-implementation-plan.md (original CLI plan, preserved)
- research/ai-systems/codex-mcp-tools-implementation-plan.md (approved MCP-first plan)
- ideas/registry.json (updated with approved MCP tools proposal)

Architech Validation: APPROVED with pivot to MCP-first approach
Human Decision: Approved (pragmatic validation-driven development)

Next: Begin Phase 1 implementation (10-15 hours, 5 core MCP tools)

🤖 Generated with CODEX Research System

Co-Authored-By: The Archivist <archivist@codex.svrnty.io>
Co-Authored-By: The Architech <architech@codex.svrnty.io>
Co-Authored-By: Mathias Beaulieu-Duncan <mat@svrnty.io>
2025-10-22 21:00:34 -04:00

337 lines
6.9 KiB
Markdown

# CodexMcpGateway Sample
Sample ASP.NET Core application demonstrating OpenHarbor.MCP.Gateway usage with multiple MCP servers.
## Purpose
Shows how to:
- Configure gateway to route to multiple backend MCP servers
- Implement custom routing strategies
- Enable authentication and rate limiting
- Monitor server health
- Manage servers via API endpoints
## Prerequisites
- .NET 8.0 SDK
- Running MCP servers (CODEX or other MCP-compatible servers)
## Configuration
Edit `appsettings.json` to configure your MCP servers:
```json
{
"Mcp": {
"Gateway": {
"Name": "CODEX MCP Gateway",
"Version": "1.0.0",
"Description": "Gateway routing to CODEX and other MCP servers",
"ListenAddress": "http://localhost:8080"
},
"Servers": [
{
"Id": "codex-server",
"Name": "CODEX Knowledge Base",
"Transport": {
"Type": "Stdio",
"Command": "dotnet",
"Args": ["run", "--project", "/path/to/CodexMcpServer/CodexMcpServer.csproj"]
},
"Enabled": true
},
{
"Id": "remote-api",
"Name": "Remote API Server",
"Transport": {
"Type": "Http",
"BaseUrl": "https://api.example.com/mcp"
},
"Enabled": true
}
],
"Routing": {
"Strategy": "ToolBased",
"HealthCheckInterval": "00:00:30",
"StrategyConfig": {
"search_": "codex-server",
"db_": "codex-server",
"api_": "remote-api"
}
},
"Security": {
"EnableAuthentication": true,
"ApiKeyHeader": "X-MCP-API-Key",
"RateLimit": {
"RequestsPerMinute": 100,
"BurstSize": 20
}
},
"Monitoring": {
"EnableMetrics": true,
"EnableTracing": true,
"EnableAuditLog": true
}
}
}
```
## Routing Strategies
### Tool-Based Routing
Routes requests based on tool name patterns:
```csharp
// In Routing/ToolBasedRouter.cs
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_") => "codex-server",
var t when t.StartsWith("api_") => "remote-api",
_ => servers.First().Id // Default
};
}
}
```
### Client-Based Routing
Routes requests based on client identity:
```csharp
// In Routing/ClientBasedRouter.cs
public class ClientBasedRouter : IRoutingStrategy
{
public string SelectServer(
RoutingContext context,
IEnumerable<ServerInfo> servers)
{
// Route admin clients to special server
if (context.ClientId == "admin-client")
{
return "remote-api";
}
// Default routing
return "codex-server";
}
}
```
### Load Balancing
Distributes load across multiple server instances:
```csharp
// In Routing/LoadBalancedRouter.cs
public class LoadBalancedRouter : IRoutingStrategy
{
private int _currentIndex = 0;
public string SelectServer(
RoutingContext context,
IEnumerable<ServerInfo> servers)
{
var healthyServers = servers.Where(s => s.IsHealthy).ToList();
if (healthyServers.Count == 0)
{
throw new NoHealthyServersException();
}
var index = Interlocked.Increment(ref _currentIndex) % healthyServers.Count;
return healthyServers[index].Id;
}
}
```
## Running the Gateway
```bash
# Start the gateway
dotnet run
# Gateway will listen on http://localhost:8080
```
## Testing the Gateway
### Health Check
```bash
curl http://localhost:8080/health
# Response:
# {
# "status": "Healthy",
# "totalServers": 2,
# "healthyServers": 2,
# "servers": [
# {
# "id": "codex-server",
# "status": "Healthy",
# "lastCheck": "2025-10-19T17:40:00Z"
# }
# ]
# }
```
### Send MCP Request
```bash
# With authentication
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "X-MCP-API-Key: your-api-key" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "search_codex",
"arguments": {
"query": "architecture"
}
},
"id": 1
}'
```
### Management Endpoints
```bash
# List registered servers
curl http://localhost:8080/gateway/servers
# Get server health
curl http://localhost:8080/gateway/servers/codex-server/health
# View metrics
curl http://localhost:8080/metrics
```
## Connecting MCP Clients
Configure MCP clients to connect to the gateway instead of individual servers:
```json
{
"Mcp": {
"Servers": [
{
"Name": "gateway",
"Transport": {
"Type": "Http",
"BaseUrl": "http://localhost:8080/mcp",
"Headers": {
"X-MCP-API-Key": "your-api-key"
}
}
}
]
}
}
```
## Authentication
### API Key Authentication
Add API keys to configuration:
```json
{
"Security": {
"ApiKeys": [
{
"Key": "admin-key-12345",
"ClientId": "admin-client",
"Roles": ["admin"]
},
{
"Key": "app-key-67890",
"ClientId": "web-app",
"Roles": ["user"]
}
]
}
}
```
### Using API Keys
Include the API key in requests:
```bash
curl -H "X-MCP-API-Key: admin-key-12345" http://localhost:8080/mcp
```
## Monitoring
### Audit Logs
All requests are logged to the audit log:
```json
{
"timestamp": "2025-10-19T17:40:00Z",
"clientId": "web-app",
"serverId": "codex-server",
"toolName": "search_codex",
"arguments": { "query": "architecture" },
"responseTime": "45ms",
"status": "success"
}
```
### Metrics
OpenTelemetry metrics are available at `/metrics`:
- `mcp_gateway_requests_total` - Total requests
- `mcp_gateway_request_duration_ms` - Request latency
- `mcp_gateway_errors_total` - Error count
- `mcp_gateway_server_health` - Server health status
## Files
- `Program.cs` - Main gateway entry point
- `appsettings.json` - Gateway configuration
- `Routing/ToolBasedRouter.cs` - Tool-based routing strategy
- `Routing/ClientBasedRouter.cs` - Client-based routing strategy
- `Routing/LoadBalancedRouter.cs` - Load balancing strategy
- `Middleware/AuthenticationMiddleware.cs` - Authentication
- `Middleware/RateLimitingMiddleware.cs` - Rate limiting
- `Middleware/AuditLoggingMiddleware.cs` - Audit logging
## Troubleshooting
### Server Not Responding
Check server health:
```bash
curl http://localhost:8080/gateway/servers/codex-server/health
```
Check circuit breaker status in logs.
### Authentication Failing
Verify API key is correct and included in request headers.
### Rate Limit Exceeded
Adjust rate limits in configuration or wait for rate limit window to reset.
## Learn More
- [OpenHarbor.MCP.Gateway Documentation](../../README.md)
- [Module Design](../../docs/module-design.md)
- [Implementation Plan](../../docs/implementation-plan.md)