svrnty-mcp-gateway/samples/CodexMcpGateway/Program.cs
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

138 lines
4.9 KiB
C#

using OpenHarbor.MCP.Gateway.Core.Models;
using OpenHarbor.MCP.Gateway.Infrastructure.Routing;
using OpenHarbor.MCP.Gateway.Infrastructure.Connection;
using OpenHarbor.MCP.Gateway.Infrastructure.Security;
using OpenHarbor.MCP.Gateway.Core.Interfaces;
namespace CodexMcpGateway;
/// <summary>
/// Sample MCP Gateway application demonstrating gateway capabilities.
/// Routes requests to multiple MCP servers with load balancing and health monitoring.
/// </summary>
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("=== CODEX MCP Gateway Sample ===");
Console.WriteLine("Gateway routes requests to MCP servers via HTTP transport\n");
// Step 1: Create connection pool
var connectionPool = new ServerConnectionPool
{
MaxConnectionsPerServer = 10,
IdleTimeout = TimeSpan.FromMinutes(5)
};
// Step 2: Choose routing strategy
Console.WriteLine("Select routing strategy:");
Console.WriteLine("1. Round Robin (default)");
Console.WriteLine("2. Tool-based routing");
Console.WriteLine("3. Client-based routing");
Console.Write("\nChoice (1-3): ");
var choice = Console.ReadLine();
IRoutingStrategy strategy = choice switch
{
"2" => new ToolBasedStrategy(new Dictionary<string, string>
{
["search_*"] = "codex-server-1",
["get_document"] = "codex-server-2",
["*"] = "codex-server-1"
}),
"3" => new ClientBasedStrategy(new Dictionary<string, string>
{
["client-a"] = "codex-server-1",
["client-b"] = "codex-server-2"
}),
_ => new RoundRobinStrategy()
};
Console.WriteLine($"Using {strategy.GetType().Name}\n");
// Step 3: Create gateway router
var router = new GatewayRouter(strategy, connectionPool);
// Step 4: Register MCP servers
Console.WriteLine("Registering MCP servers...");
var server1 = new ServerConfig
{
Id = "codex-server-1",
Name = "CODEX MCP Server 1",
TransportType = "Http",
BaseUrl = "http://localhost:5050",
Enabled = true
};
await router.RegisterServerAsync(server1);
Console.WriteLine($" ✓ Registered: {server1.Name} ({server1.BaseUrl})");
// Step 5: Check server health
Console.WriteLine("\nChecking server health...");
var health = await router.GetServerHealthAsync();
foreach (var serverHealth in health)
{
var status = serverHealth.IsHealthy ? "✓ Healthy" : "✗ Unhealthy";
Console.WriteLine($" {status}: {serverHealth.ServerName}");
}
// Step 6: Demonstrate request routing
Console.WriteLine("\n--- Simulating Gateway Requests ---\n");
Console.WriteLine("Request 1: search_codex");
var request1 = new GatewayRequest
{
ToolName = "search_codex",
Arguments = new Dictionary<string, object>
{
["query"] = "Model Context Protocol",
["maxResults"] = 5
},
ClientId = "demo-client"
};
try
{
var response1 = await router.RouteAsync(request1);
Console.WriteLine($" Response: {(response1.Success ? "Success" : "Failed")}");
Console.WriteLine($" Routed to: {response1.ServerId}");
if (!response1.Success)
{
Console.WriteLine($" Error: {response1.Error}");
}
}
catch (Exception ex)
{
Console.WriteLine($" Error: {ex.Message}");
}
// Step 7: Demonstrate authentication
Console.WriteLine("\n--- Testing Authentication ---\n");
var apiKeyProvider = new ApiKeyAuthProvider(new Dictionary<string, string>
{
["demo-client"] = "secret-key-123"
});
var authContext = new AuthenticationContext
{
ClientId = "demo-client",
Credentials = "secret-key-123"
};
var authResult = await apiKeyProvider.AuthenticateAsync(authContext);
Console.WriteLine($"Authentication: {(authResult.IsAuthenticated ? " Success" : " Failed")}");
// Step 8: Show statistics
Console.WriteLine("\n--- Gateway Statistics ---\n");
var poolStats = connectionPool.GetPoolStats();
Console.WriteLine($"Connection Pool:");
Console.WriteLine($" Total connections: {poolStats.TotalConnections}");
Console.WriteLine($" Active connections: {poolStats.ActiveConnections}");
Console.WriteLine($" Idle connections: {poolStats.IdleConnections}");
Console.WriteLine("\n=== Sample Complete ===");
}
}