MCP服务器测试框架

用于验证MCP协议合规性、测试工具/资源/提示、基准性能并确保CI/CD管道规范一致性的CLI测试框架。

  • by JSLEEKR
  • Go
  • 本地部署
  • 更新于
在 GitHub 查看 JSLEEKR/mcptest

使用说明

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)
  • 通知处理

许可证

麻省理工学院