使用说明
mcptest
MCP(模型上下文协议)服务器的CLI测试框架。
验证协议合规性、测试工具/资源/提示、基准性能,并确保CI/CD管道的规范合规性。
为什么存在
MCP是人工智能代理工具集成的主导协议。存在数千台MCP服务器,但 没有专门的测试框架服务器作者编写即席测试或手动测试 mcp-inspector这意味着:
- 协议合规性不完整 --缺少错误代码,格式错误的响应会悄无声息地传递
- 无回归测试 跨MCP规范版本
- 无CI/CD集成 用于MCP服务器验证
- 没有性能基准测试 用于工具调用延迟
mcptest填补了这一空白。这是 pytest 对于MCP服务器。
快速开始
安装
go install github.com/JSLEEKR/mcptest/cmd/mcptest@latest
运行所有测试
# Test a stdio MCP server
mcptest run --cmd "node server.js"
# Test a Python MCP server
mcptest run --cmd "python server.py"
# Test a Go MCP server
mcptest run --cmd "go run ./server"
# Test an SSE MCP server
mcptest run --url http://localhost:3000/sse
输出
mcptest - MCP Server Testing Framework
==================================================
Server: node server.js
Transport: stdio
Suite: compliance (9 passed, 0 failed, 0 skipped, 0 errors)
--------------------------------------------------
[PASS] initialize handshake - server: my-server v1.0.0 (0.012s)
[PASS] initialize response has protocolVersion - protocol version: 2024-11-05 (0.000s)
[PASS] initialize response has serverInfo - my-server v1.0.0 (0.000s)
[PASS] initialize response has capabilities - capabilities: [tools resources] (0.000s)
[PASS] json-rpc version is 2.0 (0.005s)
[PASS] response has valid id (0.004s)
[PASS] unknown method returns error - error code: -32601 (0.003s)
[PASS] invalid params returns error - error code: -32602 (0.003s)
[PASS] notification handling - server stable after notifications (0.004s)
Suite: tools (6 passed, 0 failed, 0 skipped, 0 errors)
--------------------------------------------------
[PASS] tools/list returns valid response - found 3 tools (0.005s)
[PASS] tools have required fields - all 3 tools have required fields (0.000s)
[PASS] tools have valid input schemas - all 3 tools have valid schemas (0.000s)
[PASS] tools/call with valid tool - tool "echo" returned 1 content items (0.008s)
[PASS] tools/call with unknown tool returns error (0.003s)
[PASS] tools/call result has valid content - tool call result content is valid (0.007s)
==================================================
20 tests: 20 passed, 0 failed, 0 skipped, 0 errors (0.15s)
RESULT: PASS
测试套件
合规套件
测试MCP协议合规性:
| 测试 | 它检查什么 |
|---|---|
| 初始化握手 | 服务器响应 initialize 结果有效 |
| 协议版本 | protocolVersion 字段存在 |
| 服务器信息 | serverInfo.name 和 serverInfo.version 存在 |
| 功能 | 服务器正确声明功能 |
| JSON-RPC版本 | 所有响应都有 jsonrpc: "2.0" |
| 响应ID | 响应ID与请求ID匹配 |
| 未知方法 | 服务器为未知方法返回正确的错误 |
| 无效参数 | 服务器返回格式错误的参数错误 |
| 通知 | 服务器在收到通知后保持稳定 |
工具套件
测试MCP工具功能:
| 测试 | 它检查什么 |
|---|---|
| tools/list | 返回包含工具定义的有效响应 |
| 必填字段 | 每个工具都有 name 和 inputSchema |
| 输入模式 | 每个 inputSchema 是有效的JSON架构 type: "object" |
| tools/call | 调用有效工具会返回内容 |
| 未知工具 | 调用不存在的工具返回错误 |
| 内容验证 | 工具调用结果具有有效的内容类型 |
资源套件
测试MCP资源功能:
| 测试 | 它检查什么 |
|---|---|
| resources/list | 返回包含资源定义的有效响应 |
| 必填字段 | 每个资源都有 uri 和 name |
| resources/read | 读取有效资源会返回内容 |
| URI无效 | 读取不存在的资源时返回错误 |
提示套房
测试MCP提示功能:
| 测试 | 它检查什么 |
|---|---|
| prompts/list | 返回带有提示定义的有效响应 |
| 必填字段 | 每个提示都有 name |
| promises/get | 获取提示将返回消息数组 |
| 未知提示 | 获取不存在的提示返回错误 |
| 消息角色 | 所有提示消息都具有有效角色(user 或 assistant) |
边缘案例套件
测试稳健性和错误处理:
| 测试 | 它检查什么 |
|---|---|
| 并发调用 | 5个同时进行的工具调用不会使服务器崩溃 |
| 大负载 | 100KB负载不会使服务器崩溃 |
| Unicode处理 | 正确处理多脚本Unicode输入 |
| 空参数 | 工具优雅地处理缺失的参数 |
| 快速顺序 | 20个快速顺序呼叫不会导致不稳定 |
| 特殊字符 | 带有特殊字符的工具名称被正确拒绝 |
CLI 参考
运行测试
# Run all default suites (compliance, tools, resources, prompts)
mcptest run --cmd "node server.js"
# Run specific suite
mcptest run --cmd "node server.js" --suite compliance
mcptest run --cmd "node server.js" --suite tools
mcptest run --cmd "node server.js" --suite edge
# Run multiple suites
mcptest run --cmd "node server.js" --suite compliance --suite tools
# Output formats
mcptest run --cmd "node server.js" --output json # JSON for CI parsing
mcptest run --cmd "node server.js" --output junit # JUnit XML for CI integration
mcptest run --cmd "node server.js" --output text # Human-readable (default)
# Custom timeout
mcptest run --cmd "node server.js" --timeout 60
# Verbose output
mcptest run --cmd "node server.js" -v
# Custom test file
mcptest run --cmd "node server.js" --file tests.yaml
基准
# Benchmark first available tool (100 iterations)
mcptest bench --cmd "node server.js"
# Benchmark specific tool
mcptest bench --cmd "node server.js" --tool echo
# Custom iterations
mcptest bench --cmd "node server.js" --iterations 500
# JSON output
mcptest bench --cmd "node server.js" --output json
基准产出
mcptest benchmark report
==================================================
Tool: echo
Iterations: 100
Concurrency: 1
Latency:
Min: 1.2ms
P50: 3.5ms
P95: 8.1ms
P99: 12.4ms
Max: 15.2ms
Mean: 4.1ms
Throughput: 243.90 calls/sec
Total time: 410ms
Errors: 0 (0.0%)
==================================================
验证
仅限快速合规性检查:
mcptest validate --cmd "node server.js"
自定义测试文件
在YAML中定义自定义测试:
tests:
- name: "echo returns input"
method: "tools/call"
params:
name: "echo"
arguments:
message: "hello world"
expect:
content:
- type: "text"
text: "hello world"
- name: "add returns sum"
method: "tools/call"
params:
name: "add"
arguments:
a: 1
b: 2
expect:
content:
- type: "text"
text: "3"
- name: "unknown tool returns error"
method: "tools/call"
params:
name: "nonexistent"
expect:
error:
code: -32602
运行方式:
mcptest run --cmd "node server.js" --file tests.yaml
CI/CD集成
GitHub 操作
name: MCP Server Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- run: go install github.com/JSLEEKR/mcptest/cmd/mcptest@latest
- run: npm install # or pip install, etc.
- run: mcptest run --cmd "node server.js" --output junit > results.xml
- uses: dorny/test-reporter@v1
if: always()
with:
name: MCP Tests
path: results.xml
reporter: java-junit
GitLab 的
mcp-test:
stage: test
script:
- go install github.com/JSLEEKR/mcptest/cmd/mcptest@latest
- mcptest run --cmd "node server.js" --output junit > results.xml
artifacts:
reports:
junit: results.xml
退出代码
| 代码 | 含义 |
|---|---|
| 0 | 所有测试均已通过 |
| 1 | 一个或多个测试失败 |
| 2 | 配置错误 |
| 3 | 服务器连接错误 |
程序化使用
使用 pkg/mcptest Go测试中的包:
package myserver_test
import (
"context"
"testing"
"github.com/JSLEEKR/mcptest/pkg/mcptest"
)
func TestMyMCPServer(t *testing.T) {
client := mcptest.NewStdioClient("go", []string{"run", "./cmd/server"})
ctx := context.Background()
if err := client.Start(ctx); err != nil {
t.Fatal(err)
}
defer client.Close()
caps, err := client.Initialize(ctx)
if err != nil {
t.Fatal(err)
}
t.Logf("Connected to %s v%s", caps.ServerInfo.Name, caps.ServerInfo.Version)
// Test tools
tools, err := client.ListTools(ctx)
if err != nil {
t.Fatal(err)
}
if err := mcptest.AssertToolExists(tools.Tools, "my-tool"); err != nil {
t.Fatal(err)
}
// Call a tool
result, err := client.CallTool(ctx, "my-tool", map[string]interface{}{
"input": "test",
})
if err != nil {
t.Fatal(err)
}
if err := mcptest.AssertContentContains(result, "expected output"); err != nil {
t.Fatal(err)
}
}
建筑
mcptest/
├── cmd/mcptest/ # CLI entrypoint
├── internal/
│ ├── protocol/ # JSON-RPC 2.0 + MCP message types & validation
│ ├── transport/ # Stdio and SSE transport implementations
│ ├── runner/ # Test runner orchestrator
│ ├── suite/ # Built-in test suites (compliance, tools, etc.)
│ ├── bench/ # Performance benchmarking
│ ├── config/ # Configuration loading (YAML/JSON)
│ └── output/ # Output formatters (text, JSON, JUnit XML)
└── pkg/mcptest/ # Public API (client, assertions, fixtures)
支持的交通工具
| 运输 | 标志 | 状态 |
|---|---|---|
| 站立 | --cmd "..." |
完全支持 |
上海证券交易所 --url "..." |
完全支持 |
MCP规范合规性
mcptest根据 MCP规范 版本 2024-11-05:
- JSON-RPC 2.0消息格式
- 通过能力协商初始化握手
- 具有JSON模式输入验证的工具定义
- 具有URI和MIME类型的资源定义
- 带参数处理的快速定义
- 标准错误代码(-32700至-32603)
- 通知处理
许可证
麻省理工学院
