Skip to main content
Glama

dsh-rea-mcp-lite

中文 | English

把 REA 的逆向工程 MCP 工具全部收进 5 个元工具 + 按需加载的功能族: 默认只摆出元工具、省下绝大部分工具上下文,其余工具一个都没丢,随时检索与调用。 功能族支持运行时热切换(notifications/tools/list_changed),无需重启 DSH。 常用组合可以存成命名预设,之后一键切回。 自带更新与体检:查本仓库与 REA 上游更新、把 REA 新增工具自动归类、提醒本机缺哪些工具。

A tiny zero-dependency MCP stdio proxy that turns REA's full tool set into a progressive-disclosure gateway: a handful of meta-tools by default, every tool still searchable and callable, with hot-swappable tool bundles (and named presets you can switch back to in one call) and no DSH restart. Ships update checks (this repo + REA upstream), automatic bundle classification for new tools, and coverage hints for missing ones.

具体工具数、token 与省下的百分比都是 REA 版本相关的数字,写在下面的「效果」表里并标注了实测版本; 换版本后以 node src/cli.mjs snapshot 重跑的结果为准。


效果

以下数字按 REA 6.8.0 实测(REA_MCP_INPUT_SCHEMA_PROFILE=compact,lite: "mild"):

场景

模型可见工具

约 token

默认(仅元工具)

5

624

加载全部(经本代理裁剪后)

234

35.5k

不用本代理(直连 REA,模型可见部分)

229

~75k

早期版本(REA 6.4.0,170 个工具)直连约 70k tok、经代理全量约 49k tok;到 6.7.0 变成 207 个工具、 经代理全量约 26.9k tok(compact schema profile 的裁剪强度提高了)。6.8.0 的工具数回到 229 个, 两边成本跟着涨了约四成——省下的比例仍然在一半左右(见「版本适配」)。

Related MCP server: Meta MCP Proxy

为什么不是"压缩 schema"

实测 REA 6.8.0 的 tools/list 报文(REA_MCP_INPUT_SCHEMA_PROFILE=compact):

口径

字符数

占比

REA 实际发出的报文全文

3,504,736

100%(≈974k tok)

outputSchema

3,199,098

91.3%

inputSchema

121,537

3.5%

description

135,500

3.9%

真正进模型上下文的(name + description + inputSchema)

270,966

7.7%(≈75k tok)

DSH 组装 LLM 请求时只映射三个字段 —— @deepseek-ai/dsh-llm-deepseek/lib/index.js:

tools: options.tools.map((tool) => ({
  name: tool.name,
  description: tool.description,
  input_schema: tool.parameters,          // ← 即 MCP 的 inputSchema
  ...tool.deferLoading === true ? { defer_loading: true } : {}
}))

outputSchema 只在 DSH 内部用于校验工具返回值,完全不占上下文。所以:

  • 716k tok 的报文里 91% 是"看着吓人但不花钱"的部分;

  • 砍掉它省 0%,裁掉 pattern/format 之类只省几个百分点,把描述压成一句话省约 2%;

  • 真正的成本是 工具的数量(当前版本 229 个)。

于是本项目的核心是 按需暴露(progressive disclosure),而不是压缩 schema。schema 瘦身只作为附带优化(lite 档位)。

工作原理

DSH ──stdio JSON-RPC──> proxy.mjs ──stdio JSON-RPC──> rea.mjs mcp(子进程)

零依赖,手写按行切分的 JSON-RPC(MCP stdio 就是一行一个 JSON,无 Content-Length 帧)。

消息

处理

initialize

转发;改写 serverInfo.name 为 rea-lite,并注入一段 instructions 教模型用网关

tools/list

不转发,由代理用缓存的 REA 工具表 + 配置现场合成(元工具 + 已加载族,按 lite 裁剪)

tools/call

名字是元工具就地处理;其余原样转发,结果原样回传(含图片、结构化错误)

其它

