
Table of Contents
The Model Context Protocol (MCP) has quietly become the connective tissue between AI agents and the systems they need to touch, and few targets are more consequential — or more dangerous — than a production SQL Server database. Letting a non-deterministic language model write its own T-SQL against your business data is the kind of decision that looks clever in a demo and catastrophic in an incident report. That tension is exactly why, over the past year, a small crowd of MS SQL Server MCP servers has appeared, ranging from weekend community projects to Microsoft’s own production-grade engine.
This guide maps that landscape honestly. It covers what each server actually is, how the transports work, how to stand up both the official and the most popular community option end to end, and — most importantly — how to choose between them without learning the hard way. If you take one thing from it, let it be this: the differences between these servers are almost entirely about governance, not features. The question is never “can it query my database.” It’s “what happens when the model asks for something it shouldn’t have.”
The fundamental fork in the road
Every SQL Server MCP server falls on one side of a single dividing line, and understanding that line is more useful than memorizing any individual tool.
On one side sit the ad-hoc community servers. Their pitch is simplicity: point them at a connection string, and the AI can list tables, read rows, and run SQL — frequently arbitrary SQL, including INSERT, UPDATE, and DELETE. They are fast to set up, easy to understand, and perfectly reasonable for a local development database full of throwaway data. They become a liability the moment they point at anything you’d be sad to lose.
On the other side sits Microsoft’s governed approach, built into Data API Builder (DAB). Here the model never writes SQL at all. It calls a fixed set of structured tools, and a deterministic query builder translates those calls into safe T-SQL behind a role-based permission layer. Nothing is exposed unless you explicitly configure it. This is slower to set up and demands you think about what you’re exposing — which is precisely the point.
Neither side is universally “right” for SQL Server MCP Server. A solo developer prototyping against a local database may find the official server’s configuration overhead unnecessary friction. A team wiring an agent into a customer-facing system would be reckless to use anything else. Keep this fork in mind as you read; every recommendation below traces back to it.
The contenders: six servers worth knowing
From the current ecosystem, six distinct MS SQL Server MCP servers are worth naming. They are not interchangeable, and the naming collisions between several of them are a genuine source of installation errors.
| Server | Source | Language | Auth support | Governance model | Best for |
|---|---|---|---|---|---|
| Microsoft SQL MCP Server (in DAB) | Official, open source | .NET | SQL, Windows, Entra ID, JWT | Full RBAC, fixed tool set, no NL2SQL | Production, shared, or sensitive databases |
| RichardHan/mssql_mcp_server | Community | Python | SQL, Windows, Azure AD | Runs arbitrary DML if account permits | Local dev, Claude Desktop users |
| JexinSam/mssql_mcp_server | Community | Python | SQL | Arbitrary queries | Lightweight local use |
| combiz/mssql-mcp-server | Community | Python | SQL, trusted/Windows | Arbitrary queries | Windows-auth local setups |
| @connorbritain/mssql-mcp-server | Community (npm) | Node | SQL | Markets ~20 tools + governance controls | Node-first teams wanting more structure |
| techybolek/mcp-mssql-server | Community (npm) | Node | SQL | Arbitrary queries, stdio + HTTP | Node teams needing HTTP transport |
A naming warning that catches people constantly: RichardHan’s GitHub repo is called mssql_mcp_server, but its PyPI package is microsoft_sql_server_mcp. Meanwhile the PyPI package literally named mssql-mcp-server (with hyphens) belongs to a different author, JexinSam. If you pip install mssql-mcp-server expecting RichardHan’s server, you will get the wrong project and nothing in this guide’s RichardHan section will line up. Install the exact string microsoft_sql_server_mcp for RichardHan’s work.
The rest of this guide focuses on the two SQL Server MCP Servers most people actually reach for: Microsoft’s official server (the one to use when it matters) and RichardHan’s community server (the one most Claude Desktop tutorials are built around).
Understanding MCP transports: STDIO vs HTTP
Before any SQL Server MCP Server setup, you need to understand the two ways an MCP server talks to its client, because nearly every configuration decision flows from this choice.
STDIO (standard input/output) is the most common transport for local work, and for good reason. The client launches the server as a child process and communicates with it by piping messages through standard input and output. There is no network port, no separate server process to babysit, and no HTTP endpoint exposed to anything. The advantages are concrete:
- No network ports need to be opened. Nothing is listening, so nothing can be reached by something that shouldn’t reach it.
- The server lifecycle is managed automatically by the client. When you open your workspace, the client starts the server; when you close it, the client stops it. There’s no orphaned process to clean up.
- Communication is fast and local, with no network round trips.
- It’s inherently more secure for local development because nothing is exposed over HTTP.
In SQL Server MCP Server setup, the trade-off is that STDIO is fundamentally a one-client, one-machine arrangement. The server lives and dies with the process that launched it.
HTTP (streamable HTTP) is the answer when the server needs to be reachable across a network — a hosted deployment, a shared team instance, or any scenario where multiple clients connect to one running server. You start the server as a long-running process (it typically listens on something like http://localhost:5000/mcp), and clients connect to that URL. This is the right transport for production hosting on Azure Container Apps, App Service, or similar, but it means you are now responsible for the server’s lifecycle, its port, and its network exposure.
A useful rule of thumb: choose STDIO when you want the simplest possible local setup with no open ports; choose HTTP when the server must be reachable across a network. Most individual developers should default to STDIO and only move to HTTP when a genuine sharing or hosting need appears.
Registering a server with Claude Code: the claude mcp add syntax
If you’re using Claude Code rather than Claude Desktop or VS Code, you register a local STDIO server from the terminal for SQL Server MCP Server configuration. Claude Code is Anthropic’s agentic coding tool — it wraps the model in an agent loop and uses MCP to plug in external tools like a database server, which is exactly what you’re doing here. (If you want the bigger picture of how Claude Code’s agent loop and MCP tool integration fit into the wider system, see our breakdown of how Claude’s architecture works — the model versus the harness.) The general form is:
claude mcp add [options] stdio <name> -- <command> [args…]
Each piece matters, and the separator in particular trips people up:
claude mcp add— the subcommand that registers an MCP server with Claude Code in SQL Server MCP Server configuration.[options]— flags such as scope and transport.<name>— the friendly label you give this server, for examplemssql. It’s just an identifier you’ll use to refer to the server later.--— the separator, and the single most important token in the command. Everything before it is consumed by theclaudeCLI itself; everything after it is the command Claude Code will run to launch the MCP server. Without--, the CLI cannot reliably tell where its own arguments end and the server’s launch command begins.<command>— the executable to launch (for exampledaboruvx).[args...]— the arguments passed to that executable.
That -- boundary is not a stylistic nicety. Omit it and the CLI will misinterpret your server’s arguments as its own flags, producing errors that look unrelated to the actual mistake.
Microsoft’s SQL MCP Server: the production-safe option
SQL MCP Server is Microsoft’s official, open-source SQL Server MCP Server for SQL databases, built directly into Data API Builder (DAB) — MCP support first shipped in DAB version 1.7, and the current 2.0 release is now the recommended baseline for the latest capabilities and fixes. It lets AI agents (Copilot, Claude, or any MCP-compatible client) safely read and write data in a SQL Server database without giving the AI direct database access and without letting it write its own SQL.
What separates it from the community pack comes down to four design decisions.
No NL2SQL — and why that’s the headline feature
The most consequential choice Microsoft made was to refuse to let the model generate raw T-SQL. The reasoning is blunt: models aren’t deterministic, and the complex queries users most want AI to write are exactly the ones most likely to contain subtle, hard-to-spot errors. In a production system, the gap between a query that works 95% of the time and one that works 100% of the time is the gap between a tool people trust and one they don’t.
Instead, SQL MCP Server uses what Microsoft calls an NL2DAB model. The agent’s intent is routed through DAB’s secure entity abstraction layer and its built-in query builder, which together produce well-formed, deterministic T-SQL every time. The model expresses what it wants through structured tool calls; DAB decides how that becomes SQL. This removes the unpredictability of NL2SQL while preserving safety and auditability.
Seven fixed DML tools, regardless of database size
Rather than exposing one tool per table — which would flood the model’s context window in any real database — SQL Server MCP Server exposes a fixed set of seven Data Manipulation Language (DML) tools no matter how large your schema is:
describe_entities— discovers the available entities and their operations.create_record— inserts new rows into a table or view.read_records— reads rows from a single table or view, with filtering and pagination.update_record— modifies an existing row; requires the primary key and validates that it exists, enforcing update permissions and only touching fields the current role may modify.delete_record— removes a row by primary key, with transaction support.execute_entity— runs stored procedures.aggregate_records— performs aggregations, with a configurable query timeout.
Keeping this surface small and fixed is deliberate: the context window is the agent’s thinking space, and every tool definition that fills it is reasoning capacity the agent loses. Every one of these tools respects role-based access control, entity permissions, and policies — agents never touch the database directly, only the governed abstraction.
A critical operational nuance most guides omit: read_records works against a single table or view and does not support JOINs. This is intentional, to keep responsibility isolated and limit context-window impact. When you need joined data, the recommended approaches are to expose a database view (which the tool sees as a single entity) or to encapsulate the query in a stored procedure and call it through execute_entity. DAB’s GraphQL endpoint also supports richer querying if you need it outside the MCP path.
You can toggle each of these tools individually in your configuration via the dml-tools block, enabling exactly the operations you want and disabling the rest — a read-only deployment, for instance, simply leaves create-record, update-record, and delete-record off.
Configuration-driven exposure in SQL Server MCP Server
Nothing is exposed unless you explicitly add it. You define which tables, views, or stored procedures are visible — and to which roles — in a single dab-config.json file. That file is the single source of truth for permissions, projections, and policies across REST, GraphQL, and MCP simultaneously. One configuration, three API surfaces, one security model.
Built on existing DAB infrastructure
Because it’s a feature of DAB rather than a standalone tool, SQL MCP Server inherits DAB’s role-based access control, caching, telemetry, and health checks. Every MCP tool call is instrumented with OpenTelemetry spans, so you get unified observability across REST, GraphQL, and MCP. The same security model that already governs your REST and GraphQL APIs governs your agents. Two transports are supported — STDIO for local/CLI use and streamable HTTP for hosted scenarios — and the whole thing is free, open source, and self-hosted, running locally via the DAB CLI or deployed to Azure.
What’s new in DAB 2.0
If your reference material predates it, DAB 2.0 is worth knowing about. It provides a production-ready surface for REST, GraphQL, and MCP with several additions over the 1.7 line:
- Auto-config lets enterprises comfortable with limited abstraction run without a static config file. The stateless container inspects the database each time it starts and builds the configuration dynamically. This is convenient for rapid setup and changing schemas — but treat it with care, because dynamic exposure is the opposite of the deliberate, minimal-surface philosophy that makes the governed approach safe. Use it knowingly, not by default.
- Native integration with Microsoft Foundry for agent scenarios.
- A first-class query builder and improved developer tooling, including dedicated VS Code extensions and built-in REST and GraphQL tools.
SQL MCP Server also implements MCP protocol version 2025-06-18 as a fixed default, so client compatibility is predictable.
Setting up Microsoft’s SQL MCP Server, step by step
Prerequisites
- .NET 9+ — verify with
dotnet --version. (The general DAB CLI runs on .NET 8+, but the SQL MCP Server quickstart specifically calls for 9.0 or later.) - SQL Server 2016+ — any edition works: SQL Server Developer or Express, LocalDB, or SQL Server in Docker.
- The Data API Builder (DAB) CLI, installed as a .NET tool:
dotnet new tool-manifest
dotnet tool install microsoft.dataapibuilder
dotnet tool restore
(You can also install it globally with dotnet tool install -g microsoft.dataapibuilder.) Confirm the install with dab --version.
Step 1: Create a sample database (skip if you have one)
Connect via SQLCMD or SSMS and run the following. Note the corrected table definition — the trailing comma after the final column is a syntax error and must be removed:
CREATE DATABASE ProductsDb;
GO
USE ProductsDb;
GO
CREATE TABLE dbo.Products (
ProductId INT PRIMARY KEY,
ProductName NVARCHAR(100) NOT NULL,
SOH INT NOT NULL,
Price DECIMAL(10,2) NOT NULL,
UOM NVARCHAR(100) NOT NULL
);
Step 2: Configure the server
Create a .env file in your working directory with your connection string:
MSSQL_CONNECTION_STRING=Server=localhost;Database=ProductsDb;Trusted_Connection=True;TrustServerCertificate=True
For SQL authentication instead of Windows authentication (common with Docker or cross-platform setups):
MSSQL_CONNECTION_STRING=Server=localhost,1433;Database=ProductsDb;User Id=sa;Password=<YourPassword>;TrustServerCertificate=True
Then initialize DAB and expose a table:
dab init --database-type mssql \
--connection-string "@env('MSSQL_CONNECTION_STRING')" \
--host-mode Development \
--config dab-config.json
dab add Products \
--source dbo.Products \
--permissions "anonymous:read" \
--description "Toy store products with inventory, price, and cost."
This generates dab-config.json. Repeat dab add for each table, view, or stored procedure you want exposed, and use dab update to add column-level descriptions — those descriptions matter more than they look, because without field names and descriptions the agent sees only entity names and may guess column names incorrectly.
Step 3: Start the server (choose one transport)
Option A — HTTP (server runs as a separate long-running process, good for remote or shared use):
dab start --config dab-config.json
Note the URL it prints (it defaults to http://localhost:5000/mcp) and leave the terminal running. A quick sanity check: hitting that URL in a browser will fail with a session error — that’s correct behavior, not a bug. A browser isn’t a valid MCP client, so the endpoint rejects it for lacking a session handshake. The endpoint being alive and enforcing the protocol is exactly what you want to see.
Option B — STDIO (client launches and manages the process; simplest for local dev): this requires "mcp": { "enabled": true } in the runtime section of dab-config.json. If that block is missing or set to false, DAB will fail to start in STDIO mode. No separate terminal is needed — your client starts and stops the server automatically.
Step 4: Connect a client
For SQL Server MCP Server configuration, Create an mcp.json (in VS Code, .vscode/mcp.json) in your project folder.
STDIO version:
{
"servers": {
"sql-mcp-server": {
"type": "stdio",
"command": "dab",
"args": [
"start",
"--mcp-stdio",
"role:anonymous",
"--config",
"${workspaceFolder}/dab-config.json"
]
}
}
}
A detail worth respecting: the role:<name> argument is positional and must immediately follow --mcp-stdio. It defaults to anonymous if omitted, and the role name must match a role defined in the permissions of at least one entity in your config.
HTTP version:
{
"servers": {
"sql-mcp-server": {
"type": "http",
"url": "http://localhost:5000/mcp"
}
}
}
Then in VS Code: Command Palette → MCP: List Servers → select sql-mcp-server → Start. Once connected, your exposed entities appear as MCP tools such as describe_entities and read_records.
Connecting from Claude Code (CLI): Claude Code doesn’t use a JSON config file — you register the server from the terminal with claude mcp add. For the STDIO transport, point it at the same dab start --mcp-stdio command:
claude mcp add mssql -- dab start --mcp-stdio role:anonymous --config /absolute/path/to/dab-config.json
Everything before the -- belongs to the claude CLI (mssql is the friendly name you’ll see in Claude Code); everything after it is the command Claude Code runs to launch the server. Use an absolute path to dab-config.json, since Claude Code may run from a different working directory than your project folder. If you started DAB separately in HTTP mode instead, register the endpoint with claude mcp add --transport http mssql http://localhost:5000/mcp. Confirm it registered with claude mcp list, then start a session and ask a data question to trigger the tools.
Step 5: Test it
Ask your AI client something like “Which products have an inventory under 30?” It should call describe_entities and read_records automatically and answer conversationally.
A realistic expectation about performance
One real-world data point worth internalizing before you judge the server: asking “how many customers do I have?” against a 500,000-row table took roughly two minutes in one documented test. The reason is structural, not a defect — DAB doesn’t execute arbitrary SQL, so there’s no SELECT COUNT(*) happening. The agent calls read_records, paginates through the results, and infers the count from what comes back. MCP pagination defaults to 100 rows per page (configurable via runtime.pagination.default-page-size, up to a large maximum). The lesson: the governed, auditable surface trades some efficiency on certain operations for safety, and you should design around it — use aggregation tools or stored procedures for counts and rollups rather than expecting the agent to scan. Make sure your agent knows the page size so it builds sensible calls and works through continuation tokens when needed.
Bonus: custom tools from stored procedures
Beyond the seven built-in DML tools, SQL MCP Server can register stored procedures as named custom MCP tools. Set "custom-tool": true on a stored-procedure entity, and it surfaces as its own tool. This is the clean way to give an agent a complex, parameterized operation — a multi-table report, a guarded write — without ever exposing raw SQL or the underlying tables.
RichardHan/mssql_mcp_server: the popular community option
RichardHan’s server is the one most Claude Desktop tutorials are built around, and for local development it’s a perfectly sensible choice for SQL Server MCP Server — provided you understand exactly what it does and scope its database account accordingly.
What it is
It’s an SQL Server MCP Server that gives AI assistants — primarily Claude Desktop — controlled access to a Microsoft SQL Server database. Once connected, a client can list tables, read table contents, and execute SQL queries including SELECT, INSERT, UPDATE, and DELETE. It supports three authentication modes (SQL auth, Windows auth, and Azure AD/Azure SQL), works with LocalDB, on-prem SQL Server, SQL Server in Docker, and Azure SQL Database, and ships under the MIT license.
The defining difference from Microsoft’s server: this one will run the SQL the model produces, up to whatever the connected account is permitted to do. That capability is its convenience and its risk in equal measure.
The naming trap, again
As noted earlier: RichardHan’s GitHub repo is mssql_mcp_server, but its PyPI package is microsoft_sql_server_mcp. The hyphenated PyPI package mssql-mcp-server is a different author’s project. Install microsoft_sql_server_mcp for RichardHan’s server.
Prerequisites for SQL Server MCP Server
- Python 3.10+
- An MCP-capable client (this server is built and documented around Claude Desktop)
- Network access to a SQL Server instance (LocalDB, on-prem, Docker, or Azure SQL)
- SQL Server credentials with the minimum permissions needed — never
saor an admin account (more on this below)
Step 1: Install the server
Option A — uvx (fastest, no manual install). If you have uv, you don’t install anything ahead of time; uvx fetches and runs the package on demand when Claude Desktop launches it.
Option B — pip install:
pip install microsoft_sql_server_mcp
Option C — clone and install from source (for development):
git clone https://github.com/RichardHan/mssql_mcp_server.git
cd mssql_mcp_server
pip install -e .
Step 2: Configure your client (Claude Desktop or Claude Code)
Claude Desktop
For SQL Server MCP Server configuration, open or create claude_desktop_config.json and add an entry under mcpServers.
If you installed with uvx (recommended):
{
"mcpServers": {
"mssql": {
"command": "uvx",
"args": ["microsoft_sql_server_mcp"],
"env": {
"MSSQL_SERVER": "localhost",
"MSSQL_DATABASE": "your_database",
"MSSQL_USER": "your_username",
"MSSQL_PASSWORD": "your_password"
}
}
}
}
If you installed with pip:
{
"mcpServers": {
"mssql": {
"command": "python",
"args": ["-m", "mssql_mcp_server"],
"env": {
"MSSQL_SERVER": "localhost",
"MSSQL_DATABASE": "your_database",
"MSSQL_USER": "your_username",
"MSSQL_PASSWORD": "your_password"
}
}
}
}
Restart Claude Desktop after saving. On success, the mssql server appears as active — look for the plug/tools icon in the UI.
Claude Code
Claude Code registers servers from the terminal rather than from a JSON file. Pass the launch command after the -- separator and supply the connection details as environment variables with -e flags. Using uvx (recommended):
claude mcp add mssql \
-e MSSQL_SERVER=localhost \
-e MSSQL_DATABASE=your_database \
-e MSSQL_USER=your_username \
-e MSSQL_PASSWORD=your_password \
-- uvx microsoft_sql_server_mcp
If you installed with pip instead of uvx, swap the launch command for python -m mssql_mcp_server (keep the same -e flags before the --). Verify with claude mcp list, then ask a question like “What tables are in this database?” to confirm the tools fire. The same security rule applies regardless of client: the MSSQL_USER you supply here is your security boundary, so make it a least-privilege, read-only login unless you specifically need writes.
Step 3: Set environment variables for your auth method
The server reads all connection details from environment variables in the env block. Pick the set that matches your setup.
SQL Authentication (most common):
MSSQL_SERVER=localhost # Required
MSSQL_DATABASE=your_database # Required
MSSQL_USER=your_username # Required for SQL auth
MSSQL_PASSWORD=your_password # Required for SQL auth
Windows Authentication:
MSSQL_SERVER=localhost
MSSQL_DATABASE=your_database
MSSQL_WINDOWS_AUTH=true # Uses your current Windows credentials
Azure SQL Database:
MSSQL_SERVER=your-server.database.windows.net
MSSQL_DATABASE=your_database
MSSQL_USER=your_username
MSSQL_PASSWORD=your_password
# Encryption is automatic for Azure connections
Optional extras (any mode):
MSSQL_PORT=1433 # Custom port, default is 1433
MSSQL_ENCRYPT=true # Force encryption on the connection
Step 4: Try it out
Once Claude Desktop shows the server connected, ask naturally:
- “What tables are in this database?”
- “Show me the first 10 rows of the Customers table.”
- “Insert a new row into Orders with these values…”
Claude calls the server’s tools behind the scenes and returns results conversationally.
Running it via Docker
The repo ships a Dockerfile and docker-compose.example.yml if you’d rather not install Python locally:
git clone https://github.com/RichardHan/mssql_mcp_server.git
cd mssql_mcp_server
docker build -t mssql-mcp-server .
docker run -it \
-e MSSQL_SERVER=your-server \
-e MSSQL_DATABASE=your-database \
-e MSSQL_USER=your-username \
-e MSSQL_PASSWORD=your-password \
mssql-mcp-server
Or with Compose:
docker-compose -f docker-compose.example.yml up
In the Docker case, Claude Desktop connects over the network/HTTP transport the container exposes rather than launching the process directly — check docker-compose.example.yml for the exact port mapping.
Security: the part most guides rush past
This section applies to every server in this guide for SQL Server MCP Server configuration, but it’s life-or-death for the community ones, because they will execute whatever the connected account permits.
The maintainer’s own security recommendations should be treated as requirements, not suggestions:
- Create a dedicated SQL Server login with the minimum permissions the assistant actually needs. If you only want querying, grant read-only. Nothing more.
- Never use
saor any administrative account. This is the single most common and most dangerous mistake. - Prefer Windows Authentication when your environment supports it, so you’re not managing a standing password.
- Enable encryption for any connection carrying sensitive data.
The reason this matters so much for community servers is mechanical: because they can run INSERT, UPDATE, and DELETE if the account permits, the connected login is your security boundary. A read-only login is the safe default; grant write access only when you specifically intend the assistant to modify data, and think hard before ever pointing one of these at production.
This is also the cleanest way to articulate why Microsoft’s server exists. Its governance model means the database account is no longer your only line of defense — role-based permissions, configuration-driven exposure, and the refusal to run model-generated SQL all stack on top of it. With a community server, you have one wall. With the governed server, you have several.
Choosing between SQL Server MCP Server: a decision framework
Strip away the marketing and the choice comes down to a few honest questions.
Is the data sensitive, shared, or production? If yes, use Microsoft’s SQL MCP Server. The setup overhead is the price of a governance model you’ll be glad to have the first time an agent does something unexpected. This isn’t a close call.
Is this a local, disposable development database you fully control? A community server like RichardHan’s is reasonable, faster to set up, and well-documented for Claude Desktop. Just scope the account to read-only unless you have a specific reason not to.
Do you already run DAB for REST or GraphQL? Then the decision is made for you — upgrading to DAB 1.7+ gives you a working MCP server for free, governed by the exact same configuration you already maintain. There’s no reason to bolt a separate community server alongside it.
Are you a Node-first shop? The npm options (@connorbritain/mssql-mcp-server, techybolek/mcp-mssql-server) fit your toolchain, and the former markets a larger tool set with governance controls. But weigh that against Microsoft’s server, which is cross-platform .NET and doesn’t require you to adopt a community project’s maintenance risk for a production system.
Do you need the agent to write SQL freely? Be very suspicious of this requirement. Most of the time, “I need arbitrary SQL” really means “I haven’t yet modeled the operations I want to expose.” Views, stored procedures, and the aggregate tools cover the large majority of real needs through the governed path. If you genuinely need open-ended querying, you’ve accepted real risk — make that an explicit, documented decision, not a default.
Common pitfalls across all servers
A few failure modes recur regardless of which server you pick:
- Server doesn’t show up in the client. Almost always invalid JSON or wrong key nesting in the config file. Validate the JSON and fully restart the client.
- Connection errors. Verify the server name, port, and firewall rules allow the connection from wherever the server process actually runs (which, for Docker, is not your host machine).
- Wrong package installed. If a setup guide’s steps don’t match what you see, you probably grabbed a similarly-named project. Re-check the exact package string.
- STDIO server fails silently. For DAB, confirm
"mcp": { "enabled": true }is present and that nothing writes non-JSON text to stdout before the server starts — log output must go to stderr or a file, never stdout, or it corrupts the protocol stream. - Permission errors on a specific operation. The role named in
role:<name>lacks the required permission for that entity and operation, or adml-toolstoggle is disabling it. Check the entity’s permissions and thedml-toolsblock. - Testing the connection independently. RichardHan’s repo includes a
test_connection.pyscript — run it after cloning to confirm credentials work before wiring up the client. For DAB,dab validate --config <path>checks your configuration.
The bottom line
The proliferation of MS SQL Server MCP servers can look like a confusing menu, but it resolves into a single, clarifying question: how much do you trust a language model with your data, and how much do you want the infrastructure — rather than luck — to enforce that trust?
For anything disposable and local, the community servers are quick, friendly, and entirely adequate when paired with a properly scoped account. For anything you’d regret losing, corrupting, or exposing, Microsoft’s SQL MCP Server is the prescriptive answer precisely because it takes the model’s pen away and hands it a fixed, governed set of structured tools instead. It’s more work to set up, and that’s the feature, not the bug.
Whichever you choose, the discipline is the same: minimal permissions, deliberate exposure, encryption where data is sensitive, and a clear-eyed understanding that the database account is your last line of defense — so make it a narrow one.
Project resources for SQL Server MCP Server
- Microsoft SQL Server MCP Server / Data API Builder: the official documentation under Microsoft Learn’s Data API Builder section, and the open-source repo at
github.com/Azure/data-api-builder - RichardHan/mssql_mcp_server — GitHub:
https://github.com/RichardHan/mssql_mcp_server· - PyPI:
https://pypi.org/project/microsoft_sql_server_mcp/
Frequently Asked Questions
Does Claude Code support SQL Server through MCP?
Yes. Claude Code connects to a SQL Server MCP server the same way it connects to any MCP server — through the claude mcp add command in your terminal, rather than the JSON config files Claude Desktop and VS Code use. You can register either Microsoft’s official server (claude mcp add mssql -- dab start --mcp-stdio role:anonymous --config /path/to/dab-config.json) or a community server like RichardHan’s. Confirm the registration with claude mcp list.
Is the SQL Server MCP server free?
Microsoft’s SQL Server MCP Server is free and open source — it ships inside Data API Builder, which has no premium tier and runs anywhere, including on-premises. The popular community servers (RichardHan’s, JexinSam’s, the npm options) are also free and open source under permissive licenses. Your only costs are the SQL Server instance itself and any hosting you choose for an HTTP deployment.
Can the AI write its own SQL against my database?
It depends entirely on which server you choose, and this is the most important distinction in the whole ecosystem. Microsoft’s SQL Server MCP Server deliberately does not let the model write SQL — it exposes a fixed set of seven structured tools and translates them into deterministic T-SQL behind a permission layer. Most community servers do the opposite: they execute the SQL the model produces, up to whatever the connected account is allowed to do. If arbitrary model-generated SQL against your data sounds risky, that instinct is correct, and the governed approach exists precisely to remove it.
How do I make a SQL Server MCP server read-only?
For Microsoft’s server, grant only read permissions on each entity in dab-config.json and disable the write tools in the dml-tools block (leave create-record, update-record, and delete-record off). For community servers, the connected SQL login is the boundary — create a dedicated login with read-only rights and nothing more. In both cases, never connect with sa or an administrative account.
Why isn’t my SQL Server MCP server showing up in the client?
The most common cause is a malformed config file — invalid JSON or incorrect key nesting — so validate it and fully restart the client. For Microsoft’s STDIO transport, confirm "mcp": { "enabled": true } is present in the runtime section, or DAB won’t start. Also ensure nothing writes non-JSON text to stdout before the server starts, since that corrupts the STDIO protocol stream; log output must go to stderr or a file.
Can SQL Server MCP Server perform JOINs across tables?
The built-in read_records tool works against a single table or view and does not support JOINs by design. To get joined data, expose a database view (which the tool treats as one entity) or wrap the query in a stored procedure and call it through the execute_entity tool. DAB’s GraphQL endpoint also supports richer relational querying outside the MCP path.
Should I use STDIO or HTTP transport in SQL Server MCP Server?
Use STDIO for local, single-machine development — the client launches and manages the server, no network port is opened, and it’s the simpler and more secure default. Use HTTP when the server needs to be reachable across a network, such as a shared team instance or a hosted production deployment, where you accept responsibility for the running process and its exposure.
Which package do I install for RichardHan’s server?
Install microsoft_sql_server_mcp from PyPI. This is the single most common installation mistake in the ecosystem: RichardHan’s GitHub repo is named mssql_mcp_server, but the hyphenated PyPI package mssql-mcp-server belongs to a different author entirely. Match the exact string microsoft_sql_server_mcp or your setup won’t line up with RichardHan’s documentation.
Does it work with Azure SQL Database?
Yes. Both Microsoft’s server and the major community servers support Azure SQL Database alongside on-premises SQL Server, LocalDB, and SQL Server in Docker. For Azure SQL connections, point the server at your your-server.database.windows.net endpoint; encryption is typically applied automatically.
Do I need .NET installed to use a SQL Server MCP server?
Only for Microsoft’s server, which runs on Data API Builder and requires .NET 9 or later for the SQL MCP Server quickstart. The Python community servers (RichardHan’s and others) need Python 3.10+ instead, and the npm-based servers need Node.js. Pick the server whose runtime your team already maintains.