mcp-multi-bridge 2.0.0 → 2.1.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/README.md CHANGED
@@ -13,12 +13,12 @@
13
13
  ## 安装
14
14
 
15
15
  ```bash
16
- npm i -g mcp-multi-bridge mes-login-cli
16
+ npm i -g mcp-multi-bridge mcp-multi-login
17
17
  ```
18
18
 
19
19
  两个包配合使用:
20
20
 
21
- - `mes-login-cli` 负责登录,把 token 写入本地文件
21
+ - `mcp-multi-login` 负责登录,把 token 写入本地文件(旧名 `mes-login-cli`,命令 `mes-login` 仍可用)
22
22
  - `mcp-multi-bridge` 负责读取 token 并转发请求
23
23
 
24
24
  > **从 `mes-mcp-bridge` 升级是破坏性的,按下面三步走**
@@ -108,7 +108,7 @@ mcp-multi-bridge --version | xargs echo "当前版本:"
108
108
  如果怀疑跑的不是自己想跑的那份(比如同时存在 `npm link` 的软链和全局安装),
109
109
  用 `--status` 看「安装位置」即可确认。
110
110
 
111
- `mes-login` 同样支持 `--version`。
111
+ `mcp-multi-login` 同样支持 `--version`。
112
112
 
113
113
  ## 配置 MCP 客户端
114
114
 
@@ -172,7 +172,7 @@ npm root -g
172
172
  1. 首次使用,或 token 过期时,执行登录:
173
173
 
174
174
  ```bash
175
- mes-login
175
+ mcp-multi-login
176
176
  ```
177
177
 
178
178
  2. 在打开的登录页里完成账号密码和图形验证码
@@ -183,7 +183,7 @@ npm root -g
183
183
 
184
184
  ## 未登录时的表现
185
185
 
186
- 工具调用会返回明确的引导文案,说明该执行 `mes-login` 以及要等人工完成验证码。模型拿到这段文字后可以自行发起登录。
186
+ 工具调用会返回明确的引导文案,说明该执行 `mcp-multi-login` 以及要等人工完成验证码。模型拿到这段文字后可以自行发起登录。
187
187
 
188
188
  ## 多组织
189
189
 
@@ -224,7 +224,7 @@ npm root -g
224
224
  | `hiddenArgs` | 跟随上面两个字段 | 对模型隐藏的参数。凭据与租户 ID 由本层填,露给模型只会引发「我该填什么」 |
225
225
  | `invalidCodes` | `[613,614,615,616]` | 视为「登录失效」的业务错误码,命中后返回重新登录引导 |
226
226
  | `invalidCodeReasons` | MES 的四个码 | 错误码说明,与默认值**合并**,只写要覆盖的项 |
227
- | `loginCommand` | `mes-login` | 登录引导里让模型执行的命令名 |
227
+ | `loginCommand` | `mcp-multi-login` | 登录引导里让模型执行的命令名 |
228
228
 
229
229
  > **租户 ID 由本层注入,不让模型填。** 网关的工具模板通常是
230
230
  > `{{if .args.orgId}}{{.args.orgId}}{{else}}1{{end}}` —— 不传就一律按 1 查,
@@ -239,7 +239,7 @@ npm root -g
239
239
  | 参数说明 | 要操作的组织标识 | 要操作的租户标识 |
240
240
  | 状态标题 | ## MES 组织状态 | ## ERP 中台租户状态 |
241
241
  | 更新提示 | 该组织尚未登录 | 该租户尚未登录 |
242
- | 引导命令 | `mes-login --org tc` | `erp-login --org tc` |
242
+ | 引导命令 | `mcp-multi-login --org tc` | `erp-login --org tc` |
243
243
 
244
244
  `orgKey` 这个参数名不会变——它是路由用的标识,改文案不影响调用方代码。
245
245
 
@@ -249,29 +249,62 @@ npm root -g
249
249
  不会让服务起不来。`systemName` 以汉字结尾时不加空格(「查询 ERP 中台的租户」),
250
250
  以拉丁字母结尾时加(「查询 MES 的组织」)。
251
251
 
252
- ## 配置目录
252
+ ## 配置目录与多系统并存
253
253
 