notifications/*、resources/*、ping 双向直通

热更新

族变化 → 代理发 notifications/tools/list_changed;DSH 的 MCP client 对它注册了 onChanged: () => refreshTools(),因此换工具集无需重启

安装

git clone https://github.com/MuyuYanran/dsh-rea-mcp-lite.git
cd dsh-rea-mcp-lite

(1) 准备 REA(本代理只是网关,真正干活的还是 REA):

npm i -g rea-agents          # 或 pnpm add rea-agents;也可用 npx
# 也可以用官方技能:rea setup --skill --yes

(2) 写配置:复制 config.example.json 为 config.json,把 child.args[0] 改成你的 rea.mjs 绝对路径、env.JAVA_HOME 改成你的 JDK 路径。

cp config.example.json config.json   # Windows: Copy-Item config.example.json config.json
{
  "activeBundles": [],        // 常驻功能族;[] = 只挂 5 个元工具
  "lite": "mild",             // off | mild | aggressive
  "child": {
    "command": "node",        // 建议写 node 的绝对路径
    "args": ["<...>/node_modules/rea-agents/scripts/rea.mjs", "mcp"],
    "env": { "REA_MCP_INPUT_SCHEMA_PROFILE": "compact", "JAVA_HOME": "<你的 JDK>" }
  }
}

(3) 注册到 DSH:在 ~/.dsh/cordis.patch.yml 加一条(serverName 用 rea 可与 REA 官方技能里的引用保持一致):

- insert:
    - id: rea-mcp
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: rea
        transport: stdio
        command: 'C:\Program Files\nodejs\node.exe'   # 或 DSH 内置 node 的绝对路径
        args:
          - 'D:\path\to\dsh-rea-mcp-lite\src\proxy.mjs'
        env:
          REA_LITE_CONFIG: 'D:\path\to\dsh-rea-mcp-lite\config.json'
          JAVA_HOME: 'D:\path\to\jdk'
        failOnStartupError: false

(4) 重启 DSH(cordis 配置只在启动时读取)。重启后 REA 会以 5 个元工具出现。

不想用网关时:把 args 换成 rea.mjs + mcp 并删掉 REA_LITE_CONFIG 即可直连。

5 个元工具

工具

作用

search_tools

在全部 229 个工具里搜(名字 + 说明),返回一句话用途、必填参数、所属族、是否已加载

tool_schema

取某工具的完整 inputSchema(未裁剪),用于精确构造复杂参数

call_tool

调用任意工具(含未加载族的):{"tool":"analyze_function","arguments":{"procedure":"main"}}

bundles

列出/切换功能族,以及管理命名预设:action = list | activate | deactivate | set | save-preset | load-preset | remove-preset

maintenance

网关体检与更新:查本仓库/REA 新版、找未归族的新工具并归类、刷新成本快照。默认只读,action=classify/update-* 才改本机

不需要先加载功能族就能调用工具 —— 功能族只决定"先把哪些工具的说明书摆到桌面上"。

功能族

下表按 REA 6.8.0(229 个工具,lite: "mild") 实测;旧版本的数字见下方「版本适配」。

族

工具数

约 token

内容

native

53

6.8k

原生静态分析(伪代码、汇编、交叉引用、注解)

android

40

4.0k

Android / ADB / JEB(设备、日志、APK、Flutter、HarmonyOS)

evidence

18

3.9k

证据治理(对比、验证、未知项、重建账本)

web

15

3.5k

网页/浏览器(CDP、网络、脚本、sourcemap)

nav

25

3.3k

会话与导航(打开目标、游标、字节、段表、字节搜索)

runtime

12

2.8k

运行时捕获与包体(进程、固件、EVM、应用包)

formats

11

2.6k

Go / Rust / WASM / SQLite / Electron fuses / objdump / 模型权重 / .pyc / BEAM

js

13

2.6k

JavaScript / Electron 应用图与语义追踪

debug

20

2.2k

Frida / GDB / Rizin / Cutter 动态调试

apple

14

1.6k

Objective-C / Swift / plist / 资源目录 / 动态库

managed

8

1.3k

.NET / 托管程序集 / 托管-原生边界 / Unity IL2CPP

capture

6

1.1k

PCAP / TShark / sigrok 逻辑信号

all

229

34.9k

全部(等价于直连 REA 的模型可见部分,但 schema 更瘦)

族之间有重叠(apple 的工具也属 native,runtime 的部分工具同属 js/web),所以各族 token 相加 > all。

这里的数字会随 REA 版本漂移(且方向反直觉,见下节)。上面两个表按 data/tools-model.json 的当期快照实测, 换版本后以 node src/cli.mjs snapshot 重跑的结果为准——别把这些值当作不变量抄进断言或其它文档。

版本适配(REA 6.5.0 起)

REA 6.5.0 起新增 debug / formats / capture 三族。6.8.0 共 229 个工具(比 6.7.0 多 22 个), 已全部归族;6.8.0 这批新工具主要是离线单文件解析器,按「文件是什么」分派: PE/ELF/内核模块/GPU 代码对象进 native,Apple .ips 崩溃报告与只读 .app 包进 apple, APK 签名进 android,Unity IL2CPP 元数据进 managed,模型权重 / 设备树 blob / CPython .pyc / Erlang BEAM 进 formats,桌面应用目录整体识别进 runtime,两份函数清单匹配进 evidence, REA 自身运行时限额的读写进 nav。

族

工具数

内容

注意

debug

20

Frida / GDB / Rizin / Cutter 动态调试

需目标进程或设备就绪;会改目标状态

formats

11

Go / Rust / WASM / SQLite / Electron fuses / objdump / 模型权重 / 设备树 / .pyc / BEAM

部分依赖外部工具链

capture

6

PCAP / TShark / sigrok 逻辑信号

需装 TShark 4.x / sigrok-cli

外置工具的安装与 Windows 上的真实可用性见「debug / formats / capture 三族的外部工具」一节。

成本随版本变化,而且方向来回摆:6.4.0 是 170 工具 / 全量约 49k tok;6.7.0 是 207 工具 / 全量约 26.9k tok (compact schema profile 裁剪更狠,把那批最大的工具 schema 从 6–9k 字符压到 500–900 字符,所以工具更多而成本更低); 6.8.0 是 229 工具 / 全量约 35.5k tok —— 裁剪强度没再变,成本跟着工具数一起涨回去,直连那一侧也从 ~53k 涨到 ~75k, 两边省下的比例仍是一半左右。所以不要把这几个数字当常量写进断言或文档; 一切都以 data/tools-model.json 为准,切版本后重跑 node src/cli.mjs snapshot。

用旧版 REA 时,这三个族显示 0 个工具 并标注「当前 REA 版本无此族」——那不是坏了,是版本没有这些能力。

族是静态清单(src/bundles.mjs)。再升级后新增的未归族工具,会出现在 bundles 输出的"未归族"里、以及 node src/cli.mjs status 的提示里;已归族但当前版本没有的,会显示为缺失而不是报错。

自定义分组

内置族按「REA 的能力域」划分,但每个人的常用工具组合不一样。自定义分组让你把任意工具编成一组,之后像内置族一样一键开关。

在设置页建/改:「设置 → REA 工具 → 自定义分组」→ 新建或点「编辑」:

  • 左边是全部工具,每个都带一句话定义与成本,勾选即加入(不必先搜索再选)。

  • 右边是本组已选,点 × 移除;也支持把左边的工具拖进右边。

  • 「整族并入」可把某个内置族的工具一次性全加进来或全移出去,省得一个个点。

  • 改组名时,原来勾着的这个组会跟着改名,不会悄悄失效。

  • 顶部筛选框按名字或说明过滤,229 个工具里找起来也快。

为什么以勾选为主、拖动为辅:WCAG 2.5.7(AA)要求所有拖动操作都必须有非拖动的替代路径,纯拖拽界面对键盘和触屏用户不可用。所以这里是「勾选能用,拖动更好用」。

用 CLI 建:

node src/cli.mjs custom list                       # 看已有的
node src/cli.mjs custom add --id web-audit --label "网页审计" --tools inspect_web_page,analyze_web_bundle,export_web_scripts
node src/cli.mjs custom remove web-audit

直接改配置:config.json 的 customBundles 字段:

{
  "customBundles": {
    "web-audit": { "label": "网页审计", "hint": "", "tools": ["inspect_web_page", "analyze_web_bundle"] }
  }
}

约束:

  • 组名小写字母开头,只含小写字母、数字、_、-,最长 32;不能与内置族或 all 重名。

  • 工具名必须真实存在(按当前 REA 版本校验),否则保存时直接报「未知工具」,不会存下一个调不通的组。

  • 自定义组与内置族并列,不改写内置族;同一个工具可以同时属于内置族和多个自定义组。

  • 保存后与改 activeBundles 一样走配置监听,约一秒热切换。

预设(保存与读取常用组合)

自定义分组解决的是「这几个工具算一组」,预设解决的是「这一套勾选 + 这一档裁剪,我要反复切回来」。

node src/cli.mjs preset                        # 列出预设(● = 当前生效的那套)
node src/cli.mjs preset save 原生深挖 --note "native + evidence"    # 存下当前勾选与裁剪档
node src/cli.mjs preset save 安卓动态 --bundles android,debug,nav   # 也可以显式指定族
node src/cli.mjs preset show 原生深挖
node src/cli.mjs preset use 原生深挖           # 一键切回
node src/cli.mjs preset remove 原生深挖

设置页的「预设」区块同样能做:填个名字 → 「存下当前勾选」;每条预设上有「读取」「删除」,当前生效的那条会被标出来。模型侧也能用(bundles 元工具,所以「把现在这套存下来,等下切回来」可以直接说):

{"action":"save-preset","preset":"原生深挖","note":"native + evidence"}
{"action":"load-preset","preset":"原生深挖"}

一个预设记录:勾选了哪些族 + lite / shortDescription / metaTools 三档开关 + 备注与保存时间。读取它就是把这几个键写回 config.json,随后照旧热切换(约一秒)。

三条设计取舍:

  • 不记 child。子进程命令与环境变量是本机专属(JAVA_HOME、外部工具路径),跟着预设走等于把一台机器的路径读到另一台上。

  • 引用的族没了就跳过并报出来。预设引用的自定义组被删掉、或预设来自另一台机器时,读取只加载存在的族,并明确列出跳过了哪些;不会静默加载一个空的组。

  • 裁剪档一起存。lite 档位会改变每个工具定义的长度,所以成本口径跟着变;面板会提示该重新生成快照。

  • 存在插件目录之外。预设不写进 config.json,而是单独存一份(见下),所以更新插件不会把预设清掉。

预设的落点是独立文件,不跟随 config.json 的位置:

<用户数据根>/rea-lite/presets.json      用户数据根 = DSH_HOME,未设时用 ~/.dsh

为什么单独存:config.json 的位置由 REA_LITE_CONFIG 决定,没设时落在「网关根目录」—— 而从 npm 装的网关根就在插件包里面(node_modules/dsh-rea-lite-panel/gateway/)。 插件一升级,整个包目录被替换,写在包内的任何东西都会跟着消失。预设是你手写的数据,不该这样丢。 这也和预设本身的性质相符:它只记「勾了哪些族 + 用哪档裁剪」,不含任何本机路径,本来就可以跨安装、跨 profile 复用。

文件内容:

{
  "version": 1,
  "presets": {
    "原生深挖": {
      "activeBundles": ["nav", "native", "evidence"],
      "lite": "mild", "shortDescription": true, "metaTools": true,
      "note": "native + evidence", "savedAt": "2026-10-25T05:11:14.406Z"
    }
  }
}
  • 老版本升级上来会自动迁移:若 config.json 里还留着 presets,第一次读取(代理启动、面板打开、CLI 跑一下都算)就会把它搬进独立存储,并清掉 config.json 里那份副本——两份数据会各自漂移,所以只留一处。

  • preset 子命令与面板都会显示实际落点,方便备份。

  • 要换位置:REA_LITE_PRESETS 直接指定文件,或 REA_LITE_DATA_DIR 指定目录。

预设名是最长 48 个字符的自由文本(中文可以),不能含 \ / : * ? " < > | 或控制字符——它要能安全地当 JSON 键、也能原样传给命令行;同名保存即覆盖。

三种用法

A. 默认网关模式(推荐) — 只挂 5 个元工具(约 624 tok),一切靠 call_tool 打:

node src/cli.mjs none

B. 常用族常驻 — 例如天天做 Electron 逆向,让 nav,js 常驻(36 个工具,约 4.4k tok;含元工具约 5.0k),其余按需:

node src/cli.mjs use nav js

C. 全量 — 需要模型一次性看到所有工具(例如让它自己规划长流程):

node src/cli.mjs all
node src/cli.mjs list      # 带实时 token 估算的功能族一览
node src/cli.mjs status    # 当前配置

五种开关方式(都热更新,无需重启 DSH)

  1. 设置页点选(最省事,见下一节)——「设置 → REA 工具」勾选功能族,实时看到每个族的 token 成本与实测变化。

  2. 直接对模型说 —— "把 web 和 js 族加载上" → 模型调 bundles {"action":"activate","bundles":["web","js"]} → 代理发 list_changed → DSH 当场换工具集。

  3. 改 config.json —— 代理 fs.watch 该文件,约 150ms 内生效。

  4. CLI —— node src/cli.mjs use web js(本质就是改 config.json)。

  5. 切预设 —— 面板「预设 → 读取」、node src/cli.mjs preset use <名>,或让模型调 bundles {"action":"load-preset","preset":"<名>"};一次把勾选与裁剪档都换回来。

运行时切换会写回 config.json(persistRuntimeSwitch: true),重启后保持。

更新与体检

三个都要问「外面/里面各是什么版本」,所以做成一个共用流水线(src/updates.mjs + src/maintenance.mjs), CLI、设置页、元工具 maintenance 走同一份实现。

node src/cli.mjs check                       # 三块一起看:本仓库 / REA 本体 / 工具覆盖
node src/cli.mjs doctor                      # 只看工具覆盖(REA 有但族清单没收录的工具)
node src/cli.mjs update-self [--apply]       # 本仓库快进(git merge --ff-only)
node src/cli.mjs update-rea  [--apply]       # 升级 rea-agents(装完自动刷快照 + 归类)
node src/cli.mjs classify [--apply] [--set tool=bundle,…]

check 的输出长这样:

== 本仓库 ==
  main 落后 origin/main 2 个提交(本地领先 0),可快进
    a18ab29 某个新提交
== REA 本体 ==
  已安装 6.8.0(pnpm @ D:/.../rea-agents)
  npm 最新 6.8.0,无需升级
== 工具覆盖 ==
  来源:live;当前 229 个工具,已归族 229 个
  全部工具都已归族,且没有过期条目。

三条不可越过的边界:

  • 检查只读。checkSelfUpdate 只做 git fetch + rev-list;checkReaUpdate 只读 npm registry 与本地 package.json。面板默认用快照算覆盖,不为了看一眼结论去起 REA。

  • 写动作要显式。update-self 只走 --ff-only,且工作区脏或本地有未推送提交时直接拒绝(那是分叉,得人来决定 merge 还是 rebase);update-rea 先备份清单与锁文件到 _upgrade-backup-<时间戳>/,装失败会把清单拷回并重装。

  • 默认不自动。config.updates.*.checkOnStart 只记日志,autoApply 才会真的改本机。两个默认都是 false:更新会改你的安装与仓库,必须显式开。

REA 新版的新工具怎么归类

族清单是静态的,所以 REA 每加工具就会出现「未归族」。classify 自动打分并分级:

  • 打分用词元稀有度:dart/pcap/frida 只出现在一个族(强信号),inspect/verify/compare 遍地都是(弱信号,列进停用词表)。

  • 分数够、且明显领先第二名 → high,--apply 自动写;同分或分数不够 → medium/low,只给候选。

  • low 不给建议 —— 新领域(比如 WiFi)宁可留给模型判断。classify 会打印一段题面,贴给 DSH 里的模型就能拿回 {"工具名":"族 id"} 的 JSON。

  • 写入的是 config.json 的 bundleExtras({ "capture": ["inspect_x"] }),不改 bundles.mjs:内置清单人工维护,机器判断另存一层,删掉就回到原样。

设置页里的「更新与体检」

「设置 → REA 工具 → 更新与体检」:一张卡片显示本仓库/REA/覆盖三块结论,按钮是「更新本仓库」「升级 REA」「刷新快照」「看归类建议」「写入高置信度归类」。检查默认读快照,勾「向 REA 实时查询」才真的起一次 REA。写动作会跑完自动重新检查一遍,改动结果落在日志区。

模型侧也能触发

maintenance 元工具把同一套动作暴露给模型(默认 action=report 只读):

mcp__rea__maintenance { "action": "report" }                     # 三块结论
mcp__rea__maintenance { "action": "classify" }                   # 建议 + 给模型的题面
mcp__rea__maintenance { "action": "classify", "apply": true }     # 写高置信度
mcp__rea__maintenance { "action": "snapshot" }                   # 刷新快照
mcp__rea__maintenance { "action": "update-rea", "apply": true }    # 升级(会重启子进程并重新握手)

预设也在元工具里(bundles),所以「这套组合存下来,待会儿切回来」可以直接让模型做:

mcp__rea__bundles { "action": "save-preset", "preset": "原生深挖", "note": "native + evidence" }
mcp__rea__bundles { "action": "load-preset", "preset": "原生深挖" }
mcp__rea__bundles { "action": "remove-preset", "preset": "原生深挖" }

设置页(可选,推荐)

仓库里的 dsh-plugin/ 是一个 DSH 插件(细节见 dsh-plugin/README.md),装好后在 设置 → REA 工具 多出一页。

内核版本要求:DSH 0.2.0 及以上(含 0.2.1-rc.5、0.2.2-alpha.x 这类预发布),0.1.6-alpha.1 起的旧线也仍在支持范围内。这个范围写在 dsh-plugin/package.json 的 engines.dsh 与 @deepseek-ai/dsh peer 里,DSH 加载 bundle 时会真的拿它做判定:不匹配就整个 bundle 被跳过 —— 设置页直接消失,而且默认不打日志。范围按 0.2.x 的每条预发布线显式列出,因为 semver 的预发布规则会让 >=0.2.0-rc.1 <0.3.0-0 这种写法在 pnpm/npm 眼里收不住 0.2.1-rc.5;node test/maintenance.test.mjs 的「DSH 内核兼容声明」一节会逐版本复算这一点。

页面按六个子菜单分区(一级标签栏),每个分区里还有二级子菜单、筛选与分页——200 多个工具、12 个族、若干预设不再堆在一屏里滚动:

分区

里面有什么

子菜单 / 筛选 / 分页

概览

此刻模型看到什么:元工具成本、已勾选族成本、合计与省下多少、会话内实测值;下面一条上下文构成条(已用 vs 省下)与快捷操作

—

功能族

勾选功能族,每个族标注工具数与约 token

二级:全部 / 内置 / 自定义;筛选片:全部 / 已加载 / 未加载 / 需环境;名字筛选框;每页 6 个

分组

自定义分组(可视化编辑:左边全部工具、右边已选、可拖可勾)

—

预设

命名预设:存下当前勾选与裁剪档,一键读取

二级:全部预设 / 按保存时间;名字筛选框;每页 5 个;显示存放位置(在插件目录之外,升级插件不会清掉)

工具

按名字或说明搜工具,看它属于哪些族、要花多少上下文

每页 12 个

更新与体检

本仓库 / REA 本体 / 工具覆盖三块结论 + 写动作 + 自动更新开关

「向 REA 实时查询」开关

各分区要点:

  • 勾选框切换功能族,每个族标注工具数与约 token;顶部合计「元工具 + 已勾选族」以及相对全量加载省下的百分比。

  • 族内工具可展开:点「看族内工具」列出该族每个工具名与各自成本,不用为"这族到底有什么"去翻 REA 文档。

  • 风险与版本标记:debug/capture/formats 标「需目标环境」;当前 REA 版本没有的族标「当前 REA 版本无此族」(而不是让你以为勾了没反应)。

  • 会话内实测:DSH 工具注册表里真实存在的 mcp__rea__* 数量与字符数 —— 保存后约 1 秒跟随变化,用来确认热切换真的生效。

  • 状态灯显示 rea 服务器是 已连接 / 已在 MCP 管理里停用 / 启用但未连上;被停用时额外给出"去 MCP 管理启用"的指引。

  • 预设区块:填名字存下当前勾选与裁剪档,每条预设都有「读取」「删除」,当前生效的那条会被标出来;预设引用的族若已不存在(自定义组被删/预设来自别的机器),会当场标红而不是静默失效。

  • 「查工具属于哪个族」搜索框:在 229 个工具里按名字或说明搜。

# 装进某个 profile(这里以 desktop 为例;web 同理)—— 依赖与 dsh.profile.bundles 都会自动登记
dsh plugin --profile desktop add link:/path/to/dsh-rea-mcp-lite/dsh-plugin

装好后重启一次 DSH 让插件加载;之后改勾选不需要重启 —— 面板写 config.json,代理监听文件后热切换,约 1 秒生效。

  • 面板只管「加载哪些族」,不管 MCP 服务器本身的启停(那是「MCP 管理」的事)。当前 profile 里 rea 被停用时,面板会明确提示。

  • 插件按「插件行 root → REA_LITE_ROOT → 仓库布局(本包上一级)→ 包内 gateway/」依次找网关;网关装在别处时,设环境变量 REA_LITE_ROOT 指向网关目录即可。

  • 面板读的是 data/tools-model.json(工具成本快照:全部工具的字符数 + 一句话描述 + 所属族),不含完整 schema,当前约 37 KB。代理每次连上 REA 都会刷新它;也可以手动 npm run snapshot 重新生成。

从 npm / 插件市场安装(本机不用克隆仓库)

npm i -g rea-agents                                 # 网关要连的 REA 本体
dsh plugin --profile desktop add dsh-rea-lite-panel  # 面板 + 包内自带的网关副本
# 还没从 npm 装(或想装预构建包):直接装 Release 里的 tarball
dsh plugin --profile desktop add "https://github.com/MuyuYanran/dsh-rea-mcp-lite/releases/latest/download/dsh-rea-lite-panel.tgz"

发到 npm 的包里自带一份网关(gateway/:src/ + 工具快照 + 配置模板),装进 node_modules 以后没有「仓库根的 src/」也能跑;在仓库里开发时仍以仓库根的 src/ 为准,副本只是兜底。

面板不负责注册 MCP 服务器,所以还要在 profile 的 cordis.patch.yml 里加一行(与源码安装同一份写法, args 指向包内的副本即可):

- insert:
    - id: rea-mcp
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: rea
        transport: stdio
        command: node
        args:
          - <profile>/node_modules/dsh-rea-lite-panel/gateway/src/proxy.mjs
        env:
          REA_LITE_CONFIG: <固定路径>/rea-lite/config.json
        failOnStartupError: false

REA_LITE_CONFIG 别放进 node_modules(例如用 %USERPROFILE%\.dsh\rea-lite\config.json): 插件升级会整目录替换,配置写在包内会跟着一起被换掉。把它同时设成本机环境变量,面板与代理才会读写同一份配置。

配置项

键

默认

说明

activeBundles

[]

常驻功能族

metaTools

true

是否暴露 5 个元工具(关掉就只剩 activeBundles)

lite

"mild"

off | mild | aggressive,暴露时的 schema/描述裁剪力度

shortDescription

true

只给一句话描述(完整说明仍可从 tool_schema 拿到)

persistRuntimeSwitch

true

运行时切换是否写回配置文件

toolCallTimeoutMs

600000

单次工具调用超时(反编译类工具有时会跑很久)

customBundles

{}

用户自定义族:{ id: { label?, hint?, tools: [...] } }

bundleExtras

{}

自动归类追加到内置族的工具:{ "capture": ["inspect_x"] }(只追加,不替换)

presets

—

已移出 config.json:预设存在独立文件 <用户数据根>/rea-lite/presets.json,这样更新插件不会清掉它们(详见「命名预设」)。这里只作为一次性迁移来源:读到旧副本就搬走并清理

updates.self

{ remote: "origin", checkOnStart: false }

本仓库更新;autoApply: true 才会在启动时自动快进

updates.rea

{ registry: "https://registry.npmjs.org/rea-agents", checkOnStart: false }

REA 本体更新;autoApply: true 才会在启动时自动升级

child

—

怎么拉起真正的 REA:command / args / env

  • lite 的 mild 去掉 pattern/format/minLength… 并把描述截到 80 字;aggressive 再砍 examples/default 并截到 50 字。被裁掉的约束 REA 服务端仍会校验,报参数错误时用 tool_schema 取原始 schema。

  • 环境变量:REA_LITE_CONFIG 指定配置文件位置,REA_LITE_LAUNCHER 覆盖 REA 启动器路径;REA_LITE_PRESETS / REA_LITE_DATA_DIR 指定预设存储(见上)。

  • child.env 会合并进 REA 子进程的环境,是给 REA 指定外部工具的入口(REA_TSHARK_COMMAND 等)。 改动 child(command/args/env)会触发子进程热重启:代理杀掉旧 REA、用新配置重新 spawn、 重放握手、重取工具列表,再向客户端发 notifications/tools/list_changed—— 所以补工具路径不必重启 DSH。(activeBundles / lite 这类则照旧走轻量热更新。)

自检

node test/probe.mjs         # 28 项集成测试:握手 / 元工具 / 搜索 / 转发 / 热加载 / 热卸载 / 全量 / 自定义族 / 预设
node test/plugin.test.mjs   # 91 项插件自检:假 Cordis 上下文驱动面板 API + 渲染设置页
node test/maintenance.test.mjs # 190 项:归类打分 / 追加归类 / 工具覆盖 / 版本比较 / 临时真仓库的 git 快进 / 预设 / 预设独立存储 / DSH 内核兼容声明 / 面板新接口
node test/panel-render.test.mjs # 68 项:用最小 React 运行时真的重渲染设置页(含「更新与体检」「预设」「跟随宿主语言」各分支)
node test/reload-child.mjs  # 6 项子进程热重启:改 child.env → 重启 REA → 重新握手 → 重取工具列表 → 通知客户端
node test/check-config.mjs  # 用真实 config.json 拉起 REA,确认全部工具可达
node e2e-check.mjs          # 9 项外部工具验收:真实代理 → 真实 REA → 真实 objdump/rizin/tshark/WABT/SQLite/Frida/Cutter
node src/cli.mjs snapshot   # 重新生成工具成本快照 data/tools-model.json

对应的 npm 脚本:npm run test:panel / test:maintenance / test:reload / test:e2e / test:config / probe / snapshot / check / doctor / classify。

这些断言都不写死工具数量与 token 总量——它们随 REA 版本漂移(6.4.0 = 170 工具 / ~49k tok, 6.7.0 = 207 工具 / ~26.9k tok,6.8.0 = 229 工具 / ~35.5k tok)。基准一律从快照文件派生。

改代码前建议先读 AGENTS.md:那里记了这个仓库的十条硬约束、代码地图、以及已经踩过的坑。

debug / formats / capture 三族的外部工具

这三族调用原生工具(objdump、rizin、GDB、tshark、WABT、sigrok-cli、Cutter), 而 REA 明确不安装它们,只在运行时按 PATH 或 REA_*_COMMAND 找。因此需要在操作系统里单独装, 并把绝对路径写进 child.env(见 config.example.json)。

本机的安装、选型理由、Windows 上的真实可用性(哪些通路被 REA 源码硬判平台而拒绝)、 以及遇到的上游坑(Cutter 2.5.0 Windows 无法加载 Python 插件、缺 libffi-8.dll 等), 全部记录在 _Tools/README-rea-target-env.md,配套入口脚本 _Tools/rea-target-env.sh。

配套的模型侧说明

  • skill/SKILL.md —— 独立的"网关模式"技能,教模型用这些元工具(可复制到 ~/.agents/skills/rea-tool-gateway/)。

  • 若已安装 REA 官方技能 reverse-engineer-anything,建议在其 SKILL.md 顶部加一段说明:工具列表只剩元工具时,照常用 call_tool 干活(本仓库 README 的措辞可直接借用)。

已知限制

  • 首次握手会向 REA 拉一次全量工具表(6.8.0 为 229 个 / 约 3.3MB,本机实测约 1.5s 完成握手+列表,这个数跟机器和磁盘缓存有关,只作量级参考),之后走缓存。

  • 被裁剪的 schema 关键字让调用前的参数预校验变松,错误会晚一步由 REA 抛出(表现为工具返回结构化错误)。

  • 仅代理 stdio 类 MCP;mode: "direct" 是预留字段,未实现绕过网关的分支。

  • DSH 的 LLM 层已有 defer_loading 字段(tool.deferLoading)。若将来 DSH 允许在 MCP 工具上开启它,原生方案会比本代理更省;目前用不上,列为后续方向。

  • 工具成本快照 data/tools-model.json 里的数字随 REA 版本变化,切换版本后应重跑 node src/cli.mjs snapshot, 否则设置页显示的是旧版本的成本。

  • 自动归类只处理名字/描述里的词。REA 若引入全新领域(例如无线抓包),专属词在旧族里一个都没有, 它会诚实地报「low / 无建议」而不是硬猜;这时用 classify 打印的题面让模型判断,再由 --set 写入。

  • 更新检查依赖外网(git 远端 / npm registry)。离线时 check 会在对应块写「取远端失败」而不影响其它块; 面板默认用快照算覆盖,所以离线也能看到未归族清单。

本机部署记录(作者环境)

  • 代理接管的条目在本机 ~/.dsh/cordis.patch.yml 的 rea-mcp(serverName: rea),备份为 cordis.patch.yml.bak-rea-lite-*。

  • probe/ 里是推导上面那些数字的分析脚本与原始抓包(大体积文件已 .gitignore)。

  • 分析脚本:probe/inspect-asar.mjs(解析 Electron app.asar)、probe/asar-grep.mjs(在 asar 内做内容检索)、probe/analyze-tools.mjs、probe/inspect-shape.mjs、probe/write-names.mjs。

License

MIT

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      F
      maintenance
      Enables AI models to dynamically create and execute their own custom tools through a meta-function architecture, supporting JavaScript, Python, and Shell runtimes with sandboxed security and human approval flows.
      5
      10
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      A flexible proxy that enables discovery and execution of tools across multiple Model Context Protocol (MCP) servers and JavaScript functions, reducing context size even when dealing with hundreds of tools.
      51 npm
      11
      ISC
    • F
      license
      Not graded
      quality
      D
      maintenance
      A context-efficient proxy that replaces individual tool schemas with three meta-tools for semantic search, schema retrieval, and tool routing. It enables agents to manage hundreds of backend tools while maintaining a constant context footprint of approximately 500 tokens.
      1
      -