feat: add execute_sql tool

This commit is contained in:
smartass
2026-06-12 00:08:41 +05:00
parent 96404fe0d3
commit aaa2844d46
2 changed files with 133 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import * as z from 'zod'
import type { Manager } from '../db/manager.js'
import { clampRowLimit, formatDbError, MAX_ROW_LIMIT } from '../format.js'
import { errorMessage, fail, ok } from './respond.js'
export const registerQueryTools = (server: McpServer, manager: Manager): void => {
server.registerTool(
'execute_sql',
{
description:
'Execute a single SQL statement on a named connection. SELECT returns columns/rows; ' +
'DML returns rowCount (and lastInsertId for mysql). Use positional params: $1.. for postgres, ? for mysql.',
inputSchema: {
connection: z.string().describe('connection name, see list_connections'),
sql: z.string().min(1),
params: z
.array(z.union([z.string(), z.number(), z.boolean(), z.null()]))
.optional()
.describe('positional query parameters'),
database: z
.string()
.optional()
.describe('database to run against; defaults to the connection default'),
rowLimit: z.number().int().min(1).max(MAX_ROW_LIMIT).optional()
}
},
async ({ connection, sql, params, database, rowLimit }) => {
let managed: Awaited<ReturnType<Manager['get']>>
try {
managed = await manager.get(connection)
} catch (error) {
return fail(errorMessage(error))
}
try {
const result = await managed.driver.query({
sql,
params: params ?? [],
database,
rowLimit: clampRowLimit(rowLimit)
})
return ok(result)
} catch (error) {
return fail(formatDbError(managed.config.type, error))
}
}
)
}