内容
# MS SQL Server MCP 服务器
[](https://www.npmjs.com/package/@piyapat/mssql-mcp-server)
[](https://www.npmjs.com/package/@piyapat/mssql-mcp-server)
[](https://nodejs.org)
[](LICENSE)
[](https://github.com/sponsors/PiyapatRag)
一个安全的、只读的 Microsoft SQL Server 模型上下文协议(MCP)服务器,内置性能监控和锁定检测。
📦 **npm:** [@piyapat/mssql-mcp-server](https://www.npmjs.com/package/@piyapat/mssql-mcp-server)
## 快速开始
您可以使用 `npx` 直接运行此 MCP 服务器:
```bash
npx @piyapat/mssql-mcp-server
```
## 安装
### 选项 1:使用 npx(推荐用于测试)
```bash
# 直接使用环境变量运行
MSSQL_SERVER=localhost \
MSSQL_DATABASE=mydb \
MSSQL_USER=readonly \
MSSQL_PASSWORD=password \
npx @piyapat/mssql-mcp-server
```
### 选项 2:全局安装
```bash
# 全局安装
npm install -g @piyapat/mssql-mcp-server
# 运行
mssql-mcp-server
```
### 选项 3:本地安装
```bash
# 克隆并安装
git clone https://github.com/PiyapatRag/mssql-mcp-server.git
cd mssql-mcp-server
npm install
npm run build
# 运行
npm start
```
## 配置
### 步骤 1:创建 `.env` 文件(推荐)
凭证存储在 `.env` 文件中 - **不** 硬编码在 MCP 客户端的 JSON 配置中:
```bash
cp .env.example .env
# 然后用您的凭证编辑 .env
```
服务器按以下顺序查找 `.env` 文件:
1. `MSSQL_ENV_FILE` 中指定的路径(显式覆盖)
2. 当前工作目录中的 `.env`
3. 项目根目录中的 `.env`(与 `package.json` 相邻)
MCP 客户端的 `"env"` 块中已设置的变量始终优先于 `.env` 文件,并且 `.env` 被 git 忽略。
### 步骤 2:将 Claude Desktop 指向服务器
编辑您的 Claude Desktop 配置:
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
**macOS/Linux:** `~/Library/Application Support/Claude/claude_desktop_config.json`
使用 `.env` 在项目根目录中,不需要在 JSON 中提供凭证:
```json
{
"mcpServers": {
"mssql": {
"command": "node",
"args": ["C:\\path\\to\\mssql-mcp-server\\build\\index.js"]
}
}
}
```
如果 `.env` 存放在其他位置,请仅传递其路径:
```json
{
"mcpServers": {
"mssql": {
"command": "node",
"args": ["C:\\path\\to\\mssql-mcp-server\\build\\index.js"],
"env": {
"MSSQL_ENV_FILE": "C:\\secure\\location\\mssql.env"
}
}
}
}
```
在 `"env"` 块中直接设置变量仍然有效(并覆盖 `.env` 文件)- 对于 npx 设置或针对不同数据库运行多个服务器很有用。
## 环境变量
| 变量 | 描述 | 默认值 | 必需 |
| --- | --- | --- | --- |
| `MSSQL_SERVER` | SQL Server 主机名或 IP | `localhost` | 是 |
| `MSSQL_DATABASE` | 数据库名称 | - | 是 |
| `MSSQL_USER` | SQL Server 用户名(或设置 `MSSQL_DOMAIN` 时的域用户) | - | 是 |
| `MSSQL_PASSWORD` | 密码 | - | 是 |
| `MSSQL_DOMAIN` | Windows/NTLM 域。设置后,使用 Windows 身份验证代替 SQL 身份验证 | - | 否 |
| `MSSQL_PORT` | SQL Server 端口 | `1433` | 否 |
| `MSSQL_ENCRYPT` | 使用加密(true/false) | `false` | 否 |
| `MSSQL_TRUST_CERT` | 信任服务器证书(true/false) | `false` | 否 |
| `MSSQL_READ_ONLY` | `true` = 只读允许列表验证。`false` = 写入模式:允许 INSERT/UPDATE/DELETE/DDL,但始终阻止服务器级危险语句 | `true` | 否 |
| `MSSQL_ALLOWED_PROCEDURES` | 以逗号分隔的存储过程白名单,`EXEC` 在只读模式下可以调用,例如 `dbo.GetReport,dbo.GetCustomerSummary`。空/未设置时,完全禁用 `EXEC` | - | 否 |
| `MSSQL_ENV_FILE` | `.env` 文件的显式路径 | - | 否 |
| `MSSQL_REQUEST_TIMEOUT` | 查询超时(毫秒) | `30000` | 否 |
| `MSSQL_POOL_MAX` | 最大连接池数 | `10` | 否 |
## 服务器模式
### 只读模式(`MSSQL_READ_ONLY=true`,默认)
`mssql_query` 仅接受:
- 单个 `SELECT` / `WITH...SELECT`
- 以 `DECLARE`、`INSERT` 或 `CREATE TABLE #...` 开头的多语句批处理,仅写入 **会话本地的 `#temp` 表 / `@table` 变量** - 例如 `INSERT INTO #t SELECT ...` 或 `CREATE TABLE #t (...); INSERT INTO #t ...; SELECT * FROM #t`。还允许在这样的批处理中执行 `CREATE INDEX ... ON #t`、`TRUNCATE/ALTER/DROP TABLE #t`。**全局 `##temp` 表永远不会被允许**(它们对每个会话可见,因此被视为持久的)。
- 白名单存储过程的 `EXEC`,其定义不会写入持久表
其他操作均被拒绝:持久对象上的写入/DDL、动态 SQL、`EXEC` 批处理(防止绕过存储过程白名单)、`DBCC` 和堆积语句在 `SELECT`/`WITH`/`EXEC` 之后。
### 写入模式(`MSSQL_READ_ONLY=false`)
允许 `INSERT` / `UPDATE` / `DELETE` / DDL,但 **始终阻止** 以下操作:
`xp_cmdshell`、`xp_regwrite`/`xp_regdelete*`、`sp_configure`、`RECONFIGURE`、`SHUTDOWN`、`KILL`、`DROP DATABASE`、`ALTER DATABASE`、`RESTORE`、`CREATE/ALTER/DROP LOGIN/USER/CREDENTIAL/CERTIFICATE`、`ALTER SERVER`、`GRANT`/`DENY`/`REVOKE`、`OPENROWSET`/`OPENDATASOURCE`。
> ⚠️ 仅在 SQL 登录的权限与数据库登录的权限相同时,使用写入模式 - 数据库登录仍然是主要的权限边界。
## 关键功能
### 安全第一
- ✅ **两层只读强制** - 数据库只读登录(主要)加上应用程序级允许列表(防御深度)。应用程序接受 `SELECT` / `WITH...SELECT`、仅写入 `#temp` 表 / `@table` 变量的 `DECLARE` 批处理,以及白名单存储过程的 `EXEC`,这些存储过程的定义永远不会写入持久表
- ✅ **参数化查询** - 内置 SQL 注入保护
- ✅ **SSL/TLS 支持** - 生产环境中的加密连接
- ✅ **连接池** - 优化的资源管理
### 性能监控
- 📊 **实时锁定检测** - 识别阻塞和死锁情况
- 📈 **资源使用跟踪** - CPU、内存和查询性能指标
- 🔍 **查询分析** - 查找资源密集型查询
- ⚡ **会话监控** - 跟踪活动和阻塞会话
### 数据库探索
- 🗂️ **架构内省** - 表、列、键和约束
- 📝 **存储过程分析** - 视图定义和参数
- 🔎 **智能查询** - 自然语言转换为 SQL(使用 Claude)
## 可用工具(19)
### 核心
| 工具 | 描述 |
| --- | --- |
| `mssql_query` | 执行 SQL。默认只读验证;通过 `MSSQL_READ_ONLY=false` 启用写入模式(始终阻止服务器级危险语句)。分页 + JSON/Markdown 输出。 |
| `mssql_test_connection` | 测试连接;返回服务器/版本/版本、数据库、登录和当前模式。 |
| `mssql_list_databases` | 所有数据库及其状态、恢复模型和兼容性级别。 |
| `mssql_list_tables` | 表及其行数和大小(MB),可选按架构过滤。 |
| `mssql_sample_data` | 从表中预览行(默认为 10,最大 100)- 无需 SQL,防注入。 |
### 架构探索
| 工具 | 描述 |
| --- | --- |
| `mssql_get_schema` | 表的列、数据类型、主键/外键。 |
| `mssql_get_relationships` | 外键图:从/到表+列、删除/更新操作。 |
| `mssql_get_views` | 具有完整 SQL 定义的视图。 |
| `mssql_get_stored_procedures` | 具有参数和完整定义的存储过程。 |
| `mssql_search_definitions` | 在所有存储过程/视图/函数/触发器的源中搜索文本片段 - 用于旧系统的冲击分析。 |
### 性能和存储
| 工具 | 描述 |
| --- | --- |
| `mssql_analyze_indexes` | 索引使用情况统计(查找/扫描/更新)+优化器建议的缺失索引。 |
| `mssql_index_fragmentation` | 每个索引的碎片整理 + `REBUILD`(≥ 30%)/ `REORGANIZE`(5-30%)建议和现成可运行的 `ALTER INDEX` 语句(自动在支持的版本上添加 `ONLINE = ON`)。 |
| `mssql_top_queries` | 按 `cpu`、`duration`、`reads`、`writes`、`memory`(授予大小)或 `executions` 排名的 top 查询 - 总数、平均值和 SQL 文本。 |
| `mssql_performance_health` | 健康检查:top 等待统计信息(过滤良性等待)、内存计数器(页面生存期、授予待处理、总 vs 目标)、工作负载计数器,以及基于规则的调优建议。 |
| `mssql_analyze_storage` | 按大小排列的最大表 + 数据库文件大小。 |
| `mssql_monitor_usage` | 会话、CPU、缓冲区缓存、按 CPU 排列的 top 查询。 |
### 锁、阻塞和死锁
支持 SQL Server 2019(15.x)、2022(16.x)和 2025(17.x)- 所有版本,包括 Express。输出包括检测到的服务器版本/版本,并提示在较旧版本上运行时(尽力而为)。需要 `VIEW SERVER STATE`。
**版本和版本兼容性:
| | Express | Standard | Enterprise / Developer / Eval | Azure SQL MI | Azure SQL DB |
| --- | --- | --- | --- | --- | --- |
| 查询 / 架构 / 存储工具 | ✅ | ✅ | ✅ | ✅ | ✅ |
| `mssql_monitor_locks` / `mssql_find_blocking` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `mssql_get_deadlocks`(`system_health` XE) | ✅ | ✅ | ✅ | ✅ | ❌(工具解释替代方案) |
| `mssql_list_databases` / `mssql_monitor_usage` | ✅ | ✅ | ✅ | ✅ | ⚠️ 有限范围 |
表格/列适用于 SQL Server 2019、2022 和 2025。较旧版本(2016/2017)大多可用,但工具输出报告为尽力而为。
| 工具 | 描述 |
| --- | --- |
| `mssql_monitor_locks` | 当前会话的原始锁和等待视图。 |
| `mssql_find_blocking` | 阻塞链(受害者 ← 阻塞器),阻塞器识别包括空闲会话持有打开事务,带有双方的 SQL 文本。 |
| `mssql_get_deadlocks` | 来自内置 `system_health` 扩展事件会话的最近死锁事件:受害者、涉及的查询和完整的死锁图 XML。`source: "ring_buffer"`(快速,最近)或 `"file"`(进一步回溯)。 |
**Claude 示例:```
"显示按订单数量排名的前 10 位客户"
"哪些表最大,哪些索引未使用?"
"当前哪些会话被阻塞,哪个是根阻塞器?"
"昨晚有死锁吗,哪些查询导致了死锁?"
"查找所有引用 CustomerOrders 表的存储过程"
```
## 安全设置
> **只读在两个层中强制执行。** 数据库登录是 **主要** 防护措施 - 即使到达服务器的写入语句也无法执行。应用程序级允许列表(`classifyQuery` 在 [src/index.ts](src/index.ts) 中)是 **防御深度**:它只接受只读入口点,拒绝其他所有操作(写入、DDL、动态 SQL、堆积查询)。因为它允许列表中的关键字而不是阻止单词、列或别名命名为 `Create`、`Update`、`CreatedDate` 等,**不** 被阻止。
### 创建只读 SQL 用户(推荐)
提供了一个现成的脚本 [scripts/create-readonly-login.sql](scripts/create-readonly-login.sql) - 编辑占位符并以 `sysadmin` 身份运行。它应用了以下最小权限设置:
```sql
-- 1. 创建登录
CREATE LOGIN mcp_readonly WITH PASSWORD = 'SecurePassword123!';
-- 2. 切换到您的数据库
USE YourDatabase;
-- 3. 创建用户
CREATE USER mcp_readonly FOR LOGIN mcp_readonly;
-- 4. 授予读取权限
ALTER ROLE db_datareader ADD MEMBER mcp_readonly;
-- 4b. 显式拒绝写入(防御深度)
ALTER ROLE db_denydatawriter ADD MEMBER mcp_readonly;
-- 5. 授予监控权限
GRANT VIEW SERVER STATE TO mcp_readonly;
GRANT VIEW DATABASE STATE TO mcp_readonly;
GRANT VIEW DEFINITION TO mcp_readonly;
-- 6. 验证权限
SELECT
dp.name AS DatabaseUser,
dp.type_desc,
r.name AS RoleName
FROM sys.database_principals dp
LEFT JOIN sys.database_role_members drm ON dp.principal_id = drm.member_principal_id
LEFT JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id
WHERE dp.name = 'mcp_readonly';
```
## 开发
### 构建
```bash
npm run build
```
### 监视模式
```bash
npm run dev
```
### 本地测试
```bash
# 设置环境变量
export MSSQL_SERVER=localhost
export MSSQL_DATABASE=testdb
export MSSQL_USER=sa
export MSSQL_PASSWORD=password
# 运行
npm start
```
## 故障排除
### 使用 npx 时的“command not found”错误
如果运行 npx 时出现错误:
1. 确保已安装 Node.js 18+:
```bash
node --version
```
2. 清除 npm 缓存:
```bash
npm cache clean --force
```
3. 使用完整包名尝试:
```bash
npx --package=@piyapat/mssql-mcp-server mssql-mcp-server
```
### 连接错误
**错误:用户登录失败**
```sql
-- 检查身份验证模式(必须为混合模式)
USE master;
GO
EXEC xp_instance_regread
N'HKEY_LOCAL_MACHINE',
N'Software\Microsoft\MSSQLServer\MSSQLServer',
N'LoginMode';
GO
-- 应返回 2 表示混合模式
```
**错误:无法连接到服务器**
- 验证 SQL Server 浏览器服务是否正在运行
- 检查防火墙是否允许端口 1433
- 确保 SQL Server 配置管理器中的 TCP/IP 协议已启用
### 权限错误
```sql
-- 如果需要,授予其他权限
USE YourDatabase;
GRANT EXECUTE TO mcp_readonly; -- 如果您需要调用存储过程
GRANT SHOWPLAN TO mcp_readonly; -- 用于执行计划
```
## 最佳实践
1. **始终在生产环境中使用只读帐户**
2. **启用 SSL 加密** 以确保网络安全
3. **定期监控** - 设置定期监控检查
4. **限制结果集** - 使用 maxRows 防止内存问题
5. **索引优化** - 监控慢查询并添加索引
6. **定期维护** - 保持统计信息更新
7. **审计访问** - 跟踪哪些用户查询了什么
## 贡献
欢迎贡献 - 请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 以获取开发设置、拉取请求指南和发布流程。版本历史记录在 [CHANGELOG.md](CHANGELOG.md) 中。
## 许可证
MIT 许可证 - 请根据您的需求自由使用和修改。
## 构建工具
- [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/sdk) - MCP SDK
- [mssql](https://github.com/tediousjs/node-mssql) - Node.js 的 SQL Server 客户端
## 支持
对于问题:
1. 检查故障排除部分
2. 查看 SQL Server 错误日志
3. 验证 Claude Desktop 日志
4. 检查数据库权限
---
**为 Claude Desktop 构建** • **安全第一** • **性能聚焦**