openmausbot 0.1.92 → 0.1.94
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/dist/assets/{DesktopViewer-Do6lBa4C.js → DesktopViewer-bxM7NV3N.js} +1 -1
- package/dist/assets/{abnfDiagram-O67JEVCF-Cd3X7Hxc.js → abnfDiagram-O67JEVCF-BhMdJhRJ.js} +1 -1
- package/dist/assets/{arc-DIYc7Ymx.js → arc-B5itKDcx.js} +1 -1
- package/dist/assets/{architectureDiagram-NJMV4G6O-DBmRGVyP.js → architectureDiagram-NJMV4G6O-C5d7UY6U.js} +1 -1
- package/dist/assets/{blockDiagram-BEXU5L5S-CPFePSEE.js → blockDiagram-BEXU5L5S-BrZIhMmu.js} +1 -1
- package/dist/assets/{c4Diagram-YGBWAQC7-DD_DO1qy.js → c4Diagram-YGBWAQC7-7I0ArfbD.js} +1 -1
- package/dist/assets/channel-CdJX6i8k.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-BNEeNSjX.js → chunk-2Q5K7J3B-BnEsyN36.js} +1 -1
- package/dist/assets/{chunk-3FUC2YCW-BbinLaqH.js → chunk-3FUC2YCW-BXATQ52s.js} +2 -2
- package/dist/assets/{chunk-5VM5RSS4-BBgYrgDR.js → chunk-5VM5RSS4-B0BpTkEx.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-ezXj-kA-.js → chunk-GTNCS2PH-BtLTz6FR.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-9FxZ3diV.js → chunk-GWA4HPMP-D6gcZOYt.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-CO-40JpI.js → chunk-JWPE2WC7-DCLrosvf.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-BEhjslYE.js → chunk-NETBCI7D-B9JsknV9.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-CNeq4n7_.js → chunk-WEXAMYUT-CsoTxw7z.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-OsCY7KSi.js → chunk-XXDRQBXY-0F_frB0c.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-CloRUEtk.js → classDiagram-v2-NBCMYWYE-DkrpnflX.js} +1 -1
- package/dist/assets/{cose-bilkent-JH36ORCC-D1BGZhp4.js → cose-bilkent-JH36ORCC-BNDwYBt9.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-CUf4T2CN.js → cynefin-OW5HDTMX-JUkNr1Mk.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-DPEZrFGA.js → cynefinDiagram-VND7K2PF-DKeh9N4M.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-bDe6GIv5.js → dagre-6A5THRUB-ve-6T_wX.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-CdcUQz55.js → diagram-22UHCM2B-BuJ2d8rT.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-BZpqGg7c.js → diagram-3UASUU5V-BgOs_Ni-.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-DvGM6ugp.js → diagram-ATOU4E4O-DMK6VmcP.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-DSTmMm0s.js → diagram-CDSNMT55-DksASlcY.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-15cucnMn.js → diagram-MLGK6HIB-Bgn8I5k6.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-tMbuaE6n.js → diagram-MPIPVDR6-zK0jqO8N.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-BYxYzjHI.js → ebnfDiagram-ZINNZB2B-vKrbzTwr.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-v6bj852W.js → elk-276RUBZZ-Bzv2mPNf.js} +1 -1
- package/dist/assets/{erDiagram-OPXOYQCR-5lBBlnd2.js → erDiagram-OPXOYQCR-CvOyYuxu.js} +1 -1
- package/dist/assets/{flowDiagram-KWPJA3E3-CZyl1zIj.js → flowDiagram-KWPJA3E3-CtbnDbc0.js} +1 -1
- package/dist/assets/{ganttDiagram-FUAMR5RP-BiAI-ltZ.js → ganttDiagram-FUAMR5RP-c4dMRYyG.js} +1 -1
- package/dist/assets/{gitGraphDiagram-X574FWY7-BAZISkj3.js → gitGraphDiagram-X574FWY7-B34uaQho.js} +1 -1
- package/dist/assets/index-CPYrGsv1.js +610 -0
- package/dist/assets/{index-DGBaEXrM.js → index-CPiqc_DN.js} +1 -1
- package/dist/assets/index-CzT42GR8.css +1 -0
- package/dist/assets/{infoDiagram-VRGFBTTK-B6ooOy-Z.js → infoDiagram-VRGFBTTK-o64ma4CI.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-BZ9ksi-B.js → ishikawaDiagram-OU5B5YK6-DV4C9BAm.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-DWqlzIEe.js → journeyDiagram-ZHPQQLJL-Bf0AHk1H.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-JX6piDwL.js → kanban-definition-PNTS6WVX-B1UMSKmE.js} +1 -1
- package/dist/assets/{linear-CmOWzX0P.js → linear-BpKhuyLm.js} +1 -1
- package/dist/assets/{mermaid.core-CF1zwoQ-.js → mermaid.core-B_BKNCw5.js} +5 -5
- package/dist/assets/{mindmap-definition-NLK3R4M7-CGh2K4fW.js → mindmap-definition-NLK3R4M7-DeARruT1.js} +1 -1
- package/dist/assets/{pegDiagram-GJSIUBJH-CDwYN0s7.js → pegDiagram-GJSIUBJH-BOQEk_1D.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-1rfjJocB.js → pieDiagram-5QR66LMP-EIfoiTZo.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-tKPvPiok.js → quadrantDiagram-O4NWA36T-GgZwT-fi.js} +1 -1
- package/dist/assets/{railroadDiagram-XR7U4H2S-BHLm5vXR.js → railroadDiagram-XR7U4H2S-D9rDQomj.js} +1 -1
- package/dist/assets/{requirementDiagram-PLB6GJNP-CB45STp7.js → requirementDiagram-PLB6GJNP-DAh1MIeo.js} +1 -1
- package/dist/assets/{sankeyDiagram-IPEJSGJF-55QA_huC.js → sankeyDiagram-IPEJSGJF-CPr6Uz64.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-BckFmQHn.js → sequenceDiagram-PO4LG4MO-BU6VIdcm.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-BFCOJF11.js → sizeCapture-INFHLROL-qF2HO41r.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-CZvmiVVN.js → stateDiagram-v2-GCMORJYK-DlJ8G4MD.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-BpDUCEKy.js → swimlanes-2SLR337P-DzYE8I54.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-D-U4GtLQ.js +8 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-BpxHq6IK.js → timeline-definition-EJHVYXUP-B7wzEQ0A.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-Cj66vm02.js → usecaseDiagram-POWQR4AR-BvGgrxIP.js} +1 -1
- package/dist/assets/{vennDiagram-UO4OBE2U-C9nRkWE_.js → vennDiagram-UO4OBE2U-CEECdgQg.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-D-me_nWj.js → wardleyDiagram-VNRHLVJA-XQHA0P_P.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-Dc_fL4mk.js → xychartDiagram-PMCCYNJV-B5mLcZI2.js} +1 -1
- package/dist/index.html +2 -2
- package/dist-server/cloud-home-start.js +1 -0
- package/dist-server/companion/src/routes.js +45 -1
- package/dist-server/container-mcp.js +99 -77
- package/dist-server/drivers/agents-proxy.js +40 -1
- package/dist-server/drivers/pi-mcp-extension.ts +245 -299
- package/dist-server/enterprise/server/index.js +1 -0
- package/dist-server/index.js +18361 -13794
- package/dist-server/local-computer-proxy.js +5 -1
- package/dist-server/local-computer.js +1 -0
- package/dist-server/mcp-gate.js +152 -20
- package/dist-server/mcp-remote-proxy.js +437 -0
- package/dist-server/openmausbot.js +8872 -7620
- package/dist-server/pair-cli.js +8872 -7620
- package/dist-server/permission-proxy.js +65 -1
- package/dist-server/proxy-paths.js +1 -0
- package/dist-server/server/auto-approve.js +33 -11
- package/dist-server/server/boat.js +3 -3
- package/dist-server/server/browser-live.js +14 -5
- package/dist-server/server/browser-runtime.js +6 -0
- package/dist-server/server/channel-queue.js +4 -1
- package/dist-server/server/cli.js +32 -12
- package/dist-server/server/cloud-move-http.js +9 -3
- package/dist-server/server/cloud-move.js +18 -0
- package/dist-server/server/cloud-owner.js +1 -1
- package/dist-server/server/computer-control.js +6 -0
- package/dist-server/server/computer-wait.js +33 -13
- package/dist-server/server/config.js +57 -10
- package/dist-server/server/container-computer.js +43 -32
- package/dist-server/server/decision-log.js +9 -6
- package/dist-server/server/delegations.js +47 -22
- package/dist-server/server/digest.js +12 -2
- package/dist-server/server/drivers/acp/core.js +229 -20
- package/dist-server/server/drivers/acp/cursor.js +13 -1
- package/dist-server/server/drivers/acp/grok.js +208 -3
- package/dist-server/server/drivers/acp/quiet-status.js +257 -0
- package/dist-server/server/drivers/acp/qwen.js +18 -0
- package/dist-server/server/drivers/agents-call.js +28 -0
- package/dist-server/server/drivers/agents-catalog.js +10 -1
- package/dist-server/server/drivers/boatagent.js +2 -0
- package/dist-server/server/drivers/builtIn.js +2 -0
- package/dist-server/server/drivers/cerebras.js +108 -0
- package/dist-server/server/drivers/chat-mcp-tools.js +45 -15
- package/dist-server/server/drivers/claude.js +35 -9
- package/dist-server/server/drivers/codex.js +84 -10
- package/dist-server/server/drivers/openai-chat.js +37 -5
- package/dist-server/server/drivers/pi.js +48 -4
- package/dist-server/server/drivers/prompt-split.js +2 -0
- package/dist-server/server/env-path.js +6 -2
- package/dist-server/server/environment.js +3 -0
- package/dist-server/server/guarded-requests.js +2 -1
- package/dist-server/server/index.js +1353 -311
- package/dist-server/server/live-call-controller.js +868 -0
- package/dist-server/server/live-call.js +216 -0
- package/dist-server/server/local-vm-stop-reason.js +26 -0
- package/dist-server/server/mcp-gate-config.js +43 -12
- package/dist-server/server/mcp-gate.js +127 -25
- package/dist-server/server/mcp-http.js +46 -8
- package/dist-server/server/mcp-remote-proxy.js +108 -0
- package/dist-server/server/new-bot-defaults.js +3 -0
- package/dist-server/server/peer-provenance.js +4 -2
- package/dist-server/server/permission-proxy.js +15 -1
- package/dist-server/server/plan-usage.js +797 -0
- package/dist-server/server/provider-key-check.js +2 -1
- package/dist-server/server/proxy-paths.js +1 -0
- package/dist-server/server/redact.js +2 -0
- package/dist-server/server/request-auth.js +3 -2
- package/dist-server/server/routes/desktop-viewer.js +50 -6
- package/dist-server/server/routes/live.js +98 -0
- package/dist-server/server/routines.js +6 -3
- package/dist-server/server/skill-library.js +207 -0
- package/dist-server/server/skills-library-migration.js +235 -0
- package/dist-server/server/skills.js +66 -3
- package/dist-server/server/steer-queue.js +13 -1
- package/dist-server/server/store.js +86 -4
- package/dist-server/server/surface.js +9 -3
- package/dist-server/server/team-backup.js +2 -1
- package/dist-server/server/thread-events.js +1 -1
- package/dist-server/server/tunnel.js +20 -1
- package/dist-server/server/turn-log.js +10 -0
- package/dist-server/server/turn-resources.js +124 -0
- package/dist-server/server/vps-computer.js +1 -1
- package/dist-server/server/workspace-backup.js +22 -0
- package/dist-server/server/workspace.js +1 -1
- package/dist-server/shared/approval-mode.js +1 -1
- package/dist-server/shared/ask-question.js +13 -0
- package/dist-server/shared/call-consent.js +28 -0
- package/dist-server/shared/live-approval.js +124 -0
- package/dist-server/shared/live-call.js +176 -0
- package/dist-server/shared/redact.js +1 -0
- package/dist-server/shared/skill-md.js +10 -0
- package/dist-server/shared/team-backup.js +3 -0
- package/dist-server/shared/tool-name.js +22 -0
- package/dist-server/shared/tool-scope-support.js +25 -0
- package/dist-server/shared/tool-scope.js +136 -0
- package/dist-server/src/lib/thread-refs.js +406 -0
- package/dist-server/vps-container-mcp.js +99 -77
- package/dist-server/workspace-backup.worker.js +103 -100
- package/enterprise/server/index.js +1 -0
- package/package.json +1 -1
- package/dist/assets/channel-Dtk5Mtic.js +0 -1
- package/dist/assets/index-Cdmjrl28.css +0 -1
- package/dist/assets/index-DR7YPMkW.js +0 -597
- package/dist/assets/swimlanesDiagram-TC7HE7FX-M0GYW9Y3.js +0 -8
|
@@ -130,6 +130,8 @@ function windowsKnownDirs() {
|
|
|
130
130
|
// x.ai installer
|
|
131
131
|
join(localAppData, "agy", "bin"),
|
|
132
132
|
// Antigravity installer
|
|
133
|
+
// Cursor installer: cursor-agent.* and its `agent` copies (MOCA-272)
|
|
134
|
+
join(localAppData, "cursor-agent"),
|
|
133
135
|
join(home, ".local", "bin"),
|
|
134
136
|
// claude native installer
|
|
135
137
|
join(home, ".claude", "local"),
|
|
@@ -137,7 +139,9 @@ function windowsKnownDirs() {
|
|
|
137
139
|
// Factory droid installer (%USERPROFILE%\bin)
|
|
138
140
|
join(home, ".bun", "bin"),
|
|
139
141
|
join(home, ".deno", "bin"),
|
|
140
|
-
join(home, "go", "bin")
|
|
142
|
+
join(home, "go", "bin"),
|
|
143
|
+
join(process.env.ProgramFiles ?? "C:\\Program Files", "Docker", "Docker", "resources", "bin")
|
|
144
|
+
// Docker Desktop installer
|
|
141
145
|
];
|
|
142
146
|
}
|
|
143
147
|
var cached = null;
|
|
@@ -22,6 +22,7 @@ var SPAWNED_PROXIES = {
|
|
|
22
22
|
dweb: resolveProxy("drivers/dweb-proxy"),
|
|
23
23
|
connectors: resolveProxy("connector-proxy"),
|
|
24
24
|
mcpGate: resolveProxy("mcp-gate"),
|
|
25
|
+
mcpRemote: resolveProxy("mcp-remote-proxy"),
|
|
25
26
|
phone: resolveProxy("drivers/phone-proxy"),
|
|
26
27
|
hook: resolveProxy("hooks/omb-hook"),
|
|
27
28
|
// Loaded by the external `pi` process via `-e`, not by this server — but
|
package/dist-server/mcp-gate.js
CHANGED
|
@@ -4,6 +4,60 @@ import { mkdirSync, readdirSync as readdirSync2, rmSync, statSync as statSync2,
|
|
|
4
4
|
import { join as join2 } from "node:path";
|
|
5
5
|
import { createInterface } from "node:readline";
|
|
6
6
|
|
|
7
|
+
// shared/tool-scope.ts
|
|
8
|
+
var SERVER_NAME = /^[a-z][a-z0-9_-]{0,31}$/;
|
|
9
|
+
var CONTROL_CHARACTER = /[\x00-\x1f\x7f]/;
|
|
10
|
+
var MAX_SELECTORS = 256;
|
|
11
|
+
var MAX_SELECTOR_LENGTH = 1024;
|
|
12
|
+
function validName(name) {
|
|
13
|
+
return typeof name === "string" && name.trim().length > 0 && name.length <= MAX_SELECTOR_LENGTH && !CONTROL_CHARACTER.test(name) && !name.includes("*");
|
|
14
|
+
}
|
|
15
|
+
function selectorIdentity(selector) {
|
|
16
|
+
if (selector.length > MAX_SELECTOR_LENGTH || CONTROL_CHARACTER.test(selector)) return;
|
|
17
|
+
if (selector.startsWith("native:")) {
|
|
18
|
+
const name = selector.slice(7);
|
|
19
|
+
if (name === "*" || validName(name)) return { kind: "native", name };
|
|
20
|
+
} else if (selector.startsWith("mcp:")) {
|
|
21
|
+
const separator = selector.indexOf(":", 4);
|
|
22
|
+
if (separator < 0) return;
|
|
23
|
+
const server = selector.slice(4, separator);
|
|
24
|
+
const name = selector.slice(separator + 1);
|
|
25
|
+
if (SERVER_NAME.test(server) && (name === "*" || validName(name))) {
|
|
26
|
+
return { kind: "mcp", server, name };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function parseToolScope(value) {
|
|
31
|
+
if (value === void 0) return { ok: true, scope: void 0 };
|
|
32
|
+
const invalid = { ok: false, error: "Tool selection must contain only valid allow and deny lists." };
|
|
33
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return invalid;
|
|
34
|
+
const prototype = Object.getPrototypeOf(value);
|
|
35
|
+
if (prototype !== Object.prototype && prototype !== null) return invalid;
|
|
36
|
+
const scope2 = {};
|
|
37
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
38
|
+
if (key !== "allow" && key !== "deny") return invalid;
|
|
39
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
40
|
+
if (!descriptor || !("value" in descriptor)) return invalid;
|
|
41
|
+
const list = descriptor.value;
|
|
42
|
+
if (!Array.isArray(list) || list.length > MAX_SELECTORS) return invalid;
|
|
43
|
+
if (!Array.from(list).every((entry) => typeof entry === "string" && selectorIdentity(entry))) return invalid;
|
|
44
|
+
scope2[key] = [...new Set(list)];
|
|
45
|
+
}
|
|
46
|
+
return { ok: true, scope: scope2 };
|
|
47
|
+
}
|
|
48
|
+
function matches(selector, tool) {
|
|
49
|
+
const selected = selectorIdentity(selector);
|
|
50
|
+
return selected?.kind === tool.kind && (selected.kind !== "mcp" || tool.kind === "mcp" && selected.server === tool.server) && (selected.name === "*" || selected.name === tool.name);
|
|
51
|
+
}
|
|
52
|
+
function permits(scope2, tool) {
|
|
53
|
+
if (!validName(tool.name) || tool.kind === "mcp" && !SERVER_NAME.test(tool.server)) return false;
|
|
54
|
+
return (scope2?.allow === void 0 || scope2.allow.some((selector) => matches(selector, tool))) && !scope2?.deny?.some((selector) => matches(selector, tool));
|
|
55
|
+
}
|
|
56
|
+
function allowsTool(scope2, tool) {
|
|
57
|
+
const parsed = parseToolScope(scope2);
|
|
58
|
+
return parsed.ok && permits(parsed.scope, tool);
|
|
59
|
+
}
|
|
60
|
+
|
|
7
61
|
// server/env-path.ts
|
|
8
62
|
import { execFile } from "node:child_process";
|
|
9
63
|
import { closeSync, existsSync, openSync, readFileSync, readSync, statSync, readdirSync } from "node:fs";
|
|
@@ -63,6 +117,8 @@ function windowsKnownDirs() {
|
|
|
63
117
|
// x.ai installer
|
|
64
118
|
join(localAppData, "agy", "bin"),
|
|
65
119
|
// Antigravity installer
|
|
120
|
+
// Cursor installer: cursor-agent.* and its `agent` copies (MOCA-272)
|
|
121
|
+
join(localAppData, "cursor-agent"),
|
|
66
122
|
join(home, ".local", "bin"),
|
|
67
123
|
// claude native installer
|
|
68
124
|
join(home, ".claude", "local"),
|
|
@@ -70,7 +126,9 @@ function windowsKnownDirs() {
|
|
|
70
126
|
// Factory droid installer (%USERPROFILE%\bin)
|
|
71
127
|
join(home, ".bun", "bin"),
|
|
72
128
|
join(home, ".deno", "bin"),
|
|
73
|
-
join(home, "go", "bin")
|
|
129
|
+
join(home, "go", "bin"),
|
|
130
|
+
join(process.env.ProgramFiles ?? "C:\\Program Files", "Docker", "Docker", "resources", "bin")
|
|
131
|
+
// Docker Desktop installer
|
|
74
132
|
];
|
|
75
133
|
}
|
|
76
134
|
var cached = null;
|
|
@@ -443,21 +501,60 @@ async function stopCliTree(child2, pid, timeoutMs) {
|
|
|
443
501
|
}
|
|
444
502
|
|
|
445
503
|
// server/mcp-gate.ts
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
504
|
+
function gateEnvironment() {
|
|
505
|
+
if (process.argv.length === 2) return process.env;
|
|
506
|
+
try {
|
|
507
|
+
const key = process.argv[3];
|
|
508
|
+
if (process.argv.length !== 4 || process.argv[2] !== "--config-env" || !key || !/^OMB_GATE_CONFIG_[a-f0-9]{64}$/.test(key)) throw new Error();
|
|
509
|
+
const value = JSON.parse(process.env[key] ?? "");
|
|
510
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || !["OMB_GATE_NAME", "OMB_GATE_UPSTREAM", "OMB_GATE_TOOL_SCOPE"].every((name) => typeof value[name] === "string") || !Object.entries(value).every(([name, setting]) => GATE_ENV_KEYS.includes(name) && typeof setting === "string")) throw new Error();
|
|
511
|
+
return value;
|
|
512
|
+
} catch {
|
|
513
|
+
process.stderr.write("mcp-gate: invalid private configuration\n");
|
|
514
|
+
process.exit(1);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
var GATE_ENV_KEYS = ["OMB_GATE_NAME", "OMB_GATE_SPILL_DIR", "OMB_GATE_BUDGET", "OMB_GATE_UPSTREAM", "OMB_GATE_SPILL_HINT", "OMB_GATE_TOOL_SCOPE"];
|
|
518
|
+
var gateEnv = gateEnvironment();
|
|
519
|
+
var NAME = gateEnv.OMB_GATE_NAME || "mcp";
|
|
520
|
+
var SPILL_DIR = gateEnv.OMB_GATE_SPILL_DIR || "";
|
|
521
|
+
var rawBudget = Number(gateEnv.OMB_GATE_BUDGET);
|
|
522
|
+
var BUDGET = Number.isFinite(rawBudget) && rawBudget >= 0 ? rawBudget : DEFAULT_RESULT_BUDGET;
|
|
449
523
|
var SPILL_MAX_AGE_MS = 24 * 60 * 6e4;
|
|
450
|
-
var SPILL_HINT =
|
|
451
|
-
var GATE_ENV_KEYS = ["OMB_GATE_NAME", "OMB_GATE_SPILL_DIR", "OMB_GATE_BUDGET", "OMB_GATE_UPSTREAM", "OMB_GATE_SPILL_HINT"];
|
|
524
|
+
var SPILL_HINT = gateEnv.OMB_GATE_SPILL_HINT === "1";
|
|
452
525
|
function fail(message) {
|
|
453
526
|
process.stderr.write(`mcp-gate(${NAME}): ${message}
|
|
454
527
|
`);
|
|
455
528
|
process.exit(1);
|
|
456
529
|
}
|
|
530
|
+
function toolScope() {
|
|
531
|
+
const raw = gateEnv.OMB_GATE_TOOL_SCOPE;
|
|
532
|
+
if (raw === void 0) return;
|
|
533
|
+
let value;
|
|
534
|
+
try {
|
|
535
|
+
value = JSON.parse(raw);
|
|
536
|
+
} catch {
|
|
537
|
+
fail("invalid tool selection JSON");
|
|
538
|
+
}
|
|
539
|
+
const parsed = parseToolScope(value);
|
|
540
|
+
if (!parsed.ok || parsed.scope === void 0) fail("invalid tool selection; check the bot's Access settings");
|
|
541
|
+
if (!/^[a-z][a-z0-9_-]{0,31}$/.test(NAME)) fail("invalid MCP server identity for tool selection");
|
|
542
|
+
return parsed.scope;
|
|
543
|
+
}
|
|
544
|
+
function isRecord(value) {
|
|
545
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
546
|
+
}
|
|
547
|
+
function requestKey(id) {
|
|
548
|
+
return typeof id === "string" || typeof id === "number" && Number.isFinite(id) ? `${typeof id}:${id}` : void 0;
|
|
549
|
+
}
|
|
550
|
+
function rejectRequest(id, code, message) {
|
|
551
|
+
process.stdout.write(`${JSON.stringify({ jsonrpc: "2.0", id: requestKey(id) ? id : null, error: { code, message } })}
|
|
552
|
+
`);
|
|
553
|
+
}
|
|
457
554
|
function upstreamSpec() {
|
|
458
555
|
let parsed;
|
|
459
556
|
try {
|
|
460
|
-
parsed = JSON.parse(
|
|
557
|
+
parsed = JSON.parse(gateEnv.OMB_GATE_UPSTREAM ?? "");
|
|
461
558
|
} catch {
|
|
462
559
|
fail("OMB_GATE_UPSTREAM is not valid JSON");
|
|
463
560
|
}
|
|
@@ -499,6 +596,7 @@ function spill(tool, text) {
|
|
|
499
596
|
}
|
|
500
597
|
}
|
|
501
598
|
function trimCallResult(result, tool) {
|
|
599
|
+
if (BUDGET === 0) return false;
|
|
502
600
|
const content = result.content;
|
|
503
601
|
if (!Array.isArray(content)) return false;
|
|
504
602
|
const textBlocks = content.filter(
|
|
@@ -521,10 +619,11 @@ function trimCallResult(result, tool) {
|
|
|
521
619
|
}
|
|
522
620
|
return trimmed;
|
|
523
621
|
}
|
|
622
|
+
var scope = toolScope();
|
|
524
623
|
var spec = upstreamSpec();
|
|
525
624
|
if (SPILL_DIR) sweepSpill(SPILL_DIR);
|
|
526
625
|
var childEnv = { ...process.env, ...spec.env };
|
|
527
|
-
for (const key of
|
|
626
|
+
for (const key of Object.keys(childEnv)) if (key.startsWith("OMB_GATE_")) delete childEnv[key];
|
|
528
627
|
var resolved = resolveCliSpawn(spec.command, spec.args ?? []);
|
|
529
628
|
var child = spawn2(resolved.command, resolved.args, {
|
|
530
629
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -556,14 +655,35 @@ child.on("error", (error) => {
|
|
|
556
655
|
child.stderr.pipe(process.stderr);
|
|
557
656
|
var pending = /* @__PURE__ */ new Map();
|
|
558
657
|
createInterface({ input: process.stdin }).on("line", (line) => {
|
|
658
|
+
let message;
|
|
559
659
|
if (line.trim()) {
|
|
560
660
|
try {
|
|
561
|
-
const
|
|
562
|
-
if (
|
|
563
|
-
const params = message.params;
|
|
564
|
-
pending.set(String(message.id), typeof params?.name === "string" ? params.name : "tool");
|
|
565
|
-
}
|
|
661
|
+
const parsed = JSON.parse(line);
|
|
662
|
+
if (isRecord(parsed)) message = parsed;
|
|
566
663
|
} catch {
|
|
664
|
+
if (scope) return rejectRequest(null, -32700, "Invalid JSON-RPC frame");
|
|
665
|
+
}
|
|
666
|
+
if (scope && (!message || message.jsonrpc !== "2.0")) return rejectRequest(message?.id, -32600, "Invalid JSON-RPC frame");
|
|
667
|
+
}
|
|
668
|
+
const id = requestKey(message?.id);
|
|
669
|
+
const params = isRecord(message?.params) ? message.params : void 0;
|
|
670
|
+
if (scope && message?.method === "tools/call") {
|
|
671
|
+
if (!id || typeof params?.name !== "string" || params.arguments !== void 0 && !isRecord(params.arguments)) {
|
|
672
|
+
return rejectRequest(message.id, -32602, "Invalid tool call");
|
|
673
|
+
}
|
|
674
|
+
if (!allowsTool(scope, { kind: "mcp", server: NAME, name: params.name })) {
|
|
675
|
+
return rejectRequest(message.id, -32602, "Tool selection excludes this tool. Check the bot's Access settings.");
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
if (scope && message?.method === "tools/list" && !id) {
|
|
679
|
+
return rejectRequest(message.id, -32600, "Tool listing needs a request ID");
|
|
680
|
+
}
|
|
681
|
+
if (id && typeof message?.method === "string") {
|
|
682
|
+
if (scope && pending.has(id)) fail("duplicate request ID on a restricted connection");
|
|
683
|
+
if (message.method === "tools/call") {
|
|
684
|
+
pending.set(id, { kind: "call", tool: typeof params?.name === "string" ? params.name : "tool" });
|
|
685
|
+
} else if (scope) {
|
|
686
|
+
pending.set(id, { kind: message.method === "tools/list" ? "list" : "other" });
|
|
567
687
|
}
|
|
568
688
|
}
|
|
569
689
|
child.stdin.write(`${line}
|
|
@@ -574,24 +694,36 @@ createInterface({ input: child.stdout }).on("line", (line) => {
|
|
|
574
694
|
if (!line.trim()) return;
|
|
575
695
|
let message;
|
|
576
696
|
try {
|
|
577
|
-
|
|
697
|
+
const parsed = JSON.parse(line);
|
|
698
|
+
if (isRecord(parsed)) message = parsed;
|
|
578
699
|
} catch {
|
|
700
|
+
if (scope) fail("unreadable upstream frame on a restricted connection");
|
|
701
|
+
}
|
|
702
|
+
if (!message || scope && message.jsonrpc !== "2.0") {
|
|
703
|
+
if (scope) fail("invalid upstream frame on a restricted connection");
|
|
579
704
|
process.stdout.write(`${line}
|
|
580
705
|
`);
|
|
581
706
|
return;
|
|
582
707
|
}
|
|
583
|
-
const id =
|
|
584
|
-
const
|
|
708
|
+
const id = typeof message.method === "string" ? void 0 : requestKey(message.id);
|
|
709
|
+
const request = id === void 0 ? void 0 : pending.get(id);
|
|
710
|
+
if (scope && id !== void 0 && !request) fail("unrequested upstream response on a restricted connection");
|
|
585
711
|
if (id !== void 0) pending.delete(id);
|
|
586
712
|
const result = message.result;
|
|
587
|
-
if (
|
|
713
|
+
if (scope && request?.kind === "list" && message.error === void 0) {
|
|
714
|
+
if (!isRecord(result) || !Array.isArray(result.tools) || !result.tools.every((tool) => isRecord(tool) && typeof tool.name === "string" && tool.name.trim().length > 0) || result.nextCursor !== void 0 && typeof result.nextCursor !== "string") {
|
|
715
|
+
return rejectRequest(message.id, -32603, "Invalid tool catalog on a restricted connection");
|
|
716
|
+
}
|
|
717
|
+
result.tools = result.tools.filter((tool) => allowsTool(scope, { kind: "mcp", server: NAME, name: tool.name }));
|
|
718
|
+
}
|
|
719
|
+
if (request?.kind === "call" && isRecord(result)) {
|
|
588
720
|
try {
|
|
589
|
-
if (trimCallResult(result, tool)) {
|
|
590
|
-
process.stderr.write(`mcp-gate(${NAME}): trimmed ${tool} to ${BUDGET} chars
|
|
721
|
+
if (trimCallResult(result, request.tool)) {
|
|
722
|
+
process.stderr.write(`mcp-gate(${NAME}): trimmed ${request.tool} to ${BUDGET} chars
|
|
591
723
|
`);
|
|
592
724
|
}
|
|
593
725
|
} catch (error) {
|
|
594
|
-
process.stderr.write(`mcp-gate(${NAME}): could not trim ${tool}: ${String(error)}
|
|
726
|
+
process.stderr.write(`mcp-gate(${NAME}): could not trim ${request.tool}: ${String(error)}
|
|
595
727
|
`);
|
|
596
728
|
process.stdout.write(`${line}
|
|
597
729
|
`);
|