为 Hono 构建 CLI 适配器
Source: Dev.to
Overview
hono-cli-adapter 让你可以直接从 CLI 调用 Hono 应用。
业务逻辑仍然保留在 Hono 中,这样你可以使用 Postman 或 Insomnia 进行调试,发布相同的代码作为 CLI,并且避免任何 stdout 写入——CLI 控制所有输出。
额外好处:通过切换入口点即可实现简易的 MCP 服务器支持。
调试 CLI 工具非常繁琐:运行、修改参数、再次运行——没有请求历史,也没有便捷的检查方式。
使用 hono-cli-adapter,你的 CLI 逻辑仍然位于 HTTP 端点后面,但实际上并不需要真实的 HTTP 服务器。该库会把 CLI 参数转换为 HTTP 请求并直接调用你的 Hono 应用的 app.fetch()。
Why Hono?
- Web‑tool friendly – 在构建时使用 Postman/Insomnia。保存请求、检查响应、快速迭代。
- MCP ready – 切换入口点即可同时支持本地和远程 MCP 服务器。相同的业务逻辑,不同的传输方式。
- Testable – 你的 Hono 应用是唯一的真相来源,能够独立进行测试。
Installation
npm install hono-cli-adapter
Basic Usage
创建一个 CLI 脚本(例如 my-cli.js):
#!/usr/bin/env node
import { cli } from 'hono-cli-adapter';
import { app } from './app.js';
await cli(app);
赋予可执行权限:
chmod +x my-cli.js
Running commands
# Call /hello/:name route
node my-cli.js hello Taro
# → "Hello, Taro!"
# List available routes
node my-cli.js --list
# Show help
node my-cli.js --help
CLI 参数会转化为 URL 路径和查询参数,然后调用 app.fetch()。
Design Constraints
1. Thin CLI, fat Hono
所有业务逻辑都在 Hono 中;CLI 只负责标志和输出。这保证了 CLI 与 HTTP 之间的行为一致性,并且使 Hono 应用本身可以独立进行完整测试。
2. No side effects
库永远不会向 stdout 写入。你自行决定如何格式化输出:
const { code, lines } = await runCli(app, process);
for (const l of lines) console.log(l); // 或 JSON.stringify,管道到其他地方
process.exit(code);
3. POST‑only
CLI 命令触发动作,默认使用 POST。若有需要,后续可以添加 GET 支持。
Environment Variable Precedence
三层优先级,后者覆盖前者:
process.env(基础)options.env(适配器配置)--env标志(最高优先级)
await cli(app, process, { env: { API_URL: 'https://dev.example.com' } });
node my-cli.js do-thing --env API_KEY=secret-123
Passing JSON Body
-- 之后的 token 会被转为 JSON 请求体:
node my-cli.js create-user -- name=Taro email=taro@example.com
# Sends: { "name": "Taro", "email": "taro@example.com" }
Transforming Requests per Command
await adaptAndFetch(app, process.argv.slice(2), {
beforeFetch: {
upload: async (req, argv) => {
if (argv.file) {
const buf = await fs.readFile(argv.file);
const headers = new Headers(req.headers);
headers.set('content-type', 'application/octet-stream');
return new Request(req, { body: buf, headers });
}
}
}
});
Enriching --help with OpenAPI
await runCli(app, process, { openapi: myOpenApiSpec });
生成的帮助信息会显示参数类型、必选/可选标志以及描述。它与 hono-openapi 配合得很好。
Implementation Notes
listPostRoutes检查 Hono 内部的路由结构。这在 Hono 重大更新时可能失效;在生产环境中,建议自行维护路由列表。- ESM only – 不支持 CommonJS。需要 Node 18+。
Conclusion
Hono + CLI 是一种值得更多关注的模式。你在开发期间可以使用 Web 工具,轻松获得 MCP 支持,并拥有可测试的核心——而且无需重复业务逻辑。
Check it out on GitHub: