Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
SQL Server MCP has 8 tools with explicit definitions visible in JsonRpcHandler.cs. All tools have descriptions (10-100 chars) and input schemas with type declarations. However, several critical issues prevent a higher score: (1) Output schema is never documented, McpToolResult.cs shows only a generic content[] array with no field structure defined, forcing LLMs to guess at response format. (2) Parameter descriptions are minimal and lack actionable detail, e.g., 'Optional path of the active file in the editor' repeats across 6 tools without explaining HOW it's used to find appsettings.json or what happens if not provided. (3) Schema definitions are present but lack required fields and enums, numeric limits, format constraints, and mutual-exclusivity rules are missing. (4) Error handling is generic, no recovery guidance, no categorization of retryable vs fatal errors, no examples of valid input ranges. (5) Two high-risk tools (execute_database_query, execute_procedure) lack any mention of safety checks, dry-run support, or destructive operation warnings. Per-tool analysis: naming is solid (all verb_noun pattern), but parameter documentation is sparse.
Tools (8)
execute_database_querywritesource verified50/100
Execute a SQL query against a specified database
execute_procedurewritesource verified55/100
Execute a stored procedure with optional parameters
Output schema is completely undocumented. McpToolResult.cs shows only McpContent[] and isError flag, but no field structure is defined for either. LLMs cannot predict response format or plan downstream chaining.
Parameter descriptions are generic placeholders. 'Optional path of the active file in the editor. Used to automatically find the nearest appsettings.json.' appears on 6 tools without explaining: (1) what appsettings.json keys are required, (2) what happens if not found, (3) whether it overrides server config. This forces LLMs to guess behavior.
Rewrite currentFilePath parameter descriptions. Instead of generic placeholder, explain: 'Optional. Path to active editor file. Server searches upward for appsettings.json to override default connection string. If omitted, uses server config. Requires allow_workspace_override=true.'
Add destructive operation warnings and safety gates to execute_database_query and execute_procedure. Example: 'WARNING: This tool executes arbitrary SQL and CANNOT be undone. No dry-run support. Recommended: use read-only queries via execute_system_query when possible. Use explicit WHERE clauses and LIMIT in UPDATEs/DELETEs.'
Add schema parameter constraints. Document: 'schema (optional, default: "dbo"): Schema name. Valid values depend on database. Common: dbo, temp, sys. Invalid values return error 'Schema {schema} does not exist in database {database}'. Call get_tables without schema param to discover available schemas.'
Add SQL injection warnings and parameterization guidance to execute_database_query and execute_system_query. Example: 'query (required, string): SQL query to execute. DO NOT concatenate user input directly. For parameterized queries, use sp_executesql syntax: EXEC sp_executesql N'SELECT * FROM [table] WHERE id=@id', N'@id INT', @id=value'.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
execute_database_query and execute_procedure are WRITE operations with no destructive warnings, dry-run support, or confirmation flow. Agents can execute DELETE, UPDATE, or stored procedures without any safety gate. No mention of transaction rollback, undo capability, or audit trail.
No enum constraints or range validation on parameters. 'schema' defaults to 'dbo' but no explanation of what other valid schemas exist. 'query' parameter in execute_database_query accepts any string with no warning about SQL injection risk or parameterization guidance.
Error handling is absent from source. No error classification (retryable vs fatal), no recovery guidance, no examples of invalid input or what to do on 'database not found'. JsonRpcHandler catches exceptions generically but response content is not shown.
No pagination support on list tools. get_tables, get_procedures, get_columns have no limit, offset, or cursor parameters. Large result sets risk context window explosion and token waste.
Tool descriptions do not explain WHEN to use each tool or how they compose. E.g., get_procedure_definition returns procedure definition, but no guidance on whether to call get_procedure_definition before execute_procedure, or when to prefer direct execution.
get_procedure_definitionexecute_procedure
Implement pagination on get_tables, get_columns, get_procedures. Add optional parameters: limit (1 - 100, default 20), offset (0 by default). Return {content: [{type: 'text', text: '...'}], total_count: int, has_more: bool}. Example: 'Returned 20 of 150 tables. Call again with offset=20 to fetch next batch.'
Add error recovery guidance to tool descriptions. Example for get_tables: 'If database not found, call get_databases() to list available databases. If schema not found, omit schema parameter to use default schema dbo.'
Document which tools are safe for retry. Example: 'get_* tools are idempotent and safe to retry on timeout. execute_* tools may be non-idempotent and should only retry on specific errors (e.g., connection timeout). Do NOT retry after application-level errors like 'Duplicate key' or 'Constraint violation'.'
Add parameter type and constraint detail to all schemas. For example, query parameter in execute_database_query should note: 'type: string, minLength: 1, pattern: must be valid T-SQL, recommended max 10KB to avoid token waste'.
Create separate read-only and write tool pairs if possible. Offer execute_database_query_readonly (SELECT only, safe to retry, runs with low privilege) alongside execute_database_query (any SQL, high privilege, audit logged). This enables least-privilege agent design.