把一个桌面工具做成“能点的 GUI”并不难。真正难的是:当它还要被脚本、CI 和 IDE Agent 使用时,怎样不把每个按钮都复制成另一套不可靠的接口。
ToolKnit Desktop 2.0 给了我一个很具体的练习场:Windows 桌面端有 49 个 GUI 工具、11 个分类;其中当前有 46 个 MCP 工具正式注册。两个数字故意不能混为一谈。
这篇不是功能清单,也不是“给桌面软件套一层 MCP”的宣传文。我想复盘的是,把面向人、面向终端、面向 Agent 的三种入口放在一起时,哪些边界必须先设计清楚。
三个入口,三种完全不同的决策方式
GUI、CLI 和 MCP 并不是同一件事换三层皮。
| 入口 | 最擅长的事情 | 最怕什么 |
|---|---|---|
| GUI | 预览、拖拽、页码选择、可视化编辑 | 把重复操作变成无休止点击 |
| CLI | 批处理、脚本、CI、可复现输出 | 隐式状态、模糊路径、不可解析日志 |
| MCP | 在 IDE 中由 Agent 编排工作流 | 猜测用户意图、猜测文件位置、悄悄覆盖文件 |
人的优势是看见和判断;脚本的优势是确定性;Agent 的优势是能把自然语言拆成可调用的工具。但三者如果各自长出一套业务规则,迟早会发生最糟糕的事:GUI 能处理、CLI 行为不同、Agent 又输出了第三种错误。
因此我更愿意统一的是「输入输出与安全契约」,而不是夸张地宣称三层完全共用一份实现代码。
先划清能力边界:49 个 GUI 工具,不等于 49 个 Agent 工具
这个数字差异非常重要。
桌面端的 49 个 GUI 工具覆盖 PDF、PPT、图像、音视频、文本、计算器、AI、硬件等类别,其中不少功能依赖人工预览或仍在持续打磨。当前 MCP 层只注册了 46 个真正具备自动化条件的工具。
为什么不把所有按钮都暴露给 Agent?
因为一个还没有稳定输入、输出、失败语义的功能,出现在 Agent 工具列表里只会放大风险。比如,若一个操作没有明确的输出路径、不知道是否覆盖已有文件、也无法描述依赖缺失时应该怎么处理,它就不该被叫做“可自动化”。
这个取舍看起来保守,但我认为是对用户负责:宁可少暴露,也不让 Agent 假装自己已经会做。
一个可调用的本地文件工具,至少要有这些规则
拿“PDF 转页面图或长图”举例。命令行不是让 Agent 去点桌面端按钮,而是一个独立交付物:它直接运行文件操作,不启动、不驱动、也不依赖 GUI。
toolknit pdf to-image --input .\report.pdf --output-dir .\toolknit-output --mode long --pages 1-5 --format webp --clarity print --output-name report-walkthrough --json
这条命令里值得注意的不是参数数量,而是几个约束:
- 输入与输出路径都必须显式给出;
- 默认拒绝覆盖已有文件,也拒绝把输出写回输入文件;
- 先写同目录临时文件,只有全部处理成功后才原子发布;
- 「--json」时输出是结构化结果,不混入 ASCII 横幅;
- 依赖状态可以先用「toolknit doctor --json」检查;
- 密码不走命令行参数,而是经受保护的标准输入读取,避免落入历史记录。
这些约束让工具不只是“能跑”,而是“脚本与 Agent 可以验证它有没有安全地跑完”。
MCP 不是聊天包装,它需要安静且可预测的传输层
MCP 侧的配置很短:
{
"mcpServers": {
"toolknit": {
"command": "toolknit",
"args": ["mcp", "serve"]
}
}
}
难点在配置之外。ToolKnit 的 MCP 服务通过 stdio 使用逐行 JSON-RPC:不能往 stdout 或 stderr 随手打印调试日志,否则 IDE 会把协议流当成损坏。成功与错误都要有结构化结果;IDE 传入进度令牌时,工具还会回报进度;请求取消时也要能结束对应任务。
更关键的是权限语义。一个合格的 Agent 过程应该是:
inspect 文件
-> 告知将要生成什么、写到哪里
-> 需要覆盖时明确征得用户同意
-> 再执行并返回真实输出路径
它不该猜页码、猜用户想要横拼还是竖拼、猜背景色,更不该因为一句“处理这个 PDF”就覆盖原文件。
“本地优先”也不能偷换成“永远离线”
这类项目很容易把隐私文案写得过头,所以这里必须说准确。
基础文件处理和非 AI PPT 工作流不需要 AI Key;普通文件默认留在本机。音视频等任务按需检查 FFmpeg,PDF 解密/压缩按需检查 qpdf,PPT 转 PDF/图片依赖 LibreOffice,离线转写则需要先准备模型。
但 AI 文档、AI 表格、PPT 的 AI 文本整理、AI 大纲/草稿,以及转写后的 refine,仍会把相关文字发送到用户在 CLI/MCP 环境中主动配置的模型服务。桌面端保存的密钥也不会被 CLI/MCP 自动读取。
把这个边界讲清楚,比一句“所有功能都不联网”更可信。
一个端到端的例子:同一份 PDF 的三种工作流
同一份报告,三种人会有不同的合理选择:
- 需要挑页、看预览、确认视觉效果的人,用 GUI;
- 每周都要把一批报告导出成长图的人,用 CLI 写入脚本;
- 正在 IDE 里整理项目材料、需要根据用户明确指示组织输出目录的人,用 MCP。
它们并不需要长得一样;它们只需要对以下问题给出一致答案:文件从哪里来、会生成到哪里、是否覆盖、依赖是否可用、成功和失败分别代表什么。
这才是 GUI、CLI 与 MCP 能够共存的基础。
结语:把“能做”变成“敢交给自动化做”
我越来越觉得,Agent 工具设计的门槛不是“能否被自然语言调用”,而是能否让每一次调用都可追溯、可撤销、可理解。
49 个 GUI 工具与 46 个 MCP 工具并不代表完成,而是一条清楚的边界:成熟的流程可以自动化,尚未成熟的流程继续留在 GUI 中打磨。
项目源码、CLI/MCP 文档和 Windows 发布包都在 ToolKnit Desktop 开源仓库。如果只想先看完整的桌面端功能与界面,可以访问 ToolKnit Desktop 2.0。