RitikPatill/mcp-test-bench

GitHub: RitikPatill/mcp-test-bench

一款开源的 MCP 服务器评估工具,通过自动化场景测试、LLM 评分及安全扫描来量化衡量服务器在配合 AI 代理时的功能表现与安全风险。

Stars: 0 | Forks: 0

# MCP Test Bench ![截图占位符](https://static.pigsec.cn/wp-content/uploads/repos/cas/6b/6b7fa434f92a8b80aab02d9bf1a12e49ffcae424e4013a1c4f68b67e3d2bbcd0.png) ## 功能简介 MCP Test Bench 是一个本地、开源的 [Model Context Protocol](https://modelcontextprotocol.io) 服务器评估工具。将其指向任何 MCP 服务器(stdio 命令或 SSE URL),它就会: 1. **发现**服务器暴露的每个 tool、resource 和 prompt。 2. **生成**使用 Claude 根据 tool schema 构建的真实测试场景。 3. **执行**这些场景,通过 MCP 服务器驱动 Claude 作为 agent 运行,并记录每次 tool 调用和响应。 4. **评判**每次运行,使用 LLM-as-judge 针对可配置的 rubric 进行评估(正确性、tool 选择准确度、效率、安全性)。 5. **审计**服务器的常见安全问题:tool 描述中的 prompt-injection、无限制输出、PII 泄露、缺少确认机制的危险副作用 tool。 6. **可视化**将一切呈现在 Next.js dashboard 中——包括运行历史记录、trace 时间线、tool 调用差异对比、安全发现以及各服务器排名。 ## 诞生初衷 MCP 生态正在爆炸式增长,但目前还没有一个通用的方法来回答:*这个 MCP 服务器与 LLM agent 配合得真的好吗?*以及*安装它安全吗?*现在大家的评判标准仅仅是“凭感觉”。Test Bench 将其转化为可重复的得分,并提供供您审查的 trace 记录。 ## 功能 | 功能 | 状态 | |---|---| | 基于 pnpm monorepo 与 Turborepo 构建流水线 | **M1** ✅ | | Next.js 15 App Router + Tailwind + shadcn/ui 初始示例 | **M1** ✅ | | 所有 package 启用 TypeScript 严格模式 | **M1** ✅ | | Vitest 测试框架 (`packages/core`) | **M1** ✅ | | 全工作区强制执行 ESLint + Prettier | **M1** ✅ | | stdio + SSE MCP 服务器连接 | **M2** ✅ | | Tool / resource / prompt 发现 | **M2** ✅ | | SQLite 持久化,零基础设施 | **M2** ✅ | | Claude agent 循环与实时 SSE trace 流式传输 | **M3** ✅ | | `runScenario` 异步生成器 + SQLite turn 记录 | **M3** ✅ | | `McpSession` 跨 turn 持久化 MCP 连接 | **M3** ✅ | | `/runs/[id]` trace 时间线页面(实时 + 回放) | **M3** ✅ | | LLM-as-judge 评分(4 个内置 rubric) | **M4** ✅ | | 运行页面上的雷达图及各维度评判推理 | **M4** ✅ | | 自动生成的测试场景 | **M5** ✅ | | 带有标签过滤器(happy-path/edge/adversarial)的场景浏览器 | **M5** ✅ | | 带有 schema 折叠面板的服务器详情页 | **M5** ✅ | | 主页服务器列表 + 添加服务器表单 | **M5** ✅ | | 安全扫描器(静态 + 运行时) | **M6** ✅ | | 各服务器的安全选项卡(发现列表 + 扫描按钮) | **M6** ✅ | | `findings` 数据库表,包含严重性/类别/修复建议 | **M6** ✅ | | `POST /api/servers/[id]/scan` + `GET` findings 路由 | **M6** ✅ | | 主页服务器表格,包含得分、迷你图、通过率、发现结果 | **M7** ✅ | | 服务器对比视图 (`/compare?ids=...`) 及 rubric 柱状图 | **M7** ✅ | | 各服务器的运行选项卡,支持标签 + 状态过滤 | **M7** ✅ | | 深色模式切换 (next-themes, `prefers-color-scheme`) | **M7** ✅ | | `GET /api/servers/[id]/stats` · `GET /api/servers/[id]/runs` · `GET /api/compare` | **M7** ✅ | | 针对三个新 API 路由的 Vitest 测试 | **M7** ✅ | | `mcpbench run ` CLI 及基线退出代码 | **M8** ✅ | | `mcpbench report --format json\|junit` 用于 CI pipeline | **M8** ✅ | | 包含 JUnit 报告上传的 GitHub Actions 示例工作流 | **M8** ✅ | ## 架构 ``` flowchart LR UI[Next.js Dashboard] -->|REST/SSE| API[API Routes] API --> Runner[Eval Runner] API --> DB[(SQLite)] Runner --> MCPClient[MCP Client stdio + SSE] Runner --> Agent[Claude Agent Loop] Runner --> Judge[LLM-as-Judge] Runner --> Scanner[Security Scanner] MCPClient -.spawns.-> Target[Target MCP Server] Agent --> Anthropic[Anthropic API] Judge --> Anthropic ``` ### Packages - `packages/core` — `discoverServer()` MCP 客户端,`McpSession` 长连接,`runScenario()` Claude agent 循环,`judgeRun()` LLM-as-judge(4 个内置 rubric),`generateScenarios()` 基于 Claude 的场景生成器,`scanServer()` 安全扫描器(针对 prompt-injection 模式、无限制输出 tool 和未经确认的破坏性 tool 进行静态检查;对 PII 和 injection 进行运行时输出扫描),`getDbReady()` SQLite 辅助函数 (libsql + drizzle-orm),共享类型 - `apps/web` — Next.js 15 App Router dashboard;`GET /api/servers` 列出服务器,`POST /api/servers` 注册并发现服务器,`GET /api/servers/[id]` 返回服务器详情,`GET /api/servers/[id]/stats` 返回最新得分、迷你图、通过率及发现计数,`POST /api/servers/[id]/generate-scenarios` 使用 Claude 生成 N 个测试场景,`GET /api/servers/[id]/scenarios` 列出场景(按标签过滤),`POST /api/servers/[id]/scenarios` 创建手动场景,`GET /api/servers/[id]/runs` 列出带有可选标签/状态过滤器的运行记录,`POST /api/servers/[id]/scan` 运行安全扫描器并保存发现结果,`GET /api/servers/[id]/scan` 返回现有发现,`GET /api/compare?ids=...` 返回 2-3 个服务器的对比数据,`POST /api/runs` 触发评估运行,`GET /api/runs/[id]` 返回运行记录及 turn,`GET /api/runs/[id]/stream` 以 SSE 流式传输 `RunEvent`,`/servers/[id]` 显示服务器详情 + 场景浏览器 + 安全选项卡 + 带有标签/状态过滤器的运行选项卡,`/runs/[id]` 显示实时 trace 时间线,`/compare?ids=...` 显示所选服务器的按 rubric 分组的柱状图 - `apps/cli` — `mcpbench` CLI 二进制文件;`run ` 连接到 MCP 服务器,发现 tool,自动生成或加载 YAML 场景,通过 agent 循环运行它们,评判每次运行,扫描安全发现,并在得分低于配置的基线时以非零状态退出;`report --format json|junit` 从 SQLite 读取上次运行记录并输出机器可读的 CI 报告 构建任务由 [Turborepo](https://turbo.build) 统筹管理(仓库根目录下的 `turbo.json`)。 ## 快速开始 ``` git clone https://github.com/your-org/mcp-test-bench cd mcp-test-bench pnpm install cp .env.example .env # set DATABASE_PATH (optional) and ANTHROPIC_API_KEY (required M3+) pnpm dev # starts Next.js on localhost:3000 ``` ### 环境要求 - Node.js ≥ 20 - pnpm ≥ 9 - 一个 [Anthropic API key](https://console.anthropic.com)(从 M3 阶段开始,场景生成和评判均需要此密钥) ## 开发 ``` pnpm build # build all packages pnpm test # run all tests (Vitest) pnpm lint # ESLint across all packages pnpm format # Prettier format ``` 运行单个 package: ``` pnpm --filter @mcp-test-bench/core test pnpm --filter @mcp-test-bench/web dev pnpm --filter @mcp-test-bench/cli test ``` ## CLI (`mcpbench`) 执行 `pnpm build` 后,可以从 `apps/cli/dist/index.js` 调用 `mcpbench` 二进制文件(或者执行 `npm link` 后全局调用)。 ``` # 运行完整评估 ANTHROPIC_API_KEY=sk-... mcpbench run examples/ci/mcpbench-config.yaml --db eval.db # 如果平均分降至 6.0 以下则中断 build mcpbench run examples/ci/mcpbench-config.yaml --baseline 6.0 # 跳过 security scanner mcpbench run examples/ci/mcpbench-config.yaml --no-scan # 将上次运行导出为 JSON mcpbench report --db eval.db # 导出为适用于 CI 的 JUnit XML mcpbench report --format junit --db eval.db --output junit-report.xml ``` ### 配置文件格式 (`mcpbench-config.yaml`) ``` server: name: my-server # stable ID across runs (accumulates history) type: stdio # or sse command: npx args: ["-y", "@modelcontextprotocol/server-everything"] rubric: general # general | filesystem | data-retrieval | code-execution scenarios: generate: 10 # auto-generate with Claude; or use `file: path/to/scenarios.yaml` baseline: score: 6.0 # exit 1 if mean score falls below this (0-10 scale) ``` ### GitHub Actions 集成 ## 路线图 | 里程碑 | 描述 | |---|---| | **M1** ✅ | pnpm + Turborepo monorepo 脚手架;Next.js 15 + Tailwind + shadcn/ui 初始示例;TypeScript 严格模式;Vitest;ESLint;Prettier;`.env.example` | | **M2** ✅ | `discoverServer()` 封装 `@modelcontextprotocol/sdk` 以支持 stdio + SSE;规范化的 `DiscoveredSchema`;通过 `@libsql/client` + drizzle-orm 实现 SQLite;`POST /api/servers` 路由;针对 `server-everything` 的集成测试 | | **M3** ✅ | `runScenario()` Claude agent 循环 (`@anthropic-ai/sdk`);`McpSession` 持久化 MCP 连接;`scenarios`/`runs`/`turns` 数据库表;通过进程内 broker 进行 SSE 流式传输;`/runs/[id]` trace 时间线及实时 `EventSource` 更新 | | **M4** ✅ | `judgeRun()` 使用 `claude-haiku-4-5-20251001` 的 LLM-as-judge;4 个内置 rubric(general、filesystem、data\_retrieval、code\_execution);`judgements` 数据库表;运行页面上的雷达图及各维度评判推理 | | **M5** ✅ | `generateScenarios()` 位于 `packages/core`:提示 Claude 从发现的 schema 生成 N 个场景(happy-path、edge-case、adversarial、multi-tool),去重,并作为 `Scenario` 行持久化保存;`POST /api/servers/[id]/generate-scenarios` API 路由;`/servers/[id]` 服务器详情页面,包含 schema 折叠面板和“生成场景”按钮;支持基于标签过滤的场景浏览器;带有添加服务器表单的主页服务器列表 | | **M6** ✅ | `packages/core/scanner`:静态检查用于检测 prompt-injection 模式(隐藏指令、base64 数据块、根据 CyberArk “Poison Everywhere”研究得出的越狱短语)、无限制输出 tool,以及缺乏确认语义的破坏性 tool;运行时 hook 在运行期间标记可疑的 tool 输出;`findings` 数据库表包含严重性(`info`/`warn`/`critical`)、类别和修复说明;`POST /api/servers/[id]/scan` + `GET` findings 路由;各服务器的安全选项卡,包含发现列表、严重性徽章和扫描按钮;基于 Damn Vulnerable MCP server 测试用例的测试 fixtures | | **M7** ✅ | Dashboard 对比 + 历史记录:主页服务器表格带有最新得分徽章、recharts 迷你图、通过率 % 以及按严重性区分颜色的发现计数;每行上的 Compare 复选框带有置顶的 `CompareBar`;`/compare?ids=...` 页面带有按 rubric 分组的柱状图和汇总表格;服务器详情页面上的运行选项卡带有标签 + 状态下拉过滤器;`GET /api/servers/[id]/stats`、`GET /api/servers/[id]/runs`、`GET /api/compare` API 路由;通过 `next-themes` 实现深色模式切换;Skeleton/Select shadcn 组件;针对所有三个新 API 路由的 Vitest 单元测试 | | **M8** ✅ | `apps/cli`:`mcpbench run ` 驱动完整的评估循环(发现 -> 生成/加载场景 -> 运行 -> 评判 -> 扫描),并在得分倒退或发现严重问题时以状态码 1 退出;`mcpbench report --format json|junit` 导出上次运行以供 CI 使用;经 Zod 校验的 YAML 配置,包含 `server`、`rubric`、`scenarios` 和 `baseline`;带有 shebang 的 `tsup` 构建;`examples/ci/` 中的 GitHub Actions 示例工作流;针对配置 schema + JUnit XML 格式化程序的单元测试 | ## 许可证 [MIT](LICENSE)
标签:自动化攻击