为什么不把 MCP 工具直接注册进工具表
业界有两种接法,扣瓦选了第二种,原因是提示词缓存。全量注册(未采用)
每个 MCP 工具作为一个独立工具注册给模型。模型用起来最顺手,但一个服务器就能带来
10k+ token 的 schema,而且服务器一增删就改写工具表。
代理网关(本项目采用)
只注册一个约 200 token 的网关工具。模型先
search 发现、再 call 调用,
断连状态下也能靠元数据缓存搜索。mcp 的工具,四个动作:
工具的内部全名是
mcp__<服务器>__<工具>,search 返回的就是全名,describe 和
call 接受全名。
约定是先 search 再 call。这条写进了系统提示词,模型照做。
配置:三层合并
MCP 服务器的配置分三层,低到高:
按服务器 id 合并,高层整条覆盖低层同名 id。同一 id 但传输方式不同,视为不同定义。
工作区标准层用
.mcp.json(生态标准),但只认 command / args / env / url /
headers / type 这几个字段——扣瓦专属字段写在这里会被忽略,要生效得写到
.kova/mcp.json。mcp.disabled.<层>.<id>)。个人开关不该写进
随仓库共享的文件里——和子代理的处理方式一致。
写一个配置
没有
settings 这一层,也没有全局免审批开关:approveTools 是每台服务器的字段,
输出防护是常开的。启停只在设置页切换(落本机 SQLite)——文件里写 disabled 这类
键不会被读取,上面没有列出的键同样如此。上限
合并后系统 + 工作区共 ≤ 32 个服务器,每服务器 ≤ 64 个工具,同时活跃连接 ≤ 16。 校验规则收得比较紧:id 只允许字母数字下划线连字符;stdio 与 http 字段互斥;command 不含 ..;url 必须绝对。
审批
MCP 的call 一律走现有的逐工具审批回路(和写文件、跑 bash 的是同一条路),
不另造机制。审批被拒时,模型收到的是 blocked 工具结果,和其他工具被拒的语义一致。
有两条免审批的路——都必须是”你自己机器上的决定”,跟着仓库走的文件授权不了:
- 服务器的
approveTools配了 glob 且命中该工具名,且这份声明来自系统层 (~/.kova/mcp.json)。写在工作区层(.mcp.json/.kova/mcp.json)的approveTools不产生效力,只作为审批卡上那句「这个项目请求 X 免审批」出现 ——clone 一个别人的项目不该让那个仓库给自己的工具免审批。它也不会因为你启用了 这个服务器而生效:启用表达的是”我愿意跑它”,不是”我同意它免问”。 - 本机清单
allowMcpTools:审批卡上点「允许并记住这个工具」写进<工作区>/.kova/permissions.local.json,粒度是工具全名逐字相等(记一个不会 顺带放开同服务器的其他工具)。
search / describe / status 不触发审批——它们只读本地缓存和连接状态。
输出防护
MCP 服务器返回的东西可能很大。扣瓦的做法和read / grep 一致:有界 + 可续取。
这不是丢数据,是换个方式给——模型拿到的是一个有界的结果加上一个能续读的指针。
断连了还能搜
元数据缓存(mcp-cache.ts)让 search / describe 在服务器连不上时仍然可用:
- 条目按 configHash 键控(覆盖 command/args/env/url/headers),所以换配置自动失效
- 每次成功握手后全量更新;TTL 默认 7 天,服务器自己声明
ttlMs则优先 - 读命中缓存时先返回旧值、后台异步刷新——前台不等网络
连接管理
连接是进程内全局单例,跨会话共享连接池(懒连接 + 空闲断开)。不按会话隔离—— MCP 服务器本身没有会话语义。 服务器状态有四态:idle / connecting / ready / failed(含退避 backoff)。
设置页里每行有状态点和一个「测试连接」按钮(强制重新握手)。
改配置会热重载:按新配置 diff 连接池,变更或禁用就断连、删除就释放。
系统提示词和工具表不需要重新注入——代理模式下工具表从来没变过。
设置页
设置 → MCP。骨架和子代理页一致:双层分组(系统 / 工作区),每行有传输方式图标、 名称、启停开关、状态徽章(ready · N 工具 / connecting / failed + 原因),
行菜单里有测试连接与删除。
指向非 loopback 的明文 HTTP 会显示警告条。
已知取舍
args 走 JSON 字符串
call 的参数是 JSON 字符串而不是对象。原因是部分模型对嵌套 union schema
不稳,字符串形态更鲁棒。如果实测主流模型用对象没问题,会放宽成两种都收。search 没有正则与分页
目前是字段加权匹配(名 12 / 服务器 8 / 描述 5,完整匹配 > 前缀 > 包含,
命中全名额外加权),默认返回 12 条、上限 40。正则与分页在后续迭代。
Windows 孤儿进程
stdio 服务器是 sidecar 直接 spawn 的。正常路径会 kill,异常退出(尤其 Windows)
可能残留子进程,收尾按进程树清理。这条还需要真实使用验证。
OAuth 尚未支持
目前认证靠配置里的 headers / env 静态提供。OAuth、资源(resources)、采样、
elicitation 按后续节奏推进。
下一步
权限档位
MCP 审批走的是同一条逐工具审批回路,与权限档位的关系在这里。
Agent 引擎
内置工具清单与代理网关工具的关系。
