dsh-matlab-mcp 0.0.0-stage → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,190 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this
6
+ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### 发布
11
+
12
+ - **发布准备就绪**:`npm pack` 复核通过(35 文件 / 压缩 421.9 kB;含自包含 `lib/`、`cordis.patch.yml`、README、LICENSE;`dependencies` 为空 → 安装即用、无需构建)。npm 现要求发布时提供 2FA 动态码:`npm publish --access public --registry=https://registry.npmjs.org --otp=******`(注意本机 npm 默认 registry 是只读镜像 npmmirror,必须显式指定官方源)。
13
+ - 新增 `.github/workflows/publish.yml`:推 tag 即发布,优先走 **npm trusted publishing(OIDC,无 token、带 provenance)**;`workflow_dispatch` 可只打包不发布。首次发布因包尚不存在,需手动 `--otp` 完成,之后在 npmjs.com 配置 Trusted Publisher 即可交给 CI。
14
+ ## [0.7.1] - 2026-10-14
15
+
16
+ ### 修复
17
+
18
+ - **`deploy/proxy-config.mjs` 非默认端口漏端口**:`--port 8443` 时生成的 `proxy_redirect` 目标与 `downloadMirror` 行都不带端口(指向 80/443),客户端第一跳就会走进死路。现在引入 `authority`(默认端口省略、非默认端口补上),三处 `proxy_redirect`、镜像行与验证命令统一使用它。
19
+
20
+ ### 新增
21
+
22
+ - **`deploy/DEPLOY.md`**:服务器部署详细流程 —— 现状勘察(含按发行版/宝塔/1Panel/Docker 判断配置目录)、备份、放文件、`nginx -t` + `reload`、本机 curl 判读表、安全组放行、插件填一行、回滚,以及**未备案决策树**(非标端口 / IP 直连 / 境外机器)。
23
+ ## [0.7.0] - 2026-10-14
24
+
25
+ ### 变更
26
+
27
+ - **划清边界:服务器侧部署工具移出插件目录**。原先放在 `scripts/` 的 `mirror-assets.mjs`(建静态镜像)与 `proxy-config.mjs`(生成 nginx 反代配置)移到 [`deploy/`](deploy/README.md),并配独立 README 说明「这不是插件的一部分、npm 包也不包含它」。
28
+ - `scripts/` 现在只剩插件侧内容:`install.mjs`(把插件装进 DSH)与各类验证探针。
29
+ - 插件 README 把原来大段的 nginx/备案/端口内容压成一小节「制品获取(镜像 / 本地目录)」:只保留插件自身需要配置的 `downloadMirror` / `localAssetsDir`,其余指向 `deploy/`。
30
+ - 插件运行逻辑不变:这两个字段是插件「从哪取制品」的配置能力(默认关闭/空值),与制品如何部署到服务器上无关。
31
+ ## [0.6.1] - 2026-10-14
32
+
33
+ ### 修复
34
+
35
+ - **`proxy-config.mjs` 在 IP 场景不可用**:`--host` 给 IP 时原来仍生成 `listen 443 ssl` + 证书占位符,而 IP 一般拿不到公共 CA 证书(实测 `dl.159.75.130.207` 这类「前缀+IP」连 DNS 都解析不了)。现在按主机名自动选择:IP → `--scheme http`(`listen 80`,不生成 ssl 指令)并给出提示;域名 → HTTPS。新增 `--scheme` / `--port` 显式覆盖。
36
+ - **反代下 19.5 MB 二进制缓存永远 MISS**:release 资产的最终 URL 带**会轮换的签名串**(`?sp=…&se=…&sig=…`),而 nginx 默认把整个 request URI 计入 cache key。生成配置现在给 `/mp-assets/` 指定 `proxy_cache_key "$scheme$request_method$host$uri"`(仅按路径),并加 `proxy_read_timeout/send_timeout 300s`。
37
+ - 生成文件的头部注释补充放置位置说明(Debian/Ubuntu 的 `conf.d` 已在 `http{}` 内;CentOS/宝塔注意 `server{}` 上下文)。
38
+
39
+ ## [0.6.0] - 2026-10-14
40
+
41
+ ### 新增
42
+
43
+ - **服务器反代配置生成器 `scripts/proxy-config.mjs`**:输出可直接粘贴的 nginx 片段(三段上游 + 缓存 + Range 透传 + 安全限制)与对应的 DSH 镜像行,适合「不占磁盘、配置即用」的部署。
44
+ - 实测跳转链决定了配置形态:`…/releases/latest/download/X` → **github.com**(同主机换 tag)→ **release-assets.githubusercontent.com**(19.5 MB 二进制终态);`…/archive/refs/heads/main.zip` → **codeload.github.com**。nginx 不跟随跳转,因此 `codeload` 与 `release-assets` 各需独立 `location` **并**用 `proxy_redirect` 把跳转留在代理内,否则客户端会绕过代理直连 GitHub CDN。
45
+ - 生成的配置默认包含 `limit_except GET HEAD` 与 `client_max_body_size 1m` 以**避免开放代理**,并加 `X-Mirror-Cache` 便于验证缓存命中。
46
+ - **本地制品目录 `localAssetsDir`**(可选、完全离线):命中 `mirror-assets.mjs` 产出的目录树时**直接复制、零网络请求**;优先级 本地目录 → 镜像列表 → 直连。适合内网/断网机器与「一次拷贝、多机复用」。
47
+
48
+ ### 变更
49
+
50
+ - 供给日志区分来源:`本地目录 / local`、`镜像 / via mirror` 或直连。
51
+
52
+ ## [0.5.0] - 2026-10-14
53
+
54
+ ### 新增
55
+
56
+ - **自建镜像工具 `scripts/mirror-assets.mjs`**:在一台网络好的机器上跑一次,产出可整体上传的静态目录树(按 GitHub 路径排布,因此一个 `{path}` 模板即可覆盖全部制品)、`mirror.json`(路径 + 字节数 + sha256)、`nginx.conf.example` 与 `README.txt`(上传/部署/验证清单)。
57
+ - 实测:4 个文件合计 **38.4 MB**(二进制 19.5 MB + 工具箱 0.06 MB + 两个 zipball 4.1/16.4 MB),经 `gh-proxy.com` 拉取 5.22 / 0.06 / 4.12 / 13.55 MB/s。
58
+ - 支持 `--via <模板>`:抓取时也可走镜像;`--out` / `--base-url` / `--asset` / `--force`。
59
+ - **端到端验证**:本地起静态服务器模拟「用户自己的服务器」,在**隔离的 DSH_HOME** 里跑插件的真实供给流程 —— 二进制 `v0.14.0 (via mirror)`、工具箱 `via mirror`、两个技能仓均从该服务器下载,`ready: true`。
60
+ - 文档新增「自建镜像」一节:静态模式(推荐)与反向代理模式的取舍,以及**开放代理风险**的明确警告(不得做成对全路径开放的 GitHub 代理)。
61
+
62
+ ### 说明
63
+
64
+ - 静态模式对服务器零副作用:不新开端口、不访问外网、无缓存进程;磁盘占用即上表 38.4 MB,CPU/内存开销可忽略。
65
+ - 许可提示:把 MathWorks 制品放到**自己的服务器供自己使用**属于私有使用;发布到公共 registry/公开站点则构成再分发,需遵守其许可证(保留版权与许可声明、仅配合 MathWorks 产品使用)。
66
+
67
+ ## [0.4.0] - 2026-10-14
68
+
69
+ ### 修复
70
+
71
+ - **严重:点「一键安装 / 修复」后 DSH 客户端崩溃**(`dsh: fatal uncaught exception: Error: spawn ...bin\matlab-mcp-server-windows-x64.exe ENOENT`)。
72
+ - **根因不是文件缺失**:libuv 在 **`cwd` 不存在**时同样报 `spawn <exe> ENOENT`(错误指向命令,实为 chdir 失败)。挂载配置的 `cwd` 指向 `<DSH_HOME>\matlab-mcp\workspace`,而全新机器上该目录从未被创建(一键安装只建了缓存根与 `logs/`)。新机器时间线:启动时还没有二进制 → 不挂载(安全)→ 点安装 → 二进制就位 → 路由 `reconnect()` → 用不存在的 `cwd` 启动 → 未捕获异常 → 宿主退出。
73
+ - **实测对照**:同一个真实存在的 exe,`cwd` 正常 → `spawned ok`;`cwd` 不存在 → `ENOENT`,与崩溃日志逐字一致。
74
+ - **修复(多层防护)**:① `buildLaunch` 构造启动配置时创建 `cwd` 与 `--log-folder`;② 挂载前用我们自己的 `execFile` 做 `--version` 预检,跑不起来的二进制不再交给 MCP 客户端,改为可操作报错;③ 挂载配置在 `ctx.inject(['tools'])` 回调内**现算**,压掉「检查存在」与「真正 spawn」之间的窗口;④ `probeMcp` 补上 `child.on('error')`(此前缺该监听,同样会变成未捕获异常);⑤ 下载改为**暂存校验后再原子换入**(校验在 `.partial` 上做),失败只清理暂存文件;`ensureBinary` 不再「先删后下」,也不再对下载后跑不起来的二进制返回成功。
75
+ - **这是 DSH 侧 `dsh-mcp-client` 的健壮性缺陷**:子进程 `spawn` 失败以未捕获异常终止宿主。插件已从自身侧消除可预见的触发条件,仍建议向上游反馈「`ChildProcess` 的 `'error'` 事件必须被捕获」。
76
+
77
+ ### 变更
78
+
79
+ - **多镜像 + 镜像优先**:`downloadMirror` 改为逗号分隔的模板列表(支持 `{url}` 前缀式、`{path}` 换主机式,兼容老的纯前缀写法);开启镜像后**镜像优先、直连兜底**(实测直连 0.21 MB/s vs 镜像 2.5–9.5 MB/s)。
80
+ - **默认镜像按实测重排**:`gh-proxy.com` → `gh.llkk.cc` → `ghproxy.net`(2026-10-14 关梯子实测:gh-proxy.com 2.53 MB/s / codeload 9.51 MB/s,ghproxy.net 0.03 MB/s,其余候选全部不通)。
81
+ - **技能仓优先走 zipball**(开启镜像时):codeload 经镜像实测 9.5 MB/s(40 MB ≈ 5 秒);`git clone` 直连 GitHub、绕不过镜像,退居兜底。解压成功后才切换目录,失败不会毁掉已有技能仓。
82
+ - **设置卡新增「镜像测速」**:对真实制品测 TTFB 与吞吐,并可一键「把最快的排到最前」——镜像存活期常常只有几小时,写死排序必然过期。
83
+ - README 排障表补充:崩溃日志读法(`ENOENT` ≠ 文件不存在)与杀毒软件隔离的应对。
84
+
85
+ ## [0.3.1] - 2026-10-14
86
+
87
+ ### 修复
88
+
89
+ - **内联版在 DSH 里加载失败(`matlab-mcp (dsh-matlab-mcp): failed to import`)**:
90
+ - **现象**:0.3.0 的 `lib/index.js` 在 `node -e`、DSH 自带 Node、Electron-as-Node 三种独立进程里都能 import,但 DSH 启动时该 entry 的 `fiber` 始终是 `undefined`(`dsh-app-boot` 把 `fiber === undefined` 归类为 `failed to import`,真实异常只打到控制台)。
91
+ - **定位**:把 DSH 宿主的 Electron 进程当作测试环境(`run_code` 就运行在其中),用与加载器相同的 `await import(file://…)` 复现出真实异常:
92
+ `Error: Dynamic require of "child_process" is not supported at lib/index.js:11:9`(栈上是 `cross-spawn` ← MCP SDK)。
93
+ - **根因**:把 CJS 依赖内联进 ESM bundle 后,esbuild 会把它们的 `require('child_process')` 改写成 `__require` 垫片;ESM 里没有 `require` 绑定时该垫片直接抛错 —— 只有真正走到宿主加载路径才会触发。
94
+ - **修复**:`build.mjs` 给宿主 bundle 加 banner,用 `createRequire(import.meta.url)` 恢复 CJS 全局(`require` / `__filename` / `__dirname`)。
95
+ - **验证**:在宿主 Electron 进程内 `await import()` 成功,`resolveConfig` / `Config` / `buildLaunch` 均正常。
96
+ - **CI 增补**:`inlined CJS dependencies must have their globals`(检查 banner 关键字)与 `the host bundle must import cleanly`(真实 import + 导出形状断言),防止同类问题再溜过去。
97
+
98
+ ## [0.3.0] - 2026-10-14
99
+
100
+ ### 变更
101
+
102
+ - **插件改为「clone 下来就能用」**:
103
+ - 宿主 bundle 现在**内联全部运行时依赖**(`@deepseek-ai/dsh-mcp-client`、`dsh-settings`、`schemastery` 等),`lib/index.js` 只依赖 Node 内置模块 —— 实测把 `node_modules` 整个移走后仍能 `import` 成功(`IMPORT OK -> Config,MATLAB_MCP_SETTINGS_NAMESPACE,apply,buildLaunch,inject,resolveConfig`)。
104
+ - **`lib/` 随仓库提交**(移出 `.gitignore`),新客户端 `git clone` 后无需 `pnpm install` / `pnpm build` 即可加载。
105
+ - `scripts/install.mjs` 相应简化:不再强制安装依赖与构建,只做接线(建 `%DSH_HOME%` 联接 → 写 profile → 建立/修复 `node_modules` 联接),**没有 pnpm 也能装**;新增 `--rebuild` 供开发者从源码重建。
106
+ - **CI(`.github/workflows/check.yml`)**:每次 push 跑 `typecheck` + 6 套测试 + `build`,并校验 ① `lib/` 与全新构建一致(不会悄悄过期)② `lib/index.js` 里不再残留 `@deepseek-ai/*` 外部 import(保证自包含)。
107
+ - `dependencies` 清空(依赖已内联),相关包移入 `devDependencies`。
108
+
109
+ ## [0.2.1] - 2026-10-14
110
+
111
+ ### 新增
112
+
113
+ - **新客户端一键安装器 `scripts/install.mjs`**:`git clone` 后在仓库里跑 `node scripts/install.mjs` 即可完成全部接线 ——
114
+ ① 仓库内 `pnpm install`(`prepare` 顺带构建 `lib/index.js`);
115
+ ② 在 `%DSH_HOME%` 建 `matlab-mcp-plugin` 联接指向仓库(同盘路径,规避 pnpm 跨盘 `link:` 问题);
116
+ ③ 给每个存在的 profile 写 `dependencies` / `dsh.profile.bundles` / `cordis.patch.yml`;
117
+ ④ 在 profile 内 `pnpm install`,并**统一修复所有失效的 `link:` 联接**(含其它本地插件);
118
+ ⑤ 打印后续步骤。支持 `--dry-run` / `--profile <name>` / `--skip-profile-install`,`pnpm` 缺失时给出 DSH 自带 pnpm 的用法。
119
+
120
+ ### 修复
121
+
122
+ - **新客户端启动报 `matlab-mcp (dsh-matlab-mcp): failed to import`**:根因是仓库按惯例不提交构建产物(`lib/` 被 `.gitignore` 排除)且插件从自身 `node_modules` 解析 `@deepseek-ai/*`,全新克隆后两者都不存在。安装器与文档(README「安装」第 0 节 + 排障表)现在明确覆盖这一路径。
123
+
124
+ ## [0.2.0] - 2026-10-14
125
+
126
+ ### 新增
127
+
128
+ - **聊天主界面「打开 MATLAB」按钮**:注册到会话标题栏动作位 `conversation.session.header.actions`(独立于设置页的第二个 UI 入口),点击即打开 MATLAB 桌面窗口。
129
+ - `new` 会话模式:打开独立 MATLAB 桌面窗口,按钮提示里说明 Agent 使用的是它自己启动的会话。
130
+ - `auto` / `existing` 会话模式:以 `-r shareMATLABSession` 打开**共享**会话,MCP 服务器随后连到同一个 MATLAB —— 你能在窗口里直接看着 Agent 干活。
131
+ - 以 `detached + unref` 启动,窗口独立于插件生命周期:插件卸载不会关掉它(脚本 `scripts/open-matlab.ts` 实测:新 MATLAB 进程出现,且归属判定为「非本插件所有」)。
132
+ - 新增宿主路由 `POST /api/dsh-matlab-mcp/open-matlab` 与 `buildMatlabDesktopArgs` 单测。
133
+
134
+ ## [0.1.0] - 2026-10-14
135
+
136
+ 首次发布:把 DSH 接到 MathWorks 官方 MATLAB MCP Server,实现「用自然语言让 Agent 自己动手跑 MATLAB / Simulink」。
137
+
138
+ ### 新增
139
+
140
+ - **宿主半边**
141
+ - 通过 `@deepseek-ai/dsh-mcp-client` 以 stdio 挂载官方 MATLAB MCP Server,工具命名空间 `mcp__matlab__*`。
142
+ - 启动参数构造:`--matlab-root`、`--matlab-session-mode`、`--matlab-display-mode`、`--initial-working-folder`、`--extension-file`、`--log-folder`、`--log-level`、`--disable-telemetry`;`sessionMode=existing` 时按上游要求省略 root/folder/display。
143
+ - 子进程环境显式传递 `windir`/`SystemRoot`/`PATH`/`TEMP` 等:上游 Simulink 文档指出剥离环境变量会导致 Simulink 失败,而 DSH 的 MCP 客户端只把配置里的 `env` 合并进脱敏环境。
144
+ - 单次工具调用超时默认 600000 ms(MATLAB 冷启动 20–45 秒,仿真可达数分钟),上限 1800000 ms。
145
+ - 挂载串行化 + 等待上一次 fiber 释放(MCP 客户端对 `serverName` 有唯一性守卫)。
146
+ - 系统提示词注入(`plugin:matlab-mcp`,order 212):工具用法、时间预期、图窗必须导出 PNG 才能被看见、Simulink 优先用专用工具、先探测产品再动手、错误先加载调试技能。
147
+ - 多代设置接缝自适应(0.2 `configure` / 0.1.5 `installSection` / ≤0.1.1 `register`),`volatile` 配置活值解包(复用同族插件的排查结论)。
148
+ - **一键供给**(`POST /api/dsh-matlab-mcp/setup`)
149
+ - 下载并校验官方 MCP 服务器二进制(PE 魔数 + `--version`,按平台选制品名)。
150
+ - 下载 `MATLABMCPServerToolbox.mltbx` 并调用 `matlab -batch "matlab.addons.toolbox.installToolbox(...)"` 自动安装。
151
+ - `git clone --depth 1`(失败则 zip 下载 + `tar -xf` 兜底)同步 MATLAB / Simulink Agentic Toolkit。
152
+ - `addpath(genpath(<simulink-toolkit>/tools))` + `savepath`,让 9 个 Simulink 扩展工具的函数在每个 MATLAB 会话可见。
153
+ - 幂等:已存在且可用的制品直接复用。
154
+ - **下载策略**(`src/download.ts`)
155
+ - 直连优先;**镜像默认关闭**,直连失败且未开启镜像时抛出带有可操作提示的错误码 `MIRROR_DISABLED`。
156
+ - 原子写入(`.partial` → rename)、空文件拒绝、可插拔校验回调。
157
+ - **技能注入**(`src/skills-catalog.ts`、`src/skills-provider.ts`)
158
+ - 实现 DSH `SkillProvider`,扫描两个工具包 `skills-catalog/**/SKILL.md`(含 frontmatter 与 `manifest.yaml` 的 `requires-products`)。
159
+ - 按技能组过滤,默认 6 组共 32 个技能;`none` 关闭全部;rank 500(用户自有技能优先)。
160
+ - 设置变更或工具包同步后 `invalidate()` 热刷新。
161
+ - **进程卫生**(`src/matlab-processes.ts`)
162
+ - 插件卸载时按父子进程链判定「由本插件 MCP 服务器启动的 MATLAB」并关闭;手动打开的 MATLAB 不受影响。
163
+ - **设置卡**(浏览器半边)
164
+ - 14 个字段、状态面板(二进制版本 / 工具箱 / 技能仓 / MATLAB 路径)、6 个动作按钮(保存、一键安装修复、测试连接、深度自检、重连、刷新状态、恢复默认)。
165
+ - 独立的设置命名空间桥(`/settings/describe`、`/settings/mutate`),与 DSH 0.1.5 / 0.2 两代兼容。
166
+ - **文档**:中文为主 README、英文 README、`docs/tools.md`(14 个工具的参数说明)、`scripts/`(可复跑的真实验证脚本)、验收记录 `docs/acceptance-2026-10-14.md`。
167
+
168
+ ### 修复
169
+
170
+ - **Windows 下 `matlab -batch` 吞掉内层双引号**:`matlab -batch "disp(\"x\")"` 会被拆词,导致安装工具箱、`savepath`、`which` 全部失败且 stdout 为空。改为把代码写入 `<cache>/tmp/<name>.m`,以「`-batch <脚本名>` + `cwd` 指向该目录」执行 —— 单一 token、无引号,任意代码(含引号与换行)都能安全通过。
171
+ - **`src/index.ts` 的路由 `getConfig` 类型**:暴露解析后的配置(`ResolvedConfig`)而不是原始活值配置。
172
+ - **MATLAB 安装选择**:调用方传入的候选列表也会按发布版排序,避免「谁在后面谁生效」的隐式行为。
173
+
174
+ ### 说明
175
+
176
+ - 本仓库不携带任何 MathWorks 制品;二进制、`.mltbx` 与技能文本均在安装时从 MathWorks 官方 GitHub 下载且不修改。
177
+ - **profile 联接**:DSH 通过 profile 的 `node_modules` 解析插件包。pnpm 对 `link:D:/...`(与 profile 不同盘符)会生成无效联接,导致重启后所有本地插件都不加载。请使用 `link:C:/Users/<user>/.dsh/<name>-plugin` 形态(该路径做 `mklink /J` 指向仓库),或在 `pnpm install` 后用 `mklink /J` 修复 `node_modules/<name>`。
178
+
179
+ [Unreleased]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.7.1...HEAD
180
+ [0.7.1]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.7.0...v0.7.1
181
+ [0.7.0]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.6.1...v0.7.0
182
+ [0.6.1]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.6.0...v0.6.1
183
+ [0.6.0]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.5.0...v0.6.0
184
+ [0.5.0]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.4.0...v0.5.0
185
+ [0.4.0]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.3.1...v0.4.0
186
+ [0.3.1]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.3.0...v0.3.1
187
+ [0.3.0]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.2.1...v0.3.0
188
+ [0.2.1]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.2.0...v0.2.1
189
+ [0.2.0]: https://github.com/MCviseron/dsh-matlab-mcp/compare/v0.1.0...v0.2.0
190
+ [0.1.0]: https://github.com/MCviseron/dsh-matlab-mcp/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,55 @@
1
+ Apache License
2
+
3
+ Version 2.0, January 2004
4
+
5
+ http://www.apache.org/licenses/
6
+
7
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8
+
9
+ 1. Definitions.
10
+
11
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
16
+
17
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
18
+
19
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
20
+
21
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
22
+
23
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
24
+
25
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
26
+
27
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
28
+
29
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
30
+
31
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
32
+
33
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
34
+
35
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
36
+
37
+ You must give any other recipients of the Work or Derivative Works a copy of this License; and
38
+
39
+ You must cause any modified files to carry prominent notices stating that You changed the files; and
40
+
41
+ You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
42
+
43
+ If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
44
+
45
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
46
+
47
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
48
+
49
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
50
+
51
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
52
+
53
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
54
+
55
+ END OF TERMS AND CONDITIONS
package/README.en.md ADDED
@@ -0,0 +1,143 @@
1
+ # dsh-matlab-mcp
2
+
3
+ [中文](README.md) | **English**
4
+
5
+ A DeepSeek Harness (DSH) plugin that lets the agent **actually drive MATLAB and Simulink**: run MATLAB code, execute `.m` scripts and unit tests, statically check code quality, and read/edit/query/check/simulate Simulink models — all through the **official MathWorks MATLAB MCP Server**, with the **MATLAB / Simulink Agentic Toolkit** skills injected into the session.
6
+
7
+ > This is not "an AI inside MATLAB". It is the other way round: **MATLAB is exposed as an MCP server that DSH calls**. The plugin only mounts the official server, provisions the official artifacts, and registers the official skills.
8
+
9
+ ```
10
+ you ──natural language──▶ DSH agent
11
+ ├─ tools mcp__matlab__<tool> ──stdio MCP──▶ MATLAB MCP Server (official exe) ──▶ MATLAB / Simulink
12
+ ├─ skills matlab-* / simulink-* ── from the two official Agentic Toolkits
13
+ └─ system-prompt guidance (call rules, timeouts, figure export, Simulink tool preference)
14
+ ```
15
+
16
+ ## Features
17
+
18
+ | Capability | Detail |
19
+ |---|---|
20
+ | Run MATLAB code | `mcp__matlab__evaluate_matlab_code` — code plus a project folder, returns the command-window output |
21
+ | Run scripts / tests | `run_matlab_file`, `run_matlab_test_file` |
22
+ | Static analysis | `check_matlab_code` — style, potential errors, deprecated functions, performance, best practices |
23
+ | Toolbox discovery | `detect_matlab_toolboxes` |
24
+ | Simulink model tools | `model_overview`, `model_read`, `model_query_params`, `model_resolve_params`, `model_edit`, `model_read_diagnostics`, `model_check`, `model_scan`, `model_test` |
25
+ | Expert skills | MathWorks Agentic Toolkit skills registered per group and loaded on demand through DSH's own `skill` tool |
26
+ | Open MATLAB button | A chat-header action opens a MATLAB desktop window; in `auto`/`existing` mode it opens a *shared* session so you watch the agent work in the same MATLAB |
27
+ | One-click setup | Downloads the official binary, the MATLAB-side toolbox and both toolkit repositories, then registers the Simulink toolkit path — **no manual step in MATLAB** |
28
+ | No manual operation | Default `sessionMode=new`: the plugin starts MATLAB itself (desktop visible) and you just talk to the agent |
29
+ | Network fallback | Optional mirror for blocked networks (**off by default**; only used after a direct failure, with PE/ZIP magic verification) |
30
+ | Process hygiene | On unload the plugin stops the MATLAB **it** started (decided by process parentage); a MATLAB you opened yourself is never touched |
31
+
32
+ ## Upstream components
33
+
34
+ | Upstream | Role | What this plugin does |
35
+ |---|---|---|
36
+ | [`matlab/matlab-mcp-server`](https://github.com/matlab/matlab-mcp-server) (official Go binary) | The MCP server itself, mounted over stdio by DSH's `@deepseek-ai/dsh-mcp-client` | Download, verify, cache, build arguments and child environment |
37
+ | `MATLABMCPServerToolbox.mltbx` (same release) | Provides `shareMATLABSession()` for attaching to an existing MATLAB | Download and install automatically via `matlab -batch` |
38
+ | [`matlab/matlab-agentic-toolkit`](https://github.com/matlab/matlab-agentic-toolkit) | 24 groups of MATLAB skills | Sync locally, register as DSH skills |
39
+ | [`matlab/simulink-agentic-toolkit`](https://github.com/matlab/simulink-agentic-toolkit) | 11 groups of Simulink skills + 9 MCP extension tools | Sync, register skills, `addpath`+`savepath` the tool functions, pass `tools/tools.json` as `--extension-file` |
40
+
41
+ **Why a plugin at all?** DSH's MCP client bridges **tools only** — *"MCP resources and prompts are unsupported"*. So tools travel over MCP while the domain knowledge (the official MCP resources and the Agentic Toolkit skills) is injected through DSH's skill registry. That split is the whole point of this plugin.
42
+
43
+ ## Requirements
44
+
45
+ | Item | Requirement | Verified here |
46
+ |---|---|---|
47
+ | MATLAB | R2021a+ (Simulink tools need R2023a+, `model_test` needs Simulink Test) | **R2025b (25.2.0.2998904)** with Simulink, Stateflow, Simulink Test, … (110 products) |
48
+ | DSH | 0.1.5+ (adapts to the 0.1.5 and 0.2 settings seams) | 0.2 series |
49
+ | Node.js | `^22.19.0 \|\| >=24` | v22.19.0 |
50
+ | Network | GitHub reachable for the first install; a mirror switch exists for restricted networks | direct link unstable, mirror works |
51
+
52
+ ## Install
53
+
54
+ ### Direct install (recommended, two commands)
55
+
56
+ ```powershell
57
+ git clone https://github.com/MCviseron/dsh-matlab-mcp.git D:\dsh-matlab-mcp
58
+ node D:\dsh-matlab-mcp\scripts\install.mjs # add --dry-run to preview
59
+ ```
60
+
61
+ **No `pnpm install`, no build step**: the repository ships `lib/` and the host bundle inlines every runtime dependency (`@deepseek-ai/dsh-mcp-client`, …), so only Node built-ins are needed at runtime. The installer just wires it up: creates the `<DSH_HOME>/matlab-mcp-plugin` junction, writes every profile's `dependencies` / `dsh.profile.bundles` / `cordis.patch.yml`, materializes (and repairs) the `node_modules` links — working with or without pnpm — and prints the next steps. Then restart DeepSeek Harness.
62
+
63
+ > CI (`.github/workflows/check.yml`) rebuilds on every push and fails when `lib/` is stale or when the bundle still imports `@deepseek-ai/*`, so the committed build output cannot silently drift.
64
+
65
+ ```powershell
66
+ # 1) link this repository into the DSH home
67
+ cmd /c mklink /J "$env:DSH_HOME\matlab-mcp-plugin" "D:\Program\DSH-Plugin-Class\dsh-matlab-mcp"
68
+
69
+ # 2) add to the profile package.json
70
+ # dependencies: "dsh-matlab-mcp": "link:C:/Users/<you>/.dsh/matlab-mcp-plugin"
71
+ # dsh.profile.bundles: [ ..., "dsh-matlab-mcp" ]
72
+
73
+ # 3) add the config row to the profile cordis.patch.yml (see README.md)
74
+
75
+ # 4) install the link and restart DeepSeek Harness
76
+ cd "$env:DSH_HOME\profiles\web"; pnpm install
77
+ ```
78
+
79
+ Then open **Settings → MATLAB / Simulink MCP** and press **Install / repair**. It downloads the MCP server binary into `$DSH_HOME/matlab-mcp/bin/`, installs the MATLAB toolbox, clones both toolkits, registers the Simulink toolkit path, and remounts the MCP client. Tools then appear as `mcp__matlab__*`.
80
+
81
+ ## Artifact sources
82
+
83
+ The plugin downloads the MathWorks artifacts straight from GitHub by default. A mirror list (`downloadMirror`) and a local asset directory (`localAssetsDir`) are optional; both are documented in the configuration table below. **Server-side deployment tooling is not part of the plugin** — self-hosted static mirrors and nginx reverse-proxy config generation live in [`deploy/`](deploy/README.md).
84
+
85
+ ## Configuration
86
+
87
+ | Field | Default | Meaning |
88
+ |---|---|---|
89
+ | `enabled` | `true` | Dispose the MCP client and unregister tools when off |
90
+ | `announceToAgent` | `true` | Inject MATLAB usage rules into the system prompt |
91
+ | `matlabRoot` | `""` | Empty = auto-detect the newest installation |
92
+ | `sessionMode` | `new` | `new` start our own / `auto` prefer a shared session / `existing` shared only |
93
+ | `displayMode` | `desktop` | `desktop` shows the MATLAB desktop, `nodesktop` is faster |
94
+ | `initialWorkingFolder` | `""` | Empty = `$DSH_HOME/matlab-mcp/workspace` |
95
+ | `simulinkTools` | `true` | Mount the 9 Simulink tools and register the toolkit path during setup |
96
+ | `skillsEnabled` | `true` | Register the Agentic Toolkit skills |
97
+ | `skillGroups` | `""` | Comma separated; empty = default groups; `none` disables all |
98
+ | `toolCallTimeoutMs` | `600000` | Per tool call; max 1800000 |
99
+ | `allowMirrorDownload` | `false` | Off by default; enables the mirror only after a direct failure |
100
+ | `downloadMirror` | `https://ghproxy.net/` | Mirror prefix; used only when the switch is on |
101
+ | `telemetry` | `false` | Off passes `--disable-telemetry=true` |
102
+ | `shutdownMatlabOnUnload` | `true` | Stop the MATLAB started by this plugin's MCP server on unload |
103
+
104
+ ## Tools and skills
105
+
106
+ - Full tool reference (14 tools): [`docs/tools.md`](docs/tools.md).
107
+ - Default skill groups (32 skills): `matlab-core`, `matlab-programming`, `matlab-software-development`, `matlab-data-import-and-analysis`, `model-based-design-core`, `simulink-simulation`. Add other group names to `skillGroups` to enable more (for example `matlab-app-building`, `ai-and-statistics`, `verification-validation-and-test`).
108
+ - Skill text is MathWorks content, unmodified; it is downloaded at install time and never redistributed by this repository.
109
+
110
+ ## Troubleshooting
111
+
112
+ | Symptom | Cause / fix |
113
+ |---|---|
114
+ | Error code `MIRROR_DISABLED` | Direct GitHub download failed and the mirror is off. Turn on "Allow mirror download" and retry |
115
+ | No `mcp__matlab__*` tools | The runtime is not provisioned yet. Press "Install / repair" |
116
+ | The first call takes 20–45 s | MATLAB cold start; later calls are fast |
117
+ | Tool call times out | Raise `toolCallTimeoutMs`, or turn a long job into a script plus a results file |
118
+ | Simulink tools report a missing function | The path-registration step did not run (it is skipped when `simulinkTools` is off); enable it and re-run setup |
119
+ | Logs | MCP server logs live in `$DSH_HOME/matlab-mcp/logs/`; "Refresh status" in the settings card shows binary version, MATLAB root and artifact presence |
120
+
121
+ ## Acceptance
122
+
123
+ Item-by-item acceptance with raw evidence lives in [`docs/acceptance-2026-10-14.md`](docs/acceptance-2026-10-14.md) (typecheck/tests/build, MCP handshake, MATLAB execution, Simulink simulation, skills, idempotent setup, process cleanup).
124
+
125
+ ## Development
126
+
127
+ ```bash
128
+ pnpm install
129
+ pnpm typecheck # tsc --noEmit
130
+ pnpm test # 5 pure-logic suites: config unwrapping, download policy, path detection, launch args, skill parsing
131
+ pnpm build # esbuild → lib/index.js (host) + lib/client.js (browser settings card)
132
+ pnpm check # all three
133
+ ```
134
+
135
+ ## Versioning
136
+
137
+ Semantic versioning with a git tag per release; changes are recorded in [CHANGELOG.md](CHANGELOG.md) (Keep a Changelog).
138
+
139
+ ## License and trademarks
140
+
141
+ - Plugin code: Apache-2.0 ([LICENSE](LICENSE)).
142
+ - **No MathWorks artifact is redistributed** by this repository: the binary, the `.mltbx` and the skill text are downloaded from MathWorks' official GitHub during installation and are not modified. See the upstream repositories for their licenses (the Agentic Toolkits are under a MathWorks license restricted to use with MathWorks products; see `matlab-mcp-server/LICENSE.md`).
143
+ - MATLAB, Simulink and MathWorks are trademarks of The MathWorks, Inc. This project is not affiliated with or endorsed by MathWorks.