254
- **有默认目录:`~/.mes-mcp-login`**,不设环境变量就用它。
254
+ **默认目录 `~/.mes-mcp-login`**,不设环境变量就用它。现有用户升级后行为不变。
255
255
 
256
- 目录名仍带 `mes` 是**故意不改**的——`mes-login-cli` 把 `config.json` 和 `token.json`
257
- 写在这个路径下(写死,不支持环境变量)。桥接层的默认值必须与它一致,否则登录完
258
- 照样找不到文件。要改名得两个包一起改。
256
+ 目录名带 `mes` 是历史沿革:`mcp-multi-login` 的默认值也是它,两边必须一致,
257
+ 否则登录完桥接层找不到 token。要改名得两个包一起改。
259
258
 
260
- 所以 `MCP_BRIDGE_HOME` 的用途是**跑第二套系统时隔离**,不是改默认位置:
259
+ **同一个客户端接多套系统**时,每个 bridge 实例指向不同目录:
261
260
 
262
- ```bash
263
- # 第二套系统(非 MES)单独一份配置与登录态
264
- export MCP_BRIDGE_HOME=~/.erp-bridge
261
+ ```json
262
+ {
263
+ "mcpServers": {
264
+ "mes": {
265
+ "command": "mcp-multi-bridge",
266
+ "args": [],
267
+ "env": { "MCP_MULTI_HOME": "C:/Users/你/.mes-mcp-login" }
268
+ },
269
+ "erp": {
270
+ "command": "mcp-multi-bridge",
271
+ "args": [],
272
+ "env": { "MCP_MULTI_HOME": "C:/Users/你/.erp-login" }
273
+ }
274
+ }
275
+ }
265
276
  ```
266
277
 
267
- 目录里同样放 `config.json` 和 `token.json`,两套互不干扰,各自登录各自的 token。
278
+ 工具名由客户端加前缀区分(`mcp__mes__captchaGet` / `mcp__erp__captchaGet`),同名工具不冲突。
268
279
 
269
280
  | 环境变量 | 作用 | 默认 |
270
281
  |---|---|---|
271
- | `MCP_BRIDGE_HOME` | 配置目录 | `~/.mes-mcp-login` |
282
+ | `MCP_MULTI_HOME` | 配置目录 | `~/.mes-mcp-login` |
283
+ | `MCP_BRIDGE_HOME` | 同上(旧名,仍兼容) | — |
272
284
  | `MCP_BRIDGE_PATHS` | 限定本实例负责的 path,逗号分隔 | 不限制(全部加载) |
273
285
 
274
- > 旧名 `MES_MCP_PATHS` 仍兼容,`MCP_BRIDGE_PATHS` 优先。
286
+ > `MCP_MULTI_HOME` 优先于 `MCP_BRIDGE_HOME`;`MCP_BRIDGE_PATHS` 优先于旧名 `MES_MCP_PATHS`。
287
+
288
+ ### 登录引导会带上 `--home`
289
+
290
+ 未登录或登录失效时,本服务返回的引导命令是**完整可执行**的:
291
+
292
+ ```bash
293
+ mcp-multi-login --home "C:/Users/你/.mes-mcp-login" --org tc
294
+ ```
295
+
296
+ `--home` 指向本实例实际读取的目录,不能省——省了就会写到默认目录去,
297
+ 表现是「登录成功了但这边还是未登录」,非常难查。
298
+
299
+ 若登录命令不叫 `mcp-multi-login`(例如你用的还是旧包,只有 `mes-login`),
300
+ 用 `loginCommand` 改:
301
+
302
+ ```json
303
+ { "loginCommand": "mes-login" }
304
+ ```
305
+
306
+ > 新版登录包同时提供 `mcp-multi-login` 与 `mes-login` 两个命令,指向同一程序,
307
+ > 所以默认值用新名对老用户也没有影响。
275
308
 
276
309
  ## 文件依赖
277
310
 
@@ -279,12 +312,12 @@ export MCP_BRIDGE_HOME=~/.erp-bridge
279
312
 
280
313
  | 文件 | 由谁创建 |
281
314
  |---|---|
282
- | `config.json` | 登录侧 CLI(如 `mes-login-cli`),也可手写 |
315
+ | `config.json` | 登录侧 CLI(`mcp-multi-login` / 旧 `mes-login-cli`),也可手写 |
283
316
  | `token.json` | 登录侧 CLI(登录时写入) |
284
317
 
285
318
  本包**只读不写**,不会创建、修改或删除这两个文件。
286
319
 
287
- 所以使用前必须先安装并运行一次登录 CLI(MES 用 `mes-login-cli`)。
320
+ 所以使用前必须先安装并运行一次登录 CLI(`mcp-multi-login`)。
288
321
 
289
322
  ## 提供的工具
290
323
 
package/bin.js CHANGED
@@ -146,7 +146,8 @@ async function handleCli(argv) {
146
146
  配置文件: ${CONFIG_FILE}
147
147
  登录文件: ${CONFIG_DIR}/token.json(由 ${L.loginCommand} 写入)
148
148
 
149
- 配置目录可用环境变量 MCP_BRIDGE_HOME 改到别处(默认 ~/.mes-mcp-login)。
149
+ 配置目录可用环境变量 MCP_MULTI_HOME 改到别处(旧名 MCP_BRIDGE_HOME 仍兼容)。
150
+ 放在客户端配置的 env 里,可以一个客户端同时接多套系统。默认 ~/.mes-mcp-login。
150
151
 
151
152
  本程序只读上述文件,不会修改或删除。`);
