#!/usr/bin/env node import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; // zod is a peer dep of @modelcontextprotocol/sdk import { checkMigration } from "./checker.js"; import { ALL_CHECK_DEFINITIONS } from "./checks.js"; const server = new McpServer({ name: "pg-safe-migrate", version: "1.0.0", }); server.tool( "check_migration", "Check a PostgreSQL migration SQL string for unsafe operations that could cause downtime or data loss.", { sql: z.string().describe("The migration SQL to check"), }, async ({ sql }) => { const result = checkMigration(sql); return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( "list_checks", "List all available safety checks with their severity, description, and suggested fix.", {}, async () => { return { content: [ { type: "text", text: JSON.stringify(ALL_CHECK_DEFINITIONS, null, 2), }, ], }; } ); server.tool( "explain_check", "Get a detailed explanation of a specific safety check by name.", { checkName: z.string().describe("The check name, e.g. 'create_index_without_concurrently'"), }, async ({ checkName }) => { const def = ALL_CHECK_DEFINITIONS.find((d) => d.name === checkName); if (!def) { return { content: [ { type: "text", text: `Check '${checkName}' not found. Use list_checks to see all available checks.`, }, ], }; } return { content: [ { type: "text", text: JSON.stringify(def, null, 2), }, ], }; } ); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); } main().catch((err) => { console.error(err); process.exit(1); });