Skip to main content
Glama
bpamiri
by bpamiri
mssql-mcp-prd.md9.46 kB
# MS SQL Server MCP Server - Product Requirements Document ## Overview This document defines the requirements for `mssql-mcp`, an MCP (Model Context Protocol) server that enables AI assistants to interact with Microsoft SQL Server databases. The server is modeled after the proven architecture of `u2-mcp` but tailored for relational database semantics. ## Goals 1. **Enable AI-database interaction** - Allow Claude and other AI assistants to query, read, write, and manage SQL Server data 2. **Safety first** - Prevent destructive operations through configurable blocklists, read-only mode, and query limits 3. **Production ready** - Support multiple transport modes (stdio, HTTP, streamable HTTP with OAuth) 4. **Developer friendly** - Simple configuration via environment variables, clear error messages ## Technology Stack | Component | Choice | Rationale | |-----------|--------|-----------| | Language | Python 3.10+ | Consistency with u2-mcp, broad ecosystem | | MCP Framework | FastMCP | Proven in u2-mcp, clean decorator-based API | | Database Driver | pymssql | Pure Python, no ODBC required, good for Docker/Linux | | Settings | pydantic-settings | Type-safe config, env var binding | | Testing | pytest | Standard, good async support | | Linting | ruff | Fast, comprehensive | ## MCP Tools ### Query Tools #### `execute_query` Execute a read-only SQL query and return results. **Parameters:** - `query` (str, required): SQL SELECT statement - `max_rows` (int, optional): Override default row limit **Safety:** - Only SELECT statements allowed - Query timeout enforced - Row limit applied - Blocked patterns checked **Returns:** JSON with columns and rows --- #### `validate_query` Check if a query is safe to execute without running it. **Parameters:** - `query` (str, required): SQL statement to validate **Returns:** Validation result with any warnings --- ### Schema Discovery Tools #### `list_tables` List all tables and views in the database. **Parameters:** - `schema` (str, optional): Filter by schema (default: all schemas) - `include_views` (bool, optional): Include views (default: true) - `pattern` (str, optional): Filter by name pattern (SQL LIKE syntax) **Returns:** List of table/view names with schema and type --- #### `describe_table` Get detailed column information for a table. **Parameters:** - `table` (str, required): Table name (can include schema: `dbo.Users`) **Returns:** - Column names, types, nullability - Primary key columns - Foreign key relationships - Indexes --- ### CRUD Tools #### `read_rows` Read rows from a table by primary key or filter. **Parameters:** - `table` (str, required): Table name - `id` (any, optional): Primary key value (for single row) - `ids` (list, optional): Multiple primary key values - `filter` (str, optional): WHERE clause (parameterized) - `columns` (list, optional): Columns to return (default: all) - `max_rows` (int, optional): Row limit **Returns:** Rows as JSON objects --- #### `insert_row` Insert a new row into a table. **Parameters:** - `table` (str, required): Table name - `data` (dict, required): Column-value pairs **Safety:** Blocked in read-only mode **Returns:** Inserted row with generated keys (e.g., identity columns) --- #### `update_row` Update an existing row. **Parameters:** - `table` (str, required): Table name - `id` (any, required): Primary key value - `data` (dict, required): Column-value pairs to update **Safety:** Blocked in read-only mode **Returns:** Updated row --- #### `delete_row` Delete a row by primary key. **Parameters:** - `table` (str, required): Table name - `id` (any, required): Primary key value **Safety:** Blocked in read-only mode **Returns:** Confirmation with deleted row count --- ### Stored Procedure Tools #### `list_stored_procs` List available stored procedures. **Parameters:** - `schema` (str, optional): Filter by schema - `pattern` (str, optional): Name pattern filter **Returns:** List of procedure names with schemas --- #### `describe_stored_proc` Get parameter information for a stored procedure. **Parameters:** - `procedure` (str, required): Procedure name **Returns:** Parameter names, types, directions (in/out/inout) --- #### `call_stored_proc` Execute a stored procedure. **Parameters:** - `procedure` (str, required): Procedure name - `params` (dict, optional): Input parameter values **Safety:** Blocked in read-only mode (unless procedure is whitelisted) **Returns:** Output parameters and result sets --- ### Export Tools #### `export_to_json` Export query results to a JSON file. **Parameters:** - `query` (str, required): SELECT query - `filename` (str, required): Output filename **Returns:** Path to created file, row count --- #### `export_to_csv` Export query results to a CSV file. **Parameters:** - `query` (str, required): SELECT query - `filename` (str, required): Output filename - `delimiter` (str, optional): Field delimiter (default: comma) **Returns:** Path to created file, row count --- ## Configuration ### Required Environment Variables | Variable | Description | Example | |----------|-------------|---------| | `MSSQL_HOST` | Server hostname or IP | `localhost` | | `MSSQL_USER` | SQL Server username | `sa` | | `MSSQL_PASSWORD` | Password | `MyP@ssw0rd` | | `MSSQL_DATABASE` | Database name | `AdventureWorks` | ### Optional Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `MSSQL_PORT` | `1433` | Server port | | `MSSQL_TIMEOUT` | `30` | Connection timeout (seconds) | | `MSSQL_READ_ONLY` | `false` | Block all write operations | | `MSSQL_MAX_ROWS` | `1000` | Default row limit for queries | | `MSSQL_QUERY_TIMEOUT` | `60` | Query execution timeout (seconds) | | `MSSQL_BLOCKED_COMMANDS` | (see below) | Comma-separated blocked SQL patterns | | `MSSQL_ALLOWED_SCHEMAS` | (all) | Restrict to specific schemas | ### Default Blocked Commands ``` DROP,TRUNCATE,ALTER,CREATE,GRANT,REVOKE,DENY,BACKUP,RESTORE,KILL,SHUTDOWN,RECONFIGURE ``` ## Safety Architecture ### Query Validation 1. Parse SQL to identify statement type (SELECT, INSERT, UPDATE, DELETE, etc.) 2. Check against blocked commands list 3. Verify read-only mode compliance 4. Apply row limits to unbounded queries ### Parameterized Queries All user-provided values in CRUD operations use parameterized queries to prevent SQL injection. ### Schema Restrictions Optional `MSSQL_ALLOWED_SCHEMAS` limits operations to specific schemas. ### Audit Logging All tool invocations logged with: - Timestamp - Tool name - Parameters (with sensitive data masked) - Result status - Execution time ## Transport Modes ### Stdio (Default) Direct process communication for local Claude Code usage. ### HTTP/SSE HTTP server with Server-Sent Events for centralized deployment. ### Streamable HTTP with OAuth For Claude.ai remote MCP connections with authentication. ## Project Structure ``` mssql-mcp/ ├── src/mssql_mcp/ │ ├── __init__.py │ ├── server.py # FastMCP entry point │ ├── config.py # Pydantic settings │ ├── connection.py # pymssql connection manager │ ├── tools/ │ │ ├── __init__.py │ │ ├── query.py # execute_query, validate_query │ │ ├── tables.py # list_tables, describe_table │ │ ├── crud.py # read/insert/update/delete rows │ │ ├── stored_procs.py # Stored procedure tools │ │ └── export.py # export_to_json, export_to_csv │ ├── utils/ │ │ ├── __init__.py │ │ ├── safety.py # SQL validation, blocklist │ │ └── audit.py # Audit logging │ └── resources/ │ ├── __init__.py │ └── syntax_help.py # T-SQL syntax reference ├── tests/ │ ├── __init__.py │ ├── conftest.py # Fixtures │ ├── test_connection.py │ ├── test_query.py │ ├── test_crud.py │ └── integration/ # Requires actual SQL Server ├── pyproject.toml ├── README.md ├── CLAUDE.md └── .env.sample ``` ## Implementation Notes ### Patterns from U2 MCP to Reuse - FastMCP server initialization (server.py) - Pydantic BaseSettings pattern (config.py) - Audit logging approach (utils/audit.py) - Tool registration with decorators - Error handling and response formatting ### Key Differences from U2 MCP - No dynamic arrays (relational data is flat) - No multivalue/subvalue handling - Standard SQL instead of RetrieVe/UniQuery - INFORMATION_SCHEMA for metadata instead of VOC/dictionaries - pymssql instead of uopy ### pymssql Usage Pattern ```python import pymssql # Connection conn = pymssql.connect( server=host, user=user, password=password, database=database, port=port, timeout=timeout ) # Query execution cursor = conn.cursor(as_dict=True) # Returns rows as dicts cursor.execute("SELECT * FROM Users WHERE id = %s", (user_id,)) rows = cursor.fetchall() # Stored procedure cursor.callproc('sp_GetUser', (user_id,)) ``` ## Future Considerations These are not in scope for v1.0 but may be added later: - Connection pooling for high-concurrency scenarios - Azure SQL support (may need pyodbc) - Transaction support across multiple operations - Bulk insert/update operations - Query plan analysis 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/bpamiri/pymssql-mcp'

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