archery-mcp
archery-mcp
通过 Archery 网关安全查询 MySQL / Redis / MongoDB 的 MCP Server,支持性能诊断。
数据访问路径
MCP Client (Trae/Cursor/Claude Code) -> archery-mcp (HTTP /mcp) -> Archery Web -> Database本项目不直连数据库,所有查询都通过 Archery 的 /query/ 接口执行。
功能特性
支持 MySQL / Redis / MongoDB 三种数据库查询
只读安全策略:MySQL 仅允许
SELECT/SHOW/EXPLAIN,阻塞写、DDL、多语句、会话操作和文件导出自动补 LIMIT:缺 LIMIT 的 SELECT 自动追加
预定义性能诊断集:MySQL 8 项 / Redis 9 项 / MongoDB 7 项
模拟登录:自动处理 CSRF + Cookie,session 缓存 1 小时,失效自动重登
HTTP
/mcp接口:支持多会话隔离(Mcp-Session-Id),可选 Bearer 鉴权错误信息脱敏:含
password/cookie/csrf/session/token的消息自动替换
环境要求
Node.js
>= 20npm
可访问目标 Archery 网关
安装与运行
git clone <repo-url> archery-mcp
cd archery-mcp
npm install
npm run build支持两种传输模式:stdio(默认,推荐)和 HTTP。
stdio 模式(默认)
客户端(Trae/Cursor/Claude Code)自动拉起子进程,所有配置写在 mcpServers 里,无需单独启动 server。
node dist/cli.js --archery-url https://archery.example.com --username your-user --password your-password或用环境变量:
export ARCHERY_BASE_URL=https://archery.example.com
export ARCHERY_LOGIN_USERNAME=your-user
export ARCHERY_LOGIN_PASSWORD=your-password
node dist/cli.jsstdio 模式下凭证不暴露在进程列表(ps aux)里,相对安全。
HTTP 模式
适合多客户端共享同一个 server,需要单独启动:
export ARCHERY_LOGIN_USERNAME="your-archery-user"
export ARCHERY_LOGIN_PASSWORD="your-archery-password"
node dist/cli.js --transport http --port 8080默认监听 127.0.0.1:8080。如需开放给内网,显式指定 host:
node dist/cli.js --transport http --host 0.0.0.0 --port 8080环境变量
变量 | 必需 | 默认值 | 说明 |
| 是 | - | Archery 网关地址 |
| 是 | - | Archery 登录用户名 |
| 是 | - | Archery 登录密码 |
| 否 |
| Archery 查询接口路径 |
| 否 |
| 缺省 LIMIT |
| 否 |
| 最大 LIMIT |
| 否 | 空 | 实例白名单,逗号分隔 |
| 否 | 空 | 数据库白名单 |
| 否 | 空 | 阻塞表名片段 |
| 否 |
| HTTP 监听地址(HTTP 模式) |
| 否 |
| HTTP 监听端口(HTTP 模式) |
| 否 | 空 |
|
| 否 | 空 | 黑名单:禁止访问的 Archery 地址,逗号分隔 |
| 否 | 空 | 黑名单:禁止使用的 Archery 用户名,逗号分隔 |
| 否 | 空 | 黑名单:JSON 文件路径,未设置时自动查找 |
CLI 参数会覆盖同名环境变量。完整参数列表见 node dist/cli.js --help。
黑名单配置
用于禁止特定 Archery 地址或用户名访问本服务。启动时会校验,命中黑名单则拒绝启动:
# 禁止访问生产环境 Archery
export ARCHERY_BLOCKED_URLS="https://archery-prod.example.com,https://archery-prod2.example.com"
# 禁止某些用户名
export ARCHERY_BLOCKED_USERNAMES="admin,root,sa"
# 然后正常启动
node dist/cli.js从文件读取(推荐用于较长黑名单)
当黑名单条目较多时,可改用 JSON 文件维护。文件查找优先级:
CLI 参数
--blacklist-file <path>(最高)环境变量
ARCHERY_BLACKLIST_FILE自动发现:当前工作目录(项目根)下的
./blacklist.json(最低)
// blacklist.json
{
"urls": [
"https://archery-prod.example.com",
"https://archery-prod2.example.com/"
],
"usernames": ["admin", "root", "sa"]
}# 方式一:在项目根放置 blacklist.json,自动发现(无需任何参数)
node dist/cli.js
# 方式二:环境变量指定路径
export ARCHERY_BLACKLIST_FILE="/path/to/blacklist.json"
node dist/cli.js
# 方式三:CLI 参数(覆盖环境变量与自动发现)
node dist/cli.js --blacklist-file /path/to/blacklist.json说明:
urls与usernames均为可选字段,缺失视为空数组;文件中未知字段会被忽略。自动发现的
./blacklist.json是可选的:不存在则忽略(不报错),存在则必须为合法 JSON,否则启动失败(fail-fast)。显式指定的路径(CLI/env)必须存在,否则启动失败。
文件与
ARCHERY_BLOCKED_URLS/ARCHERY_BLOCKED_USERNAMES环境变量会合并去重(非互斥)。典型用法:文件维护长期黑名单,环境变量临时追加屏蔽项。下方「匹配规则」对两种来源都生效。
文件读取/解析失败会直接拒绝启动(fail-fast),错误信息会包含文件路径。
匹配规则:
URL:不区分大小写,自动忽略末尾
/,精确匹配用户名:不区分大小写,精确匹配
两者命中任一即拒绝
客户端配置示例
stdio 模式(推荐)
Trae / Cursor / Claude Code
{
"mcpServers": {
"archery": {
"command": "node",
"args": [
"/absolute/path/to/archery-mcp/dist/cli.js"
],
"env": {
"ARCHERY_BASE_URL": "https://archery.example.com",
"ARCHERY_LOGIN_USERNAME": "your-archery-user",
"ARCHERY_LOGIN_PASSWORD": "your-archery-password"
}
}
}
}或用 CLI 参数传凭证(更直观,但密码会出现在进程列表):
{
"mcpServers": {
"archery": {
"command": "node",
"args": [
"/absolute/path/to/archery-mcp/dist/cli.js",
"--archery-url", "https://archery.example.com",
"--username", "your-archery-user",
"--password", "your-archery-password"
]
}
}
}stdio 模式不需要 --transport 参数(默认就是 stdio)。凭证只在该子进程内可见,不会污染全局环境。
HTTP 模式
Trae / Cursor
{
"mcpServers": {
"archery": {
"type": "http",
"url": "http://localhost:8080/mcp",
"headers": {
"Authorization": "Bearer your-api-key"
}
}
}
}若未配置 ARCHERY_MCP_HTTP_API_KEY,可省略 headers。
curl 调试
# 1. initialize
curl -i -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
# 从响应头取 mcp-session-id
SID="..."
# 2. notifications/initialized
curl -X POST http://localhost:8080/mcp \
-H "mcp-session-id: $SID" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
# 3. tools/list
curl -X POST http://localhost:8080/mcp \
-H "mcp-session-id: $SID" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# 4. tools/call
curl -X POST http://localhost:8080/mcp \
-H "mcp-session-id: $SID" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"archery_run_diagnostic","arguments":{"instanceName":"prod-mysql","dbName":"mydb","diagnosticKey":"processlist"}}}'MCP 工具
工具 | 说明 |
| 列出 Archery 注册的实例,可选 |
| 列出某实例下的所有数据库 |
| 执行只读 SQL(MySQL)或诊断命令(Redis/MongoDB),自动校验和补 LIMIT |
| 读取表结构元数据 |
| 搜索查询历史摘要 |
| 运行预定义性能诊断命令 |
archery_execute_query
{
"instanceName": "prod-mysql",
"dbName": "mydb",
"sql": "SELECT * FROM users WHERE created_at > '2026-01-01'",
"limitNum": 100
}archery_run_diagnostic
{
"instanceName": "prod-redis",
"dbName": "0",
"diagnosticKey": "slowlog"
}带额外参数(MongoDB 集合诊断):
{
"instanceName": "prod-mongo",
"dbName": "mydb",
"diagnosticKey": "collection_stats",
"extraParams": { "collectionName": "users" }
}支持的诊断命令
MySQL
key | 说明 |
| 当前所有连接和正在执行的 SQL |
| 全局状态计数器 |
| 全局变量(配置) |
| InnoDB 引擎状态(锁、死锁、事务) |
| 最近 50 条慢查询 |
| 按 data_length 排序的前 50 大表 |
| 按 read 次数排序的前 50 个索引 |
| 运行超过 60 秒的查询 |
| 当前 InnoDB 行锁和等待事务 |
Redis
注意:Archery 的 Redis 引擎有
safe_cmd白名单,只允许查询类命令。SLOWLOG、CLIENT LIST、CONFIG GET等性能诊断命令会被 Archery 拒绝(返回"禁止执行该命令!")。因此 Redis 诊断以 key 查询为主。
key | 说明 | 需要参数 |
| Redis INFO 输出(部分 Archery 版本可能禁用) | - |
| 扫描当前 DB 的 key(前 100 个) | - |
| 查看指定 key 的类型 |
|
| 查看指定 key 的 TTL(秒) |
|
| 检查 key 是否存在 |
|
| 获取 string 类型 key 的值 |
|
| 获取 string 类型 key 的值长度 |
|
| 获取 hash key 的所有字段和值 |
|
| 获取 hash key 的字段数量 |
|
| 获取 list key 的长度 |
|
| 获取 list key 的前 50 个元素 |
|
| 获取 set key 的所有成员 |
|
| 获取 set key 的成员数量 |
|
| 获取 zset key 的前 50 个成员(带 score) |
|
| 获取 zset key 的成员数量 |
|
MongoDB
key | 说明 |
| 服务器状态概览 |
| 当前活跃操作 |
| system.profile 中最近 50 条慢查询 |
| 连接统计 |
| 指定 collection 的统计(需 |
| 指定 collection 的索引使用统计(需 |
| 数据库级别统计 |
安全说明
只读:MySQL 仅允许
SELECT/SHOW/EXPLAIN,Redis 阻塞CONFIG SET,MongoDB 阻塞insert/update/remove/drop等写操作凭证安全:username/password 只从环境变量读取,不写日志、不返回给 AI
错误脱敏:含敏感关键词的 Archery 错误消息会被替换为通用提示
会话隔离:HTTP
/mcp每个Mcp-Session-Id独立,session cookie 进程内存缓存 1 小时默认本机:HTTP 默认监听
127.0.0.1,仅当显式--host 0.0.0.0时开放外网;建议配合ARCHERY_MCP_HTTP_API_KEY使用
开发
npm run typecheck # 类型检查
npm run build # 构建
npm test # 运行单元测试
npm run start:http # 启动 HTTP 服务目录结构:
src/
├── archeryClient.ts # Archery HTTP 客户端
├── archeryForms.ts # 表单构造
├── archeryHttpSupport.ts # CookieJar、CSRF 提取
├── archeryMappers.ts # 响应映射
├── archerySession.ts # 模拟登录
├── cli.ts # CLI 入口
├── config.ts # 环境变量加载
├── diagnostics.ts # 诊断命令集
├── httpServer.ts # HTTP /mcp 服务
├── mcpServer.ts # MCP 工具注册
├── policy.ts # 只读 SQL 策略
├── services.ts # 依赖容器
└── tools.ts # 工具 schema + 分发License
MIT