MCP服务器自动化测试工具

一个通过YAML文件定义请求和响应来测试MCP服务器的简单工具,支持语言无关的测试和动态匹配。

  • by strowk
  • Go
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 strowk/mcp-autotest

使用说明

Autotest MCP servers in a language-agnostic way


mcp-autotest

Installation ⚙ Usage ⚙ Quick Demo ⚙ Dynamic Matching

一个简单的工具,通过定义包含请求和响应的YAML文件,允许使用MCP协议测试您的MCP服务器。

MCP案例文件是一个多文档的YAML,它将每个案例定义为一个单独的文档,如下所示:

case: Listing tools
in: { "jsonrpc": "2.0", "method": "tools/list", "id": 1 }
out:
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result":
      {
        "tools":
          [
            {
              "description": "Run a read-only SQL query",
              "inputSchema":
                {
                  "type": "object",
                  "properties": { "sql": { "type": "string" } },
                },
              "name": "query",
            },
          ],
      }
  }

---
# next case...

文件必须命名为 _test.yaml 后缀被识别为测试用例文件。

安装

npm

npm install -g mcp-autotest

Github发布

从 发布 页面并放入您的PATH

从源代码构建

go install github.com/strowk/mcp-autotest@latest

用法

mcp-autotest [flags] run path/to/tests/folder [--] command-to-run-server [server-args]

例子:

# start go MCP server and test via stdio transport
mcp-autotest run testdata go run main.go
# start Postgres MCP server and test via stdio transport
mcp-autotest run -v testdata -- npx -y @modelcontextprotocol/server-postgres localhost:5432
# start go MCP server and test via Streamable HTTP transport
mcp-autotest run --url http://localhost:8080/mcp testdata go run main.go

运输

默认情况下,mcp-autotest将使用stdio传输,但如果你想使用HTTP传输,你可以使用 --url 标志指定MCP服务器的URL。 URL的格式必须为 http://host:port/path 或 https://host:port/path.

目前仅来自Streamable HTTP POST 支持该方法,但通过 GET 是为未来而计划的。

快速演示

在bash shell中运行以下命令


# create folder for test data
mkdir -p testdata

# create test cases file
cat << EOF > testdata/list_tools_test.yaml
# This is a test cases file. It contains a list of test cases in YAML format.
# Each test case has variable number of inputs (keyst starting with 'in') and outputs (keys starting with 'out').
# The test cases are separated by '---' (three dashes) on a new line, making it multi-document YAML file.
# File name must end with '_test.yaml' to be recognized as a test cases file.

case: List tools

# requesting list of tools
in: { "jsonrpc": "2.0", "method": "tools/list", "id": 1 }

# expect one tool in the list
out:
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result":
      {
        "tools":
          [
            {
              "description": "Run a read-only SQL query",
              "inputSchema":
                {
                  "type": "object",
                  "properties": { "sql": { "type": "string" } },
                },
              "name": "query",
            },
          ],
      }
  }
EOF

# Now running autotest
npx mcp-autotest run testdata -- npx -y @modelcontextprotocol/server-postgres localhost:5432

输出应该只打印一个单词 PASS.

现在,如果你改变一些事情 "description": "Run a read-only SQL query",,例如 "description": "Run a read-only SQL query 2",并再次运行最后一个命令,您应该看到如下输出:

2025/03/31 22:23:39 actual json did not match expectation,
 got: '{"id":1,"jsonrpc":"2.0","result":{"tools":[{"description":"Run a read-only SQL query","inputSchema":{"properties":{"sql":{"type":"string"}},"type":"object"},"name":"query"}]}}'
 diff with expected:
  "result": {
    "tools": {
      "0": {
        "description": {
        ^ value mismatch,
expected string: 'Run a read-only SQL query 2',
     got string: 'Run a read-only SQL query'
FAIL

动态匹配

有时,当您的响应中有动态值时,您可能需要使用正则表达式来匹配它们。您可以通过使用 !!re 在您的预期输出中添加标签。例如:

case: List tools
in_list_tools: {"jsonrpc":"2.0","method":"tools/list","id":1}
out_list_tools: {"jsonrpc":"2.0","result":{"tools":[ { "name": !!re "list-[a-z]+" } ]},"id":1}

这个例子有点过于简单,实际上你可能会使用 !!re 使用时间戳、UUID或其他动态值,而不是工具名称。 然而,它确实证明了字符串 !!re 标签将被视为正则表达式,并使用正则表达式匹配而不是字符串相等性与实际值进行匹配。

请参阅工作示例进行测试 postgres服务器.

嵌入式正则表达式

嵌入式正则表达式只是嵌入在字符串中的正则表达式。它用于匹配字符串的一部分。例如:

case: List tools
in_list_tools: {"jsonrpc":"2.0","method":"tools/list","id":1}
out_list_tools: {"jsonrpc":"2.0","result":{"tools":[ { "name": !!ere "list-/[a-z]+/-tool" } ]},"id":1}

本质上 !!ere 允许您将字符串的大部分视为普通字符串,但将其一部分(或多部分)视为正则表达式。 里面的一切都是斜线 / 将被视为正则表达式,这里的“list-”和“-tool”是正则字符串,但是 [a-z]+ 是一个正则表达式,可以匹配任何小写字母非空字符串,因此它可以匹配“list abc tool”、“list xyz tool”等。

这种方法使您无需考虑如何在字符串的其余部分转义正则表达式语法,只需匹配动态所需的位。

躲避正斜杠

对于嵌入式正则表达式,您可能需要转义斜线 / 在字符串中要使用它们但不指定正则表达式的位置,例如: "url": !! "https:\\/\\/github.com\\//[a-z]+/" 将匹配 "url": "https://github.com/strowk". 在这里 \\/ 习惯成为 / 和 [a-z]+ 用于匹配任何小写字母非空字符串。有两个反斜杠的原因 \\ 因为在YAML字符串中,反斜杠是一个转义符,所以要在字符串中有一个反斜杠,你需要用另一个反斜线转义它。