MCP server for Microsoft SQL Server using mssql-python
Server has 11 tools with basic schemas and descriptions, but significant gaps limit production readiness. All tools have descriptions (10-200 chars, mostly adequate), and input schemas are present with type definitions. However, output schemas are underdocumented, most tools return dicts without field-level documentation. Parameter descriptions exist but lack constraints (enums, ranges, formats). Error handling is minimal: tools raise generic ValueError exceptions without recovery guidance. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk levels (WRITE vs READ_ONLY). Naming is mostly clear (verb_noun pattern: connect_tool, execute_query, bulk_copy) but 'connect_tool' is awkward, should be 'connect'. No pagination support on list_connections or get_tables despite potential for large result sets. Security concern: connection_string parameter accepts raw credentials, risking exposure in logs.
Perform a bulk copy operation to load data into a table. Args: connection_id: The ID returned from connect_tool table_name: Target table name data: List of tuples or lists representing rows to insert column_mappings: Optional list of column mappings batch_size: Batch size for bulk copy (0 = all at once) keep_identity: Whether to keep identity values check_constraints: Whether to check constraints keep_nulls: Whether to keep NULL values fire_triggers: Whether to fire triggers Returns: Dictionary with bulk copy result.
Call a stored procedure. Args: connection_id: The ID returned from connect_tool procedure_name: Name of the stored procedure params: Optional list of parameters Returns: Dictionary with procedure results.
Close an existing database connection. Args: connection_id: The ID returned from connect_tool Returns: Dictionary with status confirmation.
Commit the current transaction. Args: connection_id: The ID returned from connect_tool Returns: Dictionary with status confirmation.
Connect to Microsoft SQL Server using the provided connection string. Args: connection_string: SQL Server connection string in semicolon-delimited key=value format (e.g., "SERVER=tcp:localhost;DATABASE=mydb;Authentication=ActiveDirectoryInteractive;Encrypt=yes;") Returns: Dictionary containing connection_id and server info. The connection_id should be used for subsequent operations.
Output schemas undocumented. Tools return dicts (e.g., execute_query returns {rows, cursor_id, row_count}) but field types and structures are not formally documented. LLMs cannot reliably extract nested fields or plan downstream calls.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Tools are marked with Risk levels (WRITE, READ_ONLY) in metadata but not exposed via MCP tool annotations. Agents cannot distinguish safe from destructive operations without parsing descriptions.
Credentials exposed in parameters. connect_tool accepts raw connection_string parameter containing passwords/tokens. Server-side secret injection via environment variables is not used. Credentials will appear in agent logs and traces.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 54 | 2026-07-28+ | v2 |
Execute a SQL query and return results. Args: connection_id: The ID returned from connect_tool sql: SQL statement to execute params: Optional list of parameters for parameterized query Returns: List of row dictionaries.
Execute a SQL query and return a single value. Args: connection_id: The ID returned from connect_tool sql: SQL statement that returns a single value Returns: The single value from the query result.
Fetch results from an existing cursor. Args: connection_id: The ID returned from connect_tool cursor_id: The cursor ID from execute_query mode: Fetch mode - "one", "many", or "all" (default: "all") size: Number of rows for "many" mode Returns: List of row dictionaries.
Get list of tables in the database.
List all active connections. Returns: List of connection info dictionaries.
Rollback the current transaction. Args: connection_id: The ID returned from connect_tool Returns: Dictionary with status confirmation.
Error handling lacks recovery guidance. Tools raise ValueError with generic messages ('Query execution failed: ...', 'Connection not found'). No actionable next steps for LLM (e.g., 'Try list_connections() to see available IDs').
Parameter constraints missing. 'mode' in fetch_results accepts 'one'|'many'|'all' but is not declared as enum. 'batch_size' in bulk_copy has no min/max bounds. LLMs may pass invalid values; no validation prevents hallucinated inputs.