execute_query
Execute SQL queries on SQL Server databases to retrieve, analyze, or modify data through a secure connection with configurable access levels.
Instructions
Execute a SQL query on the connected SQL Server database
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | The SQL query to execute | |
| database | No | Optional: Database name to use for this query |
Implementation Reference
- index.js:371-469 (handler)Core handler function for the 'execute_query' tool. Validates the SQL query against safety policies, executes it using the connection manager, logs performance metrics, handles errors, and formats results as a text table.async executeQuery(query, database = null) { // Validate query first const validation = this.validateQuery(query); if (!validation.allowed) { this.logger.security('QUERY_BLOCKED', 'Query blocked by safety policy', { query: query.substring(0, 200), reason: validation.reason, queryType: validation.queryType }); throw new Error(`Query blocked by safety policy: ${validation.reason}`); } const startTime = Date.now(); this.logger.debug('Executing query', { tool: 'execute_query', database, queryLength: query.length, queryType: validation.queryType }); try { const pool = await this.connectionManager.connect(); const request = pool.request(); // Switch database if specified if (database) { await request.query(`USE [${database}]`); } const result = await request.query(query); const executionTime = Date.now() - startTime; // Log successful query execution this.logger.logQueryExecution( 'execute_query', query, { database, securityLevel: validation.queryType }, { success: true, duration: executionTime, rowsAffected: result.rowsAffected } ); // Track performance (don't let performance monitoring failures break query execution) try { this.performanceMonitor.recordQuery({ tool: 'execute_query', query, executionTime, success: true, database, timestamp: new Date(startTime) }); } catch (perfError) { this.logger.warn('Performance monitoring failed', { error: perfError.message }); } // Format results if (!result.recordset || result.recordset.length === 0) { return { content: [ { type: 'text', text: `Query executed successfully. ${result.rowsAffected} rows affected.` } ] }; } return this.formatQueryResults(result.recordset); } catch (error) { const executionTime = Date.now() - startTime; // Log failed query execution this.logger.logQueryExecution( 'execute_query', query, { database, securityLevel: validation.queryType }, { success: false, duration: executionTime, error } ); // Track failed query (don't let performance monitoring failures break error handling) try { this.performanceMonitor.recordQuery({ tool: 'execute_query', query, executionTime, success: false, error: error.message, database, timestamp: new Date(startTime) }); } catch (perfError) { this.logger.warn('Performance monitoring failed during error handling', { error: perfError.message }); } throw new McpError(ErrorCode.InternalError, `Query execution failed: ${error.message}`); } }
- index.js:280-285 (registration)Tool dispatch/registration in the main CallToolRequest handler switch statement. Routes 'execute_query' calls to the executeQuery method.case 'execute_query': { const queryResult = await this.executeQuery(args.query, args.database); return { content: queryResult.content }; }
- lib/tools/tool-registry.js:8-17 (schema)Tool schema definition including name, description, and input schema for validation.name: 'execute_query', description: 'Execute a SQL query on the connected SQL Server database', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'The SQL query to execute' }, database: { type: 'string', description: 'Optional: Database name to use for this query' } }, required: ['query'] }
- index.js:241-243 (registration)Registration of ListTools handler which returns all tools including 'execute_query' from the tool registry.this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: getAllTools() }));
- index.js:474-490 (helper)Helper function used by executeQuery to format query results into a readable text table.formatQueryResults(data) { if (data.length === 0) { return { content: [{ type: 'text', text: 'No data returned' }] }; } const headers = Object.keys(data[0]); const rows = data.map(row => headers.map(header => String(row[header] || ''))); return { content: [ { type: 'text', text: this.createTextTable(headers, rows) } ] }; }