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.
Files changed (163) hide show
  1. package/dist/assets/{DesktopViewer-Do6lBa4C.js → DesktopViewer-bxM7NV3N.js} +1 -1
  2. package/dist/assets/{abnfDiagram-O67JEVCF-Cd3X7Hxc.js → abnfDiagram-O67JEVCF-BhMdJhRJ.js} +1 -1
  3. package/dist/assets/{arc-DIYc7Ymx.js → arc-B5itKDcx.js} +1 -1
  4. package/dist/assets/{architectureDiagram-NJMV4G6O-DBmRGVyP.js → architectureDiagram-NJMV4G6O-C5d7UY6U.js} +1 -1
  5. package/dist/assets/{blockDiagram-BEXU5L5S-CPFePSEE.js → blockDiagram-BEXU5L5S-BrZIhMmu.js} +1 -1
  6. package/dist/assets/{c4Diagram-YGBWAQC7-DD_DO1qy.js → c4Diagram-YGBWAQC7-7I0ArfbD.js} +1 -1
  7. package/dist/assets/channel-CdJX6i8k.js +1 -0
  8. package/dist/assets/{chunk-2Q5K7J3B-BNEeNSjX.js → chunk-2Q5K7J3B-BnEsyN36.js} +1 -1
  9. package/dist/assets/{chunk-3FUC2YCW-BbinLaqH.js → chunk-3FUC2YCW-BXATQ52s.js} +2 -2
  10. package/dist/assets/{chunk-5VM5RSS4-BBgYrgDR.js → chunk-5VM5RSS4-B0BpTkEx.js} +1 -1
  11. package/dist/assets/{chunk-GTNCS2PH-ezXj-kA-.js → chunk-GTNCS2PH-BtLTz6FR.js} +1 -1
  12. package/dist/assets/{chunk-GWA4HPMP-9FxZ3diV.js → chunk-GWA4HPMP-D6gcZOYt.js} +1 -1
  13. package/dist/assets/{chunk-JWPE2WC7-CO-40JpI.js → chunk-JWPE2WC7-DCLrosvf.js} +1 -1
  14. package/dist/assets/{chunk-NETBCI7D-BEhjslYE.js → chunk-NETBCI7D-B9JsknV9.js} +1 -1
  15. package/dist/assets/{chunk-WEXAMYUT-CNeq4n7_.js → chunk-WEXAMYUT-CsoTxw7z.js} +1 -1
  16. package/dist/assets/{chunk-XXDRQBXY-OsCY7KSi.js → chunk-XXDRQBXY-0F_frB0c.js} +1 -1
  17. package/dist/assets/{classDiagram-v2-NBCMYWYE-CloRUEtk.js → classDiagram-v2-NBCMYWYE-DkrpnflX.js} +1 -1
  18. package/dist/assets/{cose-bilkent-JH36ORCC-D1BGZhp4.js → cose-bilkent-JH36ORCC-BNDwYBt9.js} +1 -1
  19. package/dist/assets/{cynefin-OW5HDTMX-CUf4T2CN.js → cynefin-OW5HDTMX-JUkNr1Mk.js} +1 -1
  20. package/dist/assets/{cynefinDiagram-VND7K2PF-DPEZrFGA.js → cynefinDiagram-VND7K2PF-DKeh9N4M.js} +1 -1
  21. package/dist/assets/{dagre-6A5THRUB-bDe6GIv5.js → dagre-6A5THRUB-ve-6T_wX.js} +1 -1
  22. package/dist/assets/{diagram-22UHCM2B-CdcUQz55.js → diagram-22UHCM2B-BuJ2d8rT.js} +1 -1
  23. package/dist/assets/{diagram-3UASUU5V-BZpqGg7c.js → diagram-3UASUU5V-BgOs_Ni-.js} +1 -1
  24. package/dist/assets/{diagram-ATOU4E4O-DvGM6ugp.js → diagram-ATOU4E4O-DMK6VmcP.js} +1 -1
  25. package/dist/assets/{diagram-CDSNMT55-DSTmMm0s.js → diagram-CDSNMT55-DksASlcY.js} +1 -1
  26. package/dist/assets/{diagram-MLGK6HIB-15cucnMn.js → diagram-MLGK6HIB-Bgn8I5k6.js} +1 -1
  27. package/dist/assets/{diagram-MPIPVDR6-tMbuaE6n.js → diagram-MPIPVDR6-zK0jqO8N.js} +1 -1
  28. package/dist/assets/{ebnfDiagram-ZINNZB2B-BYxYzjHI.js → ebnfDiagram-ZINNZB2B-vKrbzTwr.js} +1 -1
  29. package/dist/assets/{elk-276RUBZZ-v6bj852W.js → elk-276RUBZZ-Bzv2mPNf.js} +1 -1
  30. package/dist/assets/{erDiagram-OPXOYQCR-5lBBlnd2.js → erDiagram-OPXOYQCR-CvOyYuxu.js} +1 -1
  31. package/dist/assets/{flowDiagram-KWPJA3E3-CZyl1zIj.js → flowDiagram-KWPJA3E3-CtbnDbc0.js} +1 -1
  32. package/dist/assets/{ganttDiagram-FUAMR5RP-BiAI-ltZ.js → ganttDiagram-FUAMR5RP-c4dMRYyG.js} +1 -1
  33. package/dist/assets/{gitGraphDiagram-X574FWY7-BAZISkj3.js → gitGraphDiagram-X574FWY7-B34uaQho.js} +1 -1
  34. package/dist/assets/index-CPYrGsv1.js +610 -0
  35. package/dist/assets/{index-DGBaEXrM.js → index-CPiqc_DN.js} +1 -1
  36. package/dist/assets/index-CzT42GR8.css +1 -0
  37. package/dist/assets/{infoDiagram-VRGFBTTK-B6ooOy-Z.js → infoDiagram-VRGFBTTK-o64ma4CI.js} +1 -1
  38. package/dist/assets/{ishikawaDiagram-OU5B5YK6-BZ9ksi-B.js → ishikawaDiagram-OU5B5YK6-DV4C9BAm.js} +1 -1
  39. package/dist/assets/{journeyDiagram-ZHPQQLJL-DWqlzIEe.js → journeyDiagram-ZHPQQLJL-Bf0AHk1H.js} +1 -1
  40. package/dist/assets/{kanban-definition-PNTS6WVX-JX6piDwL.js → kanban-definition-PNTS6WVX-B1UMSKmE.js} +1 -1
  41. package/dist/assets/{linear-CmOWzX0P.js → linear-BpKhuyLm.js} +1 -1
  42. package/dist/assets/{mermaid.core-CF1zwoQ-.js → mermaid.core-B_BKNCw5.js} +5 -5
  43. package/dist/assets/{mindmap-definition-NLK3R4M7-CGh2K4fW.js → mindmap-definition-NLK3R4M7-DeARruT1.js} +1 -1
  44. package/dist/assets/{pegDiagram-GJSIUBJH-CDwYN0s7.js → pegDiagram-GJSIUBJH-BOQEk_1D.js} +1 -1
  45. package/dist/assets/{pieDiagram-5QR66LMP-1rfjJocB.js → pieDiagram-5QR66LMP-EIfoiTZo.js} +1 -1
  46. package/dist/assets/{quadrantDiagram-O4NWA36T-tKPvPiok.js → quadrantDiagram-O4NWA36T-GgZwT-fi.js} +1 -1
  47. package/dist/assets/{railroadDiagram-XR7U4H2S-BHLm5vXR.js → railroadDiagram-XR7U4H2S-D9rDQomj.js} +1 -1
  48. package/dist/assets/{requirementDiagram-PLB6GJNP-CB45STp7.js → requirementDiagram-PLB6GJNP-DAh1MIeo.js} +1 -1
  49. package/dist/assets/{sankeyDiagram-IPEJSGJF-55QA_huC.js → sankeyDiagram-IPEJSGJF-CPr6Uz64.js} +1 -1
  50. package/dist/assets/{sequenceDiagram-PO4LG4MO-BckFmQHn.js → sequenceDiagram-PO4LG4MO-BU6VIdcm.js} +1 -1
  51. package/dist/assets/{sizeCapture-INFHLROL-BFCOJF11.js → sizeCapture-INFHLROL-qF2HO41r.js} +1 -1
  52. package/dist/assets/{stateDiagram-v2-GCMORJYK-CZvmiVVN.js → stateDiagram-v2-GCMORJYK-DlJ8G4MD.js} +1 -1
  53. package/dist/assets/{swimlanes-2SLR337P-BpDUCEKy.js → swimlanes-2SLR337P-DzYE8I54.js} +1 -1
  54. package/dist/assets/swimlanesDiagram-TC7HE7FX-D-U4GtLQ.js +8 -0
  55. package/dist/assets/{timeline-definition-EJHVYXUP-BpxHq6IK.js → timeline-definition-EJHVYXUP-B7wzEQ0A.js} +1 -1
  56. package/dist/assets/{usecaseDiagram-POWQR4AR-Cj66vm02.js → usecaseDiagram-POWQR4AR-BvGgrxIP.js} +1 -1
  57. package/dist/assets/{vennDiagram-UO4OBE2U-C9nRkWE_.js → vennDiagram-UO4OBE2U-CEECdgQg.js} +1 -1
  58. package/dist/assets/{wardleyDiagram-VNRHLVJA-D-me_nWj.js → wardleyDiagram-VNRHLVJA-XQHA0P_P.js} +1 -1
  59. package/dist/assets/{xychartDiagram-PMCCYNJV-Dc_fL4mk.js → xychartDiagram-PMCCYNJV-B5mLcZI2.js} +1 -1
  60. package/dist/index.html +2 -2
  61. package/dist-server/cloud-home-start.js +1 -0
  62. package/dist-server/companion/src/routes.js +45 -1
  63. package/dist-server/container-mcp.js +99 -77
  64. package/dist-server/drivers/agents-proxy.js +40 -1
  65. package/dist-server/drivers/pi-mcp-extension.ts +245 -299
  66. package/dist-server/enterprise/server/index.js +1 -0
  67. package/dist-server/index.js +18361 -13794
  68. package/dist-server/local-computer-proxy.js +5 -1
  69. package/dist-server/local-computer.js +1 -0
  70. package/dist-server/mcp-gate.js +152 -20
  71. package/dist-server/mcp-remote-proxy.js +437 -0
  72. package/dist-server/openmausbot.js +8872 -7620
  73. package/dist-server/pair-cli.js +8872 -7620
  74. package/dist-server/permission-proxy.js +65 -1
  75. package/dist-server/proxy-paths.js +1 -0
  76. package/dist-server/server/auto-approve.js +33 -11
  77. package/dist-server/server/boat.js +3 -3
  78. package/dist-server/server/browser-live.js +14 -5
  79. package/dist-server/server/browser-runtime.js +6 -0
  80. package/dist-server/server/channel-queue.js +4 -1
  81. package/dist-server/server/cli.js +32 -12
  82. package/dist-server/server/cloud-move-http.js +9 -3
  83. package/dist-server/server/cloud-move.js +18 -0
  84. package/dist-server/server/cloud-owner.js +1 -1
  85. package/dist-server/server/computer-control.js +6 -0
  86. package/dist-server/server/computer-wait.js +33 -13
  87. package/dist-server/server/config.js +57 -10
  88. package/dist-server/server/container-computer.js +43 -32
  89. package/dist-server/server/decision-log.js +9 -6
  90. package/dist-server/server/delegations.js +47 -22
  91. package/dist-server/server/digest.js +12 -2
  92. package/dist-server/server/drivers/acp/core.js +229 -20
  93. package/dist-server/server/drivers/acp/cursor.js +13 -1
  94. package/dist-server/server/drivers/acp/grok.js +208 -3
  95. package/dist-server/server/drivers/acp/quiet-status.js +257 -0
  96. package/dist-server/server/drivers/acp/qwen.js +18 -0
  97. package/dist-server/server/drivers/agents-call.js +28 -0
  98. package/dist-server/server/drivers/agents-catalog.js +10 -1
  99. package/dist-server/server/drivers/boatagent.js +2 -0
  100. package/dist-server/server/drivers/builtIn.js +2 -0
  101. package/dist-server/server/drivers/cerebras.js +108 -0
  102. package/dist-server/server/drivers/chat-mcp-tools.js +45 -15
  103. package/dist-server/server/drivers/claude.js +35 -9
  104. package/dist-server/server/drivers/codex.js +84 -10
  105. package/dist-server/server/drivers/openai-chat.js +37 -5
  106. package/dist-server/server/drivers/pi.js +48 -4
  107. package/dist-server/server/drivers/prompt-split.js +2 -0
  108. package/dist-server/server/env-path.js +6 -2
  109. package/dist-server/server/environment.js +3 -0
  110. package/dist-server/server/guarded-requests.js +2 -1
  111. package/dist-server/server/index.js +1353 -311
  112. package/dist-server/server/live-call-controller.js +868 -0
  113. package/dist-server/server/live-call.js +216 -0
  114. package/dist-server/server/local-vm-stop-reason.js +26 -0
  115. package/dist-server/server/mcp-gate-config.js +43 -12
  116. package/dist-server/server/mcp-gate.js +127 -25
  117. package/dist-server/server/mcp-http.js +46 -8
  118. package/dist-server/server/mcp-remote-proxy.js +108 -0
  119. package/dist-server/server/new-bot-defaults.js +3 -0
  120. package/dist-server/server/peer-provenance.js +4 -2
  121. package/dist-server/server/permission-proxy.js +15 -1
  122. package/dist-server/server/plan-usage.js +797 -0
  123. package/dist-server/server/provider-key-check.js +2 -1
  124. package/dist-server/server/proxy-paths.js +1 -0
  125. package/dist-server/server/redact.js +2 -0
  126. package/dist-server/server/request-auth.js +3 -2
  127. package/dist-server/server/routes/desktop-viewer.js +50 -6
  128. package/dist-server/server/routes/live.js +98 -0
  129. package/dist-server/server/routines.js +6 -3
  130. package/dist-server/server/skill-library.js +207 -0
  131. package/dist-server/server/skills-library-migration.js +235 -0
  132. package/dist-server/server/skills.js +66 -3
  133. package/dist-server/server/steer-queue.js +13 -1
  134. package/dist-server/server/store.js +86 -4
  135. package/dist-server/server/surface.js +9 -3
  136. package/dist-server/server/team-backup.js +2 -1
  137. package/dist-server/server/thread-events.js +1 -1
  138. package/dist-server/server/tunnel.js +20 -1
  139. package/dist-server/server/turn-log.js +10 -0
  140. package/dist-server/server/turn-resources.js +124 -0
  141. package/dist-server/server/vps-computer.js +1 -1
  142. package/dist-server/server/workspace-backup.js +22 -0
  143. package/dist-server/server/workspace.js +1 -1
  144. package/dist-server/shared/approval-mode.js +1 -1
  145. package/dist-server/shared/ask-question.js +13 -0
  146. package/dist-server/shared/call-consent.js +28 -0
  147. package/dist-server/shared/live-approval.js +124 -0
  148. package/dist-server/shared/live-call.js +176 -0
  149. package/dist-server/shared/redact.js +1 -0
  150. package/dist-server/shared/skill-md.js +10 -0
  151. package/dist-server/shared/team-backup.js +3 -0
  152. package/dist-server/shared/tool-name.js +22 -0
  153. package/dist-server/shared/tool-scope-support.js +25 -0
  154. package/dist-server/shared/tool-scope.js +136 -0
  155. package/dist-server/src/lib/thread-refs.js +406 -0
  156. package/dist-server/vps-container-mcp.js +99 -77
  157. package/dist-server/workspace-backup.worker.js +103 -100
  158. package/enterprise/server/index.js +1 -0
  159. package/package.json +1 -1
  160. package/dist/assets/channel-Dtk5Mtic.js +0 -1
  161. package/dist/assets/index-Cdmjrl28.css +0 -1
  162. package/dist/assets/index-DR7YPMkW.js +0 -597
  163. package/dist/assets/swimlanesDiagram-TC7HE7FX-M0GYW9Y3.js +0 -8
@@ -0,0 +1,437 @@
1
+ // server/mcp-remote-proxy.ts
2
+ import { createInterface } from "node:readline";
3
+
4
+ // server/mcp-http.ts
5
+ var McpHttpError = class extends Error {
6
+ kind;
7
+ status;
8
+ /** The server's `WWW-Authenticate` challenge on a 401: where to sign in. */
9
+ wwwAuthenticate;
10
+ constructor(kind, message, status, wwwAuthenticate) {
11
+ super(message);
12
+ this.name = "McpHttpError";
13
+ this.kind = kind;
14
+ this.status = status;
15
+ this.wwwAuthenticate = wwwAuthenticate;
16
+ }
17
+ };
18
+ var MAX_BODY_BYTES = 1048576;
19
+ var PROTOCOL_VERSION = "2025-06-18";
20
+ function isRecord(value) {
21
+ return value !== null && typeof value === "object" && !Array.isArray(value);
22
+ }
23
+ function remoteMcpSpec(value) {
24
+ if (!isRecord(value) || value.type !== "http" && value.type !== "sse" || typeof value.url !== "string") return;
25
+ try {
26
+ const url = new URL(value.url);
27
+ if (url.protocol !== "http:" && url.protocol !== "https:" || url.username || url.password) return;
28
+ const headers = value.headers ?? {};
29
+ if (!isRecord(headers) || !Object.values(headers).every((header) => typeof header === "string")) return;
30
+ new Headers(headers);
31
+ return { type: value.type, url: value.url, headers };
32
+ } catch {
33
+ return;
34
+ }
35
+ }
36
+ function unwrap(message) {
37
+ if (message.error !== void 0) {
38
+ const detail = isRecord(message.error) && typeof message.error.message === "string" ? message.error.message : "request failed";
39
+ throw new McpHttpError("protocol", `MCP error: ${detail}`);
40
+ }
41
+ return message.result;
42
+ }
43
+ function parseMessage(text) {
44
+ try {
45
+ const parsed = JSON.parse(text);
46
+ if (Array.isArray(parsed)) return parsed.filter(isRecord);
47
+ return isRecord(parsed) ? parsed : null;
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+ function parseSseBlock(block) {
53
+ let event = "message";
54
+ const data = [];
55
+ for (const line of block.split("\n")) {
56
+ if (!line || line.startsWith(":")) continue;
57
+ const colon = line.indexOf(":");
58
+ const field = colon === -1 ? line : line.slice(0, colon);
59
+ let value = colon === -1 ? "" : line.slice(colon + 1);
60
+ if (value.startsWith(" ")) value = value.slice(1);
61
+ if (field === "event") event = value;
62
+ else if (field === "data") data.push(value);
63
+ }
64
+ return data.length ? { event, data: data.join("\n") } : null;
65
+ }
66
+ async function readSse(response, signal, onEvent, maxBytes = MAX_BODY_BYTES) {
67
+ const reader = response.body?.getReader();
68
+ if (!reader) throw new McpHttpError("protocol", "empty event stream");
69
+ const decoder = new TextDecoder();
70
+ let buffer = "";
71
+ let bytes = 0;
72
+ const onAbort = () => void reader.cancel().catch(() => {
73
+ });
74
+ signal.addEventListener("abort", onAbort, { once: true });
75
+ try {
76
+ for (; ; ) {
77
+ const { value, done } = await reader.read();
78
+ if (done) return;
79
+ bytes += value.byteLength;
80
+ if (bytes > maxBytes) throw new McpHttpError("protocol", "event stream too large");
81
+ buffer += decoder.decode(value, { stream: true }).replace(/\r\n?/g, "\n");
82
+ let separator;
83
+ while ((separator = buffer.indexOf("\n\n")) !== -1) {
84
+ const block = buffer.slice(0, separator);
85
+ buffer = buffer.slice(separator + 2);
86
+ const event = parseSseBlock(block);
87
+ if (event && onEvent(event) === "stop") {
88
+ await reader.cancel().catch(() => {
89
+ });
90
+ return;
91
+ }
92
+ }
93
+ }
94
+ } finally {
95
+ signal.removeEventListener("abort", onAbort);
96
+ }
97
+ }
98
+ async function readBounded(response, maxBytes = MAX_BODY_BYTES) {
99
+ const reader = response.body?.getReader();
100
+ if (!reader) return "";
101
+ const decoder = new TextDecoder();
102
+ let text = "";
103
+ let bytes = 0;
104
+ for (; ; ) {
105
+ const { value, done } = await reader.read();
106
+ if (done) return text + decoder.decode();
107
+ bytes += value.byteLength;
108
+ if (bytes > maxBytes) {
109
+ await reader.cancel().catch(() => {
110
+ });
111
+ throw new McpHttpError("protocol", "response too large");
112
+ }
113
+ text += decoder.decode(value, { stream: true });
114
+ }
115
+ }
116
+ function drain(response) {
117
+ void response.body?.cancel().catch(() => {
118
+ });
119
+ }
120
+ var RemoteMcpClient = class {
121
+ target;
122
+ fetchImpl;
123
+ maxBytes;
124
+ onNotification;
125
+ sessionId = null;
126
+ protocolVersion = null;
127
+ nextId = 1;
128
+ closed = false;
129
+ /** Legacy SSE: one long GET stream carries every response. */
130
+ pending = /* @__PURE__ */ new Map();
131
+ sseEndpoint = null;
132
+ sseAbort = new AbortController();
133
+ constructor(target, options = {}) {
134
+ this.target = target;
135
+ this.fetchImpl = options.fetch ?? fetch;
136
+ this.maxBytes = options.maxBytes ?? MAX_BODY_BYTES;
137
+ this.onNotification = options.onNotification;
138
+ }
139
+ /** The MCP handshake: initialize, then the initialized notification. */
140
+ async initialize(clientName, signal) {
141
+ const result = await this.request("initialize", {
142
+ protocolVersion: PROTOCOL_VERSION,
143
+ capabilities: {},
144
+ clientInfo: { name: clientName, version: "1" }
145
+ }, signal);
146
+ if (isRecord(result) && typeof result.protocolVersion === "string") this.protocolVersion = result.protocolVersion;
147
+ await this.notify("notifications/initialized", void 0, signal);
148
+ return result;
149
+ }
150
+ request(method, params, signal) {
151
+ if (this.closed) return Promise.reject(new McpHttpError("protocol", "client closed"));
152
+ if (signal.aborted) return Promise.reject(new McpHttpError("network", "aborted"));
153
+ const id = this.nextId++;
154
+ const frame = { jsonrpc: "2.0", id, method, ...params === void 0 ? {} : { params } };
155
+ const onAbort = () => {
156
+ void this.notify("notifications/cancelled", { requestId: id, reason: "Request cancelled" }, AbortSignal.timeout(2e3)).catch(() => {
157
+ });
158
+ };
159
+ signal.addEventListener("abort", onAbort, { once: true });
160
+ const reply = this.target.type === "sse" ? this.sseRequest(id, frame, signal) : this.streamableRequest(id, frame, signal);
161
+ return reply.finally(() => signal.removeEventListener("abort", onAbort));
162
+ }
163
+ async notify(method, params, signal) {
164
+ if (this.closed) throw new McpHttpError("protocol", "client closed");
165
+ const frame = { jsonrpc: "2.0", method, ...params === void 0 ? {} : { params } };
166
+ if (this.target.type === "sse") {
167
+ await this.ssePost(frame, signal);
168
+ return;
169
+ }
170
+ const response = await this.post(this.target.url, frame, signal);
171
+ drain(response);
172
+ }
173
+ async close() {
174
+ if (this.closed) return;
175
+ this.closed = true;
176
+ this.sseAbort.abort();
177
+ for (const entry of this.pending.values()) entry.reject(new McpHttpError("network", "client closed"));
178
+ this.pending.clear();
179
+ if (this.sessionId && this.target.type !== "sse") {
180
+ try {
181
+ const headers = this.headers();
182
+ headers.set("mcp-session-id", this.sessionId);
183
+ const response = await this.fetchImpl(this.target.url, { method: "DELETE", headers, signal: AbortSignal.timeout(2e3) });
184
+ drain(response);
185
+ } catch {
186
+ }
187
+ }
188
+ }
189
+ headers() {
190
+ const headers = new Headers();
191
+ for (const [name, value] of Object.entries(this.target.headers)) headers.set(name, value);
192
+ headers.set("accept", "application/json, text/event-stream");
193
+ if (this.sessionId) headers.set("mcp-session-id", this.sessionId);
194
+ if (this.protocolVersion) headers.set("mcp-protocol-version", this.protocolVersion);
195
+ return headers;
196
+ }
197
+ async post(url, frame, signal) {
198
+ const headers = this.headers();
199
+ headers.set("content-type", "application/json");
200
+ let response;
201
+ try {
202
+ response = await this.fetchImpl(url, { method: "POST", headers, body: JSON.stringify(frame), signal });
203
+ } catch (error2) {
204
+ if (signal.aborted) throw error2;
205
+ throw new McpHttpError("network", "request failed");
206
+ }
207
+ if (!response.ok) {
208
+ drain(response);
209
+ throw new McpHttpError("status", `HTTP ${response.status}`, response.status, response.headers.get("www-authenticate") ?? void 0);
210
+ }
211
+ const session = response.headers.get("mcp-session-id");
212
+ if (session) this.sessionId = session;
213
+ return response;
214
+ }
215
+ // ── streamable HTTP: each request is one POST; the answer is JSON or a
216
+ // short event stream that carries the response among server messages ──
217
+ async streamableRequest(id, frame, signal) {
218
+ const response = await this.post(this.target.url, frame, signal);
219
+ const type = (response.headers.get("content-type") ?? "").toLowerCase();
220
+ if (type.startsWith("application/json")) {
221
+ const parsed = parseMessage(await readBounded(response, this.maxBytes));
222
+ this.deliverNotifications(parsed);
223
+ const message = (Array.isArray(parsed) ? parsed : parsed ? [parsed] : []).find((entry) => entry.id === id);
224
+ if (!message) throw new McpHttpError("protocol", "response did not answer the request");
225
+ return unwrap(message);
226
+ }
227
+ if (type.startsWith("text/event-stream")) {
228
+ let found;
229
+ await readSse(response, signal, (event) => {
230
+ if (event.event !== "message") return void 0;
231
+ const parsed = parseMessage(event.data);
232
+ this.deliverNotifications(parsed);
233
+ const message = (Array.isArray(parsed) ? parsed : parsed ? [parsed] : []).find((entry) => entry.id === id);
234
+ if (!message) return void 0;
235
+ found = message;
236
+ return "stop";
237
+ }, this.maxBytes);
238
+ if (signal.aborted) throw new McpHttpError("network", "aborted");
239
+ if (!found) throw new McpHttpError("protocol", "event stream ended without the response");
240
+ return unwrap(found);
241
+ }
242
+ drain(response);
243
+ throw new McpHttpError("protocol", "unexpected content type");
244
+ }
245
+ // ── legacy SSE: a GET opens the stream, its first event names where to
246
+ // POST, and every response comes back over the stream ──
247
+ openSseStream(signal) {
248
+ if (this.sseEndpoint) return this.sseEndpoint;
249
+ this.sseEndpoint = new Promise((resolveEndpoint, rejectEndpoint) => {
250
+ let settled = false;
251
+ const fail = (error2) => {
252
+ if (!settled) {
253
+ settled = true;
254
+ rejectEndpoint(error2);
255
+ }
256
+ for (const entry of this.pending.values()) entry.reject(error2);
257
+ this.pending.clear();
258
+ };
259
+ const headers = this.headers();
260
+ headers.set("accept", "text/event-stream");
261
+ const opening = AbortSignal.any([signal, this.sseAbort.signal]);
262
+ this.fetchImpl(this.target.url, { method: "GET", headers, signal: opening }).then(async (response) => {
263
+ if (!response.ok) {
264
+ drain(response);
265
+ throw new McpHttpError("status", `HTTP ${response.status}`, response.status, response.headers.get("www-authenticate") ?? void 0);
266
+ }
267
+ await readSse(response, this.sseAbort.signal, (event) => {
268
+ if (event.event === "endpoint") {
269
+ if (!settled) {
270
+ settled = true;
271
+ try {
272
+ resolveEndpoint(new URL(event.data, this.target.url).toString());
273
+ } catch {
274
+ rejectEndpoint(new McpHttpError("protocol", "invalid endpoint event"));
275
+ }
276
+ }
277
+ return void 0;
278
+ }
279
+ if (event.event !== "message") return void 0;
280
+ const parsed = parseMessage(event.data);
281
+ this.deliverNotifications(parsed);
282
+ for (const message of Array.isArray(parsed) ? parsed : parsed ? [parsed] : []) {
283
+ const entry = typeof message.id === "number" ? this.pending.get(message.id) : void 0;
284
+ if (!entry) continue;
285
+ this.pending.delete(message.id);
286
+ try {
287
+ entry.resolve(unwrap(message));
288
+ } catch (error2) {
289
+ entry.reject(error2 instanceof Error ? error2 : new McpHttpError("protocol", String(error2)));
290
+ }
291
+ }
292
+ return void 0;
293
+ }, this.maxBytes);
294
+ fail(new McpHttpError("network", "event stream ended"));
295
+ }).catch((error2) => {
296
+ fail(error2 instanceof McpHttpError ? error2 : new McpHttpError("network", "event stream failed"));
297
+ });
298
+ });
299
+ return this.sseEndpoint;
300
+ }
301
+ async ssePost(frame, signal) {
302
+ const endpoint = await this.openSseStream(signal);
303
+ const response = await this.post(endpoint, frame, signal);
304
+ drain(response);
305
+ }
306
+ sseRequest(id, frame, signal) {
307
+ return new Promise((resolve, reject) => {
308
+ const onAbort = () => {
309
+ this.pending.delete(id);
310
+ reject(new McpHttpError("network", "aborted"));
311
+ };
312
+ signal.addEventListener("abort", onAbort, { once: true });
313
+ this.pending.set(id, {
314
+ resolve: (value) => {
315
+ signal.removeEventListener("abort", onAbort);
316
+ resolve(value);
317
+ },
318
+ reject: (error2) => {
319
+ signal.removeEventListener("abort", onAbort);
320
+ reject(error2);
321
+ }
322
+ });
323
+ this.ssePost(frame, signal).catch((error2) => {
324
+ this.pending.delete(id);
325
+ signal.removeEventListener("abort", onAbort);
326
+ reject(error2 instanceof Error ? error2 : new McpHttpError("network", String(error2)));
327
+ });
328
+ });
329
+ }
330
+ deliverNotifications(parsed) {
331
+ for (const message of Array.isArray(parsed) ? parsed : parsed ? [parsed] : []) {
332
+ if (typeof message.method === "string" && message.id === void 0) this.onNotification?.(message);
333
+ }
334
+ }
335
+ };
336
+
337
+ // server/mcp-remote-proxy.ts
338
+ function isRecord2(value) {
339
+ return !!value && typeof value === "object" && !Array.isArray(value);
340
+ }
341
+ function requestKey(id) {
342
+ return typeof id === "string" || typeof id === "number" && Number.isFinite(id) ? `${typeof id}:${id}` : void 0;
343
+ }
344
+ function send(frame) {
345
+ process.stdout.write(`${JSON.stringify(frame)}
346
+ `);
347
+ }
348
+ function error(id, code, message) {
349
+ send({ jsonrpc: "2.0", id: requestKey(id) ? id : null, error: { code, message } });
350
+ }
351
+ var spec;
352
+ try {
353
+ spec = remoteMcpSpec(JSON.parse(process.env.OMB_REMOTE_MCP_SERVER ?? ""));
354
+ } catch {
355
+ }
356
+ delete process.env.OMB_REMOTE_MCP_SERVER;
357
+ if (!spec) {
358
+ process.stderr.write("mcp-remote-proxy: invalid remote MCP configuration\n");
359
+ process.exit(1);
360
+ }
361
+ var client = new RemoteMcpClient(spec, { maxBytes: 32 * 1024 * 1024, onNotification: send });
362
+ var pending = /* @__PURE__ */ new Map();
363
+ var tasks = /* @__PURE__ */ new Set();
364
+ var initialized = false;
365
+ var closing = false;
366
+ async function handle(message) {
367
+ const id = requestKey(message.id);
368
+ if (typeof message.method !== "string" || message.jsonrpc !== "2.0") {
369
+ error(message.id, -32600, "Invalid JSON-RPC request");
370
+ return;
371
+ }
372
+ if (message.method === "notifications/cancelled") {
373
+ const key = isRecord2(message.params) ? requestKey(message.params.requestId) : void 0;
374
+ if (key) pending.get(key)?.abort();
375
+ return;
376
+ }
377
+ if (!id) {
378
+ if (message.method === "notifications/initialized" && initialized) return;
379
+ try {
380
+ await client.notify(message.method, message.params, AbortSignal.timeout(3e4));
381
+ } catch {
382
+ }
383
+ return;
384
+ }
385
+ if (pending.has(id)) {
386
+ error(message.id, -32600, "Duplicate request ID");
387
+ return;
388
+ }
389
+ const controller = new AbortController();
390
+ pending.set(id, controller);
391
+ const signal = AbortSignal.any([controller.signal, AbortSignal.timeout(message.method === "tools/call" ? 12e4 : 3e4)]);
392
+ try {
393
+ const result = message.method === "initialize" ? await client.initialize("OpenMausBot tool proxy", signal) : await client.request(message.method, message.params, signal);
394
+ if (message.method === "initialize") initialized = true;
395
+ send({ jsonrpc: "2.0", id: message.id, result });
396
+ } catch {
397
+ error(message.id, signal.aborted ? -32800 : -32603, signal.aborted ? "MCP request cancelled" : "Remote MCP request failed");
398
+ } finally {
399
+ pending.delete(id);
400
+ }
401
+ }
402
+ var input = createInterface({ input: process.stdin });
403
+ input.on("line", (line) => {
404
+ if (closing || !line.trim()) return;
405
+ let value;
406
+ try {
407
+ value = JSON.parse(line);
408
+ } catch {
409
+ error(null, -32700, "Invalid JSON-RPC frame");
410
+ return;
411
+ }
412
+ if (!isRecord2(value)) {
413
+ error(null, -32600, "Invalid JSON-RPC frame");
414
+ return;
415
+ }
416
+ const task = handle(value);
417
+ tasks.add(task);
418
+ void task.finally(() => tasks.delete(task));
419
+ });
420
+ async function shutdown() {
421
+ if (closing) return;
422
+ closing = true;
423
+ input.close();
424
+ for (const controller of pending.values()) controller.abort();
425
+ await Promise.allSettled(tasks);
426
+ await client.close();
427
+ process.exit(0);
428
+ }
429
+ input.on("close", () => {
430
+ void shutdown();
431
+ });
432
+ process.on("SIGTERM", () => {
433
+ void shutdown();
434
+ });
435
+ process.on("SIGINT", () => {
436
+ void shutdown();
437
+ });