UNPKG

dj-postgres-mcp

Version:

Model Context Protocol (MCP) server for PostgreSQL database operations with centralized configuration via dj-config-mcp

74 lines (73 loc) 2.74 kB
import { QueryExecutor } from '../QueryExecutor.js'; import { ManagedError, ErrorCodes } from '../../shared/errors.js'; import { Client } from 'pg'; export function createExecuteQueryTool() { return { name: 'execute_query', description: 'Execute a SQL query against the configured PostgreSQL database', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'SQL query to execute' }, params: { type: 'array', description: 'Query parameters for parameterized queries', items: { type: ['string', 'number', 'boolean', 'null'] } } }, required: ['query'] } }; } export async function handleExecuteQuery(args, configHandler) { if (!args.query || typeof args.query !== 'string') { throw new ManagedError(ErrorCodes.INVALID_PARAMS, 'query is required and must be a string'); } if (args.params && !Array.isArray(args.params)) { throw new ManagedError(ErrorCodes.INVALID_PARAMS, 'params must be an array'); } // Validate parameters are basic types if (args.params) { for (const param of args.params) { const type = typeof param; if (param !== null && type !== 'string' && type !== 'number' && type !== 'boolean') { throw new ManagedError(ErrorCodes.INVALID_PARAMS, 'Query parameters must be string, number, boolean, or null'); } } } // Check if connection is configured if (!configHandler.isConfigured()) { throw new ManagedError(ErrorCodes.NO_CONNECTION, 'Database connection not configured. Use configure_connection tool first'); } const config = configHandler.getConfig(); const queryExecutor = new QueryExecutor(); // Create database client const client = new Client({ host: config.host, port: config.port, database: config.database, user: config.user, password: config.password, ssl: config.ssl ? { rejectUnauthorized: false } : false, connectionTimeoutMillis: config.connectionTimeout, query_timeout: config.queryTimeout }); try { await client.connect(); const result = await queryExecutor.executeQuery(client, args.query, args.params); return { content: [{ type: 'text', text: `📊 Query Results\n\n${JSON.stringify(result, null, 2)}` }] }; } finally { await client.end(); } }