← 返回列表
未验证
面向 DeepSeek Harness dsh 的省 token MCP 适配器——一个受…
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/11 · 已提供中文文档
dsh 插件:通过提示侧 shim 将 mcp__* 工具 schema 折叠为两个元工具以节省 token
综合分
30
GitHub 分
30
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add fan56/dsh-mcp-adapter该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/18(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-mcp-adapter
面向 DeepSeek Harness (dsh) 的省 token MCP 适配器——一个受 pi-mcp-adapter 启发的 prompt-side shim(提示词侧垫片)。
要求 dsh >= 0.1.5-rc.2 — 本插件只跟随 dsh RC/stable 线(CI 与发版在运行时解析 latest/next 中更新的 dist-tag)。不再支持 alpha 线。
问题
官方 @deepseek-ai/dsh-mcp-client 插件把发现的每个 MCP 工具都原生注册进工具表(mcp____),于是每次请求都要为每个 MCP 工具的完整 JSON Schema 付费——上游 README 原话:"Data-dependent schema cost is paid on every request while the tools are registered." 几个 server、几十个工具下来,就是每条消息烧掉数千 token,无论模型是否真的调用它们。
思路
本插件完全保留官方 dsh-mcp-client 作为连接层(transport、自动重连、tools/list_changed 重同步——全是上游现成的),只在提示词装配这一处介入:
- 每个匹配的 mcp__ 工具 schema 被折叠出装配后的 prompt(system-prompt/assemble waterfall);
- 原位换上两个恒定 meta-tool,常驻 prompt 成本对 server/工具数量而言是 O(1):
- mcp_list — 紧凑目录(工具名 + 截断描述,不含 schema);传 tool 按需展开单个工具的完整 schema,传 server 过滤,传 verbose 全量内联;
- mcp_call — 按 { tool, arguments } 把调用分发到仍然注册着的定义上,运行上下文原样透传。
工具本身仍注册在 ctx.tools 里,所以 TUI 渲染、tools.restrict() 掩蔽照常工作——变的只是 prompt 载荷。折叠后恒定的工具列表也比上游"每次重同步就换代"的模式更利于 KV 前缀缓存。
一个管线细节:按子工具名(mcp__server__tool)匹配的 pre-execute / guard / post-execute 阶段不会在折叠调用上触发——注册表只会看到外层的 mcp_call。要管控 MCP 使用(审批、策略),请 guard mcp_call 本身。
图片结果保持原生行为:mcp_call 把 output.render 委托给被分发的子工具,并以同一个执行对象转发子工具的 finalizeContent——带图 MCP 结果仍会投影为持久附件引用,而不是把 base64 内联进上下文。
故障放行(fail-open): 若两个 meta-tool 未成功注册(重名冲突、启动中断),本插件不动装配结果——退回官方全量直通,绝不会让 MCP 工具变得不可发现。
Code Mode: 在 mode: 'code' 下线上本来就折叠为 run_code,本插件天然 no-op。
加载位置: 经宿主组合加载(即下方 cordis.patch.yml 的 insert 行)时全局生效——所有 agent 的装配都会被折叠;若经某个 agent 的 scoped context 加载,则只对该 agent 生效。
安装
保留(或新增)你的 @deepseek-ai/dsh-mcp-client 配置行,然后把本插件加在同处:
- insert:
- id: dsh-mcp-adapter
name: '@aiwayds/dsh-mcp-adapter'
config: {}
dsh plugin --profile add @aiwayds/dsh-mcp-adapter
卸载
dsh plugin --profile remove @aiwayds/dsh-mcp-adapter
宿主会自动完成清理:dsh.profile.bundles 里对应的条目被拼接移除,插件的 patch 层随之失效。
有一份状态被刻意保留:~/.dsh/settings.yaml 里的 mcp-adapter: 小节——stable server id(1..99)和 disabled 门闩。它按设计永不回收:重装本插件后,每个 server 仍沿用之前的 id。
连这份状态也想清掉的话,请自行删除 settings.yaml 里的 mcp-adapter: 小节;重装时 id 会重新分配。
配置
| 键 | 默认值 | 含义 |
|---|---|---|
| prefix | "mcp__" | 要折叠的工具名前缀 |
| keep | [] | 保持原生进 prompt 的名字模式( 通配)——对应 pi-mcp-adapter 的 direct 模式,适合高频、值得占一等座 schema 的工具 |
| servers | [] | server 白名单:非空时只有这些 server 的工具会被折叠 / 进目录 / 可分发(三处共用同一份名单) |
| descriptionLimit | 200 | mcp_list 目录里每条工具描述的最大字符数 |
config:
keep:
- mcp__fs__read_file
- mcp__github__*
servers:
- fs
- github
信任边界: 默认所有匹配 prefix 的工具都会被折叠——前缀只是命名约定而非安全边界,第三方插件恰好用 mcp__ 注册的工具同样会折叠。若只信任官方 client 的 server,请在 servers 里显式列出;其余保持原生(仍可直调,只是不走 meta-tool)。
备注
- mcp_call 只接受匹配 prefix 的工具(配置了 servers 时还须在白名单内)——它不可能被用来绕过其它工具自己的 pre-execute 管线。
- 已知边界(waterfall 次序):若某 listener 注册早于本插件、并在自己的 next() 之后补插 mcp__ schema,该 schema 会逃过折叠——本插件折叠的是它运行时装配结果里的内容。当前上游不存在这样的 listener。
- 目录里的 server 名是启发式提取:前缀后第一段 __ 分隔段(server 名规范为 [A-Za-z0-9_-]{1,32},不会含字面 __,故不会错分组)。
- 与 ben7am1n/dsh-mcp-proxy 可共存(它是 connection-side 代理、自带连接管理,工具名互不冲突)。该项目同样致谢 pi-mcp-adapter;本仓库是独立的 prompt-side 实现:复用官方 client 而不是重造连接层。
- 权衡(与 pi-mcp-adapter 相同):首次调用多一次发现往返;模型展开过的 schema 会占据后续上下文。
命令
本插件在平台 commands 服务上注册一条斜杠命令——该依赖是软性的:宿主若没有命令服务,折叠与两个 meta-tool 照常工作(只记一条日志警告,代价是没有 /mcp)。/mcp 展示状态;v0.2.0 起它同时也是整个 MCP server 进/出适配器的唯一控制面:
| 形态 | 输出 |
|---|---|
| /mcp 或 /mcp list | 树形总览——每行 server 带 stable [] 前缀;disabled 的标 ⏸ disabled 且不列工具;尾部附折叠健康行 |
| /mcp list | 匹配某 server → 该 server 全部工具(disabled 的附加 ⏸ 说明行);匹配完整工具名 → 完整描述 + 完整 input schema |
| /mcp config | 当前生效的 prefix / keep / servers / descriptionLimit 及各自命中清单,外加持久 enable/disable 台账 |
| /mcp disable | 把一个 server 整体闩上:工具强制折叠出 prompt(keep 与 servers 豁免一并覆盖)、从 mcp_list 目录消失、mcp_call 拒绝并给 /mcp enable 指引 |
| /mcp enable | 用同一个 stable id 复原 |
其余形态一律回复用法说明。/mcp 观测到的每个 server 都会分到一个稳定数字 id(1..99,最小空闲优先),经 dsh settings 服务持久化到配置文件的 mcp-adapter: 小节(默认安装即 ~/.dsh/settings.yaml)。id 跨重启、跨 re-sync 空窗保持不变,且永不回收——一个 id 永远指同一个 server;99 个用尽时由 /mcp 视图明确标注(id space exhausted (99/99): N server(s) beyond the cap cannot be gated,受影响的分组行会带标记)。
disable 是门闩式开关,不是真断连:官方 client 不提供断连 API,工具仍留在注册表里、连接照常运行——门闩只把它请出 prompt、目录与分发。三层门闩共用同一个判定函数,彼此之间以及与 /mcp 的展示永远不会口径不一。enable/disable 经 settings 服务持久化;没有 settings 服务时其余功能照常,只有 toggle 会回一条说明性报错。
一条真实边界:门闩生效在 prompt 侧(目录/分发层);记得完整工具名的模型仍可能原生直调 mcp__server__tool 成功——需要硬性拦截时,请配合管线 guard 或 tools.restrict()。
状态是二态语义:server 出现在列表里 = 它的工具在本 scope 可见——不可见不代表未启用(可能正在重连退避);官方 client 不暴露连接状态。健康行形如 meta-tools: mcp_list/mcp_call live · folding ACTIVE — folded N, kept M · ~X chars of schema out of prompt(meta-tools 存活且至少折叠一个工具时),否则降级为 fail-open(或无可折叠)提示。X 是被折叠 schema 的 JSON 字符数,刻意标注为字符而非 token。输出超过 400 行会被截断,并提示用 /mcp list 收窄。
致谢
特别致敬 pi-mcp-adapter 及其作者 @nicobailon:本插件的核心思想——把无界的 MCP 工具面折叠为恒定的 meta-tool、schema 按需展开,从而无论挂多少 server 常驻 prompt 成本都是 O(1)——完全来自该项目;正是它重新定义了 MCP 集成应有的代价。本仓库是这个理念在 DeepSeek Harness 上的移植,机制上刻意走了不同的路线(复用官方连接层的 prompt-side shim),但灵感与理念的功劳归于原作。如果你用的是 pi,请直接用原版。
同样值得提及:ben7am1n/dsh-mcp-proxy 独立验证了 dsh 侧对这类方案的真实需求。
开发
npm install && npm run check && npm test
@deepseek-ai/* 类型由 scripts/link-dsh-closure.mjs 从全局 dsh 闭包软链解析(precheck 自动执行)——它们被刻意排除在 package.json 之外,以保证类型图中只存在一份 cordis 实例。完整设计依据与上游参考见 DESIGN.md。扫码进群