
mcp2cli源码架构剖析零代码生成动态CLI生成器的单文件设计哲学【免费下载链接】mcp2cliTurn any MCP, OpenAPI, or GraphQL server into a CLI — at runtime, with zero codegen项目地址: https://gitcode.com/gh_mirrors/mc/mcp2climcp2cli 是一个零代码生成的动态 CLI 生成器它能在运行时把任意MCP 服务器、OpenAPI 规范或GraphQL 端点直接变成一条命令即可调用的命令行工具全程不产生一行生成代码。更难得的是整个核心逻辑被压缩进一个 4783 行的 Python 单文件里。这篇文章带你剖析 mcp2cli 的源码架构看看单文件设计背后的工程哲学以及它如何为 LLM Agent 节省 96–99% 的 token 开销。先看全貌一个文件装下整个项目打开项目你会发现一个有趣的事实——所有业务逻辑都在同一个文件里文件行数职责src/mcp2cli/init.py4783全部核心逻辑解析、提取、缓存、OAuth、Bakesrc/mcp2cli/main.py4仅支持python -m mcp2cli启动tests/12578覆盖 MCP、OpenAPI、GraphQL、OAuth 的测试套件单文件不是偷懒而是刻意为之零安装心智负担——依赖只有 pyproject.toml 里声明的 httpx、mcp、pyyaml 三个读源码和读文档一样快架构一目了然——数据流从文件头部流向尾部顺着读就能理解全链路单文件 ≠ 单函数——文件内用注释横幅# Data structures、# Helpers、# List commands划分出清晰的功能区块 对新手友好的一点uvx mcp2cli --help可以直接运行而无需安装源码结构也小到能在几分钟内读完主干。三步流水线从 API 定义到子命令mcp2cli 的动态 CLI 能力靠一条三步流水线实现这也是全文最值得学习的部分。第 1 步用统一的数据结构描述命令三种来源MCP / OpenAPI / GraphQL被统一建模成两个 dataclasssrc/mcp2cli/init.py#L54-L91ParamDef—— 一个 CLI 参数名称、类型、是否必填、参数位置path/query/header/body/tool_inputCommandDef—— 一个子命令名称、描述、参数列表外加来源专属字段HTTP method、MCP tool 名、GraphQL 字段名有了这层抽象后续所有逻辑都不用关心命令从哪来只关心命令长什么样。第 2 步三个提取器把原始定义翻译成 CommandDef每种来源对应一个提取函数输出完全同构提取器输入位置extract_openapi_commands已解析的 OpenAPI 规范L1421extract_mcp_commandsMCP 服务器的工具列表L1540extract_graphql_commandsGraphQL introspection 结果L1880值得注意的细节GraphQL 模式不解析 SDL而是对端点做 introspection自动生成 selection set 和参数化查询——指过去就能跑。第 3 步build_argparse 现场生成子命令build_argparsesrc/mcp2cli/init.py#L2527-L2580遍历CommandDef列表逐个创建 argparse 子解析器参数名自动转 kebab-case冲突时由_allocate_param_cli_names分配无冲突 flag布尔类型变成store_true开关带枚举的加choices校验body/tool_input 类参数故意不设为 argparse 必填——因为用户可以用--stdin从标准输入传 JSON 绕过它们这就是零代码生成的含义没有中间产物、没有临时脚本CLI 在每次运行时按需拼装用完即弃。两阶段参数解析一个隐藏得很深的巧思如果所有 flag 都在一个 argparse 里注册会踩一个坑工具参数可能和全局选项重名比如某个 API 也有--refresh参数全局解析器会把它悄悄吃掉。mcp2cli 的解法在_main_implsrc/mcp2cli/init.py#L4683-L4691pre-parser只解析全局 flag--spec/--mcp/--mcp-stdio/--graphql等_split_at_subcommand在子命令边界处把 argv 切成两半子命令之后的参数原封不动交给动态生成的子解析器这是典型的渐进式解析先确定走哪条模式分支再把剩余参数交给该分支自己处理。分支路由逻辑非常直白——GraphQL → MCP → OpenAPI各分支互斥L4716-L4779。兼容 MCP SDK 两个大版本把差异关进小黑屋MCP Python SDK 的 1.x 和 2.x 差异不小字段改名、传输函数迁移、httpx2 等。mcp2cli 声明兼容mcp1.26,3见 pyproject.toml秘诀是把全部差异收敛到不到 10 个薄封装里_mcp_attr、_mcp_dump、_streamable_streams、_list_tools_page等小函数。其余整个代码库完全不感知 SDK 版本。这是一个教科书级的防腐层anti-corruption layer实践上游怎么变改的只有那一小圈。测试设计让测试比实现更长寿测试套件tests/conftest.py 等共 1.2 万行有一个精妙之处MCP 测试 fixture直接说 JSON-RPC 线上协议完全不 import SDK。这意味着无论 mcp2cli 支持 SDK 哪个版本fixture 都能跑——测试验证的是协议不是库的 API。另有两个测试文件值得关注tests/test_cache.py —— 验证~/.cache/mcp2cli/缓存与 TTL 行为tests/test_token_savings.py —— 用 tiktoken 实测 token 节省量支撑 README 中节省 96–99%的数据新手快速上手三步验证你的理解# 1. 免安装运行查看帮助 uvx mcp2cli --help # 2. 从 OpenAPI 规范列出所有动态子命令 mcp2cli --spec https://petstore3.swagger.io/api/v3/openapi.json --list # 3. 调用其中一条命令参数由规范自动生成 mcp2cli --spec https://petstore3.swagger.io/api/v3/openapi.json list-pets --status available如果你还想让 AI 编码助手Claude Code、Cursor 等学会使用它项目自带可安装的 Skill说明文档在 skills/mcp2cli/SKILL.md。总结单文件设计哲学的三条启示抽象统一来源解耦——CommandDef/ParamDef让三种协议共用一条执行流水线新增协议只需写一个提取器差异隔离核心稳定——SDK 兼容层、缓存、OAuth、Bake 配置各自成区块互不渗透运行时生成优于离线生成——不产出代码就永远没有过期代码这是为 LLM Agent 设计工具时的一个关键洞察相关设计思路的完整论述见 README.md对于想写元工具tool of tools的开发者来说mcp2cli 这份 4783 行的单文件可能比很多分几十个模块的项目更值得精读。【免费下载链接】mcp2cliTurn any MCP, OpenAPI, or GraphQL server into a CLI — at runtime, with zero codegen项目地址: https://gitcode.com/gh_mirrors/mc/mcp2cli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考