Skip to main content
Glama
NakiriYuuzu

MSSQL MCP Server

by NakiriYuuzu

execute-query

Execute SQL queries on a Microsoft SQL Server database using the MSSQL MCP Server. Specify queries and optional result limits to retrieve data securely and efficiently.

Instructions

執行 SQL 查詢語句

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNo結果筆數限制 (預設: 100)
queryYes要執行的 SQL 查詢語句

Implementation Reference

  • The primary handler function for the 'execute-query' tool. It checks connection, validates the query for safety using validateReadOnlyQuery, adds a TOP limit, executes the query via MSSQLManager.executeQuery, formats the result as a table using formatResultAsTable, and returns the output or error.
    async ({ query, limit }) => { try { if (!mssqlManager.isConnected()) { return { content: [ { type: 'text' as const, text: '錯誤: 尚未連接到資料庫伺服器。請先使用 connect-database 工具建立連接。' } ] } } // 驗證查詢安全性 const validation = validateReadOnlyQuery(query) if (!validation.isValid) { return { content: [ { type: 'text' as const, text: `查詢被拒絕: ${validation.reason}` } ] } } // 加入 TOP 限制 const finalQuery = addTopLimit(query, limit) const result = await mssqlManager.executeQuery(finalQuery) if (result.recordset.length === 0) { return { content: [ { type: 'text' as const, text: '查詢執行成功,但沒有返回任何資料。' } ] } } // 使用改進的表格格式化 const tableOutput = formatResultAsTable(result.recordset, limit) return { content: [ { type: 'text' as const, text: `查詢執行成功:\n\n${tableOutput}` } ] } } catch (error) { return { content: [ { type: 'text' as const, text: `查詢執行失敗: ${formatError(error)}` } ] } } }
  • Zod input schema for the 'execute-query' tool, defining the required 'query' string parameter and optional 'limit' number (default 100).
    inputSchema: { query: z.string().describe('要執行的 SQL 查詢語句'), limit: z.number().optional().default(100).describe('結果筆數限制 (預設: 100)'), }
  • src/index.ts:354-428 (registration)
    MCP server registration of the 'execute-query' tool, including name, title, description, input schema, and handler function.
    server.registerTool( 'execute-query', { title: '執行查詢', description: '執行 SQL 查詢語句', inputSchema: { query: z.string().describe('要執行的 SQL 查詢語句'), limit: z.number().optional().default(100).describe('結果筆數限制 (預設: 100)'), } }, async ({ query, limit }) => { try { if (!mssqlManager.isConnected()) { return { content: [ { type: 'text' as const, text: '錯誤: 尚未連接到資料庫伺服器。請先使用 connect-database 工具建立連接。' } ] } } // 驗證查詢安全性 const validation = validateReadOnlyQuery(query) if (!validation.isValid) { return { content: [ { type: 'text' as const, text: `查詢被拒絕: ${validation.reason}` } ] } } // 加入 TOP 限制 const finalQuery = addTopLimit(query, limit) const result = await mssqlManager.executeQuery(finalQuery) if (result.recordset.length === 0) { return { content: [ { type: 'text' as const, text: '查詢執行成功,但沒有返回任何資料。' } ] } } // 使用改進的表格格式化 const tableOutput = formatResultAsTable(result.recordset, limit) return { content: [ { type: 'text' as const, text: `查詢執行成功:\n\n${tableOutput}` } ] } } catch (error) { return { content: [ { type: 'text' as const, text: `查詢執行失敗: ${formatError(error)}` } ] } } } )
  • MSSQLManager.executeQuery method: executes the SQL query using the mssql library's ConnectionPool.request().query() and returns structured QueryResult.
    async executeQuery(query: string): Promise<QueryResult> { if (!this.isConnected() || !this.pool) { throw new Error('尚未建立資料庫連接') } try { const request = this.pool.request() const result = await request.query(query) return { recordset: result.recordset || [], recordsets: result.recordsets ? (Array.isArray(result.recordsets) ? result.recordsets.map(rs => Array.from(rs)) : [Array.from(result.recordsets as any)]) : [], rowsAffected: Array.isArray(result.rowsAffected) ? result.rowsAffected : [result.rowsAffected || 0], output: result.output || {} } } catch (error) { throw new Error(`執行查詢失敗: ${error instanceof Error ? error.message : String(error)}`) } }
  • Utility function that validates the SQL query for read-only compliance, blocks dangerous keywords, checks permissions via environment variables, and prevents multi-statement queries.
    export function validateReadOnlyQuery(query: string): { isValid: boolean; reason?: string } { const trimmedQuery = query.trim().toLowerCase() // 檢查是否為空查詢 if (!trimmedQuery) { return { isValid: false, reason: '查詢語句不能為空' } } // 檢查是否包含分號後的額外語句(防止 SQL 注入) const statements = query.split(';').filter(stmt => stmt.trim()) if (statements.length > 1) { return { isValid: false, reason: '不允許執行多個 SQL 語句' } } // 檢查環境變數權限設定 const ALLOW_INSERT = process.env.MSSQL_ALLOW_INSERT === 'true' const ALLOW_UPDATE = process.env.MSSQL_ALLOW_UPDATE === 'true' const ALLOW_DELETE = process.env.MSSQL_ALLOW_DELETE === 'true' const DANGER_MODE = process.env.MSSQL_DANGER_MODE === 'true' // 如果啟用了 danger mode,允許所有操作 if (DANGER_MODE) { process.stderr.write('[WARNING] Danger mode is enabled - allowing all SQL operations\n') return { isValid: true } } // 定義永遠危險的關鍵字(即使在 danger mode 下也應該謹慎) const alwaysDangerousKeywords = [ 'drop', 'truncate', 'alter', 'create', 'grant', 'revoke', 'deny', 'execute', 'exec', 'sp_', 'xp_', 'backup', 'restore', 'rename' ] // 定義可選權限關鍵字 const permissionKeywords = { insert: { allowed: ALLOW_INSERT, keyword: 'insert' }, update: { allowed: ALLOW_UPDATE, keyword: 'update' }, delete: { allowed: ALLOW_DELETE, keyword: 'delete' }, merge: { allowed: ALLOW_INSERT && ALLOW_UPDATE, keyword: 'merge' }, replace: { allowed: ALLOW_INSERT && ALLOW_DELETE, keyword: 'replace' } } // 檢查永遠危險的關鍵字 for (const keyword of alwaysDangerousKeywords) { const pattern = new RegExp(`\\b${keyword}\\b`, 'i') if (pattern.test(trimmedQuery)) { return { isValid: false, reason: `查詢包含高危險關鍵字: ${keyword.toUpperCase()}。此操作被禁止。` } } } // 檢查需要權限的關鍵字 for (const [key, config] of Object.entries(permissionKeywords)) { const pattern = new RegExp(`\\b${config.keyword}\\b`, 'i') if (pattern.test(trimmedQuery)) { if (!config.allowed) { return { isValid: false, reason: `查詢包含 ${config.keyword.toUpperCase()} 操作,但未授予此權限。請設定環境變數 MSSQL_ALLOW_${key.toUpperCase()}=true 來啟用。` } } // 如果有權限,記錄警告 process.stderr.write(`[INFO] Executing ${config.keyword.toUpperCase()} operation with permission\n`) return { isValid: true } } } // 檢查是否為 SELECT 查詢 if (!trimmedQuery.startsWith('select') && !trimmedQuery.startsWith('with')) { // 如果不是 SELECT 但也不包含上述關鍵字,可能是其他查詢類型 return { isValid: false, reason: '僅允許 SELECT 查詢、WITH 子句查詢,或已授權的 DML 操作' } } return { isValid: true } }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NakiriYuuzu/Mssql-Mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server