@fractaal/pi-mcp 0.86.9 → 1.6.0

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 (91) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +60 -5
  3. package/dist/auth-provider.d.ts +4 -0
  4. package/dist/auth-provider.d.ts.map +1 -1
  5. package/dist/auth-provider.js.map +1 -1
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +9 -5
  8. package/dist/client.js.map +1 -1
  9. package/dist/config.d.ts +117 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +153 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/index.d.ts +6 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +5 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/input-schema.d.ts +7 -0
  18. package/dist/input-schema.d.ts.map +1 -0
  19. package/dist/input-schema.js +13 -0
  20. package/dist/input-schema.js.map +1 -0
  21. package/dist/naming.d.ts +18 -0
  22. package/dist/naming.d.ts.map +1 -0
  23. package/dist/naming.js +29 -0
  24. package/dist/naming.js.map +1 -0
  25. package/dist/oauth/auth-provider.d.ts +52 -0
  26. package/dist/oauth/auth-provider.d.ts.map +1 -0
  27. package/dist/oauth/auth-provider.js +97 -0
  28. package/dist/oauth/auth-provider.js.map +1 -0
  29. package/dist/oauth/callback.d.ts.map +1 -1
  30. package/dist/oauth/callback.js +5 -1
  31. package/dist/oauth/callback.js.map +1 -1
  32. package/dist/oauth/client-settings.d.ts +107 -0
  33. package/dist/oauth/client-settings.d.ts.map +1 -0
  34. package/dist/oauth/client-settings.js +114 -0
  35. package/dist/oauth/client-settings.js.map +1 -0
  36. package/dist/oauth/discovery.d.ts +3 -0
  37. package/dist/oauth/discovery.d.ts.map +1 -1
  38. package/dist/oauth/discovery.js +9 -6
  39. package/dist/oauth/discovery.js.map +1 -1
  40. package/dist/oauth/errors.d.ts +10 -2
  41. package/dist/oauth/errors.d.ts.map +1 -1
  42. package/dist/oauth/errors.js +13 -1
  43. package/dist/oauth/errors.js.map +1 -1
  44. package/dist/oauth/flow.d.ts +14 -0
  45. package/dist/oauth/flow.d.ts.map +1 -1
  46. package/dist/oauth/flow.js +52 -15
  47. package/dist/oauth/flow.js.map +1 -1
  48. package/dist/oauth/index.d.ts +5 -1
  49. package/dist/oauth/index.d.ts.map +1 -1
  50. package/dist/oauth/index.js +4 -1
  51. package/dist/oauth/index.js.map +1 -1
  52. package/dist/oauth/loopback.d.ts +51 -0
  53. package/dist/oauth/loopback.d.ts.map +1 -0
  54. package/dist/oauth/loopback.js +98 -0
  55. package/dist/oauth/loopback.js.map +1 -0
  56. package/dist/oauth/sign-in.d.ts +73 -0
  57. package/dist/oauth/sign-in.d.ts.map +1 -0
  58. package/dist/oauth/sign-in.js +182 -0
  59. package/dist/oauth/sign-in.js.map +1 -0
  60. package/dist/oauth/types.d.ts +1 -0
  61. package/dist/oauth/types.d.ts.map +1 -1
  62. package/dist/oauth/types.js +9 -5
  63. package/dist/oauth/types.js.map +1 -1
  64. package/dist/output-limit.d.ts +24 -0
  65. package/dist/output-limit.d.ts.map +1 -0
  66. package/dist/output-limit.js +58 -0
  67. package/dist/output-limit.js.map +1 -0
  68. package/dist/protocol/content.d.ts +2 -1
  69. package/dist/protocol/content.d.ts.map +1 -1
  70. package/dist/protocol/content.js.map +1 -1
  71. package/dist/transports/lines.d.ts +34 -0
  72. package/dist/transports/lines.d.ts.map +1 -0
  73. package/dist/transports/lines.js +85 -0
  74. package/dist/transports/lines.js.map +1 -0
  75. package/dist/transports/pipe.d.ts +49 -0
  76. package/dist/transports/pipe.d.ts.map +1 -0
  77. package/dist/transports/pipe.js +96 -0
  78. package/dist/transports/pipe.js.map +1 -0
  79. package/dist/transports/stdio.d.ts +1 -4
  80. package/dist/transports/stdio.d.ts.map +1 -1
  81. package/dist/transports/stdio.js +20 -51
  82. package/dist/transports/stdio.js.map +1 -1
  83. package/dist/transports/streamable-http.d.ts +9 -2
  84. package/dist/transports/streamable-http.d.ts.map +1 -1
  85. package/dist/transports/streamable-http.js +105 -30
  86. package/dist/transports/streamable-http.js.map +1 -1
  87. package/dist/transports/transport.d.ts +9 -1
  88. package/dist/transports/transport.d.ts.map +1 -1
  89. package/dist/transports/transport.js.map +1 -1
  90. package/package.json +4 -5
  91. /package/{LICENSES → THIRD_PARTY_NOTICES}/modelcontextprotocol-typescript-sdk.txt +0 -0
@@ -1,5 +1,5 @@
1
- import { isJsonRpcRequest, isJsonRpcResponse, JSON_RPC_ERROR_CODES, McpConnectionClosedError, parseJsonRpcMessage, toError, } from "../protocol/jsonrpc.js";
2
- import { DEFAULT_MAX_MESSAGE_BYTES, TransportEvents } from "./transport.js";
1
+ import { isJsonRpcRequest, isJsonRpcResponse, JSON_RPC_ERROR_CODES, McpAbortError, McpConnectionClosedError, parseJsonRpcMessage, toError, } from "../protocol/jsonrpc.js";
2
+ import { DEFAULT_MAX_MESSAGE_BYTES, TransportEvents, } from "./transport.js";
3
3
  const MAX_ERROR_BODY_BYTES = 8 * 1024;
4
4
  const ERROR_MESSAGE_BODY_CHARS = 500;
5
5
  const DEFAULT_RECONNECT_INITIAL_DELAY_MS = 1_000;
@@ -29,8 +29,7 @@ export async function consumeSseStream(stream, options) {
29
29
  dataLines = [];
30
30
  dataBytes = 0;
31
31
  };
