2026年6月29日 3 分钟阅读

Ocarina 完全指南:用 YAML 为 MCP 服务器编写可重现的自动化测试

tinyash 0 条评论

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 一样简单,更重要的是——每一次执行,都能得到完全相同的答案。

相关链接:

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。