Ocarina 完全指南:用 YAML 为 MCP 服务器编写可重现的自动化测试
MCP(Model Context Protocol)生态正在急速膨胀——GitHub MCP、SQLite MCP、Playwright MCP、Docker MCP……成千上万个服务器通过标准化的 typed tools 对外提供服务。但一个现实问题随之而来:你怎么测试这些 MCP 服务器?
每次测试都靠 AI Agent 去调用?不——Agent 的响应有随机性、有 token 成本、且不可重现。你需要的是一种确定性的、可版本控制的、零 AI 成本的自动化方式。
这就是 Ocarina(MIT 许可,Go 编写)要解决的问题。它把 Ansible 式的自动化哲学带到了 MCP 世界:写一份 YAML 剧本(Rondo),在任意环境回放,每次结果完全一致,零 LLM 参与。
安装 Ocarina
Ocarina 的核心是一个 Go 二进制,安装非常简单:
go install github.com/msradam/ocarina@latest
如果本地有 Go 1.26+ 环境,这条命令会在 $GOPATH/bin 下安装 ocarina。也可以从 GitHub Releases 下载预编译的二进制文件。
验证安装:
ocarina --help
如果看到 play, docs, validate, record, hum, diff, lock 等子命令列表,安装成功。
Rondo 是什么?
Ocarina 的核心理念是 Rondo——一个 YAML 文件,描述对 MCP 服务器的一系列操作步骤。每个步骤可以:
- 调用一个工具(
tool) - 读取一个资源(
resource) - 对输出做断言检查(
expect) - 捕获输出值供后续步骤使用(
echo+grab)
一个最简单的 “Hello World” Rondo:
server:
command: uvx
args: [mcp-server-time]
rondo:
- name: get current time
tool: get_current_time
args:
timezone: UTC
expect:
contains: "UTC"
这个 Rondo 启动 mcp-server-time,调用 get_current_time 获取当前时间,然后断言输出包含”UTC”。
核心子命令详解
Ocarina 提供了 7 个主要子命令,覆盖了 MCP 服务器自动化从开发到 CI 的完整流程:
ocarina docs — 生成文档
想快速了解一个 MCP 服务器暴露了哪些工具和资源?
ocarina docs uvx mcp-server-sqlite --db-path mydb.sqlite ocarina docs npx -y @modelcontextprotocol/server-github > docs/github.md
docs 子命令扫描服务器的所有 tools、resources、resource templates,输出一份格式化的 Markdown 文档。
ocarina play — 执行 Rondo
这是最常用的命令:
ocarina play db-audit.yaml ocarina play db-audit.yaml --dry-run ocarina play db-audit.yaml --output json ocarina play db-audit.yaml -e db=/tmp/other.sqlite
--dry-run:预演模式,不实际执行工具调用,只校验 YAML 格式和变量引用--output json:输出机器可读的 JSON 报告-e key=value:运行时覆盖环境变量/keys
ocarina validate — 预检 Rondo
在不实际连接服务器的情况下,检查 Rondo 中的工具名、参数类型、变量引用是否合法:
ocarina validate db-audit.yaml
输出非零退出码表示校验失败。这个命令非常适合在 CI 的 lint 阶段使用。
ocarina diff — 版本差异检测
当一个 MCP 服务器更新了它的工具定义,Rondo 可能需要调整:
ocarina diff db-audit.yaml
比对 Rondo 中引用的工具和服务器当前 schema 的差异。
ocarina lock — 锁定 Schema
将服务器当前的工具 schema 快照到锁文件:
ocarina lock db-audit.yaml ocarina lock db-audit.yaml --check
--check 模式比对当前服务器 schema 和锁文件——如果工具有新增、重命名或参数变更,退出码非零。这就把 schema drift 变成了一个可检测的信号。
ocarina hum — 快速调用单工具
想在不写 YAML 的情况下,直接调用 MCP 服务器的某个工具?
ocarina hum uvx mcp-server-sqlite --db-path mydb.sqlite -- query "SELECT COUNT(*) FROM users"
或者配合 .mcp.json 配置文件:
ocarina hum github -- list_commits owner=pytorch repo=pytorch per_page=1
ocarina record — 录制 Rondo
这是最有意思的功能:代理模式录制。启动一个代理,让真实的 AI Agent 去调用 MCP 服务器,Ocarina 把所有工具调用录制成一个 Rondo 文件:
ocarina record my-workflow.yaml uvx mcp-server-sqlite --db-path mydb.sqlite
之后,这个 Rondo 可以脱离 AI Agent 独立回放——不需要任何 LLM,每次结果一致。
Rondo 进阶语法
变量插值与传递
keys:
owner: pytorch
repo: pytorch
server:
command: npx
args: [-y, "@modelcontextprotocol/server-github"]
rondo:
- name: recent commits
tool: list_commits
args:
owner: "{{owner}}"
repo: "{{repo}}"
grab: ".0.sha"
echo: latest_sha
- name: commit detail
tool: get_commit
args:
owner: "{{owner}}"
repo: "{{repo}}"
sha: "{{latest_sha}}"
expect:
contains: "feat"
关键特性:
{{key}}从keys:节或之前的echo捕获中取值grab: ".0.sha"用 dot-path 从 JSON 输出中提取值——.0.sha表示取数组第一个元素的sha字段echo: latest_sha将 grab 的值存储到 latest_sha 变量,供后续步骤使用{{env.NAME}}从进程环境变量取值
多服务器编排
一个 Rondo 可以同时与多个 MCP 服务器交互:
servers:
time: { command: uvx, args: [mcp-server-time] }
fetch: { command: uvx, args: [-y, "@modelcontextprotocol/server-fetch"] }
rondo:
- name: get time
server: time
tool: get_current_time
args: { timezone: UTC }
echo: current_time
- name: fetch page
server: fetch
tool: fetch
args: { url: "https://example.com" }
expect:
contains: "Example Domain"
循环与分支
rondo:
- name: check each repo
loop: "{{repos}}"
tool: list_issues
args:
owner: "{{item.owner}}"
repo: "{{item.name}}"
expect:
contains: "open"
loop 展开一个 JSON 数组,每次迭代将当前元素注入 {{item}},配合 ignore_errors 可以容忍部分步骤失败。
远程 HTTP 服务器
不只支持本地进程——通过 url: 连接远程 MCP 服务器(Streamable HTTP 传输):
server:
url: https://api.example.com/mcp/
headers:
Authorization: "Bearer {{env.API_TOKEN}}"
rondo:
- name: query data
tool: query_database
args: { sql: "SELECT count(*) FROM users" }
CI 集成:把 Rondo 变成自动化测试
Ocarina 的 play 命令退出码直接反映断言结果——所有 expect: 通过则退出 0,否则退出非零。这意味着它可以无缝嵌入任何 CI 流水线。
GitHub Actions 示例:
name: MCP Health Check
on: [push, schedule]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Ocarina
uses: msradam/ocarina@v1
with:
rondo: tests/db-audit.yaml
Ocarina 官方提供了 50+ 个实战 Rondo 示例,涵盖 SQLite、PostgreSQL、Docker、Elasticsearch、Playwright、Yahoo Finance 等常用 MCP 服务器。
实际使用场景
1. 数据库迁移验证
用 SQLite MCP 服务器编写数据质量断言——schema 变更后自动检查行数、参照完整性:
rondo:
- name: check row count
tool: read_query
args: { query: "SELECT COUNT(*) as cnt FROM users" }
expect:
contains: "1500"
2. GitHub 仓库治理
检查每个仓库是否包含 LICENSE 文件、README、和最近的提交记录。适合大型组织做合规检查。
3. API 端点监控
通过 server-fetch 定期检查外部 URL 的可达性和响应内容,替代简单的 curl 健康检查。
总结
Ocarina 的定位非常清晰:MCP 生态的 Ansible。它不试图替代 AI Agent 对 MCP 服务器的调用,而是在”需要确定性”的场景下提供一条互补的路径——CI 测试、Schema 漂移检测、数据一致性验证、仓库合规审计。
如果你已经在使用 MCP 服务器(无论是本地的 SQLite 还是云端 API),Ocarina 值得一试。它让 MCP 自动化变得像写 YAML 一样简单,更重要的是——每一次执行,都能得到完全相同的答案。
相关链接: