sqlserver
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sqlserverList all tables in the database"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP SQL Server Server
A Model Context Protocol (MCP) server that provides tools to interact with SQL Server databases. This server allows Cursor and other MCP clients to query, analyze, and manage SQL Server data intelligently.
Features
Execute SQL Queries: Run SELECT queries safely to retrieve data
List Tables: Discover all tables in the database
Get Table Schema: Inspect table structure, columns, and data types
Get Table Statistics: View row counts and column information
Insert Data: Add new records to tables
Update Data: Modify existing records
Related MCP server: Python MSSQL MCP Server
Prerequisites
Node.js v22.14.0 or higher
Docker version 28.3.3 or higher
SQL Server running in Docker (or access to an existing SQL Server instance)
Step-by-Step Setup Guide
Step 1: Install Dependencies
npm installThis will install all required packages including:
@modelcontextprotocol/sdk- MCP SDK for building the servermssql- SQL Server driver for Node.jstypescript- TypeScript compilertsx- TypeScript execution environment
Step 2: Start SQL Server with Docker
The project includes a docker-compose.yml file that will automatically:
Start SQL Server 2022
Create the
SampleDBdatabaseCreate sample tables (Customers, Products, Orders, OrderItems)
Insert sample data
Start the SQL Server container:
docker-compose up -dVerify the container is running:
docker psYou should see a container named mcp-sqlserver running.
Wait for initialization: The database initialization script runs automatically. You can check the logs:
docker logs mcp-sqlserverNote: The default password is YourStrong@Passw0rd. If you need to change it, update both docker-compose.yml and .env files.
Step 3: Configure Environment Variables
Copy the example environment file:
copy .env.example .envEdit .env and ensure the connection details match your Docker setup:
SQL_SERVER_HOST=localhost
SQL_SERVER_PORT=1433
SQL_SERVER_DATABASE=SampleDB
SQL_SERVER_USER=sa
SQL_SERVER_PASSWORD=YourStrong@Passw0rd
SQL_SERVER_ENCRYPT=falseStep 4: Build the MCP Server
Compile the TypeScript code:
npm run buildThis creates the dist/ directory with the compiled JavaScript.
Step 5: Test the MCP Server
You can test the server manually to ensure it works:
npm startThe server will start and listen on stdio (standard input/output). Press Ctrl+C to stop.
Step 6: Configure Cursor IDE
To use this MCP server in Cursor, you need to add it to Cursor's MCP configuration.
Option A: Using Cursor Settings UI
Open Cursor IDE
Go to Settings (Ctrl+,)
Search for "MCP" or "Model Context Protocol"
Click on "MCP Servers" or "Add MCP Server"
Add a new server with these settings:
Name:
sqlserverCommand:
nodeArgs:
["dist/index.js"]Working Directory:
C:\OrgProjects\SkillUps\ModelContextProtocol(or your actual project path)Environment Variables:
SQL_SERVER_HOST=localhostSQL_SERVER_PORT=1433SQL_SERVER_DATABASE=SampleDBSQL_SERVER_USER=saSQL_SERVER_PASSWORD=YourStrong@Passw0rdSQL_SERVER_ENCRYPT=false
Option B: Using Configuration File (Windows)
Navigate to Cursor's configuration directory:
%APPDATA%\Cursor\User\globalStorage\saoudrizwan.claude-dev\settings\Edit or create
cline_mcp_settings.jsonand add:
{
"mcpServers": {
"sqlserver": {
"command": "node",
"args": ["C:\\\\OrgProjects\\\\SkillUps\\\\ModelContextProtocol\\\\dist\\\\index.js"],
"env": {
"SQL_SERVER_HOST": "localhost",
"SQL_SERVER_PORT": "1433",
"SQL_SERVER_DATABASE": "SampleDB",
"SQL_SERVER_USER": "sa",
"SQL_SERVER_PASSWORD": "YourStrong@Passw0rd",
"SQL_SERVER_ENCRYPT": "false"
}
}
}
}Important: Replace C:\\OrgProjects\\SkillUps\\ModelContextProtocol with your actual project path.
Restart Cursor IDE for changes to take effect.
Step 7: Verify MCP Server in Cursor
Restart Cursor after adding the configuration
Open a chat in Cursor
Try asking questions like:
"List all tables in the database"
"Show me the schema of the Customers table"
"Get statistics for the Products table"
"Run a query to show all customers"
"Show me customers from New York"
The AI should now be able to use the MCP tools to interact with your SQL Server database!
Available MCP Tools
1. execute_query
Execute a SELECT query to retrieve data.
Example:
{
"query": "SELECT TOP 10 * FROM Customers"
}2. list_tables
List all tables in the database.
Example:
{}3. get_table_schema
Get the schema of a specific table.
Example:
{
"tableName": "Customers"
}4. get_table_stats
Get statistics about a table (row count, columns).
Example:
{
"tableName": "Products"
}5. execute_insert
Insert a new record into a table.
Example:
{
"tableName": "Customers",
"data": {
"FirstName": "John",
"LastName": "Doe",
"Email": "john.doe@example.com",
"City": "Seattle"
}
}6. execute_update
Update existing records in a table.
Example:
{
"tableName": "Customers",
"data": {
"City": "Portland"
},
"where": {
"CustomerID": 1
}
}Sample Database Schema
The initialization script creates a sample e-commerce database with:
Customers: Customer information
Products: Product catalog
Orders: Customer orders
OrderItems: Order line items
Development
Run in Development Mode
npm run devThis uses tsx watch to automatically recompile on file changes.
Project Structure
.
├── src/
│ └── index.ts # Main MCP server implementation
├── dist/ # Compiled JavaScript (generated)
├── init-db/ # SQL initialization scripts
│ └── 01-init-sample-db.sql
├── docker-compose.yml # Docker setup for SQL Server
├── package.json # Node.js dependencies
├── tsconfig.json # TypeScript configuration
└── README.md # This fileTroubleshooting
SQL Server Connection Issues
Check if SQL Server is running:
docker psCheck SQL Server logs:
docker logs mcp-sqlserverVerify connection details in
.envmatch your Docker setupTest connection manually:
docker exec -it mcp-sqlserver /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P YourStrong@Passw0rd -Q "SELECT @@VERSION"
MCP Server Not Appearing in Cursor
Verify the path in the configuration is correct and absolute
Check that the build succeeded:
npm run buildEnsure the server starts without errors:
npm startRestart Cursor after configuration changes
Check Cursor's developer console for MCP-related errors
Permission Issues
Ensure SQL Server credentials are correct
Verify the database exists and is accessible
Check that the SA password matches in both
docker-compose.ymland.env
Security Notes
Never commit
.envfiles to version controlThe
execute_querytool only allows SELECT queries for securityUse strong passwords in production
Consider using environment-specific configurations
Next Steps
Explore the sample data using natural language queries in Cursor
Try asking complex questions that require joins
Add more tables or modify the schema as needed
Extend the MCP server with additional tools for your use case
License
MIT
Available Tools
6 toolsexecute_insertA
Insert data into a table. Returns the inserted row ID if available.
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Object with column names as keys and values to insert | |
| tableName | Yes | Name of the table to insert into |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses a behavioral trait: the function returns the inserted row ID 'if available,' hinting at possible unavailability. However, it does not state side effects (e.g., data mutation), permission needs, or error conditions, leaving gaps for a write operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences, front-loading the core action. Every word contributes: 'Insert data into a table' states the function, and the second sentence provides a useful return detail. No redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with a clear schema, the description covers the action and return value. However, with no output schema, it omits when the row ID might be unavailable and gives no hint about constraints or error behavior. It is close to complete but lacks a few contextual edges.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already well documented. The description adds no extra meaning beyond the schema—it doesn't explain how the 'data' object should be structured or any special tableName considerations. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Insert data into a table.' This clearly distinguishes the tool from siblings like execute_query and execute_update by focusing on the insert operation. Adding the return behavior ('Returns the inserted row ID if available') further clarifies purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. It does not mention when to prefer insert over update/query, nor does it state conditions like table existence or constraint requirements. The description only states what the tool does, not when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_queryA
Execute a SQL query and return results. Use for SELECT queries to retrieve data.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | The SQL query to execute (SELECT only) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions executing a query and returning results, and says 'Use for SELECT queries', which implies a read-only nature, but does not explicitly state that it cannot modify data, nor does it mention side effects, permissions, or return format specifics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no unnecessary words. It conveys the primary purpose and usage context succinctly, earning a perfect score for conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, no output schema), the description is adequate: it explains the action, the return of results, and the applicable query type. It lacks a few details like explicit read-only assurance, but overall it is sufficiently complete for straightforward usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% parameter description coverage with 'The SQL query to execute (SELECT only)'. The description adds no significant semantic meaning beyond what the schema already provides, though it does reinforce the SELECT-only constraint. Baseline of 3 is appropriate given full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool executes SQL queries and returns results, specifically for SELECT queries to retrieve data. This distinctly separates it from siblings like execute_insert and execute_update, which handle mutations, and from metadata tools like list_tables.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance to use this tool for SELECT queries, clearly indicating the appropriate use case. It does not explicitly mention alternatives or exclusions, but the intended context is strongly implied, making it effective.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_updateB
Update data in a table. Returns the number of affected rows.
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Object with column names as keys and new values | |
| where | Yes | Object with column names as keys and values for WHERE clause | |
| tableName | Yes | Name of the table to update |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It mentions the return value (affected rows) but does not explicitly warn about irreversible data modification, permission requirements, or that updates are limited to rows matching the WHERE clause. Minimal risk information is provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: one sentence with two clauses. Every word earns its place, and the return value is front-loaded, making it easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is adequate for a simple update command but lacks explicit emphasis on the WHERE-clause filtering, which is crucial for safe usage. Since the where parameter is required, the description could clarify that only matching rows are updated, but the schema conveys this. With no annotations or output schema, the description is serviceable but leaves some context implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers all three parameters with descriptions, so the baseline is 3. The tool description does not add extra parameter-level meaning beyond what the schema offers; it only provides the return behavior, which is not parameter-specific.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Update data in a table' with a specific verb and resource, clearly distinguishing it from siblings like execute_query and execute_insert. The purpose is unambiguous and immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. There is no mention of prerequisites, exclusions, or comparison with execute_insert or execute_query, leaving the agent to infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_table_schemaA
Get the schema/structure of a table including column names, types, and constraints
| Name | Required | Description | Default |
|---|---|---|---|
| tableName | Yes | Name of the table to get schema for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden for behavioral disclosure. It implies a read-only operation via 'Get', but it doesn't explicitly address permissions, error conditions, or side effects. However, the tool is simple and the omission isn't critical, so it stays at a baseline adequate level.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. It efficiently conveys the tool's purpose and key output details without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains what the tool returns (columns, types, constraints) and has a single clearly described parameter. Without an output schema or annotations, this is sufficient, though slightly more detail about error handling or return format could be useful.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema fully describes the tableName parameter (100% coverage), so the description does not add meaning beyond what is already provided. The description's mention of schema contents relates to the return value, not the parameter, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a table's schema/structure, specifying the included elements (column names, types, constraints). This distinguishes it from sibling tools like list_tables or get_table_stats, which have different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool (when you need a table's schema), but it doesn't explicitly mention alternatives or exclusions. It could have indicated use cases for sibling tools, but the context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_table_statsB
Get statistics about a table including row count and column information
| Name | Required | Description | Default |
|---|---|---|---|
| tableName | Yes | Name of the table to get statistics for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It transparently indicates the tool is a read-only data retrieval (get statistics), but it omits details such as whether column information covers data types, nullable flags, or other schema details, and does not mention performance implications or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the verb and resource. It wastes no words and clearly communicates the core function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one simple parameter and no output schema, the description provides the key outputs (row count, column information) but omits potential additional statistics and error behavior. It is functional but leaves some ambiguity about the exact return structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the tableName parameter. The description adds 'including row count and column information' which loosely maps to the output, but it does not add new meaning to the parameter itself beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'gets statistics' about a table, naming the specific resource and outputs (row count, column information). It is a specific verb+resource combination, but it does not explicitly distinguish itself from siblings like get_table_schema or execute_query, which could also retrieve related data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool over alternatives such as execute_query or get_table_schema. The description implies usage for retrieving table statistics, but it does not state exclusions or comparison with siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesA
List all tables in the database
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'List all tables' clearly indicates a read-only enumeration, but it does not disclose potential performance implications, whether system tables are included, or any other behavioral nuances. This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, simple sentence of six words that precisely states the tool's function. It is front-loaded and contains no filler, earning a perfect score for conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter list operation with no output schema and no annotations, the description gives the essential purpose. However, it does not specify the return format (e.g., an array of table names) or whether the list is ordered or filtered. A brief note about the output would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter information to convey. The baseline of 4 applies because the description needs to add nothing beyond the schema, which is empty.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'List' and clearly identifies the resource as 'tables in the database'. This distinguishes it from siblings like execute_query and get_table_schema, which operate on query results or individual table schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for enumerating database tables, which provides clear context for when to use it. It does not explicitly exclude alternatives or mention siblings, but the purpose is self-evident in a database toolset.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v1.0.0- First observed
execute_insert - First observed
execute_query - First observed
execute_update - First observed
get_table_schema - First observed
get_table_stats - First observed
list_tables
TDQS
Scored across 6 tools
Each tool targets a distinct action: SELECT retrieval, listing tables, schema inspection, statistics, inserts, and updates. There is no overlap between query, DML, and metadata operations, making selection straightforward.
Naming mixes execute_query/execute_insert/execute_update with list_tables and get_table_schema/get_table_stats. The pattern is not uniform (execute_ vs list_ vs get_table_), though it remains readable and predictable within subgroups.
Six tools is a well-scoped set for a SQL server, covering query, data modification, and metadata needs without excessive surface area.
The toolset covers SELECT, INSERT, UPDATE, and metadata, but lacks a DELETE operation, DDL support (CREATE/ALTER/DROP), and transaction control. These are significant gaps that will hinder common database workflows.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
A Model Context Protocol server for Wix AI tools
Ask data questions in natural language. Get SQL, insights, and charts from your databases.
Official Microsoft MCP Server to query Microsoft Entra data using natural language
Related MCP Servers
- AlicenseBqualityDmaintenanceA Model Context Protocol server that enables AI assistants (Cursor, Windsurf, Claude Code) to interact with Microsoft SQL Server databases by providing connectivity through environment-configurable connections.84948MIT
- FlicenseNot gradedqualityDmaintenanceEnables Language Models to interact with Microsoft SQL Server databases by inspecting table schemas, executing SQL queries, and reading table data through a standardized Model Context Protocol interface.27-
- FlicenseAqualityDmaintenanceEnables AI assistants to query SQL Server databases and retrieve schema information securely through the Model Context Protocol.2-
- FlicenseCqualityDmaintenanceEnables AI assistants to analyze and query SQL Server databases, including schema discovery, health checks, and data retrieval.10-