152
153
  return true;
@@ -222,15 +223,24 @@ function textResult(text, isError = false) {
222
223
  * 之所以写这么具体,是因为模型拿不到本文件的上下文,
223
224
  * 只说「请登录」它不知道登录入口在哪、也不知道要等待人机验证。
224
225
  *
226
+ * 命令里必须带 --home:同一个客户端可能同时接多套系统,各自一个配置目录。
227
+ * 只说 `mes-login` 会让模型登到另一套系统去,那边看起来成功了、
228
+ * 这边的 token 却没变,表现是「登录了但还是未登录」,非常难查。
229
+ *
225
230
  * @param {string} status 状态描述,如「未登录」/「登录已失效(code=613:token 已过期)」
226
- * @param {{key:string, name:string}} [org] 相关组织,用于预设登录页选中的组织
231
+ * @param {{key:string, name:string}} [org] 相关租户,用于预设登录页选中的租户
227
232
  * @param {object|null} [cfg] 配置,用于取系统名与租户称谓;不传则用默认值
228
233
  */
229
234
  function loginGuide(status, org, cfg) {
230
235
  const L = cfg ? settings(cfg) : DEFAULT_SETTINGS;
236
+ // --home 用本实例实际读的目录,保证与登录写入的是同一个。
237
+ // 反斜杠统一转正斜杠:Windows 下 CMD / PowerShell / Git Bash 都能正确解析,
238
+ // 反斜杠在部分 shell 里会被当转义字符。
239
+ const homeForCmd = String(CONFIG_DIR).replace(/\\/g, '/');
240
+ const homeArg = ` --home "${homeForCmd}"`;
231
241
  const orgArg = org && org.key ? ` --org ${org.key}` : '';
232
242
  const orgLine = org
233
- ? `\n相关${L.tenantLabel}:${org.name}(已通过 --org ${orgArg.trim()} 预设选中)\n`
243
+ ? `\n相关${L.tenantLabel}:${org.name}(已通过 --org ${org.key} 预设选中)\n`
234
244
  : '';
235
245
 
236
246
  return `## ${status}
@@ -238,7 +248,7 @@ function loginGuide(status, org, cfg) {
238
248
  请调用 Bash 工具执行以下命令,启动 ${L.systemName}${L.nameGap}登录页:
239
249
 
240
250
  \`\`\`bash
241
- ${L.loginCommand}${orgArg}
251
+ ${L.loginCommand}${homeArg}${orgArg}
242
252
  \`\`\`
243
253
 
244
254
  执行说明:
@@ -246,6 +256,7 @@ ${L.loginCommand}${orgArg}
246
256
  2. 需要在页面上输入用户名密码,并完成图形点选验证码(由人操作,AI 无法代替)
247
257
  3. 登录成功后 token 会自动写入本地文件,本服务**下一次调用即可生效,无需重启**
248
258
  4. 命令会一直运行到登录完成才退出,**请以后台方式运行**(run_in_background),避免阻塞
259
+ 5. \`--home\` 不能省:本服务读的是 \`${CONFIG_DIR}\`,命令指向别的目录会写错位置
249
260
  ${orgLine}
250
261
  登录完成后,请重新调用刚才的工具。
251
262
  `;
package/lib/config.js CHANGED
@@ -19,19 +19,21 @@ const LEGACY_DIR_NAME = '.mes-mcp-login';
19
19
  /**
20
20
  * 解析配置目录
21
21
  *
22
- * 优先级:MCP_BRIDGE_HOME > ~/.mes-mcp-login
22
+ * 优先级:MCP_MULTI_HOME > MCP_BRIDGE_HOME(旧名) > ~/.mes-mcp-login
23
23
  * 用环境变量而不是 config.json 里的字段——要读配置就得先知道目录,写进配置里是循环依赖。
24
+ *
25
+ * 与登录 CLI 用同一套变量名,两边必须读到同一个目录,否则登录完 bridge 找不到 token。
24
26
  */
25
27
  function resolveDir() {
26
- const custom = process.env.MCP_BRIDGE_HOME;
27
- if (typeof custom === 'string' && custom.trim()) {
28
+ const pick = (v) => (typeof v === 'string' && v.trim() ? v.trim() : '');
29
+ const custom = pick(process.env.MCP_MULTI_HOME) || pick(process.env.MCP_BRIDGE_HOME);
30
+ if (custom) {
28
31
  // 支持 ~ 开头,避免用户写了相对路径找不到
29
- const raw = custom.trim();
30
- if (raw === '~') return os.homedir();
31
- if (raw.startsWith('~/') || raw.startsWith('~\\')) {
32
- return path.join(os.homedir(), raw.slice(2));
32
+ if (custom === '~') return os.homedir();
33
+ if (custom.startsWith('~/') || custom.startsWith('~\\')) {
34
+ return path.join(os.homedir(), custom.slice(2));
33
35
  }
34
- return path.resolve(raw);
36
+ return path.resolve(custom);
35
37
  }
36
38
  return path.join(os.homedir(), LEGACY_DIR_NAME);
37
39
  }
package/lib/settings.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * credentialField 注入到工具参数里的凭据字段名 默认 access_token
10
10
  * hiddenArgs 对模型隐藏的参数(凭据与租户 ID 由本层填) 默认 access_token / orgId
11
11
  * invalidCodes 表示登录态失效的业务错误码 默认 613/614/615/616
12
- * loginCommand 登录引导里让模型执行的命令 默认 mes-login
12
+ * loginCommand 登录引导里让模型执行的命令 默认 mcp-multi-login
13
13
  *
14
14
  * 全部有默认值,不配置时行为与改造前完全一致。
15
15
  * 每一项都做了类型校验,配错(null、空串、非数组)时回落默认而不是让服务崩掉。
@@ -27,8 +27,13 @@ export const DEFAULT_TENANT_ID_FIELD = 'orgId';
27
27
  export const DEFAULT_HIDDEN_ARGS = [DEFAULT_CREDENTIAL_FIELD, DEFAULT_TENANT_ID_FIELD];
28
28
  /** 默认的登录失效错误码 */
29
29
  export const DEFAULT_INVALID_CODES = [613, 614, 615, 616];
30
- /** 默认登录命令 */
31
- export const DEFAULT_LOGIN_COMMAND = 'mes-login';
30
+ /**
31
+ * 默认登录命令
32
+ *
33
+ * 用新包名对应的命令。登录包里 `mcp-multi-login` 与 `mes-login` 两个 bin
34
+ * 指向同一程序,所以写新名对老用户也是安全的。
35
+ */
36
+ export const DEFAULT_LOGIN_COMMAND = 'mcp-multi-login';
32
37
 
33
38
  /**
34
39
  * 默认失效码的中文说明
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-multi-bridge",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "多后端 MCP 桥接:把网关后多个后端、多个租户的工具集合并成一个 MCP 服务,凭据由登录 CLI 提供",
5
5
  "type": "module",
6
6
  "bin": {