mssql-mcp
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., "@mssql-mcpshow me all tables in the sales 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.
mssql-mcp
A Model Context Protocol (MCP) server that exposes any Microsoft SQL Server database to AI agents — supports multiple databases in a single instance, generic keyword lookup, free SELECT queries, and three transport modes (stdio / SSE / Streamable HTTP). Ships as a Docker image.
一個把 Microsoft SQL Server 資料庫包裝成 MCP(Model Context Protocol)伺服器的工具,讓 AI Agent 可以直接查詢資料庫。單一服務可同時連多個資料庫,提供通用關鍵字查詢、自由 SELECT 查詢,並支援三種連線方式(stdio / SSE / Streamable HTTP)。以 Docker image 形式發布。
English
Features
Multi-database: configure any number of SQL Server connections in one deployment via a single
DB_CONNECTIONSenvironment variable.Four MCP tools:
list_databases— list all configured database connection nameslist_tables— list all TABLEs and VIEWs (with column info) in a databaselookup— generic keyword search (LIKE) across any table/view's text columnsquery_sql— free-formSELECTqueries, with a safety guard that rejects any non-SELECT statement
Three transports, so it works with virtually any MCP client regardless of version:
stdio— for Claude Code CLI (docker run)SSE(legacy HTTP) —GET /sse+POST /messageStreamable HTTP(current spec) —POST /mcp
SQL injection protections: table/field identifiers are validated against a blacklist of dangerous characters; all values are passed as parameterized query inputs.
No hardcoded credentials — everything comes from environment variables.
Requirements
Docker (recommended), or Node.js 20+ if running without Docker
Network access to your SQL Server instance(s)
A SQL Server login with (at minimum)
db_datareaderon the target database(s)
Quick Start (Docker)
git clone <this-repo-url>
cd mssql-mcp
cp .env.example .envEdit .env and set DB_CONNECTIONS — a JSON array, one entry per database:
DB_CONNECTIONS=[{"name":"main","host":"192.168.1.10","port":1433,"database":"MyDatabase","user":"sql_user","password":"sql_password"}]To connect to more than one database, add more entries:
DB_CONNECTIONS=[
{"name":"sales","host":"192.168.1.10","database":"SalesDb","user":"u1","password":"p1"},
{"name":"inventory","host":"192.168.1.11","database":"InventoryDb","user":"u2","password":"p2"}
](Keep it on one line in the actual .env file — JSON, no line breaks.)
Then build and start:
docker compose up -d --buildCheck it's running:
docker logs mssql-mcp
# Expect: mssql-mcp HTTP server listening on port 3000Testing the endpoints
Streamable HTTP (/mcp) — requires the Accept header to include both content types:
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_databases","arguments":{}}}'Legacy SSE (/sse) — for older MCP clients, connect a client to http://<host>:3000/sse.
Connecting from Claude Code
Add to ~/.claude/settings.json (or your project's .claude/settings.json):
{
"mcpServers": {
"mssql": {
"type": "sse",
"url": "http://<docker-host>:3000/sse"
}
}
}If your Claude Code version supports the newer Streamable HTTP transport:
{
"mcpServers": {
"mssql": {
"type": "http",
"url": "http://<docker-host>:3000/mcp"
}
}
}Verify with /mcp inside Claude Code — you should see list_databases, list_tables, lookup, and query_sql.
Tool reference
Tool | Arguments | Description |
| none | Lists all configured connection names |
|
| Lists all TABLEs/VIEWs and their columns in a database. |
|
| Keyword search ( |
|
| Runs a free-form |
When more than one database is configured, database is required — call list_databases first to discover valid names.
Configuration reference
Environment variable | Required | Description |
| Yes | JSON array of |
| No | HTTP listen port (default |
| No | Force |
Local development (without Docker)
npm install
npm test # run unit tests (SQL safety guard)
npm run build # compile TypeScript
DB_CONNECTIONS='[{"name":"main","host":"...","database":"...","user":"...","password":"..."}]' npm startSecurity notes
The safety guard only permits statements starting with
SELECT. It does not attempt to block dangerous substrings inside string literals (e.g. aWHERE name = 'DROP TABLE x'search is legitimate and allowed) — the real security boundary is the database account's own permissions. Grant the SQL login used here read-only access (db_datareader).Table/field names for the
lookuptool are validated against a blacklist of characters that could break out of[...]bracket-quoting (],[,;, quotes, backticks, newlines, SQL comment sequences). This permits Unicode identifiers (e.g. Chinese table names) while blocking injection attempts.No authentication is built into the HTTP transports — deploy this only on a trusted internal network, or add your own reverse-proxy auth layer in front of it.
License
MIT (or your organization's preferred license — update this section as needed)
Related MCP server: SQL Server MCP
中文
功能特色
多資料庫支援:單一部署可透過一個
DB_CONNECTIONS環境變數設定任意數量的 SQL Server 連線。四個 MCP 工具:
list_databases— 列出所有已設定的資料庫連線名稱list_tables— 列出資料庫中所有 TABLE 和 VIEW(含欄位資訊)lookup— 通用關鍵字模糊搜尋(LIKE),可搜任意 TABLE/VIEW 的文字欄位query_sql— 自由SELECT查詢,內建安全守衛,拒絕任何非 SELECT 語句
三種連線方式,幾乎相容所有版本的 MCP client:
stdio— 給 Claude Code CLI 使用(docker run)SSE(舊版 HTTP)—GET /sse+POST /messageStreamable HTTP(新版規格)—POST /mcp
SQL injection 防護:資料表/欄位名稱以黑名單擋掉危險字元,所有數值一律走參數化查詢。
無硬編碼帳密 — 全部透過環境變數設定。
需求
Docker(建議),或 Node.js 20+(若不用 Docker)
能連到目標 SQL Server 的網路
一個至少有
db_datareader權限的 SQL Server 帳號
快速開始(Docker)
git clone <this-repo-url>
cd mssql-mcp
cp .env.example .env編輯 .env,設定 DB_CONNECTIONS(JSON 陣列,一個資料庫一個項目):
DB_CONNECTIONS=[{"name":"main","host":"192.168.1.10","port":1433,"database":"MyDatabase","user":"sql_user","password":"sql_password"}]要連多個資料庫就多加幾個項目:
DB_CONNECTIONS=[
{"name":"sales","host":"192.168.1.10","database":"SalesDb","user":"u1","password":"p1"},
{"name":"inventory","host":"192.168.1.11","database":"InventoryDb","user":"u2","password":"p2"}
](實際寫進 .env 時要是單行的 JSON,不能有換行。)
接著 build 並啟動:
docker compose up -d --build確認啟動成功:
docker logs mssql-mcp
# 應看到:mssql-mcp HTTP server listening on port 3000測試 endpoint
Streamable HTTP(/mcp)— 注意 Accept header 必須同時宣告兩種格式:
curl -X POST http://localhost:3000/mcp ^
-H "Content-Type: application/json" ^
-H "Accept: application/json, text/event-stream" ^
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"list_databases\",\"arguments\":{}}}"(Windows CMD 用 ^ 換行;PowerShell 或 Linux/Mac 請用單行或改用 \。)
舊版 SSE(/sse)— 給較舊的 MCP client 連 http://<host>:3000/sse。
接入 Claude Code
在 ~/.claude/settings.json(或專案內 .claude/settings.json)加入:
{
"mcpServers": {
"mssql": {
"type": "sse",
"url": "http://<docker-host>:3000/sse"
}
}
}若你的 Claude Code 版本支援新版 Streamable HTTP:
{
"mcpServers": {
"mssql": {
"type": "http",
"url": "http://<docker-host>:3000/mcp"
}
}
}在 Claude Code 內執行 /mcp 確認,應會看到 list_databases、list_tables、lookup、query_sql 四個工具。
工具說明
工具 | 參數 | 說明 |
| 無 | 列出所有已設定的連線名稱 |
|
| 列出指定資料庫中所有 TABLE/VIEW 及其欄位。若只設定一個連線可省略 |
|
| 在資料表文字欄位上模糊搜尋( |
|
| 執行自由 |
當設定了多個資料庫連線時,必須填入 database 參數——先呼叫 list_databases 取得可用名稱。
環境變數設定
環境變數 | 是否必填 | 說明 |
| 是 | JSON 陣列,每個項目為 |
| 否 | HTTP 監聽埠(預設 |
| 否 | 強制指定 |
本機開發(不用 Docker)
npm install
npm test # 執行單元測試(SQL 安全守衛)
npm run build # 編譯 TypeScript
DB_CONNECTIONS='[{"name":"main","host":"...","database":"...","user":"...","password":"..."}]' npm start安全性說明
安全守衛只允許以
SELECT開頭的語句,不會特別阻擋字串字面值中包含的危險關鍵字(例如WHERE name = 'DROP TABLE x'這種合法查詢會被允許)——真正的安全邊界是資料庫帳號本身的權限,請務必只給唯讀(db_datareader)權限。lookup工具的資料表/欄位名稱以黑名單方式擋掉能跳出[...]包裹或注入 SQL 的字元(]、[、;、引號、反引號、換行、SQL 註解符號),因此可以使用中文等 Unicode 名稱,同時仍防止注入。HTTP transport 本身沒有內建驗證機制——請務必只部署在信任的內網環境,或自行在前面加一層 reverse proxy 驗證。
授權
MIT(或依你的組織需求調整)
Available Tools
4 toolslist_databasesA
列出此 MCP 服務已設定的所有資料庫連線名稱
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. '列出' implies a read-only operation, which is accurate. However, it does not disclose any potential side effects, required permissions, or rate limits, though for a simple list tool these are less critical.
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?
Single clear sentence that fully describes the tool's function without any unnecessary words. Front-loaded with the action and resource.
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 list operation with no parameters and no output schema, the description is complete. It states exactly what the tool returns: a list of database connection names configured in the MCP service.
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?
Tool has zero parameters, so description naturally adds no parameter details. Schema coverage is 100% (empty properties). Baseline for 0 params is 4; no further elaboration needed.
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?
Description uses specific verb '列出' (list) and resource '所有資料庫連線名稱' (all database connection names). It clearly distinguishes from siblings like list_tables (which lists tables within a database) and query_sql (which runs queries).
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 explicit guidance on when to use this tool versus alternatives. However, its simplicity makes the usage context clear: use to enumerate available databases before querying tables or running SQL. Sibling names imply differentiation but no direct comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesA
列出指定資料庫中所有的 TABLE 和 VIEW,包含欄位名稱、型別、是否可為 NULL
| Name | Required | Description | Default |
|---|---|---|---|
| database | No | 要查詢的資料庫連線名稱(用 list_databases 取得可用清單)。若只設定一個連線可省略。 |
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. It clearly indicates a read-only listing operation with no destructive side effects, but does not discuss rate limits, performance, or other potential behaviors. The description is accurate and non-contradictory.
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 that conveys all essential information without wasted words.
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 optional parameter, no output schema), the description covers the core functionality: what it lists and the details included. It could optionally mention that results are returned as a list but is sufficient for the agent to understand the output.
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 coverage is 100% for the single parameter, and the description adds valuable context: it explains that 'database' is a connection name, suggests using list_databases to get options, and notes it can be omitted if only one connection exists.
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 it lists all TABLEs and VIEWs in a specified database, including column details, differentiating it from siblings like list_databases (lists databases) and query_sql (executes queries).
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 use for schema exploration but does not explicitly state when to use it versus alternatives or provide exclusion criteria. Context from sibling tools suggests using list_databases first, but this is not mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookupA
在指定的 TABLE 或 VIEW 中以關鍵字模糊搜尋(LIKE),最多回傳 100 筆
| Name | Required | Description | Default |
|---|---|---|---|
| field | No | 限定搜尋欄位(可選,不填則搜全部文字欄位) | |
| table | Yes | 資料表或 VIEW 名稱(用 list_tables 取得) | |
| keyword | Yes | 搜尋關鍵字 | |
| database | No | 要查詢的資料庫連線名稱(用 list_databases 取得可用清單)。若只設定一個連線可省略。 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the use of LIKE for fuzzy search and a 100-record limit. However, it does not mention that if no field is specified, all text fields are searched (only in schema), nor does it indicate case sensitivity or potential performance implications on large tables.
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, clear sentence that efficiently conveys the tool's purpose and key constraint. It is front-loaded with the verb and resource, with no unnecessary information.
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 absence of an output schema, the description could explain the return format or fields. It only mentions 'up to 100 records,' leaving details like column names or ordering unspecified. It is adequate but not comprehensive.
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?
All parameters are described in the input schema (100% coverage). The tool description adds no additional meaning beyond the schema's parameter descriptions, meeting the baseline for a tool with comprehensive schema documentation.
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 purpose: fuzzy search (LIKE) by keyword in a specified TABLE or VIEW, with a maximum return of 100 records. It distinguishes from sibling tools like list_databases and list_tables which are listing tools, and query_sql which allows arbitrary SQL queries.
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 explicit guidance on when to use this tool versus alternatives, especially query_sql. There is no mention of conditions where query_sql would be more appropriate, such as for exact matches or complex queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_sqlA
執行自由 SELECT 語句查詢指定資料庫(僅允許 SELECT,禁止 INSERT/UPDATE/DELETE 等異動語法)
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | 要執行的 SELECT SQL 語句 | |
| database | No | 要查詢的資料庫連線名稱(用 list_databases 取得可用清單)。若只設定一個連線可省略。 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description clearly states the tool is read-only (SELECT only) and enforces mutation prohibition. It could be improved by mentioning potential performance impacts or result set size, but the core safety behavior is well disclosed.
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 that efficiently conveys the core purpose and restrictions. Every word earns its place.
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 covers allowed operations, the need for a database connection, and how to obtain it via list_databases. While it doesn't explicitly state the return format, it's implied for SELECT queries. A warning about potential long-running queries 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?
Schema coverage is 100%, with both parameters described in the schema. The description adds little beyond the schema, mainly reinforcing the SELECT-only constraint already present in the schema description. 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 clearly states the tool's purpose: executing free SELECT statements on a specified database. It explicitly restricts usage to SELECT only and prohibits mutation syntax, distinguishing it from sibling tools that list databases or 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 explicitly states when to use the tool (for arbitrary SELECT queries) and when not (only SELECT allowed, no INSERT/UPDATE/DELETE). It also references using list_databases to get available database connections, providing clear context for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a unique and clearly distinct purpose: listing databases, listing tables with schema, performing keyword searches, and executing arbitrary SQL queries. There is no ambiguity or overlap.
All tool names follow a consistent verb_noun pattern in snake_case (list_databases, list_tables, lookup, query_sql). Even 'lookup' is a common verb that fits the pattern.
With 4 tools, the set is well-scoped for a read-only database server. It provides essential introspection and data access without being bloated or too sparse.
The tools cover listing databases, tables with schema, keyword search, and arbitrary SELECT queries, which is fairly complete for read-only access. However, a direct tool to fetch a single record by primary key is missing, though lookup can serve that purpose.
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
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.
- mcpOAuthcom.gibsonai
GibsonAI MCP server: manage your databases with natural language
Related MCP Servers
- AlicenseBqualityDmaintenanceAn easy-to-use bridge that lets AI assistants like Claude and Cursor IDE directly query and explore Microsoft SQL Server databases. No coding experience required!333,33878GPL 3.0
- AlicenseBqualityCmaintenanceA 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.87228MIT
- AlicenseAqualityDmaintenanceEnables AI agents to securely connect to and query Microsoft SQL Server databases with read-only access, schema discovery, and relationship mapping. Features advanced security protections, health monitoring, and bulk operations for production environments.9222MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to interact with Microsoft SQL Server databases through query execution, schema discovery, CRUD operations, stored procedures, and data export with built-in safety controls.18Apache 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/kevindump/mssql-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server