// SchemaMcp: a read-only MCP server that shows Claude Code the application's PostgreSQL schema. // Transport: stdio. stdout carries the protocol, so every log line goes to stderr. using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Npgsql; // The connection string comes from the environment, never from a file in the repository. // Point it at a role that can only read (see schema.sql): that role is the real safety net. var connectionString = Environment.GetEnvironmentVariable("SCHEMA_MCP_CONNECTION"); if (string.IsNullOrWhiteSpace(connectionString)) { Console.Error.WriteLine("SchemaMcp: set SCHEMA_MCP_CONNECTION to a connection string for a read-only role."); return 1; } var builder = Host.CreateApplicationBuilder(args); builder.Logging.AddConsole(options => options.LogToStandardErrorThreshold = LogLevel.Trace); builder.Services.AddSingleton(NpgsqlDataSource.Create(connectionString)); builder.Services .AddMcpServer(options => options.ServerInstructions = "Read-only access to the application's PostgreSQL database: list the tables, describe one " + "table (columns, keys, indexes), or run a single SELECT with a row cap.") .WithStdioServerTransport() .WithTools(); await builder.Build().RunAsync(); return 0;