把后端 OpenAPI / CLI 工具转成 agent 可加载的 skill,支持 MCP 协议。
AI agent 通过 skill 调用外部工具,skill 内部可以是 HTTP API 调用或 CLI 子进程执行。x-cli 的想法是:把后端文档(OpenAPI / CLI)变成 agent 能直接用的工具——分析、整理、生成多平台 skill 描述,agent 一加载就能调后端。
┌─► Markdown skill ← 给人读
OpenAPI ──► x parse ┼─► Anthropic skill ← Claude 系
(yaml/json) │ ├─► OpenAI tools ← function calling
│ └─► MCP skill ← MCP 协议
│ │
CLI 文档 ──► │ ┌──────┘
(agent 写 YAML) └─► x emit ──► agent 加载 skill ──► x serve ──► 后端 / CLI
- FDE 工程师:用 meta-skill + x-cli 分析后端系统(OpenAPI / CLI),封装成业务 skill,交付给业务用户
- 业务用户:加载 skill → 启动 x-cli MCP 服务 → 通过 agent 自然语言完成业务目标
- 多后端:OpenAPI(已有)+ CLI 工具统一 IR,统一 MCP 暴露
- 多步场景:用
workflow.yaml描述多步任务(带 DAG 依赖、$input / $steps 引用),agent 一次调用拿结果 - 多平台:四种输出格式(markdown / Anthropic / OpenAI tools / MCP)覆盖主流 agent 平台
npm install -g @myg133/x-cli
# 或
pnpm install -g @myg133/x-clinpm 会自动检测平台并安装对应二进制(Windows x64 / Linux x64 / macOS ARM64)。
需要 Rust 1.75+。
git clone <repo>
cd x-cli
cargo build --release
# 产物:target/release/x.exe (Windows) / target/release/x (Unix)放进 PATH 后 x 命令全局可用。
# 1. 把 OpenAPI 转成 skill(默认 markdown 格式)
x emit examples/petstore.yaml --out ./out/petstore-skill
# 2. 启动 JSON-RPC 服务(agent 调这个)
x serve --skill ./out/petstore-skill
# 3. agent 调一个 endpoint
echo '{"jsonrpc":"2.0","id":1,"method":"call","params":{
"endpoint_id":"pet__get__pets_petId",
"path_params":{"petId":"123"}
}}' | x serve --skill ./out/petstore-skill| 命令 | 作用 |
|---|---|
x parse <openapi> |
解析 OpenAPI 并打印 IR(debug 用) |
x emit <openapi> --out DIR [--workflow wf.yaml]... [--format md|anthropic|openai|mcp] [--cli-tools cli.yaml] |
生成 skill 目录 |
x serve --skill DIR [--base-url URL] |
启动 stdio JSON-RPC 服务 |
x serve --skill DIR --mcp |
启动 stdio MCP 服务(已实现) |
x serve --skill DIR --mcp --http :8080 |
后期 启动 HTTP Streamable MCP 服务 |
out/petstore-skill/
├── SKILL.md # 总索引(业务域、接口列表、调用约定)
├── endpoints/
│ ├── pet__get__pets.md
│ └── pet__get__pets_petId.md
└── .x-cli/
└── ir.json # runtime 加载用
适合:人读、agent 参考、嵌入文档站。带完整 $ref 解析后的 schema 树。
x emit examples/superset.json --out ./out/skill --format anthropic输出单个 SKILL.md,含 YAML frontmatter:
---
name: Superset
description: API 版本 1,276 个接口,覆盖 ... 当用户问及这些业务时使用此 skill。
---description 字段是关键——Claude 看这个决定何时加载 skill。
适合:Claude 系 agent(Anthropic API / Claude Code / .claude/skills/)。
x emit examples/petstore.yaml --out ./out/petstore-tools --format openai输出单个 functions.json:
{
"tools": [
{
"type": "function",
"function": {
"name": "pet__get__pets_petId",
"description": "GET /pets/{petId} — 获取一只宠物",
"parameters": {
"type": "object",
"properties": {
"petId": { "type": "string", "description": "宠物 ID" }
},
"required": ["petId"]
}
}
}
]
}适合:OpenAI function calling / ChatGPT plugins / 其他 tools 协议。
简单场景下 agent 自己串多个 endpoint 调用就行。复杂场景(创建订单 + 拿订单详情 + 调支付)用 workflow.yaml 描述,agent 一次 workflow.run 拿结果。
name: 买宠物并查询订单
description: |
1. 创建一只宠物
2. 用返回的 id 查订单
inputs:
- name: petName
type: string
default: "fluffy"
steps:
- name: create_pet
endpoint: pet__post__pets
inputs:
body:
name: "$input.petName"
- name: get_pet
endpoint: pet__get__pets_petId
inputs:
path_params:
petId: "$steps.create_pet.response.body.id"emit 时加 --workflow,serve 时不用特别处理:
x emit examples/petstore.yaml --out ./out/skill --workflow examples/petstore-workflow.yamlagent 调一次:
{
"method": "workflow.run",
"params": {
"workflow": "买宠物并查询订单",
"inputs": { "petName": "fluffy" }
}
}返回:
{
"result": {
"status": "ok",
"steps": [
{ "name": "create_pet", "endpoint": "pet__post__pets", "status": 201, "body": {...} },
{ "name": "get_pet", "endpoint": "pet__get__pets_petId", "status": 200, "body": {...} }
],
"outputs": {...} // = 最后一步 body
}
}inputs:
body:
# 1. 引用工作流外部输入
name: "$input.petName"
# 2. 引用上一步响应
petId: "$steps.create_pet.response.body.id"
# 3. 静态值(其他都算静态)
tag: "demo"数组顺序默认串行。用 depends_on 显式声明依赖 → runtime 按拓扑序执行。
name: 平行获取宠物和订单
steps:
- name: summarize
depends_on: [fetch_pet, fetch_order]
- name: fetch_pet
- name: fetch_order按拓扑序:fetch_pet + fetch_order 同层(按数组位置),summarize 在它们之后。
校验:
- 未知引用 → 拒绝
- 自依赖 → 拒绝
- 环 → 拒绝
| 码 | 含义 |
|---|---|
| -32700 | JSON 解析错误 |
| -32600 | 无效的 JSON-RPC 请求 |
| -32601 | Method 不存在 |
| -32602 | 参数不合法 |
| -32001 | 端点不存在 |
| -32002 | HTTP 错误(连接 / 超时) |
| -32010 | workflow 不存在 |
| -32011 | workflow step 失败(HTTP 4xx/5xx) |
| -32012 | workflow 缺外部输入 |
x-cli 通过 npm 分发二进制,版本号以 packages/x-cli-npm/package.json 为单一事实源。
| 文件 | 版本来源 |
|---|---|
packages/x-cli-npm/package.json |
事实源 — 手动维护 |
Cargo.toml(workspace) |
手动同步(与 npm 版本一致) |
| git tag | 手动打 v<version> |
- 更新版本号:修改
packages/x-cli-npm/package.json和Cargo.toml的 version 字段 - 提交 + 打 tag:
git commit && git tag v0.1.X - 推送:
git push --tags→ GitHub Actions CI 触发 - CI 自动:构建 3 平台二进制 → 发布到 npm → 创建 GitHub Release
详见 ci.yml。
- ✅ OAS 3.0 / 3.1 兼容(自动 3.0 → 3.1 转换:
parameters[].content→parameters[].schema) - ✅
$ref递归解析 + 循环引用 不爆栈 - ✅ 真实大文档:Apache Superset(1.27 MB / 276 endpoint / 305
$ref)0.19 秒解析 - ✅ 多 emitter:4 种格式(markdown / Anthropic / OpenAI tools / MCP),1 个 binary
- ✅ workflow DAG:依赖校验、环检测、拓扑执行
- ✅ CliSpec 解析 — FDE agent 按 schema 写 CLI 工具 YAML,x-cli 解析校验
- ✅ MCP emitter — mcp-tools.json + 服务器配置(下一阶段:MCP transport)
- ✅ 45+ 个测试,0 网络依赖(CI 友好),0.04 秒跑完
crates/
├── x-cli/ # 主二进制 x(emit / serve / parse)
├── x-cli-core/ # IR + OpenAPI/CliSpec/Workflow 解析 + protocol
├── x-cli-runtime/ # JSON-RPC/MCP transport + HTTP 客户端 + CLI exec + WorkflowExecutor
├── x-cli-emitter-md/ # markdown / anthropic / openai 三种 emitter
└── x-cli-emitter-mcp/ # MCP emitter
依赖方向:x-cli → {core, runtime, emitter-md},runtime 和 emitter 都基于 core 的 IR。
详细架构和 ABI 约定见 ARCHITECTURE.md。
# 跑全部测试
cargo test --workspace
# 跑某个 crate
cargo test -p x-cli-core
cargo test -p x-cli-emitter-md
cargo test -p x-cli-runtime
# Lint
cargo clippy --workspace
# 用真实 OpenAPI 验证
x emit examples/superset.json --out ./out/skill --format anthropicx-cli 守住的几条不变量(保证后续改造不破坏 skill ↔ x-cli 协议):
- IR 独立 crate,emitter 用 trait 抽象 — 加 emitter 不改 core
- skill ↔ x-cli 是 JSON-RPC / MCP over stdio — 不是 CLI 拼参数串,给后续 sidecar / sandbox / 多 agent 留空间
Endpoint.id稳定 — 依赖 id 匹配的已发布 skill 不会因升级中断- 错误码稳定 — agent 端 hardcode 的 JSON-RPC 错误码不会变
.x-cli/ir.json是 serve 加载 IR 的唯一入口 — 所有 emitter 必须写出这个文件
MIT OR Apache-2.0