A Model Context Protocol (MCP) server that provides tools for interacting with Microsoft SQL Server databases, built with the official C# SDK.
- 🔒 Read-Only Security: Enforced SELECT-only operations to prevent accidental data modification
- Dynamic Database Switching: Switch between databases on the same server without restarting
- Database Listing: View all available databases with current database highlighted
- Execute SQL Queries: Run read-only SQL queries against the current database
- List Tables: Get all tables in the current database with row counts
- Get Table Schema: Retrieve column information for specific tables
- Connection Info: Display current database connection status
- Stored Procedures: List stored procedures with schema and dates, get detailed info including parameters, definitions, and dependencies
- Object Definition: Unified endpoint to get detailed information for any database object (procedures, functions, views) including definitions, parameters/columns, and dependencies
- Health Check: Verify connectivity and view server properties
- Structured Logging: JSON logs to stderr with correlation IDs and timings
- Serilog Integration: Structured logging via Serilog with JSON formatting
- Row Limit Enforcement: Max 100 rows returned per query
This MCP server is designed with read-only security to prevent accidental data modification:
- ❌ INSERT, UPDATE, DELETE statements
- ❌ DROP, CREATE, ALTER statements
- ❌ TRUNCATE, MERGE operations
- ❌ EXEC/EXECUTE stored procedures
- ❌ GRANT, REVOKE, DENY permissions
- ❌ BULK operations
- ❌ SELECT INTO (object creation)
- ❌ Multiple statements in a single request
- ❌ Any non-SELECT statements
- ❌ USE, SET, DBCC, BACKUP, RESTORE, RECONFIGURE, sp_configure
- ✅ SELECT queries for data retrieval
- ✅ Database listing and switching
- ✅ Table schema inspection
- ✅ Connection status queries
When a blocked operation is attempted, the server provides clear, specific error messages:
❌ UPDATE operations are not allowed. This MCP server is READ-ONLY and only supports SELECT queries for data viewing.
- Query timeout protection (configurable, default 30 seconds)
- Input validation and sanitization
- Detailed error reporting with helpful guidance
- Security mode indicators in all responses
The MCP server now supports dynamic database switching, allowing you to:
- List all databases - See every database on the SQL Server instance
- Switch databases - Change the active database without restarting the server
- Track current context - All operations (queries, table listing) work on the current database
- Connection validation - Server validates database connections before switching
Example Workflow:
User: List all databases
Server: [Shows all databases with current one highlighted]
User: Switch to Northwind database
Server: [Successfully switches and confirms]
User: Show me all tables
Server: [Shows tables from Northwind database]
This feature is particularly useful when working with multiple databases on the same server, such as development, staging, and production environments.
- .NET 10.0 SDK
- SQL Server (local or remote)
- Access to the target database
- Clone or download this project
- Navigate to the project directory
- Restore NuGet packages:
dotnet restore- Build the project:
dotnet buildConfiguration values can be provided via environment variables or appsettings.json. Environment variables take precedence.
Set the connection string using an environment variable:
# Windows
set SQLSERVER_CONNECTION_STRING="Server=your_server;Database=your_database;User Id=your_username;Password=your_password;TrustServerCertificate=true;"
# PowerShell
$env:SQLSERVER_CONNECTION_STRING="Server=your_server;Database=your_database;User Id=your_username;Password=your_password;TrustServerCertificate=true;"
# Linux/macOS
export SQLSERVER_CONNECTION_STRING="Server=your_server;Database=your_database;User Id=your_username;Password=your_password;TrustServerCertificate=true;"Default Connection String: If no environment variable is set, it defaults to:
Server=localhost;Database=master;Trusted_Connection=true;TrustServerCertificate=true;
You can also configure the SQL command timeout (in seconds):
# Windows
set SQLSERVER_COMMAND_TIMEOUT=60
# PowerShell
$env:SQLSERVER_COMMAND_TIMEOUT=60
# Linux/macOS
export SQLSERVER_COMMAND_TIMEOUT=60If not set, the timeout defaults to 30 seconds.
Alternatively, you can configure via appsettings.json placed alongside the executable or under the project directory:
{
"SqlServer": {
"ConnectionString": "Server=localhost;Database=master;Trusted_Connection=true;TrustServerCertificate=true;",
"CommandTimeout": 30
}
}
Precedence: Environment variables → appsettings.json → built-in defaults.
dotnet runThe server will start and listen for MCP protocol messages via stdio.
- Copy the
claude_desktop_config.jsonfile to your Claude Desktop configuration directory - Update the connection string in the config file to match your database
- Restart Claude Desktop
The configuration file should be placed at:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/claude/claude_desktop_config.json
Get the current database connection info with structured request logging.
Parameters: None
Behavior:
- Emits Serilog start/end events with a correlation ID and elapsed time
- Includes read-only security indicators in the payload
Example Usage:
Show me the current database connection info
Switch to a different database on the same server with detailed audit logging.
Parameters:
databaseName(string): The name of the database to switch to
Behavior:
- Validates connectivity before switching and logs success/failure details
- Captures correlation ID, elapsed time, and error information when the switch fails
Example Usage:
Switch to the Northwind database
Get a list of all databases on the SQL Server instance with current database highlighted.
Parameters: None
Example Usage:
List all databases on this SQL Server instance
Execute a SQL query on the current database.
Parameters:
query(string): The SQL query to executemaxRows(int, optional): Requested rows (defaults to 100; clamped to 100)
Example Usage:
Please execute "SELECT TOP 10 * FROM Users ORDER BY CreatedDate DESC" and show me the results
Notes:
- The server enforces a hard cap of 100 rows per query. Any higher request is clamped to 100.
- The server safely injects
TOP <N>after the firstSELECTwhen absent, and caps an existingTOPif it exceeds 100.
Execute a read-only T-SQL query with result formatting, per-call timeout, and parameter binding. Matches the SRS read_query specification.
Parameters:
query(string, required): T-SQLSELECTstatementtimeout(int, optional): Per-call timeout in seconds; default 30; clamped 1–300max_rows(int, optional): Requested max rows; default 1000; clamped 1–10,000format(string, optional):json|csv|table(HTML); defaultjsonparameters(object, optional): Named parameters to bind (e.g.,{ id: 42 }); keys may include or omit@delimiter(string, optional): CSV delimiter; default,; usetabor\tfor tab
Behavior:
- Enforces read-only validation (SELECT-only, blocks DDL/DML/EXEC and multiple statements)
- Applies per-call timeout if provided; otherwise uses server default
- Injects or caps
TOP <N>to respectmax_rows - Returns:
json: array of objects with explicitnullvaluescsv: CSV string with header row and proper quotingtable: escaped HTML table with headers
- Includes
elapsed_ms,row_count, andcolumnsmetadata (name,data_type,allow_null,size)
Example Usage:
ReadQuery query="SELECT * FROM Orders WHERE CustomerID = @id ORDER BY CreatedAt DESC" parameters={"id": 123} max_rows=500 format=csv delimiter="," timeout=60
Get a list of all tables in the current database with row counts.
Parameters: None
Example Usage:
Show me all tables in the current database
Get the schema information for a specific table.
Parameters:
tableName(string): Name of the tableschemaName(string, optional): Schema name (defaults to "dbo")
Example Usage:
Get the schema for the Users table
Get a list of stored procedures in the current database.
Parameters: None
Example Usage:
List all stored procedures
Get detailed information about a specific stored procedure including parameters, definition, and dependencies.
Parameters:
procedureName(string): Name of the stored procedureschemaName(string, optional): Schema name (defaults to "dbo")
Returns:
- Procedure metadata (name, schema, create/modify dates)
- Complete list of parameters with data types, directions (input/output), and default values
- Full T-SQL definition of the procedure
- Dependencies (tables, views, and other objects referenced by the procedure)
Example Usage:
Get details for the stored procedure sp_GetUserOrders
Show me the parameters and definition of dbo.sp_CalculateRevenue
Response includes:
procedure_info- Name, schema, dates, definition, and metadataparameters- Full parameter list with types, precision, scale, output flagsdependencies- All database objects referenced by the procedure
Get detailed information about any database object (stored procedure, function, or view) in a unified endpoint.
Parameters:
objectName(string): Name of the database objectschemaName(string, optional): Schema name (defaults to "dbo")objectType(string, optional): Object type - 'PROCEDURE', 'FUNCTION', 'VIEW', or 'AUTO' to auto-detect (default is 'AUTO')
Returns:
- Object metadata (name, schema, type, create/modify dates, full definition)
- For Procedures & Functions: Complete parameter list with data types, directions, and default values
- For Views: Column information with data types and properties
- Dependencies (all database objects referenced)
Example Usage:
Get the definition of sp_GetCustomerOrders
Show me details for the view vw_SalesReport
Get information about the function fn_CalculateDiscount in the sales schema
Key Features:
- Auto-detection: Automatically determines if the object is a procedure, function, or view
- Unified interface: Single tool for all object types instead of separate tools
- Comprehensive: Returns object-specific information (parameters for procedures/functions, columns for views)
- Full source code: Includes complete T-SQL definition when available
Response includes:
object_info- Name, schema, type, dates, and full T-SQL definitionparameters- (For procedures/functions) Parameter details with types and directionscolumns- (For views) Column schema with data types and propertiesdependencies- All database objects referenced by this object
Check connectivity and return server properties.
Parameters: None
Example Usage:
Check server health and show properties
Returns:
server_name,product_version,product_level,edition,current_database,server_time- Status and connectivity indicators
Server=localhost;Database=YourDatabase;Trusted_Connection=true;TrustServerCertificate=true;
Server=localhost;Database=YourDatabase;User Id=your_username;Password=your_password;TrustServerCertificate=true;
Server=your_server.database.windows.net;Database=YourDatabase;User Id=your_username@your_server;Password=your_password;Encrypt=true;TrustServerCertificate=false;
- This server executes SQL queries directly against your database
- Ensure proper database permissions are configured
- Use parameterized queries when possible to prevent SQL injection
- Consider limiting the database user's permissions to only what's necessary
- Never expose connection strings with passwords in version control
The server returns descriptive error messages for:
- Connection failures
- Invalid SQL syntax
- Permission issues
- Database not found
To modify or extend the server:
- Add new methods to the
SqlServerToolsclass - Decorate them with the
[McpServerTool]attribute - Add
[Description]attributes for parameters - Rebuild the project
Example new tool:
[McpServerTool, Description("Get all stored procedures in the database")]
public static async Task<string> GetStoredProceduresAsync()
{
// Implementation here
}To test the server locally:
- Set up a local SQL Server instance
- Configure the connection string
- Run the server:
dotnet run - Test with Claude Desktop or other MCP-compatible clients
ModelContextProtocol(0.4.1-preview.1) - Official MCP C# SDKMicrosoft.Data.SqlClient(5.2.2) - SQL Server connectivityMicrosoft.Extensions.Hosting(10.0.0) - Host infrastructure
This project is provided as-is for educational and development purposes.
This project uses Serilog for structured logging.
- Default sink: JSON logs written to
stderr(non-interfering with MCP stdio) - Log content: start/end events with
correlation_id,operation,elapsed_ms, plus error details - Configuration: Serilog reads settings from
appsettings.jsonif present
Example appsettings.json Serilog block:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
}
}
}
Logs can be consumed directly from stderr or redirected as needed by your host environment.