SQL Sentinel MCP服务器
 ](https://ghcr.io/tkmawarire/sql-sentinel-mcp) 
用于SQL server监控、诊断和数据库操作的生产就绪MCP(模型上下文协议)服务器。用。NET 9和微软。数据。SqlClient用于 本机SQL Server连接--不需要ODBC驱动程序.
特性
- 会话管理 --创建、启动、停止、删除和列出扩展事件会话
- 智能过滤 --按应用程序、数据库、用户、持续时间、主机和文本模式筛选
- 查询指纹 --对仅在文字值上不同的类似查询进行规范化和分组
- 序列分析 --使用时间间隔和累计持续时间跟踪执行顺序
- 死锁检测 --捕获并分析包含受害者/进程详细信息的XML死锁报告
- 阻塞分析 --使用等待资源和SQL文本监视被阻止的进程事件
- 等待统计信息 --查询
sys.dm_os_wait_stats直接按类型分类(CPU、I/O、锁、内存等) - 健康检查 --全面的服务器诊断:慢速查询、死锁、阻塞、等待统计数据和见解
- 实时流媒体 --在指定持续时间内流式传输捕获的事件
- 安全生产 --自动排除噪音(
sp_reset_connection,SET语句、跟踪查询) - 数据库操作 --列出表、描述模式、查询数据、插入、更新和删除表
- AI优化 --具有可选Markdown格式的结构化JSON输出
需求
- 启用扩展事件的SQL Server 2012+(默认)
- 所需权限:
GRANT ALTER ANY EVENT SESSION TO [your_login];
GRANT VIEW SERVER STATE TO [your_login];- 对于阻塞进程检测:
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'blocked process threshold', 5;
RECONFIGURE;安装
选项1:Docker(推荐)
不。需要NET SDK。适用于安装了Docker的任何系统。
docker pull ghcr.io/tkmawarire/sql-sentinel-mcp:latest克劳德桌面(claude_desktop_config.json)
{
"mcpServers": {
"sql-sentinel": {
"command": "docker",
"args": ["run", "-i", "--rm", "--network", "host",
"-e", "SQL_SENTINEL_CONNECTION_STRING=Server=localhost;Database=master;User Id=sa;Password=YourPassword;TrustServerCertificate=true",
"ghcr.io/tkmawarire/sql-sentinel-mcp:latest"]
}
}
}克劳德代码
claude mcp add sql-sentinel \
-e SQL_SENTINEL_CONNECTION_STRING="Server=localhost;Database=master;User Id=sa;Password=YourPassword;TrustServerCertificate=true" \
-- docker run -i --rm --network host \
-e SQL_SENTINEL_CONNECTION_STRING \
ghcr.io/tkmawarire/sql-sentinel-mcp:latest网络接入:The-istdio传输需要标志。使用--network host因此容器可以访问您主机上的SQL Server。对于远程SQL Server,省略--network host并在连接字符串中使用可访问的主机名。 连接字符串:设置SQL_SENTINEL_CONNECTION_STRING通过-e。所有工具都从该环境变量读取连接字符串。
选项2:。NET全局工具(NuGet)
要求。NET 9 SDK或更高版本。
dotnet tool install -g Neofenyx.SqlSentinel.Mcp{
"mcpServers": {
"sql-sentinel": {
"command": "sql-sentinel-mcp",
"env": {
"SQL_SENTINEL_CONNECTION_STRING": "Server=localhost;Database=master;User Id=sa;Password=YourPassword;TrustServerCertificate=true"
}
}
}
}选项3:从源代码构建
git clone https://github.com/tkmawarire/sql-sentinel.git
cd sql-sentinel
dotnet build直接运行:
dotnet run --project SqlServer.Profiler.Mcp/或者发布一个自包含的二进制文件:
# Windows
dotnet publish SqlServer.Profiler.Mcp/ -c Release -r win-x64 --self-contained
# Linux
dotnet publish SqlServer.Profiler.Mcp/ -c Release -r linux-x64 --self-contained
# macOS (Apple Silicon)
dotnet publish SqlServer.Profiler.Mcp/ -c Release -r osx-arm64 --self-contained
# macOS (Intel)
dotnet publish SqlServer.Profiler.Mcp/ -c Release -r osx-x64 --self-contained输出将在 bin/Release/net9.0/{runtime}/publish/
连接串
所有工具都从以下位置读取连接字符串 SQL_SENTINEL_CONNECTION_STRING 环境变量。启动服务器前设置一次:
export SQL_SENTINEL_CONNECTION_STRING="Server=localhost;Database=master;User Id=sa;Password=YourPassword;TrustServerCertificate=false;Encrypt=true"SQL身份验证:
Server=localhost;Database=master;User Id=sa;Password=YourPassword;TrustServerCertificate=false;Encrypt=trueWindows身份验证:
Server=localhost;Database=master;Integrated Security=true;TrustServerCertificate=false;Encrypt=true注: 仅限使用TrustServerCertificate=true在具有自签名证书的开发环境中。 对于生产,始终使用TrustServerCertificate=false使用有效的SSL证书。
Azure SQL:
Server=yourserver.database.windows.net;Database=yourdb;User Id=user;Password=password;Encrypt=trueMCP工具参考
会话生命周期
| 工具 | 说明 |
|---|---|
sqlsentinel_create_session | 使用筛选器创建扩展事件会话(未启动) |
sqlsentinel_start_session | 开始捕获现有会话的事件 |
sqlsentinel_stop_session | 停止捕捉;事件被保留 |
sqlsentinel_drop_session | 删除会话并丢弃所有事件 |
sqlsentinel_list_sessions | 列出所有MCP创建的会话及其状态和缓冲区使用情况 |
sqlsentinel_quick_capture | 一步创建并启动会话 |
事件检索
| 工具 | 说明 |
|---|---|
sqlsentinel_get_events | 通过过滤、排序和重复数据删除检索捕获的事件 |
sqlsentinel_get_stats | 按指纹、数据库、应用程序或登录名分组的聚合统计信息 |
sqlsentinel_analyze_sequence | 分析具有时间和间隙的查询执行序列 |
sqlsentinel_get_connection_info | 列出数据库、应用程序、登录名、会话和阻止信息 |
sqlsentinel_stream_events | 指定持续时间(1-300s)内的实时事件捕获 |
诊断
| 工具 | 说明 |
|---|---|
sqlsentinel_get_deadlocks | 使用受害者、进程、锁和SQL文本检索死锁事件 |
sqlsentinel_get_blocking | 使用等待资源和SQL文本检索被阻止的进程事件 |
sqlsentinel_get_wait_stats | 查询 sys.dm_os_wait_stats 按类型分类(无需会话) |
sqlsentinel_health_check | 综合报告:缓慢查询、死锁、阻塞、等待统计数据、洞察 |
权限
| 工具 | 说明 |
|---|---|
sqlsentinel_check_permissions | 检查当前登录权限和阻止的进程阈值配置 |
sqlsentinel_grant_permissions | 授予登录所需的权限(需要sysadmin) |
数据库操作
| 工具 | 说明 |
|---|---|
sqlsentinel_list_tables | 列出数据库中的所有用户表(模式限定) |
sqlsentinel_describe_table | 详细的表架构:列、索引、约束、外键 |
sqlsentinel_create_table | 通过Create table语句创建新表 |
sqlsentinel_insert_data | 通过Insert语句插入数据 |
sqlsentinel_read_data | 执行SELECT查询并返回结果 |
sqlsentinel_update_data | 通过Update语句更新数据 |
sqlsentinel_drop_table | 通过Drop table语句删除表 |
使用示例
快速调试会话
Agent: sqlsentinel_quick_capture(
sessionName: "debug_api",
applications: "MyWebApp",
minDurationMs: 100
)
// User triggers the slow operation
Agent: sqlsentinel_get_events(
sessionName: "debug_api",
sortBy: "DurationDesc",
limit: 20
)
Agent: sqlsentinel_drop_session(sessionName: "debug_api")查找N+1个查询
Agent: sqlsentinel_quick_capture(
sessionName: "n_plus_one_check",
databases: "OrdersDB"
)
// User loads a page
Agent: sqlsentinel_get_stats(
sessionName: "n_plus_one_check",
groupBy: "QueryFingerprint"
)
// Look for queries with high execution counts跟踪特定操作
Agent: sqlsentinel_analyze_sequence(
sessionName: "my_session",
correlationId: "order-12345",
responseFormat: "Markdown"
)死锁检测
Agent: sqlsentinel_quick_capture(
sessionName: "deadlock_monitor",
eventTypes: "Deadlock"
)
// Wait for deadlocks to occur
Agent: sqlsentinel_get_deadlocks(
sessionName: "deadlock_monitor",
responseFormat: "Markdown"
)阻塞分析
Agent: sqlsentinel_quick_capture(
sessionName: "blocking_check",
eventTypes: "BlockedProcess"
)
// Requires: sp_configure 'blocked process threshold', 5
Agent: sqlsentinel_get_blocking(
sessionName: "blocking_check",
responseFormat: "Markdown"
)服务器健康检查
Agent: sqlsentinel_health_check(
sessionName: "my_session",
slowQueryThresholdMs: 1000,
responseFormat: "Markdown"
)数据库操作
Agent: sqlsentinel_list_tables()
Agent: sqlsentinel_describe_table(
name: "dbo.Products"
)
Agent: sqlsentinel_read_data(
sql: "SELECT TOP 10 * FROM dbo.Products ORDER BY CreatedDate DESC"
)等待统计信息(无需会话)
Agent: sqlsentinel_get_wait_stats(
topN: 20,
responseFormat: "Markdown"
)查询指纹
查询被规范化为对相似查询进行分组:
-- These become one fingerprint:
SELECT * FROM Users WHERE id = 123
SELECT * FROM Users WHERE id = 456
-- Fingerprint: abc123:SELECT * FROM Users WHERE id = ?
-- Execution count: 2噪声滤波
默认排除模式(当 excludeNoise=true):
sp_reset_connection--连接池重置SET TRANSACTION ISOLATION LEVEL--会话设置SET NOCOUNT,SET ANSI_*--客户端配置sp_trace_*,fn_trace_*--跟踪系统查询
支持的事件类型
SqlBatchCompleted, RpcCompleted, SqlStatementCompleted, SpStatementCompleted, Attention, ErrorReported, Deadlock, BlockedProcess, LoginEvent, SchemaChange, Recompile, AutoStats
项目结构
sql-profiler-mcp/
├── .github/
│ └── workflows/
│ ├── docker.yml # Build & push multi-arch Docker images
│ └── publish-mcp-registry.yml # Publish NuGet + MCP registry
├── .mcp/
│ └── server.json # MCP manifest (NuGet + OCI packages)
├── SqlServer.Profiler.Mcp/ # Main MCP server (stdio transport)
│ ├── SqlServer.Profiler.Mcp.csproj
│ ├── Program.cs # Entry point, DI setup, MCP config
│ ├── Models/
│ │ ├── ProfilerModels.cs # Records, enums, data models
│ │ └── DbOperationResult.cs # Result model for CRUD operations
│ ├── Services/
│ │ ├── ProfilerService.cs # Core Extended Events logic
│ │ ├── QueryFingerprintService.cs # SQL normalization & fingerprinting
│ │ ├── WaitStatsService.cs # DMV-based wait stats analysis
│ │ ├── SessionConfigStore.cs # In-memory session config storage
│ │ └── EventStreamingService.cs # Real-time event streaming
│ ├── Utilities/
│ │ └── SqlInputValidator.cs # SQL input validation & escaping
│ └── Tools/
│ ├── SessionManagementTools.cs # Session lifecycle tools (6)
│ ├── EventRetrievalTools.cs # Event retrieval tools (5)
│ ├── DiagnosticTools.cs # Diagnostic tools (4)
│ ├── PermissionTools.cs # Permission tools (2)
│ └── DatabaseTools.cs # Database CRUD tools (7)
├── SqlServer.Profiler.Mcp.Api/ # Debug REST API (Swagger on port 5100)
│ ├── SqlServer.Profiler.Mcp.Api.csproj
│ ├── Program.cs
│ ├── Controllers/
│ │ └── ProfilerController.cs
│ ├── Models/
│ │ └── RequestModels.cs
│ └── appsettings.json
├── SqlServer.Profiler.Mcp.Cli/ # Debug CLI (REPL + script mode)
│ ├── SqlServer.Profiler.Mcp.Cli.csproj
│ └── Program.cs
├── SqlServer.Profiler.Mcp.Tests/ # xUnit tests for core MCP library (228 tests)
│ └── ...
├── SqlServer.Profiler.Mcp.Api.Tests/ # xUnit tests for API project (29 tests)
│ └── ...
├── Dockerfile # Multi-stage build (bookworm-slim)
├── .dockerignore
├── SqlServer.Profiler.Mcp.slnx # Solution file
├── CLAUDE.md
├── CONTRIBUTING.md
└── README.md发展
先决条件
- .NET 9 SDK
- SQL Server 2012+实例(本地、Docker或远程)
- Docker(可选,用于容器构建)
克隆和构建
git clone https://github.com/tkmawarire/sql-sentinel.git
cd sql-sentinel
dotnet restore
dotnet build在本地运行MCP服务器
dotnet run --project SqlServer.Profiler.Mcp/服务器使用MCP协议通过stdio进行通信。将其连接到MCP客户端(Claude Desktop、Claude Code等)进行交互使用。
使用调试API
API项目为所有MCP工具提供了一个REST包装器,带有Swagger UI用于手动测试。
dotnet run --project SqlServer.Profiler.Mcp.Api/- Swagger用户界面:
http://localhost:5100/ - 通过环境变量配置连接字符串
SQL_SENTINEL_CONNECTION_STRING
使用调试CLI
CLI项目为直接测试工具提供了交互式REPL和脚本模式。
# Interactive REPL mode
dotnet run --project SqlServer.Profiler.Mcp.Cli/
# List all available tools
dotnet run --project SqlServer.Profiler.Mcp.Cli/ list
# Get help for a specific tool
dotnet run --project SqlServer.Profiler.Mcp.Cli/ help sqlsentinel_quick_capture
# Execute a single tool
dotnet run --project SqlServer.Profiler.Mcp.Cli/ call sqlsentinel_list_sessions设置 SQL_SENTINEL_CONNECTION_STRING 运行前的环境变量。
Docker构建
docker build -t sql-sentinel-mcp:test .
docker run -i --rm --network host sql-sentinel-mcp:test建筑
关键模式
- 依赖注入 通过
Microsoft.Extensions.Hosting - stdio传输 --stdout为MCP协议保留;所有日志记录都会转到stderr
- 工具自动发现 --MCP工具通过以下方式从装配中发现
WithToolsFromAssembly() - XE会话前缀 --所有创建的会话都以前缀
mcp_sentinel_ - 两种事件形状 --带类型字段的标准事件(查询、登录、重新编译)和从扩展事件XML解析的XML有效负载事件(死锁、阻塞)
添加新的MCP工具
- 创建一个
public static方法在相应的文件中Tools/(或创建新文件) - 用…装饰
[McpServerTool(Name = "sqlsentinel_your_tool")]和[Description("...")] - 添加参数
[Description("...")]属性——它们成为工具的输入模式 - 通过方法参数注入服务(例如。,
IProfilerService,IWaitStatsService) - 返回一个字符串(JSON或Markdown)——框架处理MCP响应包装
[McpServerTool(Name = "sqlsentinel_example")]
[Description("Description shown to AI agents")]
public static async Task Example(
IProfilerService profilerService,
[Description("Optional filter")] string? filter = null)
{
var connectionString = ConnectionStringResolver.Resolve();
// Implementation
return JsonSerializer.Serialize(result);
}故障排除
创建会话时“权限被拒绝”
GRANT ALTER ANY EVENT SESSION TO [your_login];
GRANT VIEW SERVER STATE TO [your_login];“登录失败”
- 检查连接字符串凭据
- 对于Windows身份验证,确保进程在正确的用户下运行
- 对于Azure SQL,确保防火墙允许您的IP
未捕获事件
- 验证会话是否正在运行(
sqlsentinel_list_sessions) - 检查过滤器是否过于严格
- 验证目标数据库/应用程序是否正在生成查询
- 检查
minDurationMs没有过滤所有内容
无死锁事件
- 确保会话是通过以下方式创建的
eventTypes: "Deadlock" - 死锁必须在会话运行时实际发生
无阻塞事件
- 确保
blocked process threshold已配置:sp_configure 'blocked process threshold', 5 - 确保会话是通过以下方式创建的
eventTypes: "BlockedProcess" - 阻塞必须超过配置的阈值(秒)
读取事件超时
具有许多事件的大型环形缓冲区解析速度可能很慢。用途:
- 时间过滤器缩小窗口
- 如果需要,增加代码中的命令超时时间
安全说明
- 这
SQL_SENTINEL_CONNECTION_STRING环境变量包含凭据——适当安全 - 不要让会话在生产环境中无限期运行
- 查询文本可能包含敏感数据
- 授予所需的最低权限
贡献
看 贡献.md 有关提交问题和拉取请求的指导方针。
许可证
麻省理工学院