32
- const processLine = (rawLine) => {
33
- const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
32
+ const processLine = (line) => {
34
33
  if (line === "") {
35
34
  dispatch();
36
35
  return;
@@ -57,26 +56,59 @@ export async function consumeSseStream(stream, options) {
57
56
  else if (field === "retry" && /^\d+$/.test(value))
58
57
  options.onRetry?.(Number(value));
59
58
  };
59
+ // SSE lines end with CRLF, LF, or a lone CR.
60
+ let skipLeadingLf = false;
61
+ const consumeLines = () => {
62
+ let start = 0;
63
+ for (let i = 0; i < buffered.length; i++) {
64
+ const char = buffered[i];
65
+ if (char !== "\r" && char !== "\n")
66
+ continue;
67
+ processLine(buffered.slice(start, i));
68
+ if (char === "\r") {
69
+ if (i + 1 < buffered.length) {
70
+ if (buffered[i + 1] === "\n")
71
+ i++;
72
+ }
73
+ else {
74
+ skipLeadingLf = true;
75
+ }
76
+ }
77
+ start = i + 1;
78
+ }
79
+ buffered = buffered.slice(start);
80
+ };
60
81
  try {
61
82
  while (true) {
62
83
  const { done, value } = await reader.read();
63
84
  if (done)
64
85
  break;
65
- buffered += decoder.decode(value, { stream: true });
66
- let newline = buffered.indexOf("\n");
67
- while (newline >= 0) {
68
- processLine(buffered.slice(0, newline));
69
- buffered = buffered.slice(newline + 1);
70
- newline = buffered.indexOf("\n");
86
+ let text = decoder.decode(value, { stream: true });
87
+ // A CRLF split across chunks: the CR already ended the line, so drop the LF.
88
+ if (skipLeadingLf && text.length > 0) {
89
+ if (text.startsWith("\n"))
90
+ text = text.slice(1);
91
+ skipLeadingLf = false;
71
92
  }
93
+ buffered += text;
94
+ consumeLines();
72
95
  if (Buffer.byteLength(buffered) > maxEventBytes)
73
96
  throw new Error(`MCP SSE event exceeds ${maxEventBytes} bytes`);
74
97
  }
75
- buffered += decoder.decode();
98
+ let tail = decoder.decode();
99
+ if (skipLeadingLf && tail.startsWith("\n"))
100
+ tail = tail.slice(1);
101
+ buffered += tail;
102
+ consumeLines();
76
103
  if (buffered)
77
104
  processLine(buffered);
78
105
  dispatch();
79
106
  }
107
+ catch (error) {
108
+ // Releasing the lock alone leaves the response open; the original error wins over a failed cancel.
109
+ await reader.cancel().catch(() => { });
110
+ throw error;
111
+ }
80
112
  finally {
81
113
  reader.releaseLock();
82
114
  }
@@ -123,6 +155,35 @@ function isTransientStatus(status) {
123
155
  function discard(response) {
124
156
  return response.body?.cancel().catch(() => { }) ?? Promise.resolve();
125
157
  }
158
+ /**
159
+ * Reads a response body as text, decoding chunks as they arrive. Once the body exceeds `maxBytes`, the rest is
160
+ * cancelled and the text holds only the first `maxBytes` bytes.
161
+ */
162
+ async function readBodyText(response, maxBytes) {
163
+ if (!response.body)
164
+ return { text: "", truncated: false };
165
+ const reader = response.body.getReader();
166
+ const decoder = new TextDecoder();
167
+ let text = "";
168
+ let remaining = maxBytes;
169
+ try {
170
+ while (true) {
171
+ const { done, value } = await reader.read();
172
+ if (done)
173
+ return { text: text + decoder.decode(), truncated: false };
174
+ if (value.byteLength > remaining) {
175
+ await reader.cancel().catch(() => { });
176
+ // Decoding a subarray copies only the kept bytes, so the result never references the dropped rest.
177
+ return { text: text + decoder.decode(value.subarray(0, remaining), { stream: true }), truncated: true };
178
+ }
179
+ remaining -= value.byteLength;
180
+ text += decoder.decode(value, { stream: true });
181
+ }
182
+ }
183
+ finally {
184
+ reader.releaseLock();
185
+ }
186
+ }
126
187
  function describeHttpFailure(status, body) {
127
188
  const text = body.trim();
128
189
  const snippet = text.length > ERROR_MESSAGE_BODY_CHARS ? `${text.slice(0, ERROR_MESSAGE_BODY_CHARS - 3)}...` : text;
@@ -138,6 +199,8 @@ export class StreamableHttpTransport extends TransportEvents {
138
199
  sessionIdValue;
139
200
  protocolVersion;
140
201
  getStreamStarted = false;
202
+ /** Access token of the latest request, which `close()` reuses instead of asking the auth provider. */
203
+ lastToken;
141
204
  constructor(options) {
142
205
  super();
143
206
  this.options = Object.freeze({ ...options, headers: options.headers ? { ...options.headers } : undefined });
@@ -160,13 +223,13 @@ export class StreamableHttpTransport extends TransportEvents {
160
223
  setProtocolVersion(version) {
161
224
  this.protocolVersion = version;
162
225
  }
163
- async send(message) {
226
+ async send(message, { signal } = {}) {
164
227
  if (!this.started || this.closed)
165
228
  throw new McpConnectionClosedError();
166
229
  const response = await this.authorizedFetch("POST", {
167
230
  headers: { accept: "application/json, text/event-stream", "content-type": "application/json" },
168
231
  body: JSON.stringify(message),
169
- });
232
+ }, signal);
170
233
  await this.checkResponse(response);
171
234
  this.captureSession(response);
172
235
  if (!isJsonRpcRequest(message)) {
@@ -182,7 +245,11 @@ export class StreamableHttpTransport extends TransportEvents {
182
245
  }
183
246
  const type = contentType(response);
184
247
  if (type === "application/json") {
185
- const body = await response.json();
248
+ const maxBytes = this.options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;
249
+ const { text, truncated } = await readBodyText(response, maxBytes);
250
+ if (truncated)
251
+ throw new Error(`MCP JSON response exceeds ${maxBytes} bytes`);
252
+ const body = JSON.parse(text);
186
253
  for (const item of Array.isArray(body) ? body : [body])
187
254
  this.emitMessage(parseJsonRpcMessage(item));
188
255
  return;
@@ -200,31 +267,34 @@ export class StreamableHttpTransport extends TransportEvents {
200
267
  this.closed = true;
201
268
  this.controller.abort();
202
269
  if (this.started && this.sessionIdValue) {
203
- const controller = new AbortController();
204
- const timeout = setTimeout(() => controller.abort(), 1_000);
270
+ // Best effort: the session expires on the server anyway. The auth provider may refresh tokens
271
+ // over the network, so it is not asked here and closing never waits for a refresh.
205
272
  try {
206
- const { headers } = await this.headers();
207
- await this.fetch(this.url, { method: "DELETE", headers, signal: controller.signal })
208
- .then(discard)
209
- .catch(() => undefined);
210
- }
211
- catch {
212
- // Resolving auth headers failed; the session will expire on the server.
213
- }
214
- finally {
215
- clearTimeout(timeout);
273
+ const response = await this.fetch(this.url, {
274
+ method: "DELETE",
275
+ headers: this.buildHeaders({}, this.lastToken),
276
+ signal: AbortSignal.timeout(1_000),
277
+ });
278
+ await discard(response);
216
279
  }
280
+ catch { }
217
281
  }
218
282
  this.emitClose();
219
283
  }
220
284
  /**
221
285
  * Fetch with auth headers. A 401 (or a 403 asking for more scope) is handed to the auth provider
222
286
  * once, and the request is retried with whatever credentials it left behind.
287
+ *
288
+ * `signal` only stops dispatch: getting a token or the authorization recovery can take a while, and a
289
+ * request its sender gave up on in the meantime must not reach the server. It does not abort the shared
290
+ * recovery, which other requests may wait for.
223
291
  */
224
- async authorizedFetch(method, init) {
292
+ async authorizedFetch(method, init, signal) {
225
293
  const onUnauthorized = this.options.authProvider?.onUnauthorized?.bind(this.options.authProvider);
226
294
  for (let attempt = 0;; attempt++) {
227
295
  const { headers, token } = await this.headers(init.headers);
296
+ if (signal?.aborted)
297
+ throw new McpAbortError();
228
298
  const response = await this.fetch(this.url, {
229
299
  method,
230
300
  headers,
@@ -242,6 +312,11 @@ export class StreamableHttpTransport extends TransportEvents {
242
312
  }
243
313
  }
244
314
  async headers(extra = {}) {
315
+ const token = await this.options.authProvider?.token();
316
+ this.lastToken = token;
317
+ return { headers: this.buildHeaders(extra, token), ...(token ? { token } : {}) };
318
+ }
319
+ buildHeaders(extra, token) {
245
320
  const headers = new Headers(this.options.headers);
246
321
  for (const [name, value] of Object.entries(extra))
247
322
  headers.set(name, value);
@@ -249,10 +324,9 @@ export class StreamableHttpTransport extends TransportEvents {
249
324
  headers.set("Mcp-Session-Id", this.sessionIdValue);
250
325
  if (this.protocolVersion)
251
326
  headers.set("MCP-Protocol-Version", this.protocolVersion);
252
- const token = await this.options.authProvider?.token();
253
327
  if (token)
254
328
  headers.set("Authorization", `Bearer ${token}`);
255
- return { headers, ...(token ? { token } : {}) };
329
+ return headers;
256
330
  }
257
331
  captureSession(response) {
258
332
  const sessionId = response.headers.get("mcp-session-id");
@@ -262,7 +336,8 @@ export class StreamableHttpTransport extends TransportEvents {
262
336
  async checkResponse(response) {
263
337
  if (response.ok)
264
338
  return;
265
- const body = (await response.text().catch(() => "")).slice(0, MAX_ERROR_BODY_BYTES);
339
+ // Reads only the excerpt the error keeps and cancels the rest, so a huge error body is never buffered.
340
+ const body = (await readBodyText(response, MAX_ERROR_BODY_BYTES).catch(() => ({ text: "" }))).text;
266
341
  if (response.status === 401)
267
342
  throw new McpAuthRequiredError(response, body);
268
343
  if (response.status === 404 && this.sessionIdValue)
@@ -1 +1 @@
1
- {"version":3,"file":"streamable-http.js","sourceRoot":"","sources":["../../src/transports/streamable-http.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthProvider, McpFetch } from \"../auth-provider.ts\";\nimport {\n\tisJsonRpcRequest,\n\tisJsonRpcResponse,\n\tJSON_RPC_ERROR_CODES,\n\ttype JsonRpcId,\n\ttype JsonRpcMessage,\n\tMcpConnectionClosedError,\n\tparseJsonRpcMessage,\n\ttoError,\n} from \"../protocol/jsonrpc.ts\";\nimport { DEFAULT_MAX_MESSAGE_BYTES, type McpTransport, TransportEvents } from \"./transport.ts\";\n\nconst MAX_ERROR_BODY_BYTES = 8 * 1024;\nconst ERROR_MESSAGE_BODY_CHARS = 500;\nconst DEFAULT_RECONNECT_INITIAL_DELAY_MS = 1_000;\nconst DEFAULT_RECONNECT_MAX_DELAY_MS = 30_000;\nconst DEFAULT_RECONNECT_MAX_RETRIES = 5;\n\nexport interface SseEvent {\n\tevent?: string;\n\tdata: string;\n\tid?: string;\n}\n\nexport interface ConsumeSseOptions {\n\tmaxEventBytes?: number;\n\tonEvent(event: SseEvent): void;\n\t/** Called for every `id` field, including events without data (for example resumption priming events). */\n\tonId?(id: string): void;\n\t/** Called for every valid `retry` field, in milliseconds. */\n\tonRetry?(delayMs: number): void;\n}\n\nexport async function consumeSseStream(stream: ReadableStream<Uint8Array>, options: ConsumeSseOptions): Promise<void> {\n\tconst reader = stream.getReader();\n\tconst decoder = new TextDecoder();\n\tlet buffered = \"\";\n\tlet eventName: string | undefined;\n\tlet eventId: string | undefined;\n\tlet dataLines: string[] = [];\n\t// Bytes of the pending event's data, including the \"\\n\" joins, so events streamed as many\n\t// short `data:` lines without a terminating blank line cannot grow without bound.\n\tlet dataBytes = 0;\n\tconst maxEventBytes = options.maxEventBytes ?? DEFAULT_MAX_MESSAGE_BYTES;\n\n\tconst dispatch = () => {\n\t\tif (dataLines.length === 0) {\n\t\t\teventName = undefined;\n\t\t\teventId = undefined;\n\t\t\treturn;\n\t\t}\n\t\tconst data = dataLines.join(\"\\n\");\n\t\toptions.onEvent({ ...(eventName ? { event: eventName } : {}), data, ...(eventId ? { id: eventId } : {}) });\n\t\teventName = undefined;\n\t\teventId = undefined;\n\t\tdataLines = [];\n\t\tdataBytes = 0;\n\t};\n\n\tconst processLine = (rawLine: string) => {\n\t\tconst line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n\t\tif (line === \"\") {\n\t\t\tdispatch();\n\t\t\treturn;\n\t\t}\n\t\tif (line.startsWith(\":\")) return;\n\t\tconst colon = line.indexOf(\":\");\n\t\tconst field = colon < 0 ? line : line.slice(0, colon);\n\t\tlet value = colon < 0 ? \"\" : line.slice(colon + 1);\n\t\tif (value.startsWith(\" \")) value = value.slice(1);\n\t\tif (field === \"data\") {\n\t\t\tdataBytes += Buffer.byteLength(value) + (dataLines.length > 0 ? 1 : 0);\n\t\t\tif (dataBytes > maxEventBytes) throw new Error(`MCP SSE event exceeds ${maxEventBytes} bytes`);\n\t\t\tdataLines.push(value);\n\t\t} else if (field === \"event\") eventName = value;\n\t\telse if (field === \"id\" && !value.includes(\"\\0\")) {\n\t\t\teventId = value;\n\t\t\toptions.onId?.(value);\n\t\t} else if (field === \"retry\" && /^\\d+$/.test(value)) options.onRetry?.(Number(value));\n\t};\n\n\ttry {\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tbuffered += decoder.decode(value, { stream: true });\n\t\t\tlet newline = buffered.indexOf(\"\\n\");\n\t\t\twhile (newline >= 0) {\n\t\t\t\tprocessLine(buffered.slice(0, newline));\n\t\t\t\tbuffered = buffered.slice(newline + 1);\n\t\t\t\tnewline = buffered.indexOf(\"\\n\");\n\t\t\t}\n\t\t\tif (Buffer.byteLength(buffered) > maxEventBytes)\n\t\t\t\tthrow new Error(`MCP SSE event exceeds ${maxEventBytes} bytes`);\n\t\t}\n\t\tbuffered += decoder.decode();\n\t\tif (buffered) processLine(buffered);\n\t\tdispatch();\n\t} finally {\n\t\treader.releaseLock();\n\t}\n}\n\nexport interface StreamableHttpReconnectOptions {\n\t/** Delay before the first reconnection attempt, unless the server sent a `retry` field. Default: 1000. */\n\tinitialDelayMs?: number;\n\t/** Upper bound for the exponential backoff. Default: 30000. */\n\tmaxDelayMs?: number;\n\t/** Consecutive failed attempts before giving up on a stream. Default: 5. */\n\tmaxRetries?: number;\n}\n\nexport interface StreamableHttpTransportOptions {\n\turl: string | URL;\n\theaders?: Record<string, string>;\n\tfetch?: McpFetch;\n\t/** Open the server-to-client GET stream after initialization. Default: true. */\n\topenGetStream?: boolean;\n\tmaxMessageBytes?: number;\n\tauthProvider?: AuthProvider;\n\t/** Reconnection of dropped SSE streams (the GET stream, and response streams that carry event IDs). */\n\treconnect?: StreamableHttpReconnectOptions;\n}\n\nexport class McpHttpError extends Error {\n\treadonly status: number;\n\treadonly body: string;\n\n\tconstructor(status: number, message: string, body = \"\") {\n\t\tsuper(message);\n\t\tthis.name = \"McpHttpError\";\n\t\tthis.status = status;\n\t\tthis.body = body;\n\t}\n}\n\nexport class McpAuthRequiredError extends McpHttpError {\n\treadonly wwwAuthenticate: string | null;\n\n\tconstructor(response: Response, body = \"\") {\n\t\tsuper(401, \"MCP server requires authentication\", body);\n\t\tthis.name = \"McpAuthRequiredError\";\n\t\tthis.wwwAuthenticate = response.headers.get(\"www-authenticate\");\n\t}\n}\n\nexport class McpSessionExpiredError extends McpHttpError {\n\tconstructor(body = \"\") {\n\t\tsuper(404, \"MCP session expired\", body);\n\t\tthis.name = \"McpSessionExpiredError\";\n\t}\n}\n\nfunction contentType(response: Response): string | undefined {\n\treturn response.headers.get(\"content-type\")?.split(\";\", 1)[0]?.trim().toLowerCase();\n}\n\n/** 401, or 403 with an `insufficient_scope` bearer challenge (step-up authorization). */\nfunction needsAuthorization(response: Response): boolean {\n\tif (response.status === 401) return true;\n\tif (response.status !== 403) return false;\n\treturn /(?:^|[\\s,])error=\"?insufficient_scope\"?/i.test(response.headers.get(\"www-authenticate\") ?? \"\");\n}\n\n/** Statuses worth retrying when a stream fails to (re)open. */\nfunction isTransientStatus(status: number): boolean {\n\treturn status === 408 || status === 429 || status >= 500;\n}\n\nfunction discard(response: Response): Promise<void> {\n\treturn response.body?.cancel().catch(() => {}) ?? Promise.resolve();\n}\n\nfunction describeHttpFailure(status: number, body: string): string {\n\tconst text = body.trim();\n\tconst snippet = text.length > ERROR_MESSAGE_BODY_CHARS ? `${text.slice(0, ERROR_MESSAGE_BODY_CHARS - 3)}...` : text;\n\treturn `MCP HTTP request failed with status ${status}${snippet ? `: ${snippet}` : \"\"}`;\n}\n\ninterface StreamCursor {\n\tlastEventId: string | undefined;\n\tretryMs: number | undefined;\n\t/** Whether the stream delivered any event since it was (re)opened. */\n\treceived: boolean;\n}\n\nexport class StreamableHttpTransport extends TransportEvents implements McpTransport {\n\treadonly url: URL;\n\treadonly options: Readonly<StreamableHttpTransportOptions>;\n\tprivate fetch: McpFetch;\n\tprivate controller = new AbortController();\n\tprivate started = false;\n\tprivate closed = false;\n\tprivate sessionIdValue: string | undefined;\n\tprivate protocolVersion: string | undefined;\n\tprivate getStreamStarted = false;\n\n\tconstructor(options: StreamableHttpTransportOptions) {\n\t\tsuper();\n\t\tthis.options = Object.freeze({ ...options, headers: options.headers ? { ...options.headers } : undefined });\n\t\tthis.url = new URL(options.url);\n\t\tconst fetch = options.fetch ?? globalThis.fetch;\n\t\t// Call fetch without a receiver. `this.fetch(...)` and `context.fetch(...)` would pass the transport or\n\t\t// the auth context as `this`, which Cloudflare Workers reject for the platform fetch (\"Illegal invocation\").\n\t\tthis.fetch = (input, init) => fetch(input, init);\n\t}\n\n\tget sessionId(): string | undefined {\n\t\treturn this.sessionIdValue;\n\t}\n\n\tasync start(): Promise<void> {\n\t\tif (this.started) throw new Error(\"MCP Streamable HTTP transport already started\");\n\t\tif (this.closed) throw new McpConnectionClosedError();\n\t\tthis.started = true;\n\t}\n\n\tsetProtocolVersion(version: string): void {\n\t\tthis.protocolVersion = version;\n\t}\n\n\tasync send(message: JsonRpcMessage): Promise<void> {\n\t\tif (!this.started || this.closed) throw new McpConnectionClosedError();\n\t\tconst response = await this.authorizedFetch(\"POST\", {\n\t\t\theaders: { accept: \"application/json, text/event-stream\", \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(message),\n\t\t});\n\t\tawait this.checkResponse(response);\n\t\tthis.captureSession(response);\n\n\t\tif (!isJsonRpcRequest(message)) {\n\t\t\t// Notifications and responses are acknowledged with 202 and carry no reply; ignore any body.\n\t\t\tawait discard(response);\n\t\t\t// The server-to-client stream may only open once the session is initialized.\n\t\t\tif (\"method\" in message && message.method === \"notifications/initialized\") this.startGetStream();\n\t\t\treturn;\n\t\t}\n\t\tif (response.status === 202 || response.status === 204) {\n\t\t\tthrow new McpHttpError(response.status, `MCP server accepted request ${message.method} without a response`);\n\t\t}\n\t\tconst type = contentType(response);\n\t\tif (type === \"application/json\") {\n\t\t\tconst body: unknown = await response.json();\n\t\t\tfor (const item of Array.isArray(body) ? body : [body]) this.emitMessage(parseJsonRpcMessage(item));\n\t\t\treturn;\n\t\t}\n\t\tif (type === \"text/event-stream\" && response.body) {\n\t\t\tvoid this.consumeResponseStream(response.body, message.id);\n\t\t\treturn;\n\t\t}\n\t\tawait discard(response);\n\t\tthrow new McpHttpError(response.status, `Unsupported MCP response content type: ${type ?? \"missing\"}`);\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.closed) return;\n\t\tthis.closed = true;\n\t\tthis.controller.abort();\n\t\tif (this.started && this.sessionIdValue) {\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timeout = setTimeout(() => controller.abort(), 1_000);\n\t\t\ttry {\n\t\t\t\tconst { headers } = await this.headers();\n\t\t\t\tawait this.fetch(this.url, { method: \"DELETE\", headers, signal: controller.signal })\n\t\t\t\t\t.then(discard)\n\t\t\t\t\t.catch(() => undefined);\n\t\t\t} catch {\n\t\t\t\t// Resolving auth headers failed; the session will expire on the server.\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t}\n\t\t}\n\t\tthis.emitClose();\n\t}\n\n\t/**\n\t * Fetch with auth headers. A 401 (or a 403 asking for more scope) is handed to the auth provider\n\t * once, and the request is retried with whatever credentials it left behind.\n\t */\n\tprivate async authorizedFetch(\n\t\tmethod: \"GET\" | \"POST\",\n\t\tinit: { headers: Record<string, string>; body?: string },\n\t): Promise<Response> {\n\t\tconst onUnauthorized = this.options.authProvider?.onUnauthorized?.bind(this.options.authProvider);\n\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\tconst { headers, token } = await this.headers(init.headers);\n\t\t\tconst response = await this.fetch(this.url, {\n\t\t\t\tmethod,\n\t\t\t\theaders,\n\t\t\t\tbody: init.body,\n\t\t\t\tsignal: this.controller.signal,\n\t\t\t});\n\t\t\tif (attempt > 0 || !onUnauthorized || !needsAuthorization(response)) return response;\n\t\t\ttry {\n\t\t\t\tawait onUnauthorized({ response, serverUrl: this.url, fetch: this.fetch, token });\n\t\t\t} finally {\n\t\t\t\tawait discard(response);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async headers(extra: Record<string, string> = {}): Promise<{ headers: Headers; token?: string }> {\n\t\tconst headers = new Headers(this.options.headers);\n\t\tfor (const [name, value] of Object.entries(extra)) headers.set(name, value);\n\t\tif (this.sessionIdValue) headers.set(\"Mcp-Session-Id\", this.sessionIdValue);\n\t\tif (this.protocolVersion) headers.set(\"MCP-Protocol-Version\", this.protocolVersion);\n\t\tconst token = await this.options.authProvider?.token();\n\t\tif (token) headers.set(\"Authorization\", `Bearer ${token}`);\n\t\treturn { headers, ...(token ? { token } : {}) };\n\t}\n\n\tprivate captureSession(response: Response): void {\n\t\tconst sessionId = response.headers.get(\"mcp-session-id\");\n\t\tif (sessionId) this.sessionIdValue = sessionId;\n\t}\n\n\tprivate async checkResponse(response: Response): Promise<void> {\n\t\tif (response.ok) return;\n\t\tconst body = (await response.text().catch(() => \"\")).slice(0, MAX_ERROR_BODY_BYTES);\n\t\tif (response.status === 401) throw new McpAuthRequiredError(response, body);\n\t\tif (response.status === 404 && this.sessionIdValue) throw new McpSessionExpiredError(body);\n\t\tthrow new McpHttpError(response.status, describeHttpFailure(response.status, body), body);\n\t}\n\n\tprivate async consumeSse(\n\t\tstream: ReadableStream<Uint8Array>,\n\t\tcursor: StreamCursor,\n\t\tonMessage?: (message: JsonRpcMessage) => void,\n\t): Promise<void> {\n\t\tawait consumeSseStream(stream, {\n\t\t\tmaxEventBytes: this.options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES,\n\t\t\tonId: (id) => {\n\t\t\t\tcursor.lastEventId = id;\n\t\t\t},\n\t\t\tonRetry: (delayMs) => {\n\t\t\t\tcursor.retryMs = delayMs;\n\t\t\t},\n\t\t\tonEvent: (event) => {\n\t\t\t\tcursor.received = true;\n\t\t\t\t// Events without data prime resumption; other event types are not JSON-RPC.\n\t\t\t\tif (!event.data.trim() || (event.event !== undefined && event.event !== \"message\")) return;\n\t\t\t\tlet message: JsonRpcMessage;\n\t\t\t\ttry {\n\t\t\t\t\tmessage = parseJsonRpcMessage(JSON.parse(event.data));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.emitError(error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tonMessage?.(message);\n\t\t\t\tthis.emitMessage(message);\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Read the SSE stream answering one request. When the stream ends or breaks before the response\n\t * arrives and the server assigned event IDs, resume it with GET and `Last-Event-ID`, as the\n\t * server may close response streams at will. Otherwise only this request fails.\n\t */\n\tprivate async consumeResponseStream(body: ReadableStream<Uint8Array>, requestId: JsonRpcId): Promise<void> {\n\t\tconst cursor: StreamCursor = { lastEventId: undefined, retryMs: undefined, received: false };\n\t\tlet answered = false;\n\t\tconst onMessage = (message: JsonRpcMessage) => {\n\t\t\tif (isJsonRpcResponse(message) && message.id === requestId) answered = true;\n\t\t};\n\t\tlet stream: ReadableStream<Uint8Array> | undefined = body;\n\t\tlet failure: unknown;\n\t\tfor (let attempt = 0; ; ) {\n\t\t\tif (stream) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.consumeSse(stream, cursor, onMessage);\n\t\t\t\t\tfailure = undefined;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfailure = error;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (answered || this.closed) return;\n\t\t\tif (failure !== undefined && !this.isRetryable(failure)) break;\n\t\t\tif (cursor.lastEventId === undefined || attempt >= this.maxRetries()) break;\n\t\t\tif (cursor.received) attempt = 0;\n\t\t\tcursor.received = false;\n\t\t\tif (!(await this.sleep(this.reconnectDelay(attempt++, cursor.retryMs)))) return;\n\t\t\ttry {\n\t\t\t\tstream = await this.openSseStream(cursor.lastEventId);\n\t\t\t} catch (error) {\n\t\t\t\tfailure = error;\n\t\t\t\tif (!this.isRetryable(error)) break;\n\t\t\t\tstream = undefined;\n\t\t\t}\n\t\t}\n\t\tif (this.closed) return;\n\t\tconst reason = failure === undefined ? \"stream ended without a response\" : toError(failure).message;\n\t\tthis.emitMessage({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\tid: requestId,\n\t\t\terror: { code: JSON_RPC_ERROR_CODES.internalError, message: `MCP response stream failed: ${reason}` },\n\t\t});\n\t}\n\n\tprivate startGetStream(): void {\n\t\tif (this.options.openGetStream === false || this.getStreamStarted || this.closed) return;\n\t\tthis.getStreamStarted = true;\n\t\tvoid this.runGetStream();\n\t}\n\n\t/** Keep the server-to-client stream open, reconnecting with backoff when it drops. */\n\tprivate async runGetStream(): Promise<void> {\n\t\tconst cursor: StreamCursor = { lastEventId: undefined, retryMs: undefined, received: false };\n\t\tfor (let attempt = 0; !this.closed; ) {\n\t\t\ttry {\n\t\t\t\tconst stream = await this.openSseStream(cursor.lastEventId);\n\t\t\t\t// The server does not offer a GET stream.\n\t\t\t\tif (!stream) return;\n\t\t\t\tconst openedAt = Date.now();\n\t\t\t\tawait this.consumeSse(stream, cursor);\n\t\t\t\t// A stream that stayed up for a while counts as healthy, even if it was idle.\n\t\t\t\tif (cursor.received || Date.now() - openedAt > this.maxDelay()) attempt = 0;\n\t\t\t} catch (error) {\n\t\t\t\tif (this.closed) return;\n\t\t\t\tif (!this.isRetryable(error)) {\n\t\t\t\t\tthis.emitError(error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcursor.received = false;\n\t\t\tif (attempt >= this.maxRetries()) {\n\t\t\t\tthis.emitError(new Error(\"MCP server-to-client stream dropped and could not be reopened\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!(await this.sleep(this.reconnectDelay(attempt++, cursor.retryMs)))) return;\n\t\t}\n\t}\n\n\t/** Open a GET SSE stream. Resolves to undefined when the server answers 405 (no GET stream). */\n\tprivate async openSseStream(lastEventId: string | undefined): Promise<ReadableStream<Uint8Array> | undefined> {\n\t\tconst response = await this.authorizedFetch(\"GET\", {\n\t\t\theaders: {\n\t\t\t\taccept: \"text/event-stream\",\n\t\t\t\t...(lastEventId === undefined ? {} : { \"last-event-id\": lastEventId }),\n\t\t\t},\n\t\t});\n\t\tif (response.status === 405) {\n\t\t\tawait discard(response);\n\t\t\treturn undefined;\n\t\t}\n\t\tawait this.checkResponse(response);\n\t\tthis.captureSession(response);\n\t\tconst type = contentType(response);\n\t\tif (type !== \"text/event-stream\" || !response.body) {\n\t\t\tawait discard(response);\n\t\t\tthrow new McpHttpError(response.status, `Unsupported MCP GET response content type: ${type ?? \"missing\"}`);\n\t\t}\n\t\treturn response.body;\n\t}\n\n\t/**\n\t * Network failures and transient statuses are retried; auth, session, and protocol errors are not.\n\t * `fetch` reports network failures, including a connection dropped mid-body, as `TypeError`.\n\t */\n\tprivate isRetryable(error: unknown): boolean {\n\t\tif (error instanceof McpHttpError) return isTransientStatus(error.status);\n\t\tif (error instanceof TypeError) return true;\n\t\tconst code = (error as { code?: unknown } | undefined)?.code;\n\t\treturn typeof code === \"string\" && (code.startsWith(\"E\") || code.startsWith(\"UND_ERR\"));\n\t}\n\n\tprivate reconnectDelay(attempt: number, serverDelayMs: number | undefined): number {\n\t\tif (serverDelayMs !== undefined) return serverDelayMs;\n\t\tconst initial = this.options.reconnect?.initialDelayMs ?? DEFAULT_RECONNECT_INITIAL_DELAY_MS;\n\t\treturn Math.min(initial * 2 ** attempt, this.maxDelay());\n\t}\n\n\tprivate maxDelay(): number {\n\t\treturn this.options.reconnect?.maxDelayMs ?? DEFAULT_RECONNECT_MAX_DELAY_MS;\n\t}\n\n\tprivate maxRetries(): number {\n\t\treturn this.options.reconnect?.maxRetries ?? DEFAULT_RECONNECT_MAX_RETRIES;\n\t}\n\n\t/** Resolves false when the transport closed while waiting. */\n\tprivate sleep(ms: number): Promise<boolean> {\n\t\tconst signal = this.controller.signal;\n\t\tif (signal.aborted) return Promise.resolve(false);\n\t\treturn new Promise((resolve) => {\n\t\t\tconst onAbort = () => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(false);\n\t\t\t};\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tresolve(true);\n\t\t\t}, ms);\n\t\t\t// A reconnect wait alone does not keep the process alive.\n\t\t\ttimer.unref?.();\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"streamable-http.js","sourceRoot":"","sources":["../../src/transports/streamable-http.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthProvider, McpFetch } from \"../auth-provider.ts\";\nimport {\n\tisJsonRpcRequest,\n\tisJsonRpcResponse,\n\tJSON_RPC_ERROR_CODES,\n\ttype JsonRpcId,\n\ttype JsonRpcMessage,\n\tMcpAbortError,\n\tMcpConnectionClosedError,\n\tparseJsonRpcMessage,\n\ttoError,\n} from \"../protocol/jsonrpc.ts\";\nimport {\n\tDEFAULT_MAX_MESSAGE_BYTES,\n\ttype McpTransport,\n\ttype McpTransportSendOptions,\n\tTransportEvents,\n} from \"./transport.ts\";\n\nconst MAX_ERROR_BODY_BYTES = 8 * 1024;\nconst ERROR_MESSAGE_BODY_CHARS = 500;\nconst DEFAULT_RECONNECT_INITIAL_DELAY_MS = 1_000;\nconst DEFAULT_RECONNECT_MAX_DELAY_MS = 30_000;\nconst DEFAULT_RECONNECT_MAX_RETRIES = 5;\n\nexport interface SseEvent {\n\tevent?: string;\n\tdata: string;\n\tid?: string;\n}\n\nexport interface ConsumeSseOptions {\n\tmaxEventBytes?: number;\n\tonEvent(event: SseEvent): void;\n\t/** Called for every `id` field, including events without data (for example resumption priming events). */\n\tonId?(id: string): void;\n\t/** Called for every valid `retry` field, in milliseconds. */\n\tonRetry?(delayMs: number): void;\n}\n\nexport async function consumeSseStream(stream: ReadableStream<Uint8Array>, options: ConsumeSseOptions): Promise<void> {\n\tconst reader = stream.getReader();\n\tconst decoder = new TextDecoder();\n\tlet buffered = \"\";\n\tlet eventName: string | undefined;\n\tlet eventId: string | undefined;\n\tlet dataLines: string[] = [];\n\t// Bytes of the pending event's data, including the \"\\n\" joins, so events streamed as many\n\t// short `data:` lines without a terminating blank line cannot grow without bound.\n\tlet dataBytes = 0;\n\tconst maxEventBytes = options.maxEventBytes ?? DEFAULT_MAX_MESSAGE_BYTES;\n\n\tconst dispatch = () => {\n\t\tif (dataLines.length === 0) {\n\t\t\teventName = undefined;\n\t\t\teventId = undefined;\n\t\t\treturn;\n\t\t}\n\t\tconst data = dataLines.join(\"\\n\");\n\t\toptions.onEvent({ ...(eventName ? { event: eventName } : {}), data, ...(eventId ? { id: eventId } : {}) });\n\t\teventName = undefined;\n\t\teventId = undefined;\n\t\tdataLines = [];\n\t\tdataBytes = 0;\n\t};\n\n\tconst processLine = (line: string) => {\n\t\tif (line === \"\") {\n\t\t\tdispatch();\n\t\t\treturn;\n\t\t}\n\t\tif (line.startsWith(\":\")) return;\n\t\tconst colon = line.indexOf(\":\");\n\t\tconst field = colon < 0 ? line : line.slice(0, colon);\n\t\tlet value = colon < 0 ? \"\" : line.slice(colon + 1);\n\t\tif (value.startsWith(\" \")) value = value.slice(1);\n\t\tif (field === \"data\") {\n\t\t\tdataBytes += Buffer.byteLength(value) + (dataLines.length > 0 ? 1 : 0);\n\t\t\tif (dataBytes > maxEventBytes) throw new Error(`MCP SSE event exceeds ${maxEventBytes} bytes`);\n\t\t\tdataLines.push(value);\n\t\t} else if (field === \"event\") eventName = value;\n\t\telse if (field === \"id\" && !value.includes(\"\\0\")) {\n\t\t\teventId = value;\n\t\t\toptions.onId?.(value);\n\t\t} else if (field === \"retry\" && /^\\d+$/.test(value)) options.onRetry?.(Number(value));\n\t};\n\n\t// SSE lines end with CRLF, LF, or a lone CR.\n\tlet skipLeadingLf = false;\n\tconst consumeLines = () => {\n\t\tlet start = 0;\n\t\tfor (let i = 0; i < buffered.length; i++) {\n\t\t\tconst char = buffered[i];\n\t\t\tif (char !== \"\\r\" && char !== \"\\n\") continue;\n\t\t\tprocessLine(buffered.slice(start, i));\n\t\t\tif (char === \"\\r\") {\n\t\t\t\tif (i + 1 < buffered.length) {\n\t\t\t\t\tif (buffered[i + 1] === \"\\n\") i++;\n\t\t\t\t} else {\n\t\t\t\t\tskipLeadingLf = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstart = i + 1;\n\t\t}\n\t\tbuffered = buffered.slice(start);\n\t};\n\n\ttry {\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tlet text = decoder.decode(value, { stream: true });\n\t\t\t// A CRLF split across chunks: the CR already ended the line, so drop the LF.\n\t\t\tif (skipLeadingLf && text.length > 0) {\n\t\t\t\tif (text.startsWith(\"\\n\")) text = text.slice(1);\n\t\t\t\tskipLeadingLf = false;\n\t\t\t}\n\t\t\tbuffered += text;\n\t\t\tconsumeLines();\n\t\t\tif (Buffer.byteLength(buffered) > maxEventBytes)\n\t\t\t\tthrow new Error(`MCP SSE event exceeds ${maxEventBytes} bytes`);\n\t\t}\n\t\tlet tail = decoder.decode();\n\t\tif (skipLeadingLf && tail.startsWith(\"\\n\")) tail = tail.slice(1);\n\t\tbuffered += tail;\n\t\tconsumeLines();\n\t\tif (buffered) processLine(buffered);\n\t\tdispatch();\n\t} catch (error) {\n\t\t// Releasing the lock alone leaves the response open; the original error wins over a failed cancel.\n\t\tawait reader.cancel().catch(() => {});\n\t\tthrow error;\n\t} finally {\n\t\treader.releaseLock();\n\t}\n}\n\nexport interface StreamableHttpReconnectOptions {\n\t/** Delay before the first reconnection attempt, unless the server sent a `retry` field. Default: 1000. */\n\tinitialDelayMs?: number;\n\t/** Upper bound for the exponential backoff. Default: 30000. */\n\tmaxDelayMs?: number;\n\t/** Consecutive failed attempts before giving up on a stream. Default: 5. */\n\tmaxRetries?: number;\n}\n\nexport interface StreamableHttpTransportOptions {\n\turl: string | URL;\n\theaders?: Record<string, string>;\n\tfetch?: McpFetch;\n\t/** Open the server-to-client GET stream after initialization. Default: true. */\n\topenGetStream?: boolean;\n\tmaxMessageBytes?: number;\n\tauthProvider?: AuthProvider;\n\t/** Reconnection of dropped SSE streams (the GET stream, and response streams that carry event IDs). */\n\treconnect?: StreamableHttpReconnectOptions;\n}\n\nexport class McpHttpError extends Error {\n\treadonly status: number;\n\treadonly body: string;\n\n\tconstructor(status: number, message: string, body = \"\") {\n\t\tsuper(message);\n\t\tthis.name = \"McpHttpError\";\n\t\tthis.status = status;\n\t\tthis.body = body;\n\t}\n}\n\nexport class McpAuthRequiredError extends McpHttpError {\n\treadonly wwwAuthenticate: string | null;\n\n\tconstructor(response: Response, body = \"\") {\n\t\tsuper(401, \"MCP server requires authentication\", body);\n\t\tthis.name = \"McpAuthRequiredError\";\n\t\tthis.wwwAuthenticate = response.headers.get(\"www-authenticate\");\n\t}\n}\n\nexport class McpSessionExpiredError extends McpHttpError {\n\tconstructor(body = \"\") {\n\t\tsuper(404, \"MCP session expired\", body);\n\t\tthis.name = \"McpSessionExpiredError\";\n\t}\n}\n\nfunction contentType(response: Response): string | undefined {\n\treturn response.headers.get(\"content-type\")?.split(\";\", 1)[0]?.trim().toLowerCase();\n}\n\n/** 401, or 403 with an `insufficient_scope` bearer challenge (step-up authorization). */\nfunction needsAuthorization(response: Response): boolean {\n\tif (response.status === 401) return true;\n\tif (response.status !== 403) return false;\n\treturn /(?:^|[\\s,])error=\"?insufficient_scope\"?/i.test(response.headers.get(\"www-authenticate\") ?? \"\");\n}\n\n/** Statuses worth retrying when a stream fails to (re)open. */\nfunction isTransientStatus(status: number): boolean {\n\treturn status === 408 || status === 429 || status >= 500;\n}\n\nfunction discard(response: Response): Promise<void> {\n\treturn response.body?.cancel().catch(() => {}) ?? Promise.resolve();\n}\n\n/**\n * Reads a response body as text, decoding chunks as they arrive. Once the body exceeds `maxBytes`, the rest is\n * cancelled and the text holds only the first `maxBytes` bytes.\n */\nasync function readBodyText(response: Response, maxBytes: number): Promise<{ text: string; truncated: boolean }> {\n\tif (!response.body) return { text: \"\", truncated: false };\n\tconst reader = response.body.getReader();\n\tconst decoder = new TextDecoder();\n\tlet text = \"\";\n\tlet remaining = maxBytes;\n\ttry {\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) return { text: text + decoder.decode(), truncated: false };\n\t\t\tif (value.byteLength > remaining) {\n\t\t\t\tawait reader.cancel().catch(() => {});\n\t\t\t\t// Decoding a subarray copies only the kept bytes, so the result never references the dropped rest.\n\t\t\t\treturn { text: text + decoder.decode(value.subarray(0, remaining), { stream: true }), truncated: true };\n\t\t\t}\n\t\t\tremaining -= value.byteLength;\n\t\t\ttext += decoder.decode(value, { stream: true });\n\t\t}\n\t} finally {\n\t\treader.releaseLock();\n\t}\n}\n\nfunction describeHttpFailure(status: number, body: string): string {\n\tconst text = body.trim();\n\tconst snippet = text.length > ERROR_MESSAGE_BODY_CHARS ? `${text.slice(0, ERROR_MESSAGE_BODY_CHARS - 3)}...` : text;\n\treturn `MCP HTTP request failed with status ${status}${snippet ? `: ${snippet}` : \"\"}`;\n}\n\ninterface StreamCursor {\n\tlastEventId: string | undefined;\n\tretryMs: number | undefined;\n\t/** Whether the stream delivered any event since it was (re)opened. */\n\treceived: boolean;\n}\n\nexport class StreamableHttpTransport extends TransportEvents implements McpTransport {\n\treadonly url: URL;\n\treadonly options: Readonly<StreamableHttpTransportOptions>;\n\tprivate fetch: McpFetch;\n\tprivate controller = new AbortController();\n\tprivate started = false;\n\tprivate closed = false;\n\tprivate sessionIdValue: string | undefined;\n\tprivate protocolVersion: string | undefined;\n\tprivate getStreamStarted = false;\n\t/** Access token of the latest request, which `close()` reuses instead of asking the auth provider. */\n\tprivate lastToken: string | undefined;\n\n\tconstructor(options: StreamableHttpTransportOptions) {\n\t\tsuper();\n\t\tthis.options = Object.freeze({ ...options, headers: options.headers ? { ...options.headers } : undefined });\n\t\tthis.url = new URL(options.url);\n\t\tconst fetch = options.fetch ?? globalThis.fetch;\n\t\t// Call fetch without a receiver. `this.fetch(...)` and `context.fetch(...)` would pass the transport or\n\t\t// the auth context as `this`, which Cloudflare Workers reject for the platform fetch (\"Illegal invocation\").\n\t\tthis.fetch = (input, init) => fetch(input, init);\n\t}\n\n\tget sessionId(): string | undefined {\n\t\treturn this.sessionIdValue;\n\t}\n\n\tasync start(): Promise<void> {\n\t\tif (this.started) throw new Error(\"MCP Streamable HTTP transport already started\");\n\t\tif (this.closed) throw new McpConnectionClosedError();\n\t\tthis.started = true;\n\t}\n\n\tsetProtocolVersion(version: string): void {\n\t\tthis.protocolVersion = version;\n\t}\n\n\tasync send(message: JsonRpcMessage, { signal }: McpTransportSendOptions = {}): Promise<void> {\n\t\tif (!this.started || this.closed) throw new McpConnectionClosedError();\n\t\tconst response = await this.authorizedFetch(\n\t\t\t\"POST\",\n\t\t\t{\n\t\t\t\theaders: { accept: \"application/json, text/event-stream\", \"content-type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify(message),\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t\tawait this.checkResponse(response);\n\t\tthis.captureSession(response);\n\n\t\tif (!isJsonRpcRequest(message)) {\n\t\t\t// Notifications and responses are acknowledged with 202 and carry no reply; ignore any body.\n\t\t\tawait discard(response);\n\t\t\t// The server-to-client stream may only open once the session is initialized.\n\t\t\tif (\"method\" in message && message.method === \"notifications/initialized\") this.startGetStream();\n\t\t\treturn;\n\t\t}\n\t\tif (response.status === 202 || response.status === 204) {\n\t\t\tthrow new McpHttpError(response.status, `MCP server accepted request ${message.method} without a response`);\n\t\t}\n\t\tconst type = contentType(response);\n\t\tif (type === \"application/json\") {\n\t\t\tconst maxBytes = this.options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;\n\t\t\tconst { text, truncated } = await readBodyText(response, maxBytes);\n\t\t\tif (truncated) throw new Error(`MCP JSON response exceeds ${maxBytes} bytes`);\n\t\t\tconst body: unknown = JSON.parse(text);\n\t\t\tfor (const item of Array.isArray(body) ? body : [body]) this.emitMessage(parseJsonRpcMessage(item));\n\t\t\treturn;\n\t\t}\n\t\tif (type === \"text/event-stream\" && response.body) {\n\t\t\tvoid this.consumeResponseStream(response.body, message.id);\n\t\t\treturn;\n\t\t}\n\t\tawait discard(response);\n\t\tthrow new McpHttpError(response.status, `Unsupported MCP response content type: ${type ?? \"missing\"}`);\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.closed) return;\n\t\tthis.closed = true;\n\t\tthis.controller.abort();\n\t\tif (this.started && this.sessionIdValue) {\n\t\t\t// Best effort: the session expires on the server anyway. The auth provider may refresh tokens\n\t\t\t// over the network, so it is not asked here and closing never waits for a refresh.\n\t\t\ttry {\n\t\t\t\tconst response = await this.fetch(this.url, {\n\t\t\t\t\tmethod: \"DELETE\",\n\t\t\t\t\theaders: this.buildHeaders({}, this.lastToken),\n\t\t\t\t\tsignal: AbortSignal.timeout(1_000),\n\t\t\t\t});\n\t\t\t\tawait discard(response);\n\t\t\t} catch {}\n\t\t}\n\t\tthis.emitClose();\n\t}\n\n\t/**\n\t * Fetch with auth headers. A 401 (or a 403 asking for more scope) is handed to the auth provider\n\t * once, and the request is retried with whatever credentials it left behind.\n\t *\n\t * `signal` only stops dispatch: getting a token or the authorization recovery can take a while, and a\n\t * request its sender gave up on in the meantime must not reach the server. It does not abort the shared\n\t * recovery, which other requests may wait for.\n\t */\n\tprivate async authorizedFetch(\n\t\tmethod: \"GET\" | \"POST\",\n\t\tinit: { headers: Record<string, string>; body?: string },\n\t\tsignal?: AbortSignal,\n\t): Promise<Response> {\n\t\tconst onUnauthorized = this.options.authProvider?.onUnauthorized?.bind(this.options.authProvider);\n\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\tconst { headers, token } = await this.headers(init.headers);\n\t\t\tif (signal?.aborted) throw new McpAbortError();\n\t\t\tconst response = await this.fetch(this.url, {\n\t\t\t\tmethod,\n\t\t\t\theaders,\n\t\t\t\tbody: init.body,\n\t\t\t\tsignal: this.controller.signal,\n\t\t\t});\n\t\t\tif (attempt > 0 || !onUnauthorized || !needsAuthorization(response)) return response;\n\t\t\ttry {\n\t\t\t\tawait onUnauthorized({ response, serverUrl: this.url, fetch: this.fetch, token });\n\t\t\t} finally {\n\t\t\t\tawait discard(response);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async headers(extra: Record<string, string> = {}): Promise<{ headers: Headers; token?: string }> {\n\t\tconst token = await this.options.authProvider?.token();\n\t\tthis.lastToken = token;\n\t\treturn { headers: this.buildHeaders(extra, token), ...(token ? { token } : {}) };\n\t}\n\n\tprivate buildHeaders(extra: Record<string, string>, token: string | undefined): Headers {\n\t\tconst headers = new Headers(this.options.headers);\n\t\tfor (const [name, value] of Object.entries(extra)) headers.set(name, value);\n\t\tif (this.sessionIdValue) headers.set(\"Mcp-Session-Id\", this.sessionIdValue);\n\t\tif (this.protocolVersion) headers.set(\"MCP-Protocol-Version\", this.protocolVersion);\n\t\tif (token) headers.set(\"Authorization\", `Bearer ${token}`);\n\t\treturn headers;\n\t}\n\n\tprivate captureSession(response: Response): void {\n\t\tconst sessionId = response.headers.get(\"mcp-session-id\");\n\t\tif (sessionId) this.sessionIdValue = sessionId;\n\t}\n\n\tprivate async checkResponse(response: Response): Promise<void> {\n\t\tif (response.ok) return;\n\t\t// Reads only the excerpt the error keeps and cancels the rest, so a huge error body is never buffered.\n\t\tconst body = (await readBodyText(response, MAX_ERROR_BODY_BYTES).catch(() => ({ text: \"\" }))).text;\n\t\tif (response.status === 401) throw new McpAuthRequiredError(response, body);\n\t\tif (response.status === 404 && this.sessionIdValue) throw new McpSessionExpiredError(body);\n\t\tthrow new McpHttpError(response.status, describeHttpFailure(response.status, body), body);\n\t}\n\n\tprivate async consumeSse(\n\t\tstream: ReadableStream<Uint8Array>,\n\t\tcursor: StreamCursor,\n\t\tonMessage?: (message: JsonRpcMessage) => void,\n\t): Promise<void> {\n\t\tawait consumeSseStream(stream, {\n\t\t\tmaxEventBytes: this.options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES,\n\t\t\tonId: (id) => {\n\t\t\t\tcursor.lastEventId = id;\n\t\t\t},\n\t\t\tonRetry: (delayMs) => {\n\t\t\t\tcursor.retryMs = delayMs;\n\t\t\t},\n\t\t\tonEvent: (event) => {\n\t\t\t\tcursor.received = true;\n\t\t\t\t// Events without data prime resumption; other event types are not JSON-RPC.\n\t\t\t\tif (!event.data.trim() || (event.event !== undefined && event.event !== \"message\")) return;\n\t\t\t\tlet message: JsonRpcMessage;\n\t\t\t\ttry {\n\t\t\t\t\tmessage = parseJsonRpcMessage(JSON.parse(event.data));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.emitError(error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tonMessage?.(message);\n\t\t\t\tthis.emitMessage(message);\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Read the SSE stream answering one request. When the stream ends or breaks before the response\n\t * arrives and the server assigned event IDs, resume it with GET and `Last-Event-ID`, as the\n\t * server may close response streams at will. Otherwise only this request fails.\n\t */\n\tprivate async consumeResponseStream(body: ReadableStream<Uint8Array>, requestId: JsonRpcId): Promise<void> {\n\t\tconst cursor: StreamCursor = { lastEventId: undefined, retryMs: undefined, received: false };\n\t\tlet answered = false;\n\t\tconst onMessage = (message: JsonRpcMessage) => {\n\t\t\tif (isJsonRpcResponse(message) && message.id === requestId) answered = true;\n\t\t};\n\t\tlet stream: ReadableStream<Uint8Array> | undefined = body;\n\t\tlet failure: unknown;\n\t\tfor (let attempt = 0; ; ) {\n\t\t\tif (stream) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.consumeSse(stream, cursor, onMessage);\n\t\t\t\t\tfailure = undefined;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfailure = error;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (answered || this.closed) return;\n\t\t\tif (failure !== undefined && !this.isRetryable(failure)) break;\n\t\t\tif (cursor.lastEventId === undefined || attempt >= this.maxRetries()) break;\n\t\t\tif (cursor.received) attempt = 0;\n\t\t\tcursor.received = false;\n\t\t\tif (!(await this.sleep(this.reconnectDelay(attempt++, cursor.retryMs)))) return;\n\t\t\ttry {\n\t\t\t\tstream = await this.openSseStream(cursor.lastEventId);\n\t\t\t} catch (error) {\n\t\t\t\tfailure = error;\n\t\t\t\tif (!this.isRetryable(error)) break;\n\t\t\t\tstream = undefined;\n\t\t\t}\n\t\t}\n\t\tif (this.closed) return;\n\t\tconst reason = failure === undefined ? \"stream ended without a response\" : toError(failure).message;\n\t\tthis.emitMessage({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\tid: requestId,\n\t\t\terror: { code: JSON_RPC_ERROR_CODES.internalError, message: `MCP response stream failed: ${reason}` },\n\t\t});\n\t}\n\n\tprivate startGetStream(): void {\n\t\tif (this.options.openGetStream === false || this.getStreamStarted || this.closed) return;\n\t\tthis.getStreamStarted = true;\n\t\tvoid this.runGetStream();\n\t}\n\n\t/** Keep the server-to-client stream open, reconnecting with backoff when it drops. */\n\tprivate async runGetStream(): Promise<void> {\n\t\tconst cursor: StreamCursor = { lastEventId: undefined, retryMs: undefined, received: false };\n\t\tfor (let attempt = 0; !this.closed; ) {\n\t\t\ttry {\n\t\t\t\tconst stream = await this.openSseStream(cursor.lastEventId);\n\t\t\t\t// The server does not offer a GET stream.\n\t\t\t\tif (!stream) return;\n\t\t\t\tconst openedAt = Date.now();\n\t\t\t\tawait this.consumeSse(stream, cursor);\n\t\t\t\t// A stream that stayed up for a while counts as healthy, even if it was idle.\n\t\t\t\tif (cursor.received || Date.now() - openedAt > this.maxDelay()) attempt = 0;\n\t\t\t} catch (error) {\n\t\t\t\tif (this.closed) return;\n\t\t\t\tif (!this.isRetryable(error)) {\n\t\t\t\t\tthis.emitError(error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcursor.received = false;\n\t\t\tif (attempt >= this.maxRetries()) {\n\t\t\t\tthis.emitError(new Error(\"MCP server-to-client stream dropped and could not be reopened\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!(await this.sleep(this.reconnectDelay(attempt++, cursor.retryMs)))) return;\n\t\t}\n\t}\n\n\t/** Open a GET SSE stream. Resolves to undefined when the server answers 405 (no GET stream). */\n\tprivate async openSseStream(lastEventId: string | undefined): Promise<ReadableStream<Uint8Array> | undefined> {\n\t\tconst response = await this.authorizedFetch(\"GET\", {\n\t\t\theaders: {\n\t\t\t\taccept: \"text/event-stream\",\n\t\t\t\t...(lastEventId === undefined ? {} : { \"last-event-id\": lastEventId }),\n\t\t\t},\n\t\t});\n\t\tif (response.status === 405) {\n\t\t\tawait discard(response);\n\t\t\treturn undefined;\n\t\t}\n\t\tawait this.checkResponse(response);\n\t\tthis.captureSession(response);\n\t\tconst type = contentType(response);\n\t\tif (type !== \"text/event-stream\" || !response.body) {\n\t\t\tawait discard(response);\n\t\t\tthrow new McpHttpError(response.status, `Unsupported MCP GET response content type: ${type ?? \"missing\"}`);\n\t\t}\n\t\treturn response.body;\n\t}\n\n\t/**\n\t * Network failures and transient statuses are retried; auth, session, and protocol errors are not.\n\t * `fetch` reports network failures, including a connection dropped mid-body, as `TypeError`.\n\t */\n\tprivate isRetryable(error: unknown): boolean {\n\t\tif (error instanceof McpHttpError) return isTransientStatus(error.status);\n\t\tif (error instanceof TypeError) return true;\n\t\tconst code = (error as { code?: unknown } | undefined)?.code;\n\t\treturn typeof code === \"string\" && (code.startsWith(\"E\") || code.startsWith(\"UND_ERR\"));\n\t}\n\n\tprivate reconnectDelay(attempt: number, serverDelayMs: number | undefined): number {\n\t\tif (serverDelayMs !== undefined) return serverDelayMs;\n\t\tconst initial = this.options.reconnect?.initialDelayMs ?? DEFAULT_RECONNECT_INITIAL_DELAY_MS;\n\t\treturn Math.min(initial * 2 ** attempt, this.maxDelay());\n\t}\n\n\tprivate maxDelay(): number {\n\t\treturn this.options.reconnect?.maxDelayMs ?? DEFAULT_RECONNECT_MAX_DELAY_MS;\n\t}\n\n\tprivate maxRetries(): number {\n\t\treturn this.options.reconnect?.maxRetries ?? DEFAULT_RECONNECT_MAX_RETRIES;\n\t}\n\n\t/** Resolves false when the transport closed while waiting. */\n\tprivate sleep(ms: number): Promise<boolean> {\n\t\tconst signal = this.controller.signal;\n\t\tif (signal.aborted) return Promise.resolve(false);\n\t\treturn new Promise((resolve) => {\n\t\t\tconst onAbort = () => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(false);\n\t\t\t};\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tresolve(true);\n\t\t\t}, ms);\n\t\t\t// A reconnect wait alone does not keep the process alive.\n\t\t\ttimer.unref?.();\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t});\n\t}\n}\n"]}
@@ -3,9 +3,17 @@ export declare const DEFAULT_MAX_MESSAGE_BYTES: number;
3
3
  export type McpTransportMessageListener = (message: JsonRpcMessage) => void;
4
4
  export type McpTransportErrorListener = (error: Error) => void;
5
5
  export type McpTransportCloseListener = () => void;
6
+ export interface McpTransportSendOptions {
7
+ /**
8
+ * Aborted once the sender no longer waits for a reply (the request was cancelled, timed out, answered,
9
+ * or the client closed). A transport must not dispatch the message after that, for example when
10
+ * retrying it after an authorization refresh. It does not undo a message already dispatched.
11
+ */
12
+ signal?: AbortSignal;
13
+ }
6
14
  export interface McpTransport {
7
15
  start(): Promise<void>;
8
- send(message: JsonRpcMessage): Promise<void>;
16
+ send(message: JsonRpcMessage, options?: McpTransportSendOptions): Promise<void>;
9
17
  close(): Promise<void>;
10
18
  onMessage(listener: McpTransportMessageListener): () => void;
11
19
  onError(listener: McpTransportErrorListener): () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transports/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAW,MAAM,wBAAwB,CAAC;AAEtE,eAAO,MAAM,yBAAyB,QAAmB,CAAC;AAE1D,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;AAC5E,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAC/D,MAAM,MAAM,yBAAyB,GAAG,MAAM,IAAI,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,SAAS,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM,IAAI,CAAC;IAC7D,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAAC;IACzD,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAAC;IACzD,kBAAkB,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,+FAA+F;AAC/F,8BAAsB,eAAe;IACpC,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,YAAY,CAAS;IAE7B,SAAS,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM,IAAI,CAG3D;IAED,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAGvD;IAED,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAGvD;IAED,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAEnD;IAED,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGxC;IAED,SAAS,CAAC,SAAS,IAAI,IAAI,CAI1B;CACD"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transports/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAW,MAAM,wBAAwB,CAAC;AAEtE,eAAO,MAAM,yBAAyB,QAAmB,CAAC;AAE1D,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;AAC5E,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAC/D,MAAM,MAAM,yBAAyB,GAAG,MAAM,IAAI,CAAC;AAEnD,MAAM,WAAW,uBAAuB;IACvC;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,SAAS,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM,IAAI,CAAC;IAC7D,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAAC;IACzD,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAAC;IACzD,kBAAkB,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,+FAA+F;AAC/F,8BAAsB,eAAe;IACpC,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,YAAY,CAAS;IAE7B,SAAS,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM,IAAI,CAG3D;IAED,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAGvD;IAED,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAGvD;IAED,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAEnD;IAED,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGxC;IAED,SAAS,CAAC,SAAS,IAAI,IAAI,CAI1B;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/transports/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAgB1D,+FAA+F;AAC/F,MAAM,OAAgB,eAAe;IAC5B,gBAAgB,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC1D,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAC;IACtD,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAC;IACtD,YAAY,GAAG,KAAK,CAAC;IAE7B,SAAS,CAAC,QAAqC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,CAAC,QAAmC;QAC1C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,QAAmC;QAC1C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAES,WAAW,CAAC,OAAuB;QAC5C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,gBAAgB;YAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC;IAES,SAAS,CAAC,KAAc;QACjC,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,cAAc;YAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAClE,CAAC;IAES,SAAS;QAClB,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,cAAc;YAAE,QAAQ,EAAE,CAAC;IACxD,CAAC;CACD","sourcesContent":["import { type JsonRpcMessage, toError } from \"../protocol/jsonrpc.ts\";\n\nexport const DEFAULT_MAX_MESSAGE_BYTES = 16 * 1024 * 1024;\n\nexport type McpTransportMessageListener = (message: JsonRpcMessage) => void;\nexport type McpTransportErrorListener = (error: Error) => void;\nexport type McpTransportCloseListener = () => void;\n\nexport interface McpTransport {\n\tstart(): Promise<void>;\n\tsend(message: JsonRpcMessage): Promise<void>;\n\tclose(): Promise<void>;\n\tonMessage(listener: McpTransportMessageListener): () => void;\n\tonError(listener: McpTransportErrorListener): () => void;\n\tonClose(listener: McpTransportCloseListener): () => void;\n\tsetProtocolVersion?(version: string): void;\n}\n\n/** Listener bookkeeping shared by transports. `emitClose` fires at most once per transport. */\nexport abstract class TransportEvents {\n\tprivate messageListeners = new Set<McpTransportMessageListener>();\n\tprivate errorListeners = new Set<McpTransportErrorListener>();\n\tprivate closeListeners = new Set<McpTransportCloseListener>();\n\tprivate closeEmitted = false;\n\n\tonMessage(listener: McpTransportMessageListener): () => void {\n\t\tthis.messageListeners.add(listener);\n\t\treturn () => this.messageListeners.delete(listener);\n\t}\n\n\tonError(listener: McpTransportErrorListener): () => void {\n\t\tthis.errorListeners.add(listener);\n\t\treturn () => this.errorListeners.delete(listener);\n\t}\n\n\tonClose(listener: McpTransportCloseListener): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tprotected emitMessage(message: JsonRpcMessage): void {\n\t\tfor (const listener of this.messageListeners) listener(message);\n\t}\n\n\tprotected emitError(error: unknown): void {\n\t\tconst normalized = toError(error);\n\t\tfor (const listener of this.errorListeners) listener(normalized);\n\t}\n\n\tprotected emitClose(): void {\n\t\tif (this.closeEmitted) return;\n\t\tthis.closeEmitted = true;\n\t\tfor (const listener of this.closeListeners) listener();\n\t}\n}\n"]}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/transports/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAyB1D,+FAA+F;AAC/F,MAAM,OAAgB,eAAe;IAC5B,gBAAgB,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC1D,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAC;IACtD,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAC;IACtD,YAAY,GAAG,KAAK,CAAC;IAE7B,SAAS,CAAC,QAAqC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,CAAC,QAAmC;QAC1C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,QAAmC;QAC1C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAES,WAAW,CAAC,OAAuB;QAC5C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,gBAAgB;YAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC;IAES,SAAS,CAAC,KAAc;QACjC,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,cAAc;YAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAClE,CAAC;IAES,SAAS;QAClB,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,cAAc;YAAE,QAAQ,EAAE,CAAC;IACxD,CAAC;CACD","sourcesContent":["import { type JsonRpcMessage, toError } from \"../protocol/jsonrpc.ts\";\n\nexport const DEFAULT_MAX_MESSAGE_BYTES = 16 * 1024 * 1024;\n\nexport type McpTransportMessageListener = (message: JsonRpcMessage) => void;\nexport type McpTransportErrorListener = (error: Error) => void;\nexport type McpTransportCloseListener = () => void;\n\nexport interface McpTransportSendOptions {\n\t/**\n\t * Aborted once the sender no longer waits for a reply (the request was cancelled, timed out, answered,\n\t * or the client closed). A transport must not dispatch the message after that, for example when\n\t * retrying it after an authorization refresh. It does not undo a message already dispatched.\n\t */\n\tsignal?: AbortSignal;\n}\n\nexport interface McpTransport {\n\tstart(): Promise<void>;\n\tsend(message: JsonRpcMessage, options?: McpTransportSendOptions): Promise<void>;\n\tclose(): Promise<void>;\n\tonMessage(listener: McpTransportMessageListener): () => void;\n\tonError(listener: McpTransportErrorListener): () => void;\n\tonClose(listener: McpTransportCloseListener): () => void;\n\tsetProtocolVersion?(version: string): void;\n}\n\n/** Listener bookkeeping shared by transports. `emitClose` fires at most once per transport. */\nexport abstract class TransportEvents {\n\tprivate messageListeners = new Set<McpTransportMessageListener>();\n\tprivate errorListeners = new Set<McpTransportErrorListener>();\n\tprivate closeListeners = new Set<McpTransportCloseListener>();\n\tprivate closeEmitted = false;\n\n\tonMessage(listener: McpTransportMessageListener): () => void {\n\t\tthis.messageListeners.add(listener);\n\t\treturn () => this.messageListeners.delete(listener);\n\t}\n\n\tonError(listener: McpTransportErrorListener): () => void {\n\t\tthis.errorListeners.add(listener);\n\t\treturn () => this.errorListeners.delete(listener);\n\t}\n\n\tonClose(listener: McpTransportCloseListener): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tprotected emitMessage(message: JsonRpcMessage): void {\n\t\tfor (const listener of this.messageListeners) listener(message);\n\t}\n\n\tprotected emitError(error: unknown): void {\n\t\tconst normalized = toError(error);\n\t\tfor (const listener of this.errorListeners) listener(normalized);\n\t}\n\n\tprotected emitClose(): void {\n\t\tif (this.closeEmitted) return;\n\t\tthis.closeEmitted = true;\n\t\tfor (const listener of this.closeListeners) listener();\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fractaal/pi-mcp",
3
- "version": "0.86.9",
3
+ "version": "1.6.0",
4
4
  "description": "Standalone Model Context Protocol client for pi and other applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -27,10 +27,10 @@
27
27
  "dist",
28
28
  "README.md",
29
29
  "CHANGELOG.md",
30
- "LICENSES"
30
+ "THIRD_PARTY_NOTICES"
31
31
  ],
32
32
  "scripts": {
33
- "clean": "shx rm -rf dist",
33
+ "clean": "node ../../scripts/package-files.mjs clean dist",
34
34
  "build": "tsc -p tsconfig.build.json",
35
35
  "test": "vitest --run",
36
36
  "prepublishOnly": "npm run clean && npm run build"
@@ -55,8 +55,7 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/cross-spawn": "6.0.6",
58
- "shx": "0.4.0",
59
- "vitest": "4.1.11"
58
+ "vitest": "4.1.12"
60
59
  },
61
60
  "homepage": "https://github.com/fractaal/pi",
62
61
  "bugs": {