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>
157 lines
5.4 KiB
C#
157 lines
5.4 KiB
C#
using System;
|
|
using System.Net.Http;
|
|
using System.Threading.Tasks;
|
|
using CodexMcpServer.Tools;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using OpenHarbor.MCP.AspNetCore.Extensions;
|
|
using OpenHarbor.MCP.Core;
|
|
|
|
namespace CodexMcpServer;
|
|
|
|
/// <summary>
|
|
/// CODEX MCP Server entry point.
|
|
/// Exposes 6 CODEX tools via Model Context Protocol.
|
|
/// Supports both HTTP (default) and stdio transports.
|
|
/// </summary>
|
|
internal class Program
|
|
{
|
|
private static async Task Main(string[] args)
|
|
{
|
|
// Check if stdio mode is requested
|
|
bool useStdio = args.Length > 0 && args[0] == "--stdio";
|
|
|
|
if (useStdio)
|
|
{
|
|
await RunStdioModeAsync();
|
|
}
|
|
else
|
|
{
|
|
await RunHttpModeAsync(args);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs the MCP server in HTTP mode (default).
|
|
/// Listens on http://localhost:5050 for MCP requests.
|
|
/// </summary>
|
|
private static async Task RunHttpModeAsync(string[] args)
|
|
{
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Configure services
|
|
builder.Services.AddSingleton<HttpClient>(sp => new HttpClient
|
|
{
|
|
BaseAddress = new Uri("http://localhost:5099"),
|
|
Timeout = TimeSpan.FromSeconds(30)
|
|
});
|
|
|
|
// Create and register MCP server
|
|
var httpClient = new HttpClient
|
|
{
|
|
BaseAddress = new Uri("http://localhost:5099"),
|
|
Timeout = TimeSpan.FromSeconds(30)
|
|
};
|
|
|
|
var registry = new ToolRegistry();
|
|
registry.AddTool(new SearchCodexTool(httpClient));
|
|
registry.AddTool(new GetDocumentTool(httpClient));
|
|
registry.AddTool(new ListDocumentsTool(httpClient));
|
|
registry.AddTool(new SearchByTagTool(httpClient));
|
|
registry.AddTool(new GetDocumentSectionsTool(httpClient));
|
|
registry.AddTool(new ListTagsTool(httpClient));
|
|
|
|
var server = new McpServer(registry);
|
|
builder.Services.AddMcpServer(server);
|
|
|
|
// Configure Kestrel to listen on port 5050
|
|
builder.WebHost.ConfigureKestrel(options =>
|
|
{
|
|
options.ListenLocalhost(5050);
|
|
});
|
|
|
|
var app = builder.Build();
|
|
|
|
// Map MCP endpoints
|
|
app.MapMcpEndpoints(server);
|
|
|
|
Console.WriteLine("=== CODEX MCP Server (HTTP Mode) ===");
|
|
Console.WriteLine("Listening on: http://localhost:5050");
|
|
Console.WriteLine("Endpoints:");
|
|
Console.WriteLine(" POST /mcp/invoke - MCP JSON-RPC endpoint");
|
|
Console.WriteLine(" GET /health - Health check");
|
|
Console.WriteLine();
|
|
Console.WriteLine("Connected to CODEX API: http://localhost:5099");
|
|
Console.WriteLine();
|
|
Console.WriteLine("Available Tools:");
|
|
Console.WriteLine(" - search_codex");
|
|
Console.WriteLine(" - get_document");
|
|
Console.WriteLine(" - list_documents");
|
|
Console.WriteLine(" - search_by_tag");
|
|
Console.WriteLine(" - get_document_sections");
|
|
Console.WriteLine(" - list_tags");
|
|
Console.WriteLine();
|
|
Console.WriteLine("Press Ctrl+C to shutdown");
|
|
Console.WriteLine();
|
|
|
|
await app.RunAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs the MCP server in stdio mode (legacy).
|
|
/// Communicates via stdin/stdout for Claude Desktop integration.
|
|
/// </summary>
|
|
private static async Task RunStdioModeAsync()
|
|
{
|
|
try
|
|
{
|
|
// Initialize HTTP client for CODEX API calls
|
|
var httpClient = new HttpClient
|
|
{
|
|
BaseAddress = new Uri("http://localhost:5099"),
|
|
Timeout = TimeSpan.FromSeconds(30)
|
|
};
|
|
|
|
// Create tool registry and register all 6 CODEX tools
|
|
var registry = new ToolRegistry();
|
|
registry.AddTool(new SearchCodexTool(httpClient));
|
|
registry.AddTool(new GetDocumentTool(httpClient));
|
|
registry.AddTool(new ListDocumentsTool(httpClient));
|
|
registry.AddTool(new SearchByTagTool(httpClient));
|
|
registry.AddTool(new GetDocumentSectionsTool(httpClient));
|
|
registry.AddTool(new ListTagsTool(httpClient));
|
|
|
|
// Create MCP server
|
|
var server = new McpServer(registry);
|
|
|
|
// Create stdio transport (JSON-RPC 2.0 over stdin/stdout)
|
|
using var transport = new StdioTransport(
|
|
Console.OpenStandardInput(),
|
|
Console.OpenStandardOutput()
|
|
);
|
|
|
|
// Main request/response loop
|
|
while (true)
|
|
{
|
|
var request = await transport.ReadRequestAsync();
|
|
if (request == null)
|
|
{
|
|
// End of stream - exit gracefully
|
|
break;
|
|
}
|
|
|
|
var response = await server.HandleRequestAsync(request);
|
|
await transport.WriteResponseAsync(response);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log errors to stderr (stdout is reserved for MCP protocol)
|
|
await Console.Error.WriteLineAsync($"Fatal error: {ex.Message}");
|
|
await Console.Error.WriteLineAsync(ex.StackTrace);
|
|
Environment.Exit(1);
|
|
}
|
|
}
|
|
}
|