feat(sqlserver): surface informational messages (STATISTICS, PRINT) in query results#307
feat(sqlserver): surface informational messages (STATISTICS, PRINT) in query results#307esetnik wants to merge 2 commits intobytebase:mainfrom
Conversation
…n query results SQL Server emits informational messages via the TDS protocol for SET STATISTICS TIME/IO output, PRINT statements, and warnings. The mssql driver's Request object exposes these through 'info' events, but they were previously discarded. This change captures those messages during query execution and includes them in the response when present, enabling MCP clients to access query performance statistics and diagnostic output. Changes: - Add optional `messages` field to SQLResult interface - Listen for 'info' events on SQL Server Request before execution - Include non-empty messages array in execute_sql tool response
There was a problem hiding this comment.
Pull request overview
This PR adds support for surfacing SQL Server informational messages (e.g., SET STATISTICS TIME/IO, PRINT, warnings) by capturing mssql Request info events during execution and returning them to MCP clients when present.
Changes:
- Extend
SQLResultwith an optionalmessages?: string[]field for informational DB messages. - Capture SQL Server
Requestinfoevents during query execution and include them in the connector result. - Pass
messagesthrough theexecute_sqltool response when non-empty.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/connectors/interface.ts | Adds optional messages to the shared SQLResult contract. |
| src/connectors/sqlserver/index.ts | Collects SQL Server informational messages via Request.on('info') and returns them in SQLResult. |
| src/tools/execute-sql.ts | Includes messages in the tool response payload when provided by the connector. |
…ture Adds three tests covering the new messages behavior: - PRINT output is captured and returned in messages array - SET STATISTICS TIME output contains CPU/elapsed timing info - messages field is absent when no informational messages are emitted
| return { | ||
| rows: result.recordset || [], | ||
| rowCount: result.rowsAffected[0] || 0, |
There was a problem hiding this comment.
rowCount is derived from result.rowsAffected[0], which is incorrect for multi-statement batches (e.g. SET STATISTICS TIME ON; SELECT ...; SET STATISTICS TIME OFF; or PRINT ...; SELECT ...;). In those cases the first statement often affects 0 rows, so count will be reported as 0 even when recordset contains rows. Consider computing rowCount based on the returned recordset (for SELECT) and/or using the last entry in rowsAffected (or summing it) to reflect the statement(s) that actually produced the returned rows.
| return { | |
| rows: result.recordset || [], | |
| rowCount: result.rowsAffected[0] || 0, | |
| const rows = result.recordset || []; | |
| const rowCount = rows.length > 0 | |
| ? rows.length | |
| : (result.rowsAffected && result.rowsAffected.length > 0 | |
| ? result.rowsAffected[result.rowsAffected.length - 1] || 0 | |
| : 0); | |
| return { | |
| rows, | |
| rowCount, |
Summary
SQL Server emits informational messages via the TDS protocol for
SET STATISTICS TIME/IOoutput,PRINTstatements, and warnings. Themssqldriver'sRequestobject exposes these throughinfoevents, but they were previously discarded.This change captures those messages during query execution and includes them in the response when present, enabling MCP clients to access query performance statistics and diagnostic output.
Motivation
When using DBHub as an MCP server to analyze SQL Server query performance, there's currently no way to see
SET STATISTICS TIME ONorSET STATISTICS IO ONoutput — the tool only returns result set rows. This forces users to work around the limitation withDECLARE @starttiming variables or DMV queries, which provide less detail than the native statistics output.With this change, running:
...will include the CPU/elapsed time breakdown in the response's
messagesarray alongside the result rows.Changes
src/connectors/interface.ts: Add optionalmessages?: string[]field toSQLResultsrc/connectors/sqlserver/index.ts: Listen forinfoevents on theRequestobject before executing queries, collect messages, and include them in the result when presentsrc/tools/execute-sql.ts: Passmessagesthrough to the MCP tool response when non-emptyNotes
messagesis optional and only included when non-emptySQLResultshapemssqlpackage'sRequest.on('info')event covers all SQL Server informational messages (severity < 10): statistics, print output, warnings, etc.