execute_query
Run SQL queries like SELECT, SHOW, DESCRIBE, and EXPLAIN on MariaDB/MySQL databases with secure, read-only access through MariaDB MCP Server.
Instructions
Execute a SQL query
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| database | No | Database name (optional, uses default if not specified) | |
| query | Yes | SQL query (only SELECT, SHOW, DESCRIBE, and EXPLAIN statements are allowed) |
Input Schema (JSON Schema)
{
"properties": {
"database": {
"description": "Database name (optional, uses default if not specified)",
"type": "string"
},
"query": {
"description": "SQL query (only SELECT, SHOW, DESCRIBE, and EXPLAIN statements are allowed)",
"type": "string"
}
},
"required": [
"query"
],
"type": "object"
}
Implementation Reference
- src/index.ts:147-156 (handler)The MCP CallTool request handler implementation for the 'execute_query' tool. It validates the query parameter, calls the executeQuery helper with optional database, and returns the query results as formatted JSON text.case "execute_query": { const qry = args.query as string; if (!qry) throw new McpError(ErrorCode.InvalidParams, "`query` is required"); const db = args.database as string | undefined; const { rows } = await executeQuery(qry, [], db); return { content: [{ type: "text", text: JSON.stringify(rows, null, 2) }], }; }
- src/index.ts:104-112 (schema)Tool schema definition for 'execute_query', registered in ListTools response. Specifies name, description, input schema with 'query' (required) and optional 'database' parameters.{ name: "execute_query", description: "Run an arbitrary SQL query", inputSchema: { type: "object", properties: { query: { type: "string" }, database: { type: "string" } }, required: ["query"], }, },
- src/index.ts:80-114 (registration)Registration of all tools including 'execute_query' via the ListToolsRequestSchema handler on the MCP server.mcpServer.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: "list_databases", description: "List all databases", inputSchema: { type: "object" }, }, { name: "list_tables", description: "List tables in a database", inputSchema: { type: "object", properties: { database: { type: "string" } }, }, }, { name: "describe_table", description: "Show schema of a table", inputSchema: { type: "object", properties: { database: { type: "string" }, table: { type: "string" } }, required: ["table"], }, }, { name: "execute_query", description: "Run an arbitrary SQL query", inputSchema: { type: "object", properties: { query: { type: "string" }, database: { type: "string" } }, required: ["query"], }, }, ], }));
- src/connection.ts:49-114 (helper)Helper function executeQuery that performs the actual SQL execution: manages MariaDB connection pool, switches database if specified, validates query, executes with params and timeout, limits rows, handles errors and releases connections.export async function executeQuery( sql: string, params: any[] = [], database?: string ): Promise<{ rows: any; fields: mariadb.FieldInfo[] }> { console.error(`[Query] Executing: ${sql}`); // Create connection pool if not already created if (!pool) { console.error("[Setup] Connection pool not found, creating a new one"); pool = createConnectionPool(); } try { // Get connection from pool if (connection) { console.error("[Query] Reusing existing connection"); } else { console.error("[Query] Creating new connection"); connection = await pool.getConnection(); } // Use specific database if provided if (database) { console.error(`[Query] Using database: ${database}`); await connection.query(`USE \`${database}\``); } if (!isAlloowedQuery(sql)) { throw new Error("Query not allowed"); } // Execute query with timeout const [rows, fields] = await connection.query({ metaAsArray: true, namedPlaceholders: true, sql, ...params, timeout: DEFAULT_TIMEOUT, }); // Apply row limit if result is an array const limitedRows = Array.isArray(rows) && rows.length > DEFAULT_ROW_LIMIT ? rows.slice(0, DEFAULT_ROW_LIMIT) : rows; // Log result summary console.error( `[Query] Success: ${ Array.isArray(rows) ? rows.length : 1 } rows returned with ${JSON.stringify(params)}` ); return { rows: limitedRows, fields }; } catch (error) { if (connection) { connection.release(); console.error("[Query] Connection released with error"); } console.error("[Error] Query execution failed:", error); throw error; } finally { // Release connection back to pool if (connection) { connection.release(); console.error("[Query] Connection released"); } } }