做前端逆向的时候,工具面天然就宽:浏览器控制、流量抓取、反混淆、WASM 反汇编、进程调试。我把这些收进了一个 MCP server(jshookmcp),结果工具数涨到 735 个 —— 然后撞上了一个比想象中严重得多的问题。
大家讨论「上下文很贵」时,通常盯着 prompt 和文档。但真正把预算吃光的是一件更容易被忽略的事:每个 MCP server 都会在第一轮把自己的完整工具 schema 全量塞进来,而且是每一轮。
这个成本有多大,是可以量的。我实测了构建产物发 tools/list 的 payload,用 bytes / 4 估算 token(这也是项目自己 TokenBudgetManager.BYTES_PER_TOKEN = 4 的口径):
| profile |
工具数 |
payload 字节 |
~token |
search |
8 |
7,527 |
~1,882 |
workflow |
360 |
209,005 |
~52,251 |
full |
743 |
435,820 |
~108,955 |
也就是说,如果一个 server 有 735 个工具且全部前置,你要在还没看到一行代码之前先付出约 109K token。
五个这样的 server 叠起来,第一轮就没预算了。
二、常见的两种解法,都在把成本转移给用户
解法 A:砍工具。 只留最常用的十几个。问题是逆向是探索性的 —— 你经常在过程中才发现需要硬件断点、需要 WASM 反汇编、需要抓 HTTP/2 帧。砍掉的工具不会消失,只是变成了「用户得再装一个 server」。
解法 B:拆成多个 server。 看起来解耦了,实际上把 109K 拆成了 5 × 22K —— 总成本没变,而且每个 server 的 schema 照样每轮全量加载。更糟的是模型现在要先判断「我该去哪个 server 找」,这本身也要花推理预算。
三、我们试的第三条路:搜索优先 + 档位阶梯
核心想法很简单:工具面可以很大,但开场成本必须很小。
jshookmcp 默认跑在 search 档,只暴露 8 个元工具,约 3K token:
search_tools —— 用 BM25 + 向量混合检索找工具
describe_tool —— 拿某个工具的完整 JSON Schema
activate_tools / activate_domain —— 激活具体工具或整个域
deactivate_tools —— 主动释放
call_tool —— 带参数校验的调用通道
route_tool / coverage_report —— 路由与「当前激活了什么」的自查
agent 的工作流变成:先搜 → 再激活 → 再调用。激活有 TTL,运行时按 LRU 淘汰,保证不超预算。任务变大就逐级升档:
search(~3K token) → workflow(~52K) → full(~109K)
关键点是:full 档的 109K 你只在实际需要时才付,而不是第一轮就付。
四、代价必须说清楚
这套设计不是免费的,有三个真实代价:
- 多一次往返。 模型得先决定「去搜」,这要花一轮。省下的 107K token 换一次 round trip,我觉得划算,但这不是零成本。
- 检索会失败。 逆向场景里经常是「我不知道我要什么工具」。BM25 + 向量检索在「已知工具名、不知道细节」时表现好,在「完全不知道存在什么」时就是碰运气。所以我留了
coverage_report 让你随时看当前激活了什么,也方便人工纠偏。
- 数字会漂。 上面
full 的 109K 是 2026-10-10 实测的,它随工具总数增长。工具目录变大后必须重测 —— 这也是我在 README 里标注测量日期的原因。
五、怎么用
npx -y @jshookmcp/jshook@latest
Node 22.22.2+ / 24.15+,AGPL-3.0。
需要提前说明的是,这是 dual-use 工具:它有进程注入、TLS keylog、反检测能力,仓库根的 DISCLOSURE 里写得很明确,不是藏着的。CAPTCHA 求解只接受显式输入,不会主动探测页面。是否合规使用取决于使用者。
六、想听听不同的意见
「搜索优先」对逆向这类探索性任务是不是错的抽象?我倾向于认为它至少比「全量前置」好,但确实没有解决「我不知道我要什么」这个根本问题。
如果你也在处理 MCP 的工具膨胀,欢迎聊聊你是怎么做的 —— 拆 server、砍工具,还是别的路子。
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。