db-mcp-tool

by wirdes
Verified
  • src
#!/usr/bin/env node import { McpServer, } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import { DatabaseService } from "./services/database.js"; import { DatabaseConfig, DatabaseConnectionConfig, DatabaseType } from "./types/database.js"; // Create an MCP server const server = new McpServer({ name: "database-explorer", version: "1.0.0", description: "Database Explorer MCP Tool", }); // Initialize database service as null let dbService: DatabaseService | null = null; // Define connection schemas for each database type const postgresConnectionSchema = { connection: z.object({ host: z.string(), port: z.number().optional(), database: z.string(), user: z.string(), password: z.string(), }), }; const mysqlConnectionSchema = { connection: z.object({ host: z.string(), port: z.number().optional(), database: z.string(), user: z.string(), password: z.string(), }), }; const firestoreConnectionSchema = { connection: z.object({ projectId: z.string(), keyFilename: z.string(), }), }; // Add PostgreSQL connection tool server.tool( "!pg", postgresConnectionSchema, async (args: { connection: DatabaseConnectionConfig }) => { try { const config: DatabaseConfig = { type: 'postgres', connection: args.connection }; dbService = new DatabaseService(config); await dbService.connect(); return { content: [{ type: "text", text: "Successfully connected to PostgreSQL database!" }], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `PostgreSQL connection error: ${errorMessage}` }], isError: true, }; } } ); // Add MySQL connection tool server.tool( "!mysql", mysqlConnectionSchema, async (args: { connection: DatabaseConnectionConfig }) => { try { const config: DatabaseConfig = { type: 'mysql', connection: args.connection }; dbService = new DatabaseService(config); await dbService.connect(); return { content: [{ type: "text", text: "Successfully connected to MySQL database!" }], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `MySQL connection error: ${errorMessage}` }], isError: true, }; } } ); // Add Firestore connection tool server.tool( "!firestore", firestoreConnectionSchema, async (args: { connection: DatabaseConnectionConfig }) => { try { const config: DatabaseConfig = { type: 'firestore', connection: args.connection }; dbService = new DatabaseService(config); await dbService.connect(); return { content: [{ type: "text", text: "Successfully connected to Firestore database!" }], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `Firestore connection error: ${errorMessage}` }], isError: true, }; } } ); // Add get tables tool server.tool( "!tables", {}, async () => { if (!dbService) { return { content: [{ type: "text", text: "You must connect to a database first!" }], isError: true, }; } try { const tables = await dbService.getTables(); return { content: [ { type: "text", text: JSON.stringify(tables, null, 2), }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `Failed to get table information: ${errorMessage}` }], isError: true, }; } } ); // Add get triggers tool server.tool( "!triggers", {}, async () => { if (!dbService) { return { content: [{ type: "text", text: "You must connect to a database first!" }], isError: true, }; } try { const triggers = await dbService.getTriggers(); return { content: [ { type: "text", text: JSON.stringify(triggers, null, 2), }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `Failed to get trigger information: ${errorMessage}` }], isError: true, }; } } ); // Add get functions tool server.tool( "!functions", {}, async () => { if (!dbService) { return { content: [{ type: "text", text: "You must connect to a database first!" }], isError: true, }; } try { const functions = await dbService.getFunctions(); return { content: [ { type: "text", text: JSON.stringify(functions, null, 2), }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `Failed to get function information: ${errorMessage}` }], isError: true, }; } } ); // Add query execution tool server.tool( "!query", { query: z.string(), }, async (args: { query: string }) => { if (!dbService) { return { content: [{ type: "text", text: "You must connect to a database first!" }], isError: true, }; } try { const results = await dbService.executeQuery(args.query); return { content: [ { type: "text", text: JSON.stringify(results, null, 2), }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `Failed to execute query: ${errorMessage}` }], isError: true, }; } } ); // Add export schema tool server.tool( "!export-db", { table: z.string(), }, async (args: { table: string }) => { if (!dbService) { return { content: [{ type: "text", text: "You must connect to a database first!" }], isError: true, }; } try { const schema = await dbService.exportTableSchema(args.table); return { content: [ { type: "text", text: schema, }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `Failed to export table schema: ${errorMessage}` }], isError: true, }; } } ); // Add export data tool server.tool( "!export-data", { table: z.string(), }, async (args: { table: string }) => { if (!dbService) { return { content: [{ type: "text", text: "You must connect to a database first!" }], isError: true, }; } try { const data = await dbService.exportTableData(args.table); return { content: [ { type: "text", text: data, }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `Failed to export table data: ${errorMessage}` }], isError: true, }; } } ); // Start receiving messages on stdin and sending messages on stdout const transport = new StdioServerTransport(); // Handle errors process.on('uncaughtException', (error) => { console.error('Uncaught Exception:', error); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection at:', promise, 'reason:', reason); process.exit(1); }); // Connect the server await server.connect(transport);