UNPKG

@bluspace/mssql-mcp-server

Version:

Microsoft SQL Server MCP (Model Context Protocol) Server - AI-powered database interaction tool

127 lines (126 loc) 5.55 kB
#!/usr/bin/env node import { Command } from "commander"; import { z } from "zod"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { initDb } from "./db.js"; import { registerSchemaTools } from "./tools/schema.js"; import { registerCrudTools } from "./tools/crud.js"; import { registerQueryBuilderTools } from "./tools/query-builder.js"; import { registerStoredProcedureTools } from "./tools/stored-procedures.js"; import { registerTransactionTools } from "./tools/transactions.js"; import { registerBulkOperationTools } from "./tools/bulk-operations.js"; import { registerDdlTools } from "./tools/ddl.js"; import https from "https"; const cli = new Command(); cli .name("mssql-mcp-server") .description("An MCP server for interacting with Microsoft SQL Server databases") .version("1.2.0") .requiredOption("--user <string>", "Database user") .requiredOption("--password <string>", "Database password") .requiredOption("--server <string>", "SQL Server hostname or IP") .option("--port <number>", "Database port", "1433") .requiredOption("--database <string>", "Database name") .option("--permissions <string>", "Allowed operations: read, write, or all", "all"); const opts = cli.parse(process.argv).opts(); // Validate permissions using Zod const permissionsSchema = z.enum(["read", "write", "all"]); try { // This will throw if validation fails const perms = permissionsSchema.parse(opts.permissions); // Logging functions that all go to stderr to keep stdout clean for JSON-RPC function debug(message) { console.error(`[DEBUG] ${message}`); } // Replace console.log with a function that logs to stderr instead const log = (message) => { console.error(`[INFO] ${message}`); }; async function main() { debug('MCP server process started'); log("Starting SQL MCP Server..."); // Version check - helps users know if they're on an old cached version log(`Running version 1.2.0`); // Check for latest version (non-blocking) https.get('https://registry.npmjs.org/@bluspace/mssql-mcp-server/latest', (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { try { const latest = JSON.parse(data).version; if (latest && latest !== '1.2.0') { log(`\n⚠️ Update available: ${latest} (current: 1.2.0)`); log(`To update: npx clear-npx-cache && npx @bluspace/mssql-mcp-server@latest\n`); } } catch (e) { // Silently ignore version check errors } }); }).on('error', () => { // Silently ignore network errors }); // Initialize MCP server debug('Creating MCP server instance'); const server = new McpServer({ name: "SQL MCP Server", version: "1.2.0" }); try { // Connect to DB debug(`Attempting to connect to SQL Server at ${opts.server}:${opts.port}/${opts.database}...`); log(`Connecting to SQL Server at ${opts.server}:${opts.port}/${opts.database}...`); const db = await initDb({ user: opts.user, password: opts.password, server: opts.server, port: Number(opts.port), database: opts.database, permissions: perms }); log("Database connection successful"); // Register tools based on permissions debug('About to register schema tools'); log("Registering schema tools..."); registerSchemaTools(server, db); // Always register query builder (read-only tool) log("Registering query builder tools..."); registerQueryBuilderTools(server, db); // Register stored procedure tools (can be read-only) log("Registering stored procedure tools..."); registerStoredProcedureTools(server, db); if (perms === "write" || perms === "all") { log("Registering CRUD tools..."); registerCrudTools(server, db); log("Registering DDL tools..."); registerDdlTools(server, db); log("Registering transaction tools..."); registerTransactionTools(server, db); log("Registering bulk operation tools..."); registerBulkOperationTools(server, db); } // Start STDIO transport debug('About to start MCP server over STDIO'); log("Starting MCP server over STDIO..."); const transport = new StdioServerTransport(); await server.connect(transport); log("SQL MCP Server is ready"); debug('Server initialization complete'); } catch (err) { console.error("Failed to initialize server:", err); process.exit(1); } } main().catch(err => { console.error("Fatal error:", err); process.exit(1); }); } catch (err) { const validationError = err; console.error("Invalid permissions value:", validationError.message); console.error("Please use one of: read, write, all"); process.exit(1); }