fastmcp 4.16.2 → 4.16.3

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.
@@ -29,12 +29,27 @@ var WebStreamableHTTPServerTransport = (_class = class {
29
29
  __init3() {this._jsonResponseCollectors = /* @__PURE__ */ new Map()}
30
30
 
31
31
 
32
- __init4() {this._requestToStreamMapping = /* @__PURE__ */ new Map()}
33
- __init5() {this._standaloneSseStreamId = "_GET_stream"}
34
- __init6() {this._started = false}
35
- __init7() {this._streamMapping = /* @__PURE__ */ new Map()}
32
+ /**
33
+ * Replays whose stream id is still being resolved. `replayEventsAfter` only
34
+ * reveals which stream it was replaying once it settles, so a standalone
35
+ * send during that window has nothing to test against; persist rather than
36
+ * drop, since over-storing for the length of a replay beats losing an event.
37
+ */
38
+ __init4() {this._replaysInFlight = 0}
39
+ __init5() {this._requestToStreamMapping = /* @__PURE__ */ new Map()}
40
+ __init6() {this._standaloneSseStreamId = "_GET_stream"}
41
+ /**
42
+ * Whether a client has held the standalone GET stream during this session.
43
+ * Latched rather than read from `_streamMapping`, so persistence survives
44
+ * the disconnect window the store exists to cover while still telling a
45
+ * dropped stream apart from one that was never opened. Reset with the rest
46
+ * of the per-session state, since the next session starts with no stream.
47
+ */
48
+ __init7() {this._standaloneStreamOpened = false}
49
+ __init8() {this._started = false}
50
+ __init9() {this._streamMapping = /* @__PURE__ */ new Map()}
36
51
 
37
- constructor(options) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);
52
+ constructor(options) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);
38
53
  this.sessionIdGenerator = options.sessionIdGenerator;
39
54
  this._enableJsonResponse = _nullishCoalesce(options.enableJsonResponse, () => ( false));
40
55
  this._eventStore = options.eventStore;
@@ -52,6 +67,7 @@ var WebStreamableHTTPServerTransport = (_class = class {
52
67
  }
53
68
  }
54
69
  this._streamMapping.clear();
70
+ this._standaloneStreamOpened = false;
55
71
  this.releasePendingRequests();
56
72
  this._started = false;
57
73
  _optionalChain([this, 'access', _ => _.onclose, 'optionalCall', _2 => _2()]);
@@ -91,11 +107,12 @@ var WebStreamableHTTPServerTransport = (_class = class {
91
107
  return;
92
108
  }
93
109
  const writer = this._streamMapping.get(streamId);
94
- if (writer || this._eventStore) {
110
+ const store = this.shouldPersist(streamId, writer) ? this._eventStore : void 0;
111
+ if (writer || store) {
95
112
  try {
96
113
  let eventId;
97
- if (this._eventStore) {
98
- eventId = await this._eventStore.storeEvent(streamId, message);
114
+ if (store) {
115
+ eventId = await store.storeEvent(streamId, message);
99
116
  }
100
117
  if (writer) {
101
118
  if (eventId === void 0) {
@@ -104,23 +121,29 @@ var WebStreamableHTTPServerTransport = (_class = class {
104
121
  await this.writeSSEEventWithId(writer, eventId, message);
105
122
  }
106
123
  }
107
- if (requestId !== void 0 && isResponse) {
108
- this._requestToStreamMapping.delete(requestId);
109
- const streamInUse = Array.from(
110
- this._requestToStreamMapping.values()
111
- ).includes(streamId);
112
- if (!streamInUse) {
113
- this._streamMapping.delete(streamId);
114
- if (writer) {
115
- await writer.close();
116
- }
117
- }
118
- }
119
124
  } catch (error) {
120
125
  _optionalChain([this, 'access', _4 => _4.onerror, 'optionalCall', _5 => _5(
121
126
  error instanceof Error ? error : new Error(String(error))
122
127
  )]);
123
128
  }
129
+ if (requestId !== void 0 && isResponse) {
130
+ this._requestToStreamMapping.delete(requestId);
131
+ const streamInUse = Array.from(
132
+ this._requestToStreamMapping.values()
133
+ ).includes(streamId);
134
+ if (!streamInUse) {
135
+ this._streamMapping.delete(streamId);
136
+ if (writer) {
137
+ try {
138
+ await writer.close();
139
+ } catch (error) {
140
+ _optionalChain([this, 'access', _6 => _6.onerror, 'optionalCall', _7 => _7(
141
+ error instanceof Error ? error : new Error(String(error))
142
+ )]);
143
+ }
144
+ }
145
+ }
146
+ }
124
147
  }
125
148
  }
126
149
  }
@@ -183,8 +206,9 @@ var WebStreamableHTTPServerTransport = (_class = class {
183
206
  }
184
207
  }
185
208
  this._streamMapping.clear();
209
+ this._standaloneStreamOpened = false;
186
210
  this.releasePendingRequests();
187
- await _optionalChain([this, 'access', _6 => _6._onsessionclosed, 'optionalCall', _7 => _7(_nullishCoalesce(this.sessionId, () => ( "")))]);
211
+ await _optionalChain([this, 'access', _8 => _8._onsessionclosed, 'optionalCall', _9 => _9(_nullishCoalesce(this.sessionId, () => ( "")))]);
188
212
  this.sessionId = void 0;
189
213
  return new Response(null, {
190
214
  headers: this.getResponseHeaders(),
@@ -196,7 +220,7 @@ var WebStreamableHTTPServerTransport = (_class = class {
196
220
  */
197
221
  async handleGetRequest(request) {
198
222
  const acceptHeader = request.headers.get("accept");
199
- if (!_optionalChain([acceptHeader, 'optionalAccess', _8 => _8.includes, 'call', _9 => _9("text/event-stream")])) {
223
+ if (!_optionalChain([acceptHeader, 'optionalAccess', _10 => _10.includes, 'call', _11 => _11("text/event-stream")])) {
200
224
  return this.createErrorResponse(
201
225
  406,
202
226
  -32e3,
@@ -245,7 +269,7 @@ var WebStreamableHTTPServerTransport = (_class = class {
245
269
  */
246
270
  async handlePostRequest(request, parsedBody) {
247
271
  const acceptHeader = request.headers.get("accept");
248
- if (!_optionalChain([acceptHeader, 'optionalAccess', _10 => _10.includes, 'call', _11 => _11("application/json")]) && !_optionalChain([acceptHeader, 'optionalAccess', _12 => _12.includes, 'call', _13 => _13("text/event-stream")])) {
272
+ if (!_optionalChain([acceptHeader, 'optionalAccess', _12 => _12.includes, 'call', _13 => _13("application/json")]) && !_optionalChain([acceptHeader, 'optionalAccess', _14 => _14.includes, 'call', _15 => _15("text/event-stream")])) {
249
273
  return this.createErrorResponse(
250
274
  406,
251
275
  -32e3,
@@ -253,7 +277,7 @@ var WebStreamableHTTPServerTransport = (_class = class {
253
277
  );
254
278
  }
255
279
  const contentType = request.headers.get("content-type");
256
- if (!_optionalChain([contentType, 'optionalAccess', _14 => _14.includes, 'call', _15 => _15("application/json")])) {
280
+ if (!_optionalChain([contentType, 'optionalAccess', _16 => _16.includes, 'call', _17 => _17("application/json")])) {
257
281
  return this.createErrorResponse(
258
282
  415,
259
283
  -32e3,
@@ -323,14 +347,14 @@ var WebStreamableHTTPServerTransport = (_class = class {
323
347
  }
324
348
  if (hasInitRequest && this.sessionIdGenerator) {
325
349
  this.sessionId = this.sessionIdGenerator();
326
- await _optionalChain([this, 'access', _16 => _16._onsessioninitialized, 'optionalCall', _17 => _17(this.sessionId)]);
350
+ await _optionalChain([this, 'access', _18 => _18._onsessioninitialized, 'optionalCall', _19 => _19(this.sessionId)]);
327
351
  } else if (requestSessionId) {
328
352
  if (this.sessionIdGenerator && this.sessionId !== requestSessionId) {
329
353
  return this.createErrorResponse(404, -32001, "Session not found");
330
354
  }
331
355
  }
332
356
  const requestIds = messages.filter((msg) => _typesjs.isJSONRPCRequest.call(void 0, msg)).map((msg) => msg.id);
333
- const useJsonResponse = this._enableJsonResponse && Boolean(_optionalChain([acceptHeader, 'optionalAccess', _18 => _18.includes, 'call', _19 => _19("application/json")]));
357
+ const useJsonResponse = this._enableJsonResponse && Boolean(_optionalChain([acceptHeader, 'optionalAccess', _20 => _20.includes, 'call', _21 => _21("application/json")]));
334
358
  let jsonResponses;
335
359
  let sseReadable;
336
360
  if (requestIds.length > 0) {
@@ -359,7 +383,7 @@ var WebStreamableHTTPServerTransport = (_class = class {
359
383
  }
360
384
  }
361
385
  for (const message of messages) {
362
- _optionalChain([this, 'access', _20 => _20.onmessage, 'optionalCall', _21 => _21(message, { authInfo: void 0 })]);
386
+ _optionalChain([this, 'access', _22 => _22.onmessage, 'optionalCall', _23 => _23(message, { authInfo: void 0 })]);
363
387
  }
364
388
  if (requestIds.length === 0) {
365
389
  return new Response(null, {
@@ -401,6 +425,7 @@ var WebStreamableHTTPServerTransport = (_class = class {
401
425
  }
402
426
  const { readable, writable } = new TransformStream();
403
427
  const writer = writable.getWriter();
428
+ this._replaysInFlight += 1;
404
429
  try {
405
430
  const streamId = await this._eventStore.replayEventsAfter(lastEventId, {
406
431
  send: async (eventId, message) => {
@@ -411,6 +436,8 @@ var WebStreamableHTTPServerTransport = (_class = class {
411
436
  } catch (error) {
412
437
  await writer.close();
413
438
  return this.createErrorResponse(500, -32e3, `Replay failed: ${error}`);
439
+ } finally {
440
+ this._replaysInFlight -= 1;
414
441
  }
415
442
  return new Response(readable, {
416
443
  headers: {
@@ -455,7 +482,7 @@ var WebStreamableHTTPServerTransport = (_class = class {
455
482
  try {
456
483
  await writer.close();
457
484
  } catch (error) {
458
- _optionalChain([this, 'access', _22 => _22.onerror, 'optionalCall', _23 => _23(
485
+ _optionalChain([this, 'access', _24 => _24.onerror, 'optionalCall', _25 => _25(
459
486
  error instanceof Error ? error : new Error(String(error))
460
487
  )]);
461
488
  }
@@ -493,7 +520,32 @@ var WebStreamableHTTPServerTransport = (_class = class {
493
520
  }
494
521
  collector.resolve(responses);
495
522
  }
523
+ /**
524
+ * Whether an event addressed to `streamId` should go to the event store.
525
+ *
526
+ * Everything but the standalone stream is persisted whenever a store is
527
+ * configured: those ids exist only because their stream did. The standalone
528
+ * id is a constant, so it resolves whether or not a client ever opened that
529
+ * stream, and storing before the first GET writes events nothing can reach —
530
+ * replay is keyed off Last-Event-Id, and a client that never held the stream
531
+ * was never handed an id to resume from.
532
+ */
533
+ shouldPersist(streamId, writer) {
534
+ if (this._eventStore === void 0) {
535
+ return false;
536
+ }
537
+ if (streamId !== this._standaloneSseStreamId) {
538
+ return true;
539
+ }
540
+ return this._standaloneStreamOpened || // A live writer means the stream is open now, which is stronger evidence
541
+ // than the latch. Belt and braces: it keeps a writer reaching this point
542
+ // without `trackStream` from producing an SSE event with no `id:`.
543
+ writer !== void 0 || this._replaysInFlight > 0;
544
+ }
496
545
  trackStream(streamId, writer) {
546
+ if (streamId === this._standaloneSseStreamId) {
547
+ this._standaloneStreamOpened = true;
548
+ }
497
549
  this._streamMapping.set(streamId, writer);
498
550
  const removeStreamIfCurrent = () => {
499
551
  if (this._streamMapping.get(streamId) !== writer) {
@@ -624,7 +676,7 @@ var EdgeFastMCP = class {
624
676
  */
625
677
  async #handleMcpRequest(request) {
626
678
  const acceptHeader = request.headers.get("accept");
627
- if (!_optionalChain([acceptHeader, 'optionalAccess', _24 => _24.includes, 'call', _25 => _25("application/json")]) && !_optionalChain([acceptHeader, 'optionalAccess', _26 => _26.includes, 'call', _27 => _27("text/event-stream")])) {
679
+ if (!_optionalChain([acceptHeader, 'optionalAccess', _26 => _26.includes, 'call', _27 => _27("application/json")]) && !_optionalChain([acceptHeader, 'optionalAccess', _28 => _28.includes, 'call', _29 => _29("text/event-stream")])) {
628
680
  return this.#errorResponse(
629
681
  406,
630
682
  -32e3,
@@ -632,7 +684,7 @@ var EdgeFastMCP = class {
632
684
  );
633
685
  }
634
686
  const contentType = request.headers.get("content-type");
635
- if (!_optionalChain([contentType, 'optionalAccess', _28 => _28.includes, 'call', _29 => _29("application/json")])) {
687
+ if (!_optionalChain([contentType, 'optionalAccess', _30 => _30.includes, 'call', _31 => _31("application/json")])) {
636
688
  return this.#errorResponse(
637
689
  415,
638
690
  -32e3,
@@ -677,7 +729,7 @@ var EdgeFastMCP = class {
677
729
  */
678
730
  async #handleMcpSseRequest(request) {
679
731
  const acceptHeader = request.headers.get("accept");
680
- if (!_optionalChain([acceptHeader, 'optionalAccess', _30 => _30.includes, 'call', _31 => _31("text/event-stream")])) {
732
+ if (!_optionalChain([acceptHeader, 'optionalAccess', _32 => _32.includes, 'call', _33 => _33("text/event-stream")])) {
681
733
  return this.#errorResponse(
682
734
  406,
683
735
  -32e3,
@@ -745,8 +797,8 @@ var EdgeFastMCP = class {
745
797
  * Handle prompts/get request
746
798
  */
747
799
  async #handlePromptsGet(id, params) {
748
- const promptName = _optionalChain([params, 'optionalAccess', _32 => _32.name]);
749
- const promptArgs = _optionalChain([params, 'optionalAccess', _33 => _33.arguments]);
800
+ const promptName = _optionalChain([params, 'optionalAccess', _34 => _34.name]);
801
+ const promptArgs = _optionalChain([params, 'optionalAccess', _35 => _35.arguments]);
750
802
  const prompt = this.#prompts.find((p) => p.name === promptName);
751
803
  if (!prompt) {
752
804
  return this.#rpcError(
@@ -808,7 +860,7 @@ var EdgeFastMCP = class {
808
860
  * Handle resources/read request
809
861
  */
810
862
  async #handleResourcesRead(id, params) {
811
- const uri = _optionalChain([params, 'optionalAccess', _34 => _34.uri]);
863
+ const uri = _optionalChain([params, 'optionalAccess', _36 => _36.uri]);
812
864
  const resource = this.#resources.find((r) => r.uri === uri);
813
865
  if (!resource) {
814
866
  return this.#rpcError(
@@ -837,8 +889,8 @@ var EdgeFastMCP = class {
837
889
  * Handle tools/call request
838
890
  */
839
891
  async #handleToolsCall(id, params) {
840
- const toolName = _optionalChain([params, 'optionalAccess', _35 => _35.name]);
841
- const toolArgs = _optionalChain([params, 'optionalAccess', _36 => _36.arguments]);
892
+ const toolName = _optionalChain([params, 'optionalAccess', _37 => _37.name]);
893
+ const toolArgs = _optionalChain([params, 'optionalAccess', _38 => _38.arguments]);
842
894
  const tool = this.#tools.find((t) => t.name === toolName);
843
895
  if (!tool) {
844
896
  return this.#rpcError(
@@ -861,7 +913,7 @@ var EdgeFastMCP = class {
861
913
  }
862
914
  if (parsed.issues) {
863
915
  const friendlyErrors = parsed.issues.map((issue) => {
864
- const path = _optionalChain([issue, 'access', _37 => _37.path, 'optionalAccess', _38 => _38.join, 'call', _39 => _39(".")]) || "root";
916
+ const path = _optionalChain([issue, 'access', _39 => _39.path, 'optionalAccess', _40 => _40.join, 'call', _41 => _41(".")]) || "root";
865
917
  return `${path}: ${issue.message}`;
866
918
  }).join(", ");
867
919
  return this.#rpcError(
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/fastmcp/fastmcp/dist/edge/index.cjs","../../src/edge/index.ts","../../src/edge/WebStreamableHTTPServerTransport.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fastmcp/fastmcp/dist/edge/index.cjs","sourcesContent":[null,"/**\n * FastMCP Edge Runtime Support\n *\n * This module provides edge runtime compatibility for FastMCP, enabling\n * deployment to Cloudflare Workers, Deno Deploy, and other edge platforms.\n *\n * @example\n * ```typescript\n * // Cloudflare Workers\n * import { EdgeFastMCP } from \"fastmcp/edge\";\n * import { z } from \"zod\";\n *\n * const server = new EdgeFastMCP({ name: \"MyMCP\", version: \"1.0.0\" });\n *\n * server.addTool({\n * name: \"hello\",\n * description: \"Say hello\",\n * parameters: z.object({ name: z.string() }),\n * execute: async ({ name }) => `Hello, ${name}!`,\n * });\n *\n * export default server;\n * ```\n */\n\nimport {\n ErrorCode,\n JSONRPCMessage,\n LATEST_PROTOCOL_VERSION,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { Hono } from \"hono\";\nimport { strictJsonSchema } from \"xsschema\";\nimport { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\n\nexport { WebStreamableHTTPServerTransport } from \"./WebStreamableHTTPServerTransport.js\";\nexport type {\n EventStore,\n WebStreamableHTTPServerTransportOptions,\n} from \"./WebStreamableHTTPServerTransport.js\";\n\n/**\n * Options for EdgeFastMCP\n */\nexport interface EdgeFastMCPOptions {\n description?: string;\n logger?: EdgeLogger;\n /**\n * Base path for MCP endpoints (default: \"/mcp\")\n */\n mcpPath?: string;\n name: string;\n version: string;\n}\n\n/**\n * Type for edge runtime fetch handler\n */\nexport type EdgeFetchHandler = (request: Request) => Promise<Response>;\n\n/**\n * Logger interface for edge environments\n */\nexport interface EdgeLogger {\n debug(...args: unknown[]): void;\n error(...args: unknown[]): void;\n info(...args: unknown[]): void;\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n}\n\n/**\n * Prompt definition for EdgeFastMCP\n */\nexport interface EdgePrompt {\n arguments?: Array<{ description?: string; name: string; required?: boolean }>;\n description?: string;\n load: (args: Record<string, string>) => Promise<\n | {\n messages: Array<{\n content: { text: string; type: string };\n role: string;\n }>;\n }\n | string\n >;\n name: string;\n}\n\n/**\n * Resource definition for EdgeFastMCP\n */\nexport interface EdgeResource {\n description?: string;\n load: () => Promise<\n { blob?: string; mimeType?: string; text?: string } | string\n >;\n mimeType?: string;\n name: string;\n uri: string;\n}\n\n/**\n * Tool definition for EdgeFastMCP\n */\nexport interface EdgeTool<TParams = unknown> {\n description: string;\n execute: (params: TParams) => Promise<\n | {\n content: Array<{\n data?: string;\n mimeType?: string;\n text?: string;\n type: string;\n }>;\n }\n | string\n >;\n name: string;\n parameters?: StandardSchemaV1<TParams> | z.ZodType<TParams>;\n}\n\n/**\n * Edge-compatible FastMCP server for Cloudflare Workers, Deno, and Bun\n *\n * This is a simplified implementation optimized for stateless edge environments.\n * It uses web-standard APIs only (no Node.js dependencies).\n */\nexport class EdgeFastMCP {\n #honoApp = new Hono();\n #logger: EdgeLogger;\n #mcpPath: string;\n #name: string;\n #prompts: EdgePrompt[] = [];\n #resources: EdgeResource[] = [];\n #tools: EdgeTool[] = [];\n #version: string;\n\n constructor(options: EdgeFastMCPOptions) {\n this.#name = options.name;\n this.#version = options.version;\n this.#logger = options.logger ?? console;\n this.#mcpPath = options.mcpPath ?? \"/mcp\";\n\n this.#setupRoutes();\n }\n\n /**\n * Add a prompt to the server\n */\n addPrompt(prompt: EdgePrompt): this {\n this.#prompts.push(prompt);\n return this;\n }\n\n /**\n * Add a resource to the server\n */\n addResource(resource: EdgeResource): this {\n this.#resources.push(resource);\n return this;\n }\n\n /**\n * Add a tool to the server\n */\n addTool<TParams>(tool: EdgeTool<TParams>): this {\n this.#tools.push(tool as EdgeTool);\n return this;\n }\n\n /**\n * Handle an incoming request (main entry point for edge runtimes)\n */\n async fetch(request: Request): Promise<Response> {\n return this.#honoApp.fetch(request);\n }\n\n /**\n * Get the Hono app for adding custom routes\n */\n getApp(): Hono {\n return this.#honoApp;\n }\n\n /**\n * Create an error HTTP response\n */\n #errorResponse(status: number, code: number, message: string): Response {\n return new Response(\n JSON.stringify({\n error: { code, message },\n id: null,\n jsonrpc: \"2.0\",\n }),\n {\n headers: { \"Content-Type\": \"application/json\" },\n status,\n },\n );\n }\n\n /**\n * Handle initialize request\n */\n #handleInitialize(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n capabilities: {\n prompts: this.#prompts.length > 0 ? {} : undefined,\n resources: this.#resources.length > 0 ? {} : undefined,\n tools: this.#tools.length > 0 ? {} : undefined,\n },\n protocolVersion: LATEST_PROTOCOL_VERSION,\n serverInfo: {\n name: this.#name,\n version: this.#version,\n },\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle MCP POST requests\n */\n async #handleMcpRequest(request: Request): Promise<Response> {\n // Validate headers\n const acceptHeader = request.headers.get(\"accept\");\n if (\n !acceptHeader?.includes(\"application/json\") &&\n !acceptHeader?.includes(\"text/event-stream\")\n ) {\n return this.#errorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept application/json or text/event-stream\",\n );\n }\n\n const contentType = request.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return this.#errorResponse(\n 415,\n -32000,\n \"Unsupported Media Type: Content-Type must be application/json\",\n );\n }\n\n // Parse request body\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return this.#errorResponse(400, -32700, \"Parse error: Invalid JSON\");\n }\n\n // Handle single or batch requests\n const isBatch = Array.isArray(body);\n const messages = Array.isArray(body) ? body : [body];\n\n if (isBatch && messages.length === 0) {\n return this.#errorResponse(\n 400,\n ErrorCode.InvalidRequest,\n \"Invalid Request: Batch must contain at least one message\",\n );\n }\n\n const responses: JSONRPCMessage[] = [];\n\n for (const message of messages) {\n const response = await this.#handleMessage(message);\n if (response) {\n responses.push(response);\n }\n }\n\n // Return appropriate response format\n if (responses.length === 0) {\n return new Response(null, { status: 202 });\n }\n\n const responseBody = JSON.stringify(isBatch ? responses : responses[0]);\n\n return new Response(responseBody, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n status: 200,\n });\n }\n\n /**\n * Handle SSE GET requests\n */\n async #handleMcpSseRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return this.#errorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept text/event-stream\",\n );\n }\n\n // In stateless mode, GET requests are not supported (no server-initiated messages)\n return this.#errorResponse(\n 405,\n -32000,\n \"Method Not Allowed: SSE streams not supported in stateless mode\",\n );\n }\n\n /**\n * Handle individual MCP messages\n */\n async #handleMessage(message: unknown): Promise<JSONRPCMessage | null> {\n if (!message || typeof message !== \"object\") {\n return this.#rpcError(null, -32700, \"Parse error: Invalid message\");\n }\n\n const msg = message as {\n id?: number | string;\n jsonrpc?: string;\n method?: string;\n params?: unknown;\n };\n\n if (msg.jsonrpc !== \"2.0\") {\n return this.#rpcError(\n msg.id ?? null,\n -32600,\n \"Invalid Request: jsonrpc must be 2.0\",\n );\n }\n\n // Handle notifications (no response expected)\n if (!(\"id\" in msg) || msg.id === undefined) {\n return null;\n }\n\n const method = msg.method;\n const id = msg.id;\n const params = msg.params as Record<string, unknown> | undefined;\n\n try {\n switch (method) {\n case \"initialize\":\n return this.#handleInitialize(id);\n\n case \"ping\":\n return { id, jsonrpc: \"2.0\", result: {} } as JSONRPCMessage;\n\n case \"prompts/get\":\n return this.#handlePromptsGet(id, params);\n\n case \"prompts/list\":\n return this.#handlePromptsList(id);\n\n case \"resources/list\":\n return this.#handleResourcesList(id);\n\n case \"resources/read\":\n return this.#handleResourcesRead(id, params);\n\n case \"tools/call\":\n return this.#handleToolsCall(id, params);\n\n case \"tools/list\":\n return this.#handleToolsList(id);\n\n default:\n return this.#rpcError(id, -32601, `Method not found: ${method}`);\n }\n } catch (error) {\n this.#logger.error(`Error handling ${method}:`, error);\n return this.#rpcError(\n id,\n -32603,\n `Internal error: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle prompts/get request\n */\n async #handlePromptsGet(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const promptName = params?.name as string;\n const promptArgs = params?.arguments as Record<string, string> | undefined;\n\n const prompt = this.#prompts.find((p) => p.name === promptName);\n if (!prompt) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Prompt not found: ${promptName}`,\n );\n }\n\n try {\n const result = await prompt.load(promptArgs ?? {});\n const messages =\n typeof result === \"string\"\n ? [{ content: { text: result, type: \"text\" }, role: \"user\" }]\n : result.messages;\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { messages },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Prompt load failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle prompts/list request\n */\n #handlePromptsList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n prompts: this.#prompts.map((p) => ({\n arguments: p.arguments,\n description: p.description,\n name: p.name,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle resources/list request\n */\n #handleResourcesList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n resources: this.#resources.map((r) => ({\n description: r.description,\n mimeType: r.mimeType,\n name: r.name,\n uri: r.uri,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle resources/read request\n */\n async #handleResourcesRead(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const uri = params?.uri as string;\n const resource = this.#resources.find((r) => r.uri === uri);\n\n if (!resource) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Resource not found: ${uri}`,\n );\n }\n\n try {\n const result = await resource.load();\n const content =\n typeof result === \"string\"\n ? { mimeType: resource.mimeType ?? \"text/plain\", text: result, uri }\n : { uri, ...result };\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { contents: [content] },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Resource load failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle tools/call request\n */\n async #handleToolsCall(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const toolName = params?.name as string;\n const toolArgs = params?.arguments as Record<string, unknown> | undefined;\n\n const tool = this.#tools.find((t) => t.name === toolName);\n if (!tool) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Tool not found: ${toolName}`,\n );\n }\n\n let args: unknown = toolArgs ?? {};\n\n if (tool.parameters) {\n let parsed: StandardSchemaV1.Result<unknown>;\n\n try {\n parsed = await tool.parameters[\"~standard\"].validate(toolArgs);\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Tool '${toolName}' parameter validation failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (parsed.issues) {\n const friendlyErrors = parsed.issues\n .map((issue) => {\n const path = issue.path?.join(\".\") || \"root\";\n return `${path}: ${issue.message}`;\n })\n .join(\", \");\n\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Tool '${toolName}' parameter validation failed: ${friendlyErrors}. Please check the parameter types and values according to the tool's schema.`,\n );\n }\n\n args = parsed.value;\n }\n\n try {\n const result = await tool.execute(args);\n\n // Normalize result to content array\n const content =\n typeof result === \"string\"\n ? [{ text: result, type: \"text\" }]\n : result.content;\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { content },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle tools/list request\n */\n #handleToolsList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n tools: this.#tools.map((tool) => ({\n description: tool.description,\n inputSchema: tool.parameters\n ? this.#schemaToJsonSchema(tool.parameters)\n : { type: \"object\" },\n name: tool.name,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Create an RPC error message\n */\n #rpcError(\n id: null | number | string,\n code: number,\n message: string,\n ): JSONRPCMessage {\n return {\n error: { code, message },\n id,\n jsonrpc: \"2.0\",\n } as JSONRPCMessage;\n }\n\n /**\n * Convert schema to JSON Schema\n */\n #schemaToJsonSchema(\n schema: StandardSchemaV1 | z.ZodType,\n ): Record<string, unknown> {\n try {\n // Zod 4+: use native toJSONSchema if available\n /* eslint-disable @typescript-eslint/no-explicit-any */\n if (typeof (z as any).toJSONSchema === \"function\") {\n return strictJsonSchema(\n (z as any).toJSONSchema(schema) as Record<string, unknown>,\n ) as Record<string, unknown>;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n // Zod 3 fallback: use zod-to-json-schema\n /* eslint-disable @typescript-eslint/no-explicit-any */\n if (\"_def\" in (schema as any) || schema instanceof z.ZodType) {\n return strictJsonSchema(\n zodToJsonSchema(schema as any, { target: \"openApi3\" }) as Record<\n string,\n unknown\n >,\n ) as Record<string, unknown>;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n // For StandardSchema, fall back to a generic object schema\n return { type: \"object\" };\n } catch {\n return { type: \"object\" };\n }\n }\n\n /**\n * Set up MCP and health routes\n */\n #setupRoutes(): void {\n // Health endpoint\n this.#honoApp.get(\"/health\", (c) => c.text(\"✓ Ok\"));\n\n // MCP endpoint - handles all MCP protocol messages\n this.#honoApp.post(this.#mcpPath, async (c) => {\n return this.#handleMcpRequest(c.req.raw);\n });\n\n // MCP GET endpoint for SSE streams (server-initiated messages)\n this.#honoApp.get(this.#mcpPath, async (c) => {\n return this.#handleMcpSseRequest(c.req.raw);\n });\n\n // MCP DELETE endpoint for session termination\n this.#honoApp.delete(this.#mcpPath, async () => {\n return new Response(null, { status: 204 });\n });\n }\n}\n","/**\n * Web-standard Streamable HTTP Server Transport for MCP\n *\n * This transport implements the MCP Streamable HTTP specification using\n * web standard APIs (Request, Response, TransformStream) for compatibility\n * with edge runtimes like Cloudflare Workers, Deno, and Bun.\n */\n\nimport { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n CancelledNotificationSchema,\n isInitializeRequest,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n JSONRPCMessage,\n JSONRPCMessageSchema,\n MessageExtraInfo,\n RequestId,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type EventId = string;\n/**\n * Interface for resumability support via event storage\n */\nexport interface EventStore {\n getStreamIdForEventId?(eventId: EventId): Promise<StreamId | undefined>;\n replayEventsAfter(\n lastEventId: EventId,\n options: {\n send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;\n },\n ): Promise<StreamId>;\n storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;\n}\n\nexport type StreamId = string;\n\n/**\n * Configuration options for WebStreamableHTTPServerTransport\n */\nexport interface WebStreamableHTTPServerTransportOptions {\n /**\n * If true, return JSON responses instead of SSE streams\n */\n enableJsonResponse?: boolean;\n\n /**\n * Event store for resumability support\n */\n eventStore?: EventStore;\n\n /**\n * Callback for session close events\n */\n onsessionclosed?: (sessionId: string) => Promise<void> | void;\n\n /**\n * Callback for session initialization events\n */\n onsessioninitialized?: (sessionId: string) => Promise<void> | void;\n\n /**\n * Function that generates a session ID for the transport.\n * Return undefined to disable session management (stateless mode).\n */\n sessionIdGenerator: (() => string) | undefined;\n}\n\n/**\n * Collects the responses to every request that arrived on a single POST, so\n * that JSON mode can answer once all of them are in.\n */\ninterface PendingJsonResponse {\n expectedIds: RequestId[];\n resolve: (responses: JSONRPCMessage[]) => void;\n responses: Map<RequestId, JSONRPCMessage>;\n}\n\nconst MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024; // 4MB\n\n/**\n * Web-standard Server transport for Streamable HTTP.\n * Uses web APIs (Request, Response, TransformStream) for edge runtime compatibility.\n */\nexport class WebStreamableHTTPServerTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n sessionId?: string;\n private _enableJsonResponse = false;\n private _encoder = new TextEncoder();\n private _eventStore?: EventStore;\n private _jsonResponseCollectors = new Map<StreamId, PendingJsonResponse>();\n private _onsessionclosed?: (sessionId: string) => Promise<void> | void;\n private _onsessioninitialized?: (sessionId: string) => Promise<void> | void;\n private _requestToStreamMapping = new Map<RequestId, StreamId>();\n\n private _standaloneSseStreamId = \"_GET_stream\";\n private _started = false;\n private _streamMapping = new Map<\n StreamId,\n WritableStreamDefaultWriter<Uint8Array>\n >();\n private sessionIdGenerator: (() => string) | undefined;\n\n constructor(options: WebStreamableHTTPServerTransportOptions) {\n this.sessionIdGenerator = options.sessionIdGenerator;\n this._enableJsonResponse = options.enableJsonResponse ?? false;\n this._eventStore = options.eventStore;\n this._onsessioninitialized = options.onsessioninitialized;\n this._onsessionclosed = options.onsessionclosed;\n }\n\n /**\n * Close the transport\n */\n async close(): Promise<void> {\n for (const writer of this._streamMapping.values()) {\n try {\n await writer.close();\n } catch {\n // Ignore close errors\n }\n }\n this._streamMapping.clear();\n this.releasePendingRequests();\n this._started = false;\n this.onclose?.();\n }\n\n /**\n * Handles an incoming web Request and returns a Response\n */\n async handleRequest(\n request: Request,\n parsedBody?: unknown,\n ): Promise<Response> {\n const method = request.method;\n\n if (method === \"POST\") {\n return this.handlePostRequest(request, parsedBody);\n } else if (method === \"GET\") {\n return this.handleGetRequest(request);\n } else if (method === \"DELETE\") {\n return this.handleDeleteRequest(request);\n } else {\n return this.handleUnsupportedRequest();\n }\n }\n\n /**\n * Send a message to connected clients\n */\n async send(\n message: JSONRPCMessage,\n options?: { relatedRequestId?: RequestId },\n ): Promise<void> {\n let requestId = options?.relatedRequestId;\n const isResponse = isJSONRPCResponse(message) || isJSONRPCError(message);\n if (isResponse) {\n // Responses are routed by the id of the request they answer\n requestId = message.id;\n }\n\n const streamId =\n requestId === undefined\n ? this._standaloneSseStreamId\n : this._requestToStreamMapping.get(requestId);\n\n if (streamId) {\n // JSON mode has no stream to write to: collect the responses instead and\n // let handlePostRequest answer once every request on this POST is done.\n const collector = this._jsonResponseCollectors.get(streamId);\n if (collector) {\n if (isResponse && requestId !== undefined) {\n collector.responses.set(requestId, message);\n this.settleJsonResponse(streamId, collector);\n }\n return;\n }\n\n const writer = this._streamMapping.get(streamId);\n // With an event store the message must be persisted even if the client\n // has already disconnected, so a reconnect with Last-Event-Id can replay\n // it. The live write to the SSE stream is best-effort on top of that.\n if (writer || this._eventStore) {\n try {\n let eventId: string | undefined;\n if (this._eventStore) {\n eventId = await this._eventStore.storeEvent(streamId, message);\n }\n if (writer) {\n if (eventId === undefined) {\n await this.writeSSEEvent(writer, message);\n } else {\n await this.writeSSEEventWithId(writer, eventId, message);\n }\n }\n\n // Close the POST stream once all of its requests are answered\n if (requestId !== undefined && isResponse) {\n this._requestToStreamMapping.delete(requestId);\n const streamInUse = Array.from(\n this._requestToStreamMapping.values(),\n ).includes(streamId);\n if (!streamInUse) {\n this._streamMapping.delete(streamId);\n if (writer) {\n await writer.close();\n }\n }\n }\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n }\n\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n /**\n * Create an error response\n */\n private createErrorResponse(\n status: number,\n code: number,\n message: string,\n ): Response {\n return new Response(\n JSON.stringify({\n error: { code, message },\n id: null,\n jsonrpc: \"2.0\",\n }),\n {\n headers: {\n ...this.getResponseHeaders(),\n \"Content-Type\": \"application/json\",\n },\n status,\n },\n );\n }\n\n /**\n * Get common response headers\n */\n private getResponseHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this.sessionId) {\n headers[\"mcp-session-id\"] = this.sessionId;\n }\n return headers;\n }\n\n /**\n * Handles DELETE requests to terminate sessions\n */\n private async handleDeleteRequest(request: Request): Promise<Response> {\n const sessionId = request.headers.get(\"mcp-session-id\");\n\n if (this.sessionIdGenerator) {\n if (!sessionId) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n if (this.sessionId !== sessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n }\n\n // Close all streams\n for (const writer of this._streamMapping.values()) {\n try {\n await writer.close();\n } catch {\n // Ignore close errors\n }\n }\n this._streamMapping.clear();\n this.releasePendingRequests();\n\n await this._onsessionclosed?.(this.sessionId ?? \"\");\n this.sessionId = undefined;\n\n return new Response(null, {\n headers: this.getResponseHeaders(),\n status: 204,\n });\n }\n\n /**\n * Handles GET requests for SSE stream\n */\n private async handleGetRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return this.createErrorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept text/event-stream\",\n );\n }\n\n // Validate session\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (this.sessionIdGenerator && !sessionId) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n if (this.sessionIdGenerator && this.sessionId !== sessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n\n // Check for existing standalone stream\n if (this._streamMapping.has(this._standaloneSseStreamId)) {\n return this.createErrorResponse(\n 409,\n -32000,\n \"Conflict: SSE stream already exists for this session\",\n );\n }\n\n // Handle resumability\n if (this._eventStore) {\n const lastEventId = request.headers.get(\"last-event-id\");\n if (lastEventId) {\n return this.handleReplayEvents(lastEventId);\n }\n }\n\n // Create SSE stream\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n this.trackStream(this._standaloneSseStreamId, writer);\n\n return new Response(readable, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Handles POST requests containing JSON-RPC messages\n */\n private async handlePostRequest(\n request: Request,\n parsedBody?: unknown,\n ): Promise<Response> {\n // Validate Accept header\n const acceptHeader = request.headers.get(\"accept\");\n if (\n !acceptHeader?.includes(\"application/json\") &&\n !acceptHeader?.includes(\"text/event-stream\")\n ) {\n return this.createErrorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept application/json or text/event-stream\",\n );\n }\n\n // Validate Content-Type\n const contentType = request.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return this.createErrorResponse(\n 415,\n -32000,\n \"Unsupported Media Type: Content-Type must be application/json\",\n );\n }\n\n // Validate Content-Length\n const contentLength = parseInt(\n request.headers.get(\"content-length\") ?? \"0\",\n 10,\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE) {\n return this.createErrorResponse(\n 413,\n -32000,\n `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE} bytes`,\n );\n }\n\n // Parse body\n let rawMessage: unknown;\n try {\n rawMessage = parsedBody ?? (await request.json());\n } catch {\n return this.createErrorResponse(400, -32700, \"Parse error: Invalid JSON\");\n }\n\n // Handle batch or single message. The original shape decides the response\n // envelope: a batch always answers with an array, even when only one\n // response survives.\n const isBatch = Array.isArray(rawMessage);\n const arrayMessage: unknown[] = Array.isArray(rawMessage)\n ? rawMessage\n : [rawMessage];\n\n if (isBatch && arrayMessage.length === 0) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Batch must contain at least one message\",\n );\n }\n\n // Validate messages\n const messages: JSONRPCMessage[] = [];\n for (const msg of arrayMessage) {\n const result = JSONRPCMessageSchema.safeParse(msg);\n if (!result.success) {\n return this.createErrorResponse(\n 400,\n -32700,\n \"Parse error: Invalid JSON-RPC message\",\n );\n }\n messages.push(result.data);\n }\n\n // Handle session ID\n const requestSessionId = request.headers.get(\"mcp-session-id\");\n const hasInitRequest = messages.some((msg) => isInitializeRequest(msg));\n\n // Validate session requirements\n if (hasInitRequest && requestSessionId) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Initialization requests must not include a sessionId\",\n );\n }\n\n if (hasInitRequest && messages.length > 1) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Only one initialization request is allowed\",\n );\n }\n\n if (!hasInitRequest && !requestSessionId && this.sessionIdGenerator) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n // Generate or validate session ID\n if (hasInitRequest && this.sessionIdGenerator) {\n this.sessionId = this.sessionIdGenerator();\n await this._onsessioninitialized?.(this.sessionId);\n } else if (requestSessionId) {\n if (this.sessionIdGenerator && this.sessionId !== requestSessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n }\n\n const requestIds = messages\n .filter((msg) => isJSONRPCRequest(msg))\n .map((msg) => msg.id);\n const useJsonResponse =\n this._enableJsonResponse &&\n Boolean(acceptHeader?.includes(\"application/json\"));\n\n // Register the response sink before dispatching: the SDK produces\n // responses asynchronously and send() routes them back by request id.\n let jsonResponses: Promise<JSONRPCMessage[]> | undefined;\n let sseReadable: ReadableStream<Uint8Array> | undefined;\n if (requestIds.length > 0) {\n // Must be unique: a wall-clock id collides between two POSTs issued in\n // the same millisecond, which would cross-deliver their responses.\n const streamId = crypto.randomUUID();\n for (const id of requestIds) {\n this._requestToStreamMapping.set(id, streamId);\n }\n\n if (useJsonResponse) {\n jsonResponses = new Promise((resolve) => {\n this._jsonResponseCollectors.set(streamId, {\n expectedIds: requestIds,\n resolve,\n responses: new Map(),\n });\n });\n } else {\n const { readable, writable } = new TransformStream<Uint8Array>();\n this.trackStream(streamId, writable.getWriter());\n sseReadable = readable;\n }\n }\n\n // A cancelled request is never answered — the SDK suppresses the response\n // of a request whose abort signal fired — so send() never runs for its id\n // and nothing else would ever drop its routing entry. Release it here.\n for (const message of messages) {\n const cancelled = CancelledNotificationSchema.safeParse(message);\n if (cancelled.success) {\n await this.releaseCancelledRequest(cancelled.data.params.requestId);\n }\n }\n\n // Process messages through the transport\n for (const message of messages) {\n this.onmessage?.(message, { authInfo: undefined });\n }\n\n // Nothing to answer: the batch was only notifications and/or responses\n if (requestIds.length === 0) {\n return new Response(null, {\n headers: this.getResponseHeaders(),\n status: 202,\n });\n }\n\n // Return JSON response if enabled and client accepts it\n if (jsonResponses) {\n // Wait for the handlers to actually answer, however long they take\n const responses = await jsonResponses;\n\n const responseBody = JSON.stringify(isBatch ? responses : responses[0]);\n\n return new Response(responseBody, {\n headers: {\n ...this.getResponseHeaders(),\n \"Content-Type\": \"application/json\",\n },\n status: 200,\n });\n }\n\n // Return SSE stream\n return new Response(sseReadable ?? null, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Replay events for resumability\n */\n private async handleReplayEvents(lastEventId: string): Promise<Response> {\n if (!this._eventStore) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Resumability not supported\",\n );\n }\n\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n\n try {\n const streamId = await this._eventStore.replayEventsAfter(lastEventId, {\n send: async (eventId, message) => {\n await this.writeSSEEventWithId(writer, eventId, message);\n },\n });\n this.trackStream(streamId, writer);\n } catch (error) {\n await writer.close();\n return this.createErrorResponse(500, -32000, `Replay failed: ${error}`);\n }\n\n return new Response(readable, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Handles unsupported HTTP methods\n */\n private handleUnsupportedRequest(): Response {\n return this.createErrorResponse(405, -32000, \"Method not allowed\");\n }\n\n /**\n * Settle the routing state of a request the client cancelled, which will\n * therefore never produce a response: the same drain `send()` performs once\n * a response has been written, minus the response. Idempotent, so it is a\n * no-op if the response won the race against the cancellation.\n *\n * JSON-mode POSTs are left alone: `_jsonResponseCollectors` owns their\n * settlement.\n */\n private async releaseCancelledRequest(requestId: RequestId): Promise<void> {\n const streamId = this._requestToStreamMapping.get(requestId);\n if (streamId === undefined || this._jsonResponseCollectors.has(streamId)) {\n return;\n }\n\n this._requestToStreamMapping.delete(requestId);\n const streamInUse = Array.from(\n this._requestToStreamMapping.values(),\n ).includes(streamId);\n if (streamInUse) {\n return;\n }\n\n // Nothing will ever be written to this stream again; close it rather than\n // leaving the client reading a stream that can only hang.\n const writer = this._streamMapping.get(streamId);\n this._streamMapping.delete(streamId);\n if (writer) {\n try {\n await writer.close();\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n\n /**\n * Drop the routing state left over once every stream is gone, answering any\n * POST still waiting on a JSON response with whatever arrived rather than\n * leaving the request hanging.\n */\n private releasePendingRequests(): void {\n for (const collector of this._jsonResponseCollectors.values()) {\n collector.resolve(\n collector.expectedIds\n .map((id) => collector.responses.get(id))\n .filter((response) => response !== undefined),\n );\n }\n this._jsonResponseCollectors.clear();\n this._requestToStreamMapping.clear();\n }\n\n /**\n * Answer a JSON-mode POST once every request it carried has a response\n */\n private settleJsonResponse(\n streamId: StreamId,\n collector: PendingJsonResponse,\n ): void {\n const responses: JSONRPCMessage[] = [];\n for (const id of collector.expectedIds) {\n const response = collector.responses.get(id);\n if (!response) {\n // Still waiting on at least one of this POST's requests\n return;\n }\n responses.push(response);\n }\n\n this._jsonResponseCollectors.delete(streamId);\n for (const id of collector.expectedIds) {\n this._requestToStreamMapping.delete(id);\n }\n collector.resolve(responses);\n }\n\n private trackStream(\n streamId: StreamId,\n writer: WritableStreamDefaultWriter<Uint8Array>,\n ): void {\n this._streamMapping.set(streamId, writer);\n const removeStreamIfCurrent = () => {\n if (this._streamMapping.get(streamId) !== writer) {\n return;\n }\n this._streamMapping.delete(streamId);\n // With an event store, a response can still arrive after the client gave\n // up, and it must be persisted for replay. Keep the routing entry so\n // send() can resolve the stream id and store under it; send() drops the\n // entry once the response has been stored.\n if (this._eventStore) {\n return;\n }\n // No event store: nothing will be persisted for this stream, so drop the\n // routing entries now rather than leaking them. No-op for the standalone\n // GET stream, which is never a request target.\n for (const [requestId, mappedStreamId] of this._requestToStreamMapping) {\n if (mappedStreamId === streamId) {\n this._requestToStreamMapping.delete(requestId);\n }\n }\n };\n void writer.closed.then(removeStreamIfCurrent, removeStreamIfCurrent);\n }\n\n /**\n * Write an SSE event to the stream\n */\n private async writeSSEEvent(\n writer: WritableStreamDefaultWriter<Uint8Array>,\n message: JSONRPCMessage,\n ): Promise<void> {\n const data = `data: ${JSON.stringify(message)}\\n\\n`;\n await writer.write(this._encoder.encode(data));\n }\n\n /**\n * Write an SSE event with ID to the stream\n */\n private async writeSSEEventWithId(\n writer: WritableStreamDefaultWriter<Uint8Array>,\n eventId: string,\n message: JSONRPCMessage,\n ): Promise<void> {\n const data = `id: ${eventId}\\ndata: ${JSON.stringify(message)}\\n\\n`;\n await writer.write(this._encoder.encode(data));\n }\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/fastmcp/fastmcp/dist/edge/index.cjs","../../src/edge/index.ts","../../src/edge/WebStreamableHTTPServerTransport.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fastmcp/fastmcp/dist/edge/index.cjs","sourcesContent":[null,"/**\n * FastMCP Edge Runtime Support\n *\n * This module provides edge runtime compatibility for FastMCP, enabling\n * deployment to Cloudflare Workers, Deno Deploy, and other edge platforms.\n *\n * @example\n * ```typescript\n * // Cloudflare Workers\n * import { EdgeFastMCP } from \"fastmcp/edge\";\n * import { z } from \"zod\";\n *\n * const server = new EdgeFastMCP({ name: \"MyMCP\", version: \"1.0.0\" });\n *\n * server.addTool({\n * name: \"hello\",\n * description: \"Say hello\",\n * parameters: z.object({ name: z.string() }),\n * execute: async ({ name }) => `Hello, ${name}!`,\n * });\n *\n * export default server;\n * ```\n */\n\nimport {\n ErrorCode,\n JSONRPCMessage,\n LATEST_PROTOCOL_VERSION,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { Hono } from \"hono\";\nimport { strictJsonSchema } from \"xsschema\";\nimport { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\n\nexport { WebStreamableHTTPServerTransport } from \"./WebStreamableHTTPServerTransport.js\";\nexport type {\n EventStore,\n WebStreamableHTTPServerTransportOptions,\n} from \"./WebStreamableHTTPServerTransport.js\";\n\n/**\n * Options for EdgeFastMCP\n */\nexport interface EdgeFastMCPOptions {\n description?: string;\n logger?: EdgeLogger;\n /**\n * Base path for MCP endpoints (default: \"/mcp\")\n */\n mcpPath?: string;\n name: string;\n version: string;\n}\n\n/**\n * Type for edge runtime fetch handler\n */\nexport type EdgeFetchHandler = (request: Request) => Promise<Response>;\n\n/**\n * Logger interface for edge environments\n */\nexport interface EdgeLogger {\n debug(...args: unknown[]): void;\n error(...args: unknown[]): void;\n info(...args: unknown[]): void;\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n}\n\n/**\n * Prompt definition for EdgeFastMCP\n */\nexport interface EdgePrompt {\n arguments?: Array<{ description?: string; name: string; required?: boolean }>;\n description?: string;\n load: (args: Record<string, string>) => Promise<\n | {\n messages: Array<{\n content: { text: string; type: string };\n role: string;\n }>;\n }\n | string\n >;\n name: string;\n}\n\n/**\n * Resource definition for EdgeFastMCP\n */\nexport interface EdgeResource {\n description?: string;\n load: () => Promise<\n { blob?: string; mimeType?: string; text?: string } | string\n >;\n mimeType?: string;\n name: string;\n uri: string;\n}\n\n/**\n * Tool definition for EdgeFastMCP\n */\nexport interface EdgeTool<TParams = unknown> {\n description: string;\n execute: (params: TParams) => Promise<\n | {\n content: Array<{\n data?: string;\n mimeType?: string;\n text?: string;\n type: string;\n }>;\n }\n | string\n >;\n name: string;\n parameters?: StandardSchemaV1<TParams> | z.ZodType<TParams>;\n}\n\n/**\n * Edge-compatible FastMCP server for Cloudflare Workers, Deno, and Bun\n *\n * This is a simplified implementation optimized for stateless edge environments.\n * It uses web-standard APIs only (no Node.js dependencies).\n */\nexport class EdgeFastMCP {\n #honoApp = new Hono();\n #logger: EdgeLogger;\n #mcpPath: string;\n #name: string;\n #prompts: EdgePrompt[] = [];\n #resources: EdgeResource[] = [];\n #tools: EdgeTool[] = [];\n #version: string;\n\n constructor(options: EdgeFastMCPOptions) {\n this.#name = options.name;\n this.#version = options.version;\n this.#logger = options.logger ?? console;\n this.#mcpPath = options.mcpPath ?? \"/mcp\";\n\n this.#setupRoutes();\n }\n\n /**\n * Add a prompt to the server\n */\n addPrompt(prompt: EdgePrompt): this {\n this.#prompts.push(prompt);\n return this;\n }\n\n /**\n * Add a resource to the server\n */\n addResource(resource: EdgeResource): this {\n this.#resources.push(resource);\n return this;\n }\n\n /**\n * Add a tool to the server\n */\n addTool<TParams>(tool: EdgeTool<TParams>): this {\n this.#tools.push(tool as EdgeTool);\n return this;\n }\n\n /**\n * Handle an incoming request (main entry point for edge runtimes)\n */\n async fetch(request: Request): Promise<Response> {\n return this.#honoApp.fetch(request);\n }\n\n /**\n * Get the Hono app for adding custom routes\n */\n getApp(): Hono {\n return this.#honoApp;\n }\n\n /**\n * Create an error HTTP response\n */\n #errorResponse(status: number, code: number, message: string): Response {\n return new Response(\n JSON.stringify({\n error: { code, message },\n id: null,\n jsonrpc: \"2.0\",\n }),\n {\n headers: { \"Content-Type\": \"application/json\" },\n status,\n },\n );\n }\n\n /**\n * Handle initialize request\n */\n #handleInitialize(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n capabilities: {\n prompts: this.#prompts.length > 0 ? {} : undefined,\n resources: this.#resources.length > 0 ? {} : undefined,\n tools: this.#tools.length > 0 ? {} : undefined,\n },\n protocolVersion: LATEST_PROTOCOL_VERSION,\n serverInfo: {\n name: this.#name,\n version: this.#version,\n },\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle MCP POST requests\n */\n async #handleMcpRequest(request: Request): Promise<Response> {\n // Validate headers\n const acceptHeader = request.headers.get(\"accept\");\n if (\n !acceptHeader?.includes(\"application/json\") &&\n !acceptHeader?.includes(\"text/event-stream\")\n ) {\n return this.#errorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept application/json or text/event-stream\",\n );\n }\n\n const contentType = request.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return this.#errorResponse(\n 415,\n -32000,\n \"Unsupported Media Type: Content-Type must be application/json\",\n );\n }\n\n // Parse request body\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return this.#errorResponse(400, -32700, \"Parse error: Invalid JSON\");\n }\n\n // Handle single or batch requests\n const isBatch = Array.isArray(body);\n const messages = Array.isArray(body) ? body : [body];\n\n if (isBatch && messages.length === 0) {\n return this.#errorResponse(\n 400,\n ErrorCode.InvalidRequest,\n \"Invalid Request: Batch must contain at least one message\",\n );\n }\n\n const responses: JSONRPCMessage[] = [];\n\n for (const message of messages) {\n const response = await this.#handleMessage(message);\n if (response) {\n responses.push(response);\n }\n }\n\n // Return appropriate response format\n if (responses.length === 0) {\n return new Response(null, { status: 202 });\n }\n\n const responseBody = JSON.stringify(isBatch ? responses : responses[0]);\n\n return new Response(responseBody, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n status: 200,\n });\n }\n\n /**\n * Handle SSE GET requests\n */\n async #handleMcpSseRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return this.#errorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept text/event-stream\",\n );\n }\n\n // In stateless mode, GET requests are not supported (no server-initiated messages)\n return this.#errorResponse(\n 405,\n -32000,\n \"Method Not Allowed: SSE streams not supported in stateless mode\",\n );\n }\n\n /**\n * Handle individual MCP messages\n */\n async #handleMessage(message: unknown): Promise<JSONRPCMessage | null> {\n if (!message || typeof message !== \"object\") {\n return this.#rpcError(null, -32700, \"Parse error: Invalid message\");\n }\n\n const msg = message as {\n id?: number | string;\n jsonrpc?: string;\n method?: string;\n params?: unknown;\n };\n\n if (msg.jsonrpc !== \"2.0\") {\n return this.#rpcError(\n msg.id ?? null,\n -32600,\n \"Invalid Request: jsonrpc must be 2.0\",\n );\n }\n\n // Handle notifications (no response expected)\n if (!(\"id\" in msg) || msg.id === undefined) {\n return null;\n }\n\n const method = msg.method;\n const id = msg.id;\n const params = msg.params as Record<string, unknown> | undefined;\n\n try {\n switch (method) {\n case \"initialize\":\n return this.#handleInitialize(id);\n\n case \"ping\":\n return { id, jsonrpc: \"2.0\", result: {} } as JSONRPCMessage;\n\n case \"prompts/get\":\n return this.#handlePromptsGet(id, params);\n\n case \"prompts/list\":\n return this.#handlePromptsList(id);\n\n case \"resources/list\":\n return this.#handleResourcesList(id);\n\n case \"resources/read\":\n return this.#handleResourcesRead(id, params);\n\n case \"tools/call\":\n return this.#handleToolsCall(id, params);\n\n case \"tools/list\":\n return this.#handleToolsList(id);\n\n default:\n return this.#rpcError(id, -32601, `Method not found: ${method}`);\n }\n } catch (error) {\n this.#logger.error(`Error handling ${method}:`, error);\n return this.#rpcError(\n id,\n -32603,\n `Internal error: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle prompts/get request\n */\n async #handlePromptsGet(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const promptName = params?.name as string;\n const promptArgs = params?.arguments as Record<string, string> | undefined;\n\n const prompt = this.#prompts.find((p) => p.name === promptName);\n if (!prompt) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Prompt not found: ${promptName}`,\n );\n }\n\n try {\n const result = await prompt.load(promptArgs ?? {});\n const messages =\n typeof result === \"string\"\n ? [{ content: { text: result, type: \"text\" }, role: \"user\" }]\n : result.messages;\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { messages },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Prompt load failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle prompts/list request\n */\n #handlePromptsList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n prompts: this.#prompts.map((p) => ({\n arguments: p.arguments,\n description: p.description,\n name: p.name,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle resources/list request\n */\n #handleResourcesList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n resources: this.#resources.map((r) => ({\n description: r.description,\n mimeType: r.mimeType,\n name: r.name,\n uri: r.uri,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle resources/read request\n */\n async #handleResourcesRead(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const uri = params?.uri as string;\n const resource = this.#resources.find((r) => r.uri === uri);\n\n if (!resource) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Resource not found: ${uri}`,\n );\n }\n\n try {\n const result = await resource.load();\n const content =\n typeof result === \"string\"\n ? { mimeType: resource.mimeType ?? \"text/plain\", text: result, uri }\n : { uri, ...result };\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { contents: [content] },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Resource load failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle tools/call request\n */\n async #handleToolsCall(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const toolName = params?.name as string;\n const toolArgs = params?.arguments as Record<string, unknown> | undefined;\n\n const tool = this.#tools.find((t) => t.name === toolName);\n if (!tool) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Tool not found: ${toolName}`,\n );\n }\n\n let args: unknown = toolArgs ?? {};\n\n if (tool.parameters) {\n let parsed: StandardSchemaV1.Result<unknown>;\n\n try {\n parsed = await tool.parameters[\"~standard\"].validate(toolArgs);\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Tool '${toolName}' parameter validation failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (parsed.issues) {\n const friendlyErrors = parsed.issues\n .map((issue) => {\n const path = issue.path?.join(\".\") || \"root\";\n return `${path}: ${issue.message}`;\n })\n .join(\", \");\n\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Tool '${toolName}' parameter validation failed: ${friendlyErrors}. Please check the parameter types and values according to the tool's schema.`,\n );\n }\n\n args = parsed.value;\n }\n\n try {\n const result = await tool.execute(args);\n\n // Normalize result to content array\n const content =\n typeof result === \"string\"\n ? [{ text: result, type: \"text\" }]\n : result.content;\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { content },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle tools/list request\n */\n #handleToolsList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n tools: this.#tools.map((tool) => ({\n description: tool.description,\n inputSchema: tool.parameters\n ? this.#schemaToJsonSchema(tool.parameters)\n : { type: \"object\" },\n name: tool.name,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Create an RPC error message\n */\n #rpcError(\n id: null | number | string,\n code: number,\n message: string,\n ): JSONRPCMessage {\n return {\n error: { code, message },\n id,\n jsonrpc: \"2.0\",\n } as JSONRPCMessage;\n }\n\n /**\n * Convert schema to JSON Schema\n */\n #schemaToJsonSchema(\n schema: StandardSchemaV1 | z.ZodType,\n ): Record<string, unknown> {\n try {\n // Zod 4+: use native toJSONSchema if available\n /* eslint-disable @typescript-eslint/no-explicit-any */\n if (typeof (z as any).toJSONSchema === \"function\") {\n return strictJsonSchema(\n (z as any).toJSONSchema(schema) as Record<string, unknown>,\n ) as Record<string, unknown>;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n // Zod 3 fallback: use zod-to-json-schema\n /* eslint-disable @typescript-eslint/no-explicit-any */\n if (\"_def\" in (schema as any) || schema instanceof z.ZodType) {\n return strictJsonSchema(\n zodToJsonSchema(schema as any, { target: \"openApi3\" }) as Record<\n string,\n unknown\n >,\n ) as Record<string, unknown>;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n // For StandardSchema, fall back to a generic object schema\n return { type: \"object\" };\n } catch {\n return { type: \"object\" };\n }\n }\n\n /**\n * Set up MCP and health routes\n */\n #setupRoutes(): void {\n // Health endpoint\n this.#honoApp.get(\"/health\", (c) => c.text(\"✓ Ok\"));\n\n // MCP endpoint - handles all MCP protocol messages\n this.#honoApp.post(this.#mcpPath, async (c) => {\n return this.#handleMcpRequest(c.req.raw);\n });\n\n // MCP GET endpoint for SSE streams (server-initiated messages)\n this.#honoApp.get(this.#mcpPath, async (c) => {\n return this.#handleMcpSseRequest(c.req.raw);\n });\n\n // MCP DELETE endpoint for session termination\n this.#honoApp.delete(this.#mcpPath, async () => {\n return new Response(null, { status: 204 });\n });\n }\n}\n","/**\n * Web-standard Streamable HTTP Server Transport for MCP\n *\n * This transport implements the MCP Streamable HTTP specification using\n * web standard APIs (Request, Response, TransformStream) for compatibility\n * with edge runtimes like Cloudflare Workers, Deno, and Bun.\n */\n\nimport { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n CancelledNotificationSchema,\n isInitializeRequest,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n JSONRPCMessage,\n JSONRPCMessageSchema,\n MessageExtraInfo,\n RequestId,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type EventId = string;\n/**\n * Interface for resumability support via event storage\n */\nexport interface EventStore {\n getStreamIdForEventId?(eventId: EventId): Promise<StreamId | undefined>;\n replayEventsAfter(\n lastEventId: EventId,\n options: {\n send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;\n },\n ): Promise<StreamId>;\n storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;\n}\n\nexport type StreamId = string;\n\n/**\n * Configuration options for WebStreamableHTTPServerTransport\n */\nexport interface WebStreamableHTTPServerTransportOptions {\n /**\n * If true, return JSON responses instead of SSE streams\n */\n enableJsonResponse?: boolean;\n\n /**\n * Event store for resumability support\n */\n eventStore?: EventStore;\n\n /**\n * Callback for session close events\n */\n onsessionclosed?: (sessionId: string) => Promise<void> | void;\n\n /**\n * Callback for session initialization events\n */\n onsessioninitialized?: (sessionId: string) => Promise<void> | void;\n\n /**\n * Function that generates a session ID for the transport.\n * Return undefined to disable session management (stateless mode).\n */\n sessionIdGenerator: (() => string) | undefined;\n}\n\n/**\n * Collects the responses to every request that arrived on a single POST, so\n * that JSON mode can answer once all of them are in.\n */\ninterface PendingJsonResponse {\n expectedIds: RequestId[];\n resolve: (responses: JSONRPCMessage[]) => void;\n responses: Map<RequestId, JSONRPCMessage>;\n}\n\nconst MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024; // 4MB\n\n/**\n * Web-standard Server transport for Streamable HTTP.\n * Uses web APIs (Request, Response, TransformStream) for edge runtime compatibility.\n */\nexport class WebStreamableHTTPServerTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n sessionId?: string;\n private _enableJsonResponse = false;\n private _encoder = new TextEncoder();\n private _eventStore?: EventStore;\n private _jsonResponseCollectors = new Map<StreamId, PendingJsonResponse>();\n private _onsessionclosed?: (sessionId: string) => Promise<void> | void;\n private _onsessioninitialized?: (sessionId: string) => Promise<void> | void;\n /**\n * Replays whose stream id is still being resolved. `replayEventsAfter` only\n * reveals which stream it was replaying once it settles, so a standalone\n * send during that window has nothing to test against; persist rather than\n * drop, since over-storing for the length of a replay beats losing an event.\n */\n private _replaysInFlight = 0;\n\n private _requestToStreamMapping = new Map<RequestId, StreamId>();\n\n private _standaloneSseStreamId = \"_GET_stream\";\n /**\n * Whether a client has held the standalone GET stream during this session.\n * Latched rather than read from `_streamMapping`, so persistence survives\n * the disconnect window the store exists to cover while still telling a\n * dropped stream apart from one that was never opened. Reset with the rest\n * of the per-session state, since the next session starts with no stream.\n */\n private _standaloneStreamOpened = false;\n private _started = false;\n private _streamMapping = new Map<\n StreamId,\n WritableStreamDefaultWriter<Uint8Array>\n >();\n private sessionIdGenerator: (() => string) | undefined;\n\n constructor(options: WebStreamableHTTPServerTransportOptions) {\n this.sessionIdGenerator = options.sessionIdGenerator;\n this._enableJsonResponse = options.enableJsonResponse ?? false;\n this._eventStore = options.eventStore;\n this._onsessioninitialized = options.onsessioninitialized;\n this._onsessionclosed = options.onsessionclosed;\n }\n\n /**\n * Close the transport\n */\n async close(): Promise<void> {\n for (const writer of this._streamMapping.values()) {\n try {\n await writer.close();\n } catch {\n // Ignore close errors\n }\n }\n this._streamMapping.clear();\n this._standaloneStreamOpened = false;\n this.releasePendingRequests();\n this._started = false;\n this.onclose?.();\n }\n\n /**\n * Handles an incoming web Request and returns a Response\n */\n async handleRequest(\n request: Request,\n parsedBody?: unknown,\n ): Promise<Response> {\n const method = request.method;\n\n if (method === \"POST\") {\n return this.handlePostRequest(request, parsedBody);\n } else if (method === \"GET\") {\n return this.handleGetRequest(request);\n } else if (method === \"DELETE\") {\n return this.handleDeleteRequest(request);\n } else {\n return this.handleUnsupportedRequest();\n }\n }\n\n /**\n * Send a message to connected clients\n */\n async send(\n message: JSONRPCMessage,\n options?: { relatedRequestId?: RequestId },\n ): Promise<void> {\n let requestId = options?.relatedRequestId;\n const isResponse = isJSONRPCResponse(message) || isJSONRPCError(message);\n if (isResponse) {\n // Responses are routed by the id of the request they answer\n requestId = message.id;\n }\n\n const streamId =\n requestId === undefined\n ? this._standaloneSseStreamId\n : this._requestToStreamMapping.get(requestId);\n\n if (streamId) {\n // JSON mode has no stream to write to: collect the responses instead and\n // let handlePostRequest answer once every request on this POST is done.\n const collector = this._jsonResponseCollectors.get(streamId);\n if (collector) {\n if (isResponse && requestId !== undefined) {\n collector.responses.set(requestId, message);\n this.settleJsonResponse(streamId, collector);\n }\n return;\n }\n\n const writer = this._streamMapping.get(streamId);\n // With an event store the message must be persisted even if the client\n // has already disconnected, so a reconnect with Last-Event-Id can replay\n // it. The live write to the SSE stream is best-effort on top of that.\n const store = this.shouldPersist(streamId, writer)\n ? this._eventStore\n : undefined;\n\n if (writer || store) {\n try {\n let eventId: string | undefined;\n if (store) {\n eventId = await store.storeEvent(streamId, message);\n }\n if (writer) {\n if (eventId === undefined) {\n await this.writeSSEEvent(writer, message);\n } else {\n await this.writeSSEEventWithId(writer, eventId, message);\n }\n }\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n\n // Close the POST stream once all of its requests are answered. Drained\n // whether or not the store and the socket cooperated: with an event\n // store configured `trackStream` deliberately leaves routing entries\n // alone on disconnect, so this is the only thing that reclaims them,\n // and giving up on a failed write strands the entry until the session\n // ends.\n if (requestId !== undefined && isResponse) {\n this._requestToStreamMapping.delete(requestId);\n const streamInUse = Array.from(\n this._requestToStreamMapping.values(),\n ).includes(streamId);\n if (!streamInUse) {\n this._streamMapping.delete(streamId);\n if (writer) {\n try {\n await writer.close();\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n }\n }\n }\n }\n\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n /**\n * Create an error response\n */\n private createErrorResponse(\n status: number,\n code: number,\n message: string,\n ): Response {\n return new Response(\n JSON.stringify({\n error: { code, message },\n id: null,\n jsonrpc: \"2.0\",\n }),\n {\n headers: {\n ...this.getResponseHeaders(),\n \"Content-Type\": \"application/json\",\n },\n status,\n },\n );\n }\n\n /**\n * Get common response headers\n */\n private getResponseHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this.sessionId) {\n headers[\"mcp-session-id\"] = this.sessionId;\n }\n return headers;\n }\n\n /**\n * Handles DELETE requests to terminate sessions\n */\n private async handleDeleteRequest(request: Request): Promise<Response> {\n const sessionId = request.headers.get(\"mcp-session-id\");\n\n if (this.sessionIdGenerator) {\n if (!sessionId) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n if (this.sessionId !== sessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n }\n\n // Close all streams\n for (const writer of this._streamMapping.values()) {\n try {\n await writer.close();\n } catch {\n // Ignore close errors\n }\n }\n this._streamMapping.clear();\n // Per-session, like the session id below: this instance stays usable, and\n // the next session starts having opened no standalone stream of its own.\n this._standaloneStreamOpened = false;\n this.releasePendingRequests();\n\n await this._onsessionclosed?.(this.sessionId ?? \"\");\n this.sessionId = undefined;\n\n return new Response(null, {\n headers: this.getResponseHeaders(),\n status: 204,\n });\n }\n\n /**\n * Handles GET requests for SSE stream\n */\n private async handleGetRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return this.createErrorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept text/event-stream\",\n );\n }\n\n // Validate session\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (this.sessionIdGenerator && !sessionId) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n if (this.sessionIdGenerator && this.sessionId !== sessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n\n // Check for existing standalone stream\n if (this._streamMapping.has(this._standaloneSseStreamId)) {\n return this.createErrorResponse(\n 409,\n -32000,\n \"Conflict: SSE stream already exists for this session\",\n );\n }\n\n // Handle resumability\n if (this._eventStore) {\n const lastEventId = request.headers.get(\"last-event-id\");\n if (lastEventId) {\n return this.handleReplayEvents(lastEventId);\n }\n }\n\n // Create SSE stream\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n this.trackStream(this._standaloneSseStreamId, writer);\n\n return new Response(readable, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Handles POST requests containing JSON-RPC messages\n */\n private async handlePostRequest(\n request: Request,\n parsedBody?: unknown,\n ): Promise<Response> {\n // Validate Accept header\n const acceptHeader = request.headers.get(\"accept\");\n if (\n !acceptHeader?.includes(\"application/json\") &&\n !acceptHeader?.includes(\"text/event-stream\")\n ) {\n return this.createErrorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept application/json or text/event-stream\",\n );\n }\n\n // Validate Content-Type\n const contentType = request.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return this.createErrorResponse(\n 415,\n -32000,\n \"Unsupported Media Type: Content-Type must be application/json\",\n );\n }\n\n // Validate Content-Length\n const contentLength = parseInt(\n request.headers.get(\"content-length\") ?? \"0\",\n 10,\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE) {\n return this.createErrorResponse(\n 413,\n -32000,\n `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE} bytes`,\n );\n }\n\n // Parse body\n let rawMessage: unknown;\n try {\n rawMessage = parsedBody ?? (await request.json());\n } catch {\n return this.createErrorResponse(400, -32700, \"Parse error: Invalid JSON\");\n }\n\n // Handle batch or single message. The original shape decides the response\n // envelope: a batch always answers with an array, even when only one\n // response survives.\n const isBatch = Array.isArray(rawMessage);\n const arrayMessage: unknown[] = Array.isArray(rawMessage)\n ? rawMessage\n : [rawMessage];\n\n if (isBatch && arrayMessage.length === 0) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Batch must contain at least one message\",\n );\n }\n\n // Validate messages\n const messages: JSONRPCMessage[] = [];\n for (const msg of arrayMessage) {\n const result = JSONRPCMessageSchema.safeParse(msg);\n if (!result.success) {\n return this.createErrorResponse(\n 400,\n -32700,\n \"Parse error: Invalid JSON-RPC message\",\n );\n }\n messages.push(result.data);\n }\n\n // Handle session ID\n const requestSessionId = request.headers.get(\"mcp-session-id\");\n const hasInitRequest = messages.some((msg) => isInitializeRequest(msg));\n\n // Validate session requirements\n if (hasInitRequest && requestSessionId) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Initialization requests must not include a sessionId\",\n );\n }\n\n if (hasInitRequest && messages.length > 1) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Only one initialization request is allowed\",\n );\n }\n\n if (!hasInitRequest && !requestSessionId && this.sessionIdGenerator) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n // Generate or validate session ID\n if (hasInitRequest && this.sessionIdGenerator) {\n this.sessionId = this.sessionIdGenerator();\n await this._onsessioninitialized?.(this.sessionId);\n } else if (requestSessionId) {\n if (this.sessionIdGenerator && this.sessionId !== requestSessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n }\n\n const requestIds = messages\n .filter((msg) => isJSONRPCRequest(msg))\n .map((msg) => msg.id);\n const useJsonResponse =\n this._enableJsonResponse &&\n Boolean(acceptHeader?.includes(\"application/json\"));\n\n // Register the response sink before dispatching: the SDK produces\n // responses asynchronously and send() routes them back by request id.\n let jsonResponses: Promise<JSONRPCMessage[]> | undefined;\n let sseReadable: ReadableStream<Uint8Array> | undefined;\n if (requestIds.length > 0) {\n // Must be unique: a wall-clock id collides between two POSTs issued in\n // the same millisecond, which would cross-deliver their responses.\n const streamId = crypto.randomUUID();\n for (const id of requestIds) {\n this._requestToStreamMapping.set(id, streamId);\n }\n\n if (useJsonResponse) {\n jsonResponses = new Promise((resolve) => {\n this._jsonResponseCollectors.set(streamId, {\n expectedIds: requestIds,\n resolve,\n responses: new Map(),\n });\n });\n } else {\n const { readable, writable } = new TransformStream<Uint8Array>();\n this.trackStream(streamId, writable.getWriter());\n sseReadable = readable;\n }\n }\n\n // A cancelled request is never answered — the SDK suppresses the response\n // of a request whose abort signal fired — so send() never runs for its id\n // and nothing else would ever drop its routing entry. Release it here.\n for (const message of messages) {\n const cancelled = CancelledNotificationSchema.safeParse(message);\n if (cancelled.success) {\n await this.releaseCancelledRequest(cancelled.data.params.requestId);\n }\n }\n\n // Process messages through the transport\n for (const message of messages) {\n this.onmessage?.(message, { authInfo: undefined });\n }\n\n // Nothing to answer: the batch was only notifications and/or responses\n if (requestIds.length === 0) {\n return new Response(null, {\n headers: this.getResponseHeaders(),\n status: 202,\n });\n }\n\n // Return JSON response if enabled and client accepts it\n if (jsonResponses) {\n // Wait for the handlers to actually answer, however long they take\n const responses = await jsonResponses;\n\n const responseBody = JSON.stringify(isBatch ? responses : responses[0]);\n\n return new Response(responseBody, {\n headers: {\n ...this.getResponseHeaders(),\n \"Content-Type\": \"application/json\",\n },\n status: 200,\n });\n }\n\n // Return SSE stream\n return new Response(sseReadable ?? null, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Replay events for resumability\n */\n private async handleReplayEvents(lastEventId: string): Promise<Response> {\n if (!this._eventStore) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Resumability not supported\",\n );\n }\n\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n\n this._replaysInFlight += 1;\n try {\n const streamId = await this._eventStore.replayEventsAfter(lastEventId, {\n send: async (eventId, message) => {\n await this.writeSSEEventWithId(writer, eventId, message);\n },\n });\n this.trackStream(streamId, writer);\n } catch (error) {\n await writer.close();\n return this.createErrorResponse(500, -32000, `Replay failed: ${error}`);\n } finally {\n this._replaysInFlight -= 1;\n }\n\n return new Response(readable, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Handles unsupported HTTP methods\n */\n private handleUnsupportedRequest(): Response {\n return this.createErrorResponse(405, -32000, \"Method not allowed\");\n }\n\n /**\n * Settle the routing state of a request the client cancelled, which will\n * therefore never produce a response: the same drain `send()` performs once\n * a response has been written, minus the response. Idempotent, so it is a\n * no-op if the response won the race against the cancellation.\n *\n * JSON-mode POSTs are left alone: `_jsonResponseCollectors` owns their\n * settlement.\n */\n private async releaseCancelledRequest(requestId: RequestId): Promise<void> {\n const streamId = this._requestToStreamMapping.get(requestId);\n if (streamId === undefined || this._jsonResponseCollectors.has(streamId)) {\n return;\n }\n\n this._requestToStreamMapping.delete(requestId);\n const streamInUse = Array.from(\n this._requestToStreamMapping.values(),\n ).includes(streamId);\n if (streamInUse) {\n return;\n }\n\n // Nothing will ever be written to this stream again; close it rather than\n // leaving the client reading a stream that can only hang.\n const writer = this._streamMapping.get(streamId);\n this._streamMapping.delete(streamId);\n if (writer) {\n try {\n await writer.close();\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n\n /**\n * Drop the routing state left over once every stream is gone, answering any\n * POST still waiting on a JSON response with whatever arrived rather than\n * leaving the request hanging.\n */\n private releasePendingRequests(): void {\n for (const collector of this._jsonResponseCollectors.values()) {\n collector.resolve(\n collector.expectedIds\n .map((id) => collector.responses.get(id))\n .filter((response) => response !== undefined),\n );\n }\n this._jsonResponseCollectors.clear();\n this._requestToStreamMapping.clear();\n }\n\n /**\n * Answer a JSON-mode POST once every request it carried has a response\n */\n private settleJsonResponse(\n streamId: StreamId,\n collector: PendingJsonResponse,\n ): void {\n const responses: JSONRPCMessage[] = [];\n for (const id of collector.expectedIds) {\n const response = collector.responses.get(id);\n if (!response) {\n // Still waiting on at least one of this POST's requests\n return;\n }\n responses.push(response);\n }\n\n this._jsonResponseCollectors.delete(streamId);\n for (const id of collector.expectedIds) {\n this._requestToStreamMapping.delete(id);\n }\n collector.resolve(responses);\n }\n\n /**\n * Whether an event addressed to `streamId` should go to the event store.\n *\n * Everything but the standalone stream is persisted whenever a store is\n * configured: those ids exist only because their stream did. The standalone\n * id is a constant, so it resolves whether or not a client ever opened that\n * stream, and storing before the first GET writes events nothing can reach —\n * replay is keyed off Last-Event-Id, and a client that never held the stream\n * was never handed an id to resume from.\n */\n private shouldPersist(\n streamId: StreamId,\n writer: undefined | WritableStreamDefaultWriter<Uint8Array>,\n ): boolean {\n if (this._eventStore === undefined) {\n return false;\n }\n\n if (streamId !== this._standaloneSseStreamId) {\n return true;\n }\n\n return (\n this._standaloneStreamOpened ||\n // A live writer means the stream is open now, which is stronger evidence\n // than the latch. Belt and braces: it keeps a writer reaching this point\n // without `trackStream` from producing an SSE event with no `id:`.\n writer !== undefined ||\n this._replaysInFlight > 0\n );\n }\n\n private trackStream(\n streamId: StreamId,\n writer: WritableStreamDefaultWriter<Uint8Array>,\n ): void {\n // Latched here rather than at each call site so a new way of opening the\n // standalone stream cannot forget to record it.\n if (streamId === this._standaloneSseStreamId) {\n this._standaloneStreamOpened = true;\n }\n this._streamMapping.set(streamId, writer);\n const removeStreamIfCurrent = () => {\n if (this._streamMapping.get(streamId) !== writer) {\n return;\n }\n this._streamMapping.delete(streamId);\n // With an event store, a response can still arrive after the client gave\n // up, and it must be persisted for replay. Keep the routing entry so\n // send() can resolve the stream id and store under it; send() drops the\n // entry once the response has been stored.\n if (this._eventStore) {\n return;\n }\n // No event store: nothing will be persisted for this stream, so drop the\n // routing entries now rather than leaking them. No-op for the standalone\n // GET stream, which is never a request target.\n for (const [requestId, mappedStreamId] of this._requestToStreamMapping) {\n if (mappedStreamId === streamId) {\n this._requestToStreamMapping.delete(requestId);\n }\n }\n };\n void writer.closed.then(removeStreamIfCurrent, removeStreamIfCurrent);\n }\n\n /**\n * Write an SSE event to the stream\n */\n private async writeSSEEvent(\n writer: WritableStreamDefaultWriter<Uint8Array>,\n message: JSONRPCMessage,\n ): Promise<void> {\n const data = `data: ${JSON.stringify(message)}\\n\\n`;\n await writer.write(this._encoder.encode(data));\n }\n\n /**\n * Write an SSE event with ID to the stream\n */\n private async writeSSEEventWithId(\n writer: WritableStreamDefaultWriter<Uint8Array>,\n eventId: string,\n message: JSONRPCMessage,\n ): Promise<void> {\n const data = `id: ${eventId}\\ndata: ${JSON.stringify(message)}\\n\\n`;\n await writer.write(this._encoder.encode(data));\n }\n}\n"]}
@@ -65,8 +65,23 @@ declare class WebStreamableHTTPServerTransport implements Transport {
65
65
  private _jsonResponseCollectors;
66
66
  private _onsessionclosed?;
67
67
  private _onsessioninitialized?;
68
+ /**
69
+ * Replays whose stream id is still being resolved. `replayEventsAfter` only
70
+ * reveals which stream it was replaying once it settles, so a standalone
71
+ * send during that window has nothing to test against; persist rather than
72
+ * drop, since over-storing for the length of a replay beats losing an event.
73
+ */
74
+ private _replaysInFlight;
68
75
  private _requestToStreamMapping;
69
76
  private _standaloneSseStreamId;
77
+ /**
78
+ * Whether a client has held the standalone GET stream during this session.
79
+ * Latched rather than read from `_streamMapping`, so persistence survives
80
+ * the disconnect window the store exists to cover while still telling a
81
+ * dropped stream apart from one that was never opened. Reset with the rest
82
+ * of the per-session state, since the next session starts with no stream.
83
+ */
84
+ private _standaloneStreamOpened;
70
85
  private _started;
71
86
  private _streamMapping;
72
87
  private sessionIdGenerator;
@@ -134,6 +149,17 @@ declare class WebStreamableHTTPServerTransport implements Transport {
134
149
  * Answer a JSON-mode POST once every request it carried has a response
135
150
  */
136
151
  private settleJsonResponse;
152
+ /**
153
+ * Whether an event addressed to `streamId` should go to the event store.
154
+ *
155
+ * Everything but the standalone stream is persisted whenever a store is
156
+ * configured: those ids exist only because their stream did. The standalone
157
+ * id is a constant, so it resolves whether or not a client ever opened that
158
+ * stream, and storing before the first GET writes events nothing can reach —
159
+ * replay is keyed off Last-Event-Id, and a client that never held the stream
160
+ * was never handed an id to resume from.
161
+ */
162
+ private shouldPersist;
137
163
  private trackStream;
138
164
  /**
139
165
  * Write an SSE event to the stream
@@ -65,8 +65,23 @@ declare class WebStreamableHTTPServerTransport implements Transport {
65
65
  private _jsonResponseCollectors;
66
66
  private _onsessionclosed?;
67
67
  private _onsessioninitialized?;
68
+ /**
69
+ * Replays whose stream id is still being resolved. `replayEventsAfter` only
70
+ * reveals which stream it was replaying once it settles, so a standalone
71
+ * send during that window has nothing to test against; persist rather than
72
+ * drop, since over-storing for the length of a replay beats losing an event.
73
+ */
74
+ private _replaysInFlight;
68
75
  private _requestToStreamMapping;
69
76
  private _standaloneSseStreamId;
77
+ /**
78
+ * Whether a client has held the standalone GET stream during this session.
79
+ * Latched rather than read from `_streamMapping`, so persistence survives
80
+ * the disconnect window the store exists to cover while still telling a
81
+ * dropped stream apart from one that was never opened. Reset with the rest
82
+ * of the per-session state, since the next session starts with no stream.
83
+ */
84
+ private _standaloneStreamOpened;
70
85
  private _started;
71
86
  private _streamMapping;
72
87
  private sessionIdGenerator;
@@ -134,6 +149,17 @@ declare class WebStreamableHTTPServerTransport implements Transport {
134
149
  * Answer a JSON-mode POST once every request it carried has a response
135
150
  */
136
151
  private settleJsonResponse;
152
+ /**
153
+ * Whether an event addressed to `streamId` should go to the event store.
154
+ *
155
+ * Everything but the standalone stream is persisted whenever a store is
156
+ * configured: those ids exist only because their stream did. The standalone
157
+ * id is a constant, so it resolves whether or not a client ever opened that
158
+ * stream, and storing before the first GET writes events nothing can reach —
159
+ * replay is keyed off Last-Event-Id, and a client that never held the stream
160
+ * was never handed an id to resume from.
161
+ */
162
+ private shouldPersist;
137
163
  private trackStream;
138
164
  /**
139
165
  * Write an SSE event to the stream
@@ -29,8 +29,23 @@ var WebStreamableHTTPServerTransport = class {
29
29
  _jsonResponseCollectors = /* @__PURE__ */ new Map();
30
30
  _onsessionclosed;
31
31
  _onsessioninitialized;
32
+ /**
33
+ * Replays whose stream id is still being resolved. `replayEventsAfter` only
34
+ * reveals which stream it was replaying once it settles, so a standalone
35
+ * send during that window has nothing to test against; persist rather than
36
+ * drop, since over-storing for the length of a replay beats losing an event.
37
+ */
38
+ _replaysInFlight = 0;
32
39
  _requestToStreamMapping = /* @__PURE__ */ new Map();
33
40
  _standaloneSseStreamId = "_GET_stream";
41
+ /**
42
+ * Whether a client has held the standalone GET stream during this session.
43
+ * Latched rather than read from `_streamMapping`, so persistence survives
44
+ * the disconnect window the store exists to cover while still telling a
45
+ * dropped stream apart from one that was never opened. Reset with the rest
46
+ * of the per-session state, since the next session starts with no stream.
47
+ */
48
+ _standaloneStreamOpened = false;
34
49
  _started = false;
35
50
  _streamMapping = /* @__PURE__ */ new Map();
36
51
  sessionIdGenerator;
@@ -52,6 +67,7 @@ var WebStreamableHTTPServerTransport = class {
52
67
  }
53
68
  }
54
69
  this._streamMapping.clear();
70
+ this._standaloneStreamOpened = false;
55
71
  this.releasePendingRequests();
56
72
  this._started = false;
57
73
  this.onclose?.();
@@ -91,11 +107,12 @@ var WebStreamableHTTPServerTransport = class {
91
107
  return;
92
108
  }
93
109
  const writer = this._streamMapping.get(streamId);
94
- if (writer || this._eventStore) {
110
+ const store = this.shouldPersist(streamId, writer) ? this._eventStore : void 0;
111
+ if (writer || store) {
95
112
  try {
96
113
  let eventId;
97
- if (this._eventStore) {
98
- eventId = await this._eventStore.storeEvent(streamId, message);
114
+ if (store) {
115
+ eventId = await store.storeEvent(streamId, message);
99
116
  }
100
117
  if (writer) {
101
118
  if (eventId === void 0) {
@@ -104,23 +121,29 @@ var WebStreamableHTTPServerTransport = class {
104
121
  await this.writeSSEEventWithId(writer, eventId, message);
105
122
  }
106
123
  }
107
- if (requestId !== void 0 && isResponse) {
108
- this._requestToStreamMapping.delete(requestId);
109
- const streamInUse = Array.from(
110
- this._requestToStreamMapping.values()
111
- ).includes(streamId);
112
- if (!streamInUse) {
113
- this._streamMapping.delete(streamId);
114
- if (writer) {
115
- await writer.close();
116
- }
117
- }
118
- }
119
124
  } catch (error) {
120
125
  this.onerror?.(
121
126
  error instanceof Error ? error : new Error(String(error))
122
127
  );
123
128
  }
129
+ if (requestId !== void 0 && isResponse) {
130
+ this._requestToStreamMapping.delete(requestId);
131
+ const streamInUse = Array.from(
132
+ this._requestToStreamMapping.values()
133
+ ).includes(streamId);
134
+ if (!streamInUse) {
135
+ this._streamMapping.delete(streamId);
136
+ if (writer) {
137
+ try {
138
+ await writer.close();
139
+ } catch (error) {
140
+ this.onerror?.(
141
+ error instanceof Error ? error : new Error(String(error))
142
+ );
143
+ }
144
+ }
145
+ }
146
+ }
124
147
  }
125
148
  }
126
149
  }
@@ -183,6 +206,7 @@ var WebStreamableHTTPServerTransport = class {
183
206
  }
184
207
  }
185
208
  this._streamMapping.clear();
209
+ this._standaloneStreamOpened = false;
186
210
  this.releasePendingRequests();
187
211
  await this._onsessionclosed?.(this.sessionId ?? "");
188
212
  this.sessionId = void 0;
@@ -401,6 +425,7 @@ var WebStreamableHTTPServerTransport = class {
401
425
  }
402
426
  const { readable, writable } = new TransformStream();
403
427
  const writer = writable.getWriter();
428
+ this._replaysInFlight += 1;
404
429
  try {
405
430
  const streamId = await this._eventStore.replayEventsAfter(lastEventId, {
406
431
  send: async (eventId, message) => {
@@ -411,6 +436,8 @@ var WebStreamableHTTPServerTransport = class {
411
436
  } catch (error) {
412
437
  await writer.close();
413
438
  return this.createErrorResponse(500, -32e3, `Replay failed: ${error}`);
439
+ } finally {
440
+ this._replaysInFlight -= 1;
414
441
  }
415
442
  return new Response(readable, {
416
443
  headers: {
@@ -493,7 +520,32 @@ var WebStreamableHTTPServerTransport = class {
493
520
  }
494
521
  collector.resolve(responses);
495
522
  }
523
+ /**
524
+ * Whether an event addressed to `streamId` should go to the event store.
525
+ *
526
+ * Everything but the standalone stream is persisted whenever a store is
527
+ * configured: those ids exist only because their stream did. The standalone
528
+ * id is a constant, so it resolves whether or not a client ever opened that
529
+ * stream, and storing before the first GET writes events nothing can reach —
530
+ * replay is keyed off Last-Event-Id, and a client that never held the stream
531
+ * was never handed an id to resume from.
532
+ */
533
+ shouldPersist(streamId, writer) {
534
+ if (this._eventStore === void 0) {
535
+ return false;
536
+ }
537
+ if (streamId !== this._standaloneSseStreamId) {
538
+ return true;
539
+ }
540
+ return this._standaloneStreamOpened || // A live writer means the stream is open now, which is stronger evidence
541
+ // than the latch. Belt and braces: it keeps a writer reaching this point
542
+ // without `trackStream` from producing an SSE event with no `id:`.
543
+ writer !== void 0 || this._replaysInFlight > 0;
544
+ }
496
545
  trackStream(streamId, writer) {
546
+ if (streamId === this._standaloneSseStreamId) {
547
+ this._standaloneStreamOpened = true;
548
+ }
497
549
  this._streamMapping.set(streamId, writer);
498
550
  const removeStreamIfCurrent = () => {
499
551
  if (this._streamMapping.get(streamId) !== writer) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/edge/index.ts","../../src/edge/WebStreamableHTTPServerTransport.ts"],"sourcesContent":["/**\n * FastMCP Edge Runtime Support\n *\n * This module provides edge runtime compatibility for FastMCP, enabling\n * deployment to Cloudflare Workers, Deno Deploy, and other edge platforms.\n *\n * @example\n * ```typescript\n * // Cloudflare Workers\n * import { EdgeFastMCP } from \"fastmcp/edge\";\n * import { z } from \"zod\";\n *\n * const server = new EdgeFastMCP({ name: \"MyMCP\", version: \"1.0.0\" });\n *\n * server.addTool({\n * name: \"hello\",\n * description: \"Say hello\",\n * parameters: z.object({ name: z.string() }),\n * execute: async ({ name }) => `Hello, ${name}!`,\n * });\n *\n * export default server;\n * ```\n */\n\nimport {\n ErrorCode,\n JSONRPCMessage,\n LATEST_PROTOCOL_VERSION,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { Hono } from \"hono\";\nimport { strictJsonSchema } from \"xsschema\";\nimport { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\n\nexport { WebStreamableHTTPServerTransport } from \"./WebStreamableHTTPServerTransport.js\";\nexport type {\n EventStore,\n WebStreamableHTTPServerTransportOptions,\n} from \"./WebStreamableHTTPServerTransport.js\";\n\n/**\n * Options for EdgeFastMCP\n */\nexport interface EdgeFastMCPOptions {\n description?: string;\n logger?: EdgeLogger;\n /**\n * Base path for MCP endpoints (default: \"/mcp\")\n */\n mcpPath?: string;\n name: string;\n version: string;\n}\n\n/**\n * Type for edge runtime fetch handler\n */\nexport type EdgeFetchHandler = (request: Request) => Promise<Response>;\n\n/**\n * Logger interface for edge environments\n */\nexport interface EdgeLogger {\n debug(...args: unknown[]): void;\n error(...args: unknown[]): void;\n info(...args: unknown[]): void;\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n}\n\n/**\n * Prompt definition for EdgeFastMCP\n */\nexport interface EdgePrompt {\n arguments?: Array<{ description?: string; name: string; required?: boolean }>;\n description?: string;\n load: (args: Record<string, string>) => Promise<\n | {\n messages: Array<{\n content: { text: string; type: string };\n role: string;\n }>;\n }\n | string\n >;\n name: string;\n}\n\n/**\n * Resource definition for EdgeFastMCP\n */\nexport interface EdgeResource {\n description?: string;\n load: () => Promise<\n { blob?: string; mimeType?: string; text?: string } | string\n >;\n mimeType?: string;\n name: string;\n uri: string;\n}\n\n/**\n * Tool definition for EdgeFastMCP\n */\nexport interface EdgeTool<TParams = unknown> {\n description: string;\n execute: (params: TParams) => Promise<\n | {\n content: Array<{\n data?: string;\n mimeType?: string;\n text?: string;\n type: string;\n }>;\n }\n | string\n >;\n name: string;\n parameters?: StandardSchemaV1<TParams> | z.ZodType<TParams>;\n}\n\n/**\n * Edge-compatible FastMCP server for Cloudflare Workers, Deno, and Bun\n *\n * This is a simplified implementation optimized for stateless edge environments.\n * It uses web-standard APIs only (no Node.js dependencies).\n */\nexport class EdgeFastMCP {\n #honoApp = new Hono();\n #logger: EdgeLogger;\n #mcpPath: string;\n #name: string;\n #prompts: EdgePrompt[] = [];\n #resources: EdgeResource[] = [];\n #tools: EdgeTool[] = [];\n #version: string;\n\n constructor(options: EdgeFastMCPOptions) {\n this.#name = options.name;\n this.#version = options.version;\n this.#logger = options.logger ?? console;\n this.#mcpPath = options.mcpPath ?? \"/mcp\";\n\n this.#setupRoutes();\n }\n\n /**\n * Add a prompt to the server\n */\n addPrompt(prompt: EdgePrompt): this {\n this.#prompts.push(prompt);\n return this;\n }\n\n /**\n * Add a resource to the server\n */\n addResource(resource: EdgeResource): this {\n this.#resources.push(resource);\n return this;\n }\n\n /**\n * Add a tool to the server\n */\n addTool<TParams>(tool: EdgeTool<TParams>): this {\n this.#tools.push(tool as EdgeTool);\n return this;\n }\n\n /**\n * Handle an incoming request (main entry point for edge runtimes)\n */\n async fetch(request: Request): Promise<Response> {\n return this.#honoApp.fetch(request);\n }\n\n /**\n * Get the Hono app for adding custom routes\n */\n getApp(): Hono {\n return this.#honoApp;\n }\n\n /**\n * Create an error HTTP response\n */\n #errorResponse(status: number, code: number, message: string): Response {\n return new Response(\n JSON.stringify({\n error: { code, message },\n id: null,\n jsonrpc: \"2.0\",\n }),\n {\n headers: { \"Content-Type\": \"application/json\" },\n status,\n },\n );\n }\n\n /**\n * Handle initialize request\n */\n #handleInitialize(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n capabilities: {\n prompts: this.#prompts.length > 0 ? {} : undefined,\n resources: this.#resources.length > 0 ? {} : undefined,\n tools: this.#tools.length > 0 ? {} : undefined,\n },\n protocolVersion: LATEST_PROTOCOL_VERSION,\n serverInfo: {\n name: this.#name,\n version: this.#version,\n },\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle MCP POST requests\n */\n async #handleMcpRequest(request: Request): Promise<Response> {\n // Validate headers\n const acceptHeader = request.headers.get(\"accept\");\n if (\n !acceptHeader?.includes(\"application/json\") &&\n !acceptHeader?.includes(\"text/event-stream\")\n ) {\n return this.#errorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept application/json or text/event-stream\",\n );\n }\n\n const contentType = request.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return this.#errorResponse(\n 415,\n -32000,\n \"Unsupported Media Type: Content-Type must be application/json\",\n );\n }\n\n // Parse request body\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return this.#errorResponse(400, -32700, \"Parse error: Invalid JSON\");\n }\n\n // Handle single or batch requests\n const isBatch = Array.isArray(body);\n const messages = Array.isArray(body) ? body : [body];\n\n if (isBatch && messages.length === 0) {\n return this.#errorResponse(\n 400,\n ErrorCode.InvalidRequest,\n \"Invalid Request: Batch must contain at least one message\",\n );\n }\n\n const responses: JSONRPCMessage[] = [];\n\n for (const message of messages) {\n const response = await this.#handleMessage(message);\n if (response) {\n responses.push(response);\n }\n }\n\n // Return appropriate response format\n if (responses.length === 0) {\n return new Response(null, { status: 202 });\n }\n\n const responseBody = JSON.stringify(isBatch ? responses : responses[0]);\n\n return new Response(responseBody, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n status: 200,\n });\n }\n\n /**\n * Handle SSE GET requests\n */\n async #handleMcpSseRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return this.#errorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept text/event-stream\",\n );\n }\n\n // In stateless mode, GET requests are not supported (no server-initiated messages)\n return this.#errorResponse(\n 405,\n -32000,\n \"Method Not Allowed: SSE streams not supported in stateless mode\",\n );\n }\n\n /**\n * Handle individual MCP messages\n */\n async #handleMessage(message: unknown): Promise<JSONRPCMessage | null> {\n if (!message || typeof message !== \"object\") {\n return this.#rpcError(null, -32700, \"Parse error: Invalid message\");\n }\n\n const msg = message as {\n id?: number | string;\n jsonrpc?: string;\n method?: string;\n params?: unknown;\n };\n\n if (msg.jsonrpc !== \"2.0\") {\n return this.#rpcError(\n msg.id ?? null,\n -32600,\n \"Invalid Request: jsonrpc must be 2.0\",\n );\n }\n\n // Handle notifications (no response expected)\n if (!(\"id\" in msg) || msg.id === undefined) {\n return null;\n }\n\n const method = msg.method;\n const id = msg.id;\n const params = msg.params as Record<string, unknown> | undefined;\n\n try {\n switch (method) {\n case \"initialize\":\n return this.#handleInitialize(id);\n\n case \"ping\":\n return { id, jsonrpc: \"2.0\", result: {} } as JSONRPCMessage;\n\n case \"prompts/get\":\n return this.#handlePromptsGet(id, params);\n\n case \"prompts/list\":\n return this.#handlePromptsList(id);\n\n case \"resources/list\":\n return this.#handleResourcesList(id);\n\n case \"resources/read\":\n return this.#handleResourcesRead(id, params);\n\n case \"tools/call\":\n return this.#handleToolsCall(id, params);\n\n case \"tools/list\":\n return this.#handleToolsList(id);\n\n default:\n return this.#rpcError(id, -32601, `Method not found: ${method}`);\n }\n } catch (error) {\n this.#logger.error(`Error handling ${method}:`, error);\n return this.#rpcError(\n id,\n -32603,\n `Internal error: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle prompts/get request\n */\n async #handlePromptsGet(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const promptName = params?.name as string;\n const promptArgs = params?.arguments as Record<string, string> | undefined;\n\n const prompt = this.#prompts.find((p) => p.name === promptName);\n if (!prompt) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Prompt not found: ${promptName}`,\n );\n }\n\n try {\n const result = await prompt.load(promptArgs ?? {});\n const messages =\n typeof result === \"string\"\n ? [{ content: { text: result, type: \"text\" }, role: \"user\" }]\n : result.messages;\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { messages },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Prompt load failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle prompts/list request\n */\n #handlePromptsList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n prompts: this.#prompts.map((p) => ({\n arguments: p.arguments,\n description: p.description,\n name: p.name,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle resources/list request\n */\n #handleResourcesList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n resources: this.#resources.map((r) => ({\n description: r.description,\n mimeType: r.mimeType,\n name: r.name,\n uri: r.uri,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle resources/read request\n */\n async #handleResourcesRead(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const uri = params?.uri as string;\n const resource = this.#resources.find((r) => r.uri === uri);\n\n if (!resource) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Resource not found: ${uri}`,\n );\n }\n\n try {\n const result = await resource.load();\n const content =\n typeof result === \"string\"\n ? { mimeType: resource.mimeType ?? \"text/plain\", text: result, uri }\n : { uri, ...result };\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { contents: [content] },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Resource load failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle tools/call request\n */\n async #handleToolsCall(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const toolName = params?.name as string;\n const toolArgs = params?.arguments as Record<string, unknown> | undefined;\n\n const tool = this.#tools.find((t) => t.name === toolName);\n if (!tool) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Tool not found: ${toolName}`,\n );\n }\n\n let args: unknown = toolArgs ?? {};\n\n if (tool.parameters) {\n let parsed: StandardSchemaV1.Result<unknown>;\n\n try {\n parsed = await tool.parameters[\"~standard\"].validate(toolArgs);\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Tool '${toolName}' parameter validation failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (parsed.issues) {\n const friendlyErrors = parsed.issues\n .map((issue) => {\n const path = issue.path?.join(\".\") || \"root\";\n return `${path}: ${issue.message}`;\n })\n .join(\", \");\n\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Tool '${toolName}' parameter validation failed: ${friendlyErrors}. Please check the parameter types and values according to the tool's schema.`,\n );\n }\n\n args = parsed.value;\n }\n\n try {\n const result = await tool.execute(args);\n\n // Normalize result to content array\n const content =\n typeof result === \"string\"\n ? [{ text: result, type: \"text\" }]\n : result.content;\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { content },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle tools/list request\n */\n #handleToolsList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n tools: this.#tools.map((tool) => ({\n description: tool.description,\n inputSchema: tool.parameters\n ? this.#schemaToJsonSchema(tool.parameters)\n : { type: \"object\" },\n name: tool.name,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Create an RPC error message\n */\n #rpcError(\n id: null | number | string,\n code: number,\n message: string,\n ): JSONRPCMessage {\n return {\n error: { code, message },\n id,\n jsonrpc: \"2.0\",\n } as JSONRPCMessage;\n }\n\n /**\n * Convert schema to JSON Schema\n */\n #schemaToJsonSchema(\n schema: StandardSchemaV1 | z.ZodType,\n ): Record<string, unknown> {\n try {\n // Zod 4+: use native toJSONSchema if available\n /* eslint-disable @typescript-eslint/no-explicit-any */\n if (typeof (z as any).toJSONSchema === \"function\") {\n return strictJsonSchema(\n (z as any).toJSONSchema(schema) as Record<string, unknown>,\n ) as Record<string, unknown>;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n // Zod 3 fallback: use zod-to-json-schema\n /* eslint-disable @typescript-eslint/no-explicit-any */\n if (\"_def\" in (schema as any) || schema instanceof z.ZodType) {\n return strictJsonSchema(\n zodToJsonSchema(schema as any, { target: \"openApi3\" }) as Record<\n string,\n unknown\n >,\n ) as Record<string, unknown>;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n // For StandardSchema, fall back to a generic object schema\n return { type: \"object\" };\n } catch {\n return { type: \"object\" };\n }\n }\n\n /**\n * Set up MCP and health routes\n */\n #setupRoutes(): void {\n // Health endpoint\n this.#honoApp.get(\"/health\", (c) => c.text(\"✓ Ok\"));\n\n // MCP endpoint - handles all MCP protocol messages\n this.#honoApp.post(this.#mcpPath, async (c) => {\n return this.#handleMcpRequest(c.req.raw);\n });\n\n // MCP GET endpoint for SSE streams (server-initiated messages)\n this.#honoApp.get(this.#mcpPath, async (c) => {\n return this.#handleMcpSseRequest(c.req.raw);\n });\n\n // MCP DELETE endpoint for session termination\n this.#honoApp.delete(this.#mcpPath, async () => {\n return new Response(null, { status: 204 });\n });\n }\n}\n","/**\n * Web-standard Streamable HTTP Server Transport for MCP\n *\n * This transport implements the MCP Streamable HTTP specification using\n * web standard APIs (Request, Response, TransformStream) for compatibility\n * with edge runtimes like Cloudflare Workers, Deno, and Bun.\n */\n\nimport { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n CancelledNotificationSchema,\n isInitializeRequest,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n JSONRPCMessage,\n JSONRPCMessageSchema,\n MessageExtraInfo,\n RequestId,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type EventId = string;\n/**\n * Interface for resumability support via event storage\n */\nexport interface EventStore {\n getStreamIdForEventId?(eventId: EventId): Promise<StreamId | undefined>;\n replayEventsAfter(\n lastEventId: EventId,\n options: {\n send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;\n },\n ): Promise<StreamId>;\n storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;\n}\n\nexport type StreamId = string;\n\n/**\n * Configuration options for WebStreamableHTTPServerTransport\n */\nexport interface WebStreamableHTTPServerTransportOptions {\n /**\n * If true, return JSON responses instead of SSE streams\n */\n enableJsonResponse?: boolean;\n\n /**\n * Event store for resumability support\n */\n eventStore?: EventStore;\n\n /**\n * Callback for session close events\n */\n onsessionclosed?: (sessionId: string) => Promise<void> | void;\n\n /**\n * Callback for session initialization events\n */\n onsessioninitialized?: (sessionId: string) => Promise<void> | void;\n\n /**\n * Function that generates a session ID for the transport.\n * Return undefined to disable session management (stateless mode).\n */\n sessionIdGenerator: (() => string) | undefined;\n}\n\n/**\n * Collects the responses to every request that arrived on a single POST, so\n * that JSON mode can answer once all of them are in.\n */\ninterface PendingJsonResponse {\n expectedIds: RequestId[];\n resolve: (responses: JSONRPCMessage[]) => void;\n responses: Map<RequestId, JSONRPCMessage>;\n}\n\nconst MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024; // 4MB\n\n/**\n * Web-standard Server transport for Streamable HTTP.\n * Uses web APIs (Request, Response, TransformStream) for edge runtime compatibility.\n */\nexport class WebStreamableHTTPServerTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n sessionId?: string;\n private _enableJsonResponse = false;\n private _encoder = new TextEncoder();\n private _eventStore?: EventStore;\n private _jsonResponseCollectors = new Map<StreamId, PendingJsonResponse>();\n private _onsessionclosed?: (sessionId: string) => Promise<void> | void;\n private _onsessioninitialized?: (sessionId: string) => Promise<void> | void;\n private _requestToStreamMapping = new Map<RequestId, StreamId>();\n\n private _standaloneSseStreamId = \"_GET_stream\";\n private _started = false;\n private _streamMapping = new Map<\n StreamId,\n WritableStreamDefaultWriter<Uint8Array>\n >();\n private sessionIdGenerator: (() => string) | undefined;\n\n constructor(options: WebStreamableHTTPServerTransportOptions) {\n this.sessionIdGenerator = options.sessionIdGenerator;\n this._enableJsonResponse = options.enableJsonResponse ?? false;\n this._eventStore = options.eventStore;\n this._onsessioninitialized = options.onsessioninitialized;\n this._onsessionclosed = options.onsessionclosed;\n }\n\n /**\n * Close the transport\n */\n async close(): Promise<void> {\n for (const writer of this._streamMapping.values()) {\n try {\n await writer.close();\n } catch {\n // Ignore close errors\n }\n }\n this._streamMapping.clear();\n this.releasePendingRequests();\n this._started = false;\n this.onclose?.();\n }\n\n /**\n * Handles an incoming web Request and returns a Response\n */\n async handleRequest(\n request: Request,\n parsedBody?: unknown,\n ): Promise<Response> {\n const method = request.method;\n\n if (method === \"POST\") {\n return this.handlePostRequest(request, parsedBody);\n } else if (method === \"GET\") {\n return this.handleGetRequest(request);\n } else if (method === \"DELETE\") {\n return this.handleDeleteRequest(request);\n } else {\n return this.handleUnsupportedRequest();\n }\n }\n\n /**\n * Send a message to connected clients\n */\n async send(\n message: JSONRPCMessage,\n options?: { relatedRequestId?: RequestId },\n ): Promise<void> {\n let requestId = options?.relatedRequestId;\n const isResponse = isJSONRPCResponse(message) || isJSONRPCError(message);\n if (isResponse) {\n // Responses are routed by the id of the request they answer\n requestId = message.id;\n }\n\n const streamId =\n requestId === undefined\n ? this._standaloneSseStreamId\n : this._requestToStreamMapping.get(requestId);\n\n if (streamId) {\n // JSON mode has no stream to write to: collect the responses instead and\n // let handlePostRequest answer once every request on this POST is done.\n const collector = this._jsonResponseCollectors.get(streamId);\n if (collector) {\n if (isResponse && requestId !== undefined) {\n collector.responses.set(requestId, message);\n this.settleJsonResponse(streamId, collector);\n }\n return;\n }\n\n const writer = this._streamMapping.get(streamId);\n // With an event store the message must be persisted even if the client\n // has already disconnected, so a reconnect with Last-Event-Id can replay\n // it. The live write to the SSE stream is best-effort on top of that.\n if (writer || this._eventStore) {\n try {\n let eventId: string | undefined;\n if (this._eventStore) {\n eventId = await this._eventStore.storeEvent(streamId, message);\n }\n if (writer) {\n if (eventId === undefined) {\n await this.writeSSEEvent(writer, message);\n } else {\n await this.writeSSEEventWithId(writer, eventId, message);\n }\n }\n\n // Close the POST stream once all of its requests are answered\n if (requestId !== undefined && isResponse) {\n this._requestToStreamMapping.delete(requestId);\n const streamInUse = Array.from(\n this._requestToStreamMapping.values(),\n ).includes(streamId);\n if (!streamInUse) {\n this._streamMapping.delete(streamId);\n if (writer) {\n await writer.close();\n }\n }\n }\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n }\n\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n /**\n * Create an error response\n */\n private createErrorResponse(\n status: number,\n code: number,\n message: string,\n ): Response {\n return new Response(\n JSON.stringify({\n error: { code, message },\n id: null,\n jsonrpc: \"2.0\",\n }),\n {\n headers: {\n ...this.getResponseHeaders(),\n \"Content-Type\": \"application/json\",\n },\n status,\n },\n );\n }\n\n /**\n * Get common response headers\n */\n private getResponseHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this.sessionId) {\n headers[\"mcp-session-id\"] = this.sessionId;\n }\n return headers;\n }\n\n /**\n * Handles DELETE requests to terminate sessions\n */\n private async handleDeleteRequest(request: Request): Promise<Response> {\n const sessionId = request.headers.get(\"mcp-session-id\");\n\n if (this.sessionIdGenerator) {\n if (!sessionId) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n if (this.sessionId !== sessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n }\n\n // Close all streams\n for (const writer of this._streamMapping.values()) {\n try {\n await writer.close();\n } catch {\n // Ignore close errors\n }\n }\n this._streamMapping.clear();\n this.releasePendingRequests();\n\n await this._onsessionclosed?.(this.sessionId ?? \"\");\n this.sessionId = undefined;\n\n return new Response(null, {\n headers: this.getResponseHeaders(),\n status: 204,\n });\n }\n\n /**\n * Handles GET requests for SSE stream\n */\n private async handleGetRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return this.createErrorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept text/event-stream\",\n );\n }\n\n // Validate session\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (this.sessionIdGenerator && !sessionId) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n if (this.sessionIdGenerator && this.sessionId !== sessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n\n // Check for existing standalone stream\n if (this._streamMapping.has(this._standaloneSseStreamId)) {\n return this.createErrorResponse(\n 409,\n -32000,\n \"Conflict: SSE stream already exists for this session\",\n );\n }\n\n // Handle resumability\n if (this._eventStore) {\n const lastEventId = request.headers.get(\"last-event-id\");\n if (lastEventId) {\n return this.handleReplayEvents(lastEventId);\n }\n }\n\n // Create SSE stream\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n this.trackStream(this._standaloneSseStreamId, writer);\n\n return new Response(readable, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Handles POST requests containing JSON-RPC messages\n */\n private async handlePostRequest(\n request: Request,\n parsedBody?: unknown,\n ): Promise<Response> {\n // Validate Accept header\n const acceptHeader = request.headers.get(\"accept\");\n if (\n !acceptHeader?.includes(\"application/json\") &&\n !acceptHeader?.includes(\"text/event-stream\")\n ) {\n return this.createErrorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept application/json or text/event-stream\",\n );\n }\n\n // Validate Content-Type\n const contentType = request.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return this.createErrorResponse(\n 415,\n -32000,\n \"Unsupported Media Type: Content-Type must be application/json\",\n );\n }\n\n // Validate Content-Length\n const contentLength = parseInt(\n request.headers.get(\"content-length\") ?? \"0\",\n 10,\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE) {\n return this.createErrorResponse(\n 413,\n -32000,\n `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE} bytes`,\n );\n }\n\n // Parse body\n let rawMessage: unknown;\n try {\n rawMessage = parsedBody ?? (await request.json());\n } catch {\n return this.createErrorResponse(400, -32700, \"Parse error: Invalid JSON\");\n }\n\n // Handle batch or single message. The original shape decides the response\n // envelope: a batch always answers with an array, even when only one\n // response survives.\n const isBatch = Array.isArray(rawMessage);\n const arrayMessage: unknown[] = Array.isArray(rawMessage)\n ? rawMessage\n : [rawMessage];\n\n if (isBatch && arrayMessage.length === 0) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Batch must contain at least one message\",\n );\n }\n\n // Validate messages\n const messages: JSONRPCMessage[] = [];\n for (const msg of arrayMessage) {\n const result = JSONRPCMessageSchema.safeParse(msg);\n if (!result.success) {\n return this.createErrorResponse(\n 400,\n -32700,\n \"Parse error: Invalid JSON-RPC message\",\n );\n }\n messages.push(result.data);\n }\n\n // Handle session ID\n const requestSessionId = request.headers.get(\"mcp-session-id\");\n const hasInitRequest = messages.some((msg) => isInitializeRequest(msg));\n\n // Validate session requirements\n if (hasInitRequest && requestSessionId) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Initialization requests must not include a sessionId\",\n );\n }\n\n if (hasInitRequest && messages.length > 1) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Only one initialization request is allowed\",\n );\n }\n\n if (!hasInitRequest && !requestSessionId && this.sessionIdGenerator) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n // Generate or validate session ID\n if (hasInitRequest && this.sessionIdGenerator) {\n this.sessionId = this.sessionIdGenerator();\n await this._onsessioninitialized?.(this.sessionId);\n } else if (requestSessionId) {\n if (this.sessionIdGenerator && this.sessionId !== requestSessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n }\n\n const requestIds = messages\n .filter((msg) => isJSONRPCRequest(msg))\n .map((msg) => msg.id);\n const useJsonResponse =\n this._enableJsonResponse &&\n Boolean(acceptHeader?.includes(\"application/json\"));\n\n // Register the response sink before dispatching: the SDK produces\n // responses asynchronously and send() routes them back by request id.\n let jsonResponses: Promise<JSONRPCMessage[]> | undefined;\n let sseReadable: ReadableStream<Uint8Array> | undefined;\n if (requestIds.length > 0) {\n // Must be unique: a wall-clock id collides between two POSTs issued in\n // the same millisecond, which would cross-deliver their responses.\n const streamId = crypto.randomUUID();\n for (const id of requestIds) {\n this._requestToStreamMapping.set(id, streamId);\n }\n\n if (useJsonResponse) {\n jsonResponses = new Promise((resolve) => {\n this._jsonResponseCollectors.set(streamId, {\n expectedIds: requestIds,\n resolve,\n responses: new Map(),\n });\n });\n } else {\n const { readable, writable } = new TransformStream<Uint8Array>();\n this.trackStream(streamId, writable.getWriter());\n sseReadable = readable;\n }\n }\n\n // A cancelled request is never answered — the SDK suppresses the response\n // of a request whose abort signal fired — so send() never runs for its id\n // and nothing else would ever drop its routing entry. Release it here.\n for (const message of messages) {\n const cancelled = CancelledNotificationSchema.safeParse(message);\n if (cancelled.success) {\n await this.releaseCancelledRequest(cancelled.data.params.requestId);\n }\n }\n\n // Process messages through the transport\n for (const message of messages) {\n this.onmessage?.(message, { authInfo: undefined });\n }\n\n // Nothing to answer: the batch was only notifications and/or responses\n if (requestIds.length === 0) {\n return new Response(null, {\n headers: this.getResponseHeaders(),\n status: 202,\n });\n }\n\n // Return JSON response if enabled and client accepts it\n if (jsonResponses) {\n // Wait for the handlers to actually answer, however long they take\n const responses = await jsonResponses;\n\n const responseBody = JSON.stringify(isBatch ? responses : responses[0]);\n\n return new Response(responseBody, {\n headers: {\n ...this.getResponseHeaders(),\n \"Content-Type\": \"application/json\",\n },\n status: 200,\n });\n }\n\n // Return SSE stream\n return new Response(sseReadable ?? null, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Replay events for resumability\n */\n private async handleReplayEvents(lastEventId: string): Promise<Response> {\n if (!this._eventStore) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Resumability not supported\",\n );\n }\n\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n\n try {\n const streamId = await this._eventStore.replayEventsAfter(lastEventId, {\n send: async (eventId, message) => {\n await this.writeSSEEventWithId(writer, eventId, message);\n },\n });\n this.trackStream(streamId, writer);\n } catch (error) {\n await writer.close();\n return this.createErrorResponse(500, -32000, `Replay failed: ${error}`);\n }\n\n return new Response(readable, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Handles unsupported HTTP methods\n */\n private handleUnsupportedRequest(): Response {\n return this.createErrorResponse(405, -32000, \"Method not allowed\");\n }\n\n /**\n * Settle the routing state of a request the client cancelled, which will\n * therefore never produce a response: the same drain `send()` performs once\n * a response has been written, minus the response. Idempotent, so it is a\n * no-op if the response won the race against the cancellation.\n *\n * JSON-mode POSTs are left alone: `_jsonResponseCollectors` owns their\n * settlement.\n */\n private async releaseCancelledRequest(requestId: RequestId): Promise<void> {\n const streamId = this._requestToStreamMapping.get(requestId);\n if (streamId === undefined || this._jsonResponseCollectors.has(streamId)) {\n return;\n }\n\n this._requestToStreamMapping.delete(requestId);\n const streamInUse = Array.from(\n this._requestToStreamMapping.values(),\n ).includes(streamId);\n if (streamInUse) {\n return;\n }\n\n // Nothing will ever be written to this stream again; close it rather than\n // leaving the client reading a stream that can only hang.\n const writer = this._streamMapping.get(streamId);\n this._streamMapping.delete(streamId);\n if (writer) {\n try {\n await writer.close();\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n\n /**\n * Drop the routing state left over once every stream is gone, answering any\n * POST still waiting on a JSON response with whatever arrived rather than\n * leaving the request hanging.\n */\n private releasePendingRequests(): void {\n for (const collector of this._jsonResponseCollectors.values()) {\n collector.resolve(\n collector.expectedIds\n .map((id) => collector.responses.get(id))\n .filter((response) => response !== undefined),\n );\n }\n this._jsonResponseCollectors.clear();\n this._requestToStreamMapping.clear();\n }\n\n /**\n * Answer a JSON-mode POST once every request it carried has a response\n */\n private settleJsonResponse(\n streamId: StreamId,\n collector: PendingJsonResponse,\n ): void {\n const responses: JSONRPCMessage[] = [];\n for (const id of collector.expectedIds) {\n const response = collector.responses.get(id);\n if (!response) {\n // Still waiting on at least one of this POST's requests\n return;\n }\n responses.push(response);\n }\n\n this._jsonResponseCollectors.delete(streamId);\n for (const id of collector.expectedIds) {\n this._requestToStreamMapping.delete(id);\n }\n collector.resolve(responses);\n }\n\n private trackStream(\n streamId: StreamId,\n writer: WritableStreamDefaultWriter<Uint8Array>,\n ): void {\n this._streamMapping.set(streamId, writer);\n const removeStreamIfCurrent = () => {\n if (this._streamMapping.get(streamId) !== writer) {\n return;\n }\n this._streamMapping.delete(streamId);\n // With an event store, a response can still arrive after the client gave\n // up, and it must be persisted for replay. Keep the routing entry so\n // send() can resolve the stream id and store under it; send() drops the\n // entry once the response has been stored.\n if (this._eventStore) {\n return;\n }\n // No event store: nothing will be persisted for this stream, so drop the\n // routing entries now rather than leaking them. No-op for the standalone\n // GET stream, which is never a request target.\n for (const [requestId, mappedStreamId] of this._requestToStreamMapping) {\n if (mappedStreamId === streamId) {\n this._requestToStreamMapping.delete(requestId);\n }\n }\n };\n void writer.closed.then(removeStreamIfCurrent, removeStreamIfCurrent);\n }\n\n /**\n * Write an SSE event to the stream\n */\n private async writeSSEEvent(\n writer: WritableStreamDefaultWriter<Uint8Array>,\n message: JSONRPCMessage,\n ): Promise<void> {\n const data = `data: ${JSON.stringify(message)}\\n\\n`;\n await writer.write(this._encoder.encode(data));\n }\n\n /**\n * Write an SSE event with ID to the stream\n */\n private async writeSSEEventWithId(\n writer: WritableStreamDefaultWriter<Uint8Array>,\n eventId: string,\n message: JSONRPCMessage,\n ): Promise<void> {\n const data = `id: ${eventId}\\ndata: ${JSON.stringify(message)}\\n\\n`;\n await writer.write(this._encoder.encode(data));\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/edge/index.ts","../../src/edge/WebStreamableHTTPServerTransport.ts"],"sourcesContent":["/**\n * FastMCP Edge Runtime Support\n *\n * This module provides edge runtime compatibility for FastMCP, enabling\n * deployment to Cloudflare Workers, Deno Deploy, and other edge platforms.\n *\n * @example\n * ```typescript\n * // Cloudflare Workers\n * import { EdgeFastMCP } from \"fastmcp/edge\";\n * import { z } from \"zod\";\n *\n * const server = new EdgeFastMCP({ name: \"MyMCP\", version: \"1.0.0\" });\n *\n * server.addTool({\n * name: \"hello\",\n * description: \"Say hello\",\n * parameters: z.object({ name: z.string() }),\n * execute: async ({ name }) => `Hello, ${name}!`,\n * });\n *\n * export default server;\n * ```\n */\n\nimport {\n ErrorCode,\n JSONRPCMessage,\n LATEST_PROTOCOL_VERSION,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { Hono } from \"hono\";\nimport { strictJsonSchema } from \"xsschema\";\nimport { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\n\nexport { WebStreamableHTTPServerTransport } from \"./WebStreamableHTTPServerTransport.js\";\nexport type {\n EventStore,\n WebStreamableHTTPServerTransportOptions,\n} from \"./WebStreamableHTTPServerTransport.js\";\n\n/**\n * Options for EdgeFastMCP\n */\nexport interface EdgeFastMCPOptions {\n description?: string;\n logger?: EdgeLogger;\n /**\n * Base path for MCP endpoints (default: \"/mcp\")\n */\n mcpPath?: string;\n name: string;\n version: string;\n}\n\n/**\n * Type for edge runtime fetch handler\n */\nexport type EdgeFetchHandler = (request: Request) => Promise<Response>;\n\n/**\n * Logger interface for edge environments\n */\nexport interface EdgeLogger {\n debug(...args: unknown[]): void;\n error(...args: unknown[]): void;\n info(...args: unknown[]): void;\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n}\n\n/**\n * Prompt definition for EdgeFastMCP\n */\nexport interface EdgePrompt {\n arguments?: Array<{ description?: string; name: string; required?: boolean }>;\n description?: string;\n load: (args: Record<string, string>) => Promise<\n | {\n messages: Array<{\n content: { text: string; type: string };\n role: string;\n }>;\n }\n | string\n >;\n name: string;\n}\n\n/**\n * Resource definition for EdgeFastMCP\n */\nexport interface EdgeResource {\n description?: string;\n load: () => Promise<\n { blob?: string; mimeType?: string; text?: string } | string\n >;\n mimeType?: string;\n name: string;\n uri: string;\n}\n\n/**\n * Tool definition for EdgeFastMCP\n */\nexport interface EdgeTool<TParams = unknown> {\n description: string;\n execute: (params: TParams) => Promise<\n | {\n content: Array<{\n data?: string;\n mimeType?: string;\n text?: string;\n type: string;\n }>;\n }\n | string\n >;\n name: string;\n parameters?: StandardSchemaV1<TParams> | z.ZodType<TParams>;\n}\n\n/**\n * Edge-compatible FastMCP server for Cloudflare Workers, Deno, and Bun\n *\n * This is a simplified implementation optimized for stateless edge environments.\n * It uses web-standard APIs only (no Node.js dependencies).\n */\nexport class EdgeFastMCP {\n #honoApp = new Hono();\n #logger: EdgeLogger;\n #mcpPath: string;\n #name: string;\n #prompts: EdgePrompt[] = [];\n #resources: EdgeResource[] = [];\n #tools: EdgeTool[] = [];\n #version: string;\n\n constructor(options: EdgeFastMCPOptions) {\n this.#name = options.name;\n this.#version = options.version;\n this.#logger = options.logger ?? console;\n this.#mcpPath = options.mcpPath ?? \"/mcp\";\n\n this.#setupRoutes();\n }\n\n /**\n * Add a prompt to the server\n */\n addPrompt(prompt: EdgePrompt): this {\n this.#prompts.push(prompt);\n return this;\n }\n\n /**\n * Add a resource to the server\n */\n addResource(resource: EdgeResource): this {\n this.#resources.push(resource);\n return this;\n }\n\n /**\n * Add a tool to the server\n */\n addTool<TParams>(tool: EdgeTool<TParams>): this {\n this.#tools.push(tool as EdgeTool);\n return this;\n }\n\n /**\n * Handle an incoming request (main entry point for edge runtimes)\n */\n async fetch(request: Request): Promise<Response> {\n return this.#honoApp.fetch(request);\n }\n\n /**\n * Get the Hono app for adding custom routes\n */\n getApp(): Hono {\n return this.#honoApp;\n }\n\n /**\n * Create an error HTTP response\n */\n #errorResponse(status: number, code: number, message: string): Response {\n return new Response(\n JSON.stringify({\n error: { code, message },\n id: null,\n jsonrpc: \"2.0\",\n }),\n {\n headers: { \"Content-Type\": \"application/json\" },\n status,\n },\n );\n }\n\n /**\n * Handle initialize request\n */\n #handleInitialize(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n capabilities: {\n prompts: this.#prompts.length > 0 ? {} : undefined,\n resources: this.#resources.length > 0 ? {} : undefined,\n tools: this.#tools.length > 0 ? {} : undefined,\n },\n protocolVersion: LATEST_PROTOCOL_VERSION,\n serverInfo: {\n name: this.#name,\n version: this.#version,\n },\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle MCP POST requests\n */\n async #handleMcpRequest(request: Request): Promise<Response> {\n // Validate headers\n const acceptHeader = request.headers.get(\"accept\");\n if (\n !acceptHeader?.includes(\"application/json\") &&\n !acceptHeader?.includes(\"text/event-stream\")\n ) {\n return this.#errorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept application/json or text/event-stream\",\n );\n }\n\n const contentType = request.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return this.#errorResponse(\n 415,\n -32000,\n \"Unsupported Media Type: Content-Type must be application/json\",\n );\n }\n\n // Parse request body\n let body: unknown;\n try {\n body = await request.json();\n } catch {\n return this.#errorResponse(400, -32700, \"Parse error: Invalid JSON\");\n }\n\n // Handle single or batch requests\n const isBatch = Array.isArray(body);\n const messages = Array.isArray(body) ? body : [body];\n\n if (isBatch && messages.length === 0) {\n return this.#errorResponse(\n 400,\n ErrorCode.InvalidRequest,\n \"Invalid Request: Batch must contain at least one message\",\n );\n }\n\n const responses: JSONRPCMessage[] = [];\n\n for (const message of messages) {\n const response = await this.#handleMessage(message);\n if (response) {\n responses.push(response);\n }\n }\n\n // Return appropriate response format\n if (responses.length === 0) {\n return new Response(null, { status: 202 });\n }\n\n const responseBody = JSON.stringify(isBatch ? responses : responses[0]);\n\n return new Response(responseBody, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n status: 200,\n });\n }\n\n /**\n * Handle SSE GET requests\n */\n async #handleMcpSseRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return this.#errorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept text/event-stream\",\n );\n }\n\n // In stateless mode, GET requests are not supported (no server-initiated messages)\n return this.#errorResponse(\n 405,\n -32000,\n \"Method Not Allowed: SSE streams not supported in stateless mode\",\n );\n }\n\n /**\n * Handle individual MCP messages\n */\n async #handleMessage(message: unknown): Promise<JSONRPCMessage | null> {\n if (!message || typeof message !== \"object\") {\n return this.#rpcError(null, -32700, \"Parse error: Invalid message\");\n }\n\n const msg = message as {\n id?: number | string;\n jsonrpc?: string;\n method?: string;\n params?: unknown;\n };\n\n if (msg.jsonrpc !== \"2.0\") {\n return this.#rpcError(\n msg.id ?? null,\n -32600,\n \"Invalid Request: jsonrpc must be 2.0\",\n );\n }\n\n // Handle notifications (no response expected)\n if (!(\"id\" in msg) || msg.id === undefined) {\n return null;\n }\n\n const method = msg.method;\n const id = msg.id;\n const params = msg.params as Record<string, unknown> | undefined;\n\n try {\n switch (method) {\n case \"initialize\":\n return this.#handleInitialize(id);\n\n case \"ping\":\n return { id, jsonrpc: \"2.0\", result: {} } as JSONRPCMessage;\n\n case \"prompts/get\":\n return this.#handlePromptsGet(id, params);\n\n case \"prompts/list\":\n return this.#handlePromptsList(id);\n\n case \"resources/list\":\n return this.#handleResourcesList(id);\n\n case \"resources/read\":\n return this.#handleResourcesRead(id, params);\n\n case \"tools/call\":\n return this.#handleToolsCall(id, params);\n\n case \"tools/list\":\n return this.#handleToolsList(id);\n\n default:\n return this.#rpcError(id, -32601, `Method not found: ${method}`);\n }\n } catch (error) {\n this.#logger.error(`Error handling ${method}:`, error);\n return this.#rpcError(\n id,\n -32603,\n `Internal error: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle prompts/get request\n */\n async #handlePromptsGet(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const promptName = params?.name as string;\n const promptArgs = params?.arguments as Record<string, string> | undefined;\n\n const prompt = this.#prompts.find((p) => p.name === promptName);\n if (!prompt) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Prompt not found: ${promptName}`,\n );\n }\n\n try {\n const result = await prompt.load(promptArgs ?? {});\n const messages =\n typeof result === \"string\"\n ? [{ content: { text: result, type: \"text\" }, role: \"user\" }]\n : result.messages;\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { messages },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Prompt load failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle prompts/list request\n */\n #handlePromptsList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n prompts: this.#prompts.map((p) => ({\n arguments: p.arguments,\n description: p.description,\n name: p.name,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle resources/list request\n */\n #handleResourcesList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n resources: this.#resources.map((r) => ({\n description: r.description,\n mimeType: r.mimeType,\n name: r.name,\n uri: r.uri,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Handle resources/read request\n */\n async #handleResourcesRead(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const uri = params?.uri as string;\n const resource = this.#resources.find((r) => r.uri === uri);\n\n if (!resource) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Resource not found: ${uri}`,\n );\n }\n\n try {\n const result = await resource.load();\n const content =\n typeof result === \"string\"\n ? { mimeType: resource.mimeType ?? \"text/plain\", text: result, uri }\n : { uri, ...result };\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { contents: [content] },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Resource load failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle tools/call request\n */\n async #handleToolsCall(\n id: number | string,\n params?: Record<string, unknown>,\n ): Promise<JSONRPCMessage> {\n const toolName = params?.name as string;\n const toolArgs = params?.arguments as Record<string, unknown> | undefined;\n\n const tool = this.#tools.find((t) => t.name === toolName);\n if (!tool) {\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Tool not found: ${toolName}`,\n );\n }\n\n let args: unknown = toolArgs ?? {};\n\n if (tool.parameters) {\n let parsed: StandardSchemaV1.Result<unknown>;\n\n try {\n parsed = await tool.parameters[\"~standard\"].validate(toolArgs);\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Tool '${toolName}' parameter validation failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (parsed.issues) {\n const friendlyErrors = parsed.issues\n .map((issue) => {\n const path = issue.path?.join(\".\") || \"root\";\n return `${path}: ${issue.message}`;\n })\n .join(\", \");\n\n return this.#rpcError(\n id,\n ErrorCode.InvalidParams,\n `Tool '${toolName}' parameter validation failed: ${friendlyErrors}. Please check the parameter types and values according to the tool's schema.`,\n );\n }\n\n args = parsed.value;\n }\n\n try {\n const result = await tool.execute(args);\n\n // Normalize result to content array\n const content =\n typeof result === \"string\"\n ? [{ text: result, type: \"text\" }]\n : result.content;\n\n return {\n id,\n jsonrpc: \"2.0\",\n result: { content },\n } as JSONRPCMessage;\n } catch (error) {\n return this.#rpcError(\n id,\n ErrorCode.InternalError,\n `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n /**\n * Handle tools/list request\n */\n #handleToolsList(id: number | string): JSONRPCMessage {\n return {\n id,\n jsonrpc: \"2.0\",\n result: {\n tools: this.#tools.map((tool) => ({\n description: tool.description,\n inputSchema: tool.parameters\n ? this.#schemaToJsonSchema(tool.parameters)\n : { type: \"object\" },\n name: tool.name,\n })),\n },\n } as JSONRPCMessage;\n }\n\n /**\n * Create an RPC error message\n */\n #rpcError(\n id: null | number | string,\n code: number,\n message: string,\n ): JSONRPCMessage {\n return {\n error: { code, message },\n id,\n jsonrpc: \"2.0\",\n } as JSONRPCMessage;\n }\n\n /**\n * Convert schema to JSON Schema\n */\n #schemaToJsonSchema(\n schema: StandardSchemaV1 | z.ZodType,\n ): Record<string, unknown> {\n try {\n // Zod 4+: use native toJSONSchema if available\n /* eslint-disable @typescript-eslint/no-explicit-any */\n if (typeof (z as any).toJSONSchema === \"function\") {\n return strictJsonSchema(\n (z as any).toJSONSchema(schema) as Record<string, unknown>,\n ) as Record<string, unknown>;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n // Zod 3 fallback: use zod-to-json-schema\n /* eslint-disable @typescript-eslint/no-explicit-any */\n if (\"_def\" in (schema as any) || schema instanceof z.ZodType) {\n return strictJsonSchema(\n zodToJsonSchema(schema as any, { target: \"openApi3\" }) as Record<\n string,\n unknown\n >,\n ) as Record<string, unknown>;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n // For StandardSchema, fall back to a generic object schema\n return { type: \"object\" };\n } catch {\n return { type: \"object\" };\n }\n }\n\n /**\n * Set up MCP and health routes\n */\n #setupRoutes(): void {\n // Health endpoint\n this.#honoApp.get(\"/health\", (c) => c.text(\"✓ Ok\"));\n\n // MCP endpoint - handles all MCP protocol messages\n this.#honoApp.post(this.#mcpPath, async (c) => {\n return this.#handleMcpRequest(c.req.raw);\n });\n\n // MCP GET endpoint for SSE streams (server-initiated messages)\n this.#honoApp.get(this.#mcpPath, async (c) => {\n return this.#handleMcpSseRequest(c.req.raw);\n });\n\n // MCP DELETE endpoint for session termination\n this.#honoApp.delete(this.#mcpPath, async () => {\n return new Response(null, { status: 204 });\n });\n }\n}\n","/**\n * Web-standard Streamable HTTP Server Transport for MCP\n *\n * This transport implements the MCP Streamable HTTP specification using\n * web standard APIs (Request, Response, TransformStream) for compatibility\n * with edge runtimes like Cloudflare Workers, Deno, and Bun.\n */\n\nimport { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n CancelledNotificationSchema,\n isInitializeRequest,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n JSONRPCMessage,\n JSONRPCMessageSchema,\n MessageExtraInfo,\n RequestId,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type EventId = string;\n/**\n * Interface for resumability support via event storage\n */\nexport interface EventStore {\n getStreamIdForEventId?(eventId: EventId): Promise<StreamId | undefined>;\n replayEventsAfter(\n lastEventId: EventId,\n options: {\n send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;\n },\n ): Promise<StreamId>;\n storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;\n}\n\nexport type StreamId = string;\n\n/**\n * Configuration options for WebStreamableHTTPServerTransport\n */\nexport interface WebStreamableHTTPServerTransportOptions {\n /**\n * If true, return JSON responses instead of SSE streams\n */\n enableJsonResponse?: boolean;\n\n /**\n * Event store for resumability support\n */\n eventStore?: EventStore;\n\n /**\n * Callback for session close events\n */\n onsessionclosed?: (sessionId: string) => Promise<void> | void;\n\n /**\n * Callback for session initialization events\n */\n onsessioninitialized?: (sessionId: string) => Promise<void> | void;\n\n /**\n * Function that generates a session ID for the transport.\n * Return undefined to disable session management (stateless mode).\n */\n sessionIdGenerator: (() => string) | undefined;\n}\n\n/**\n * Collects the responses to every request that arrived on a single POST, so\n * that JSON mode can answer once all of them are in.\n */\ninterface PendingJsonResponse {\n expectedIds: RequestId[];\n resolve: (responses: JSONRPCMessage[]) => void;\n responses: Map<RequestId, JSONRPCMessage>;\n}\n\nconst MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024; // 4MB\n\n/**\n * Web-standard Server transport for Streamable HTTP.\n * Uses web APIs (Request, Response, TransformStream) for edge runtime compatibility.\n */\nexport class WebStreamableHTTPServerTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n sessionId?: string;\n private _enableJsonResponse = false;\n private _encoder = new TextEncoder();\n private _eventStore?: EventStore;\n private _jsonResponseCollectors = new Map<StreamId, PendingJsonResponse>();\n private _onsessionclosed?: (sessionId: string) => Promise<void> | void;\n private _onsessioninitialized?: (sessionId: string) => Promise<void> | void;\n /**\n * Replays whose stream id is still being resolved. `replayEventsAfter` only\n * reveals which stream it was replaying once it settles, so a standalone\n * send during that window has nothing to test against; persist rather than\n * drop, since over-storing for the length of a replay beats losing an event.\n */\n private _replaysInFlight = 0;\n\n private _requestToStreamMapping = new Map<RequestId, StreamId>();\n\n private _standaloneSseStreamId = \"_GET_stream\";\n /**\n * Whether a client has held the standalone GET stream during this session.\n * Latched rather than read from `_streamMapping`, so persistence survives\n * the disconnect window the store exists to cover while still telling a\n * dropped stream apart from one that was never opened. Reset with the rest\n * of the per-session state, since the next session starts with no stream.\n */\n private _standaloneStreamOpened = false;\n private _started = false;\n private _streamMapping = new Map<\n StreamId,\n WritableStreamDefaultWriter<Uint8Array>\n >();\n private sessionIdGenerator: (() => string) | undefined;\n\n constructor(options: WebStreamableHTTPServerTransportOptions) {\n this.sessionIdGenerator = options.sessionIdGenerator;\n this._enableJsonResponse = options.enableJsonResponse ?? false;\n this._eventStore = options.eventStore;\n this._onsessioninitialized = options.onsessioninitialized;\n this._onsessionclosed = options.onsessionclosed;\n }\n\n /**\n * Close the transport\n */\n async close(): Promise<void> {\n for (const writer of this._streamMapping.values()) {\n try {\n await writer.close();\n } catch {\n // Ignore close errors\n }\n }\n this._streamMapping.clear();\n this._standaloneStreamOpened = false;\n this.releasePendingRequests();\n this._started = false;\n this.onclose?.();\n }\n\n /**\n * Handles an incoming web Request and returns a Response\n */\n async handleRequest(\n request: Request,\n parsedBody?: unknown,\n ): Promise<Response> {\n const method = request.method;\n\n if (method === \"POST\") {\n return this.handlePostRequest(request, parsedBody);\n } else if (method === \"GET\") {\n return this.handleGetRequest(request);\n } else if (method === \"DELETE\") {\n return this.handleDeleteRequest(request);\n } else {\n return this.handleUnsupportedRequest();\n }\n }\n\n /**\n * Send a message to connected clients\n */\n async send(\n message: JSONRPCMessage,\n options?: { relatedRequestId?: RequestId },\n ): Promise<void> {\n let requestId = options?.relatedRequestId;\n const isResponse = isJSONRPCResponse(message) || isJSONRPCError(message);\n if (isResponse) {\n // Responses are routed by the id of the request they answer\n requestId = message.id;\n }\n\n const streamId =\n requestId === undefined\n ? this._standaloneSseStreamId\n : this._requestToStreamMapping.get(requestId);\n\n if (streamId) {\n // JSON mode has no stream to write to: collect the responses instead and\n // let handlePostRequest answer once every request on this POST is done.\n const collector = this._jsonResponseCollectors.get(streamId);\n if (collector) {\n if (isResponse && requestId !== undefined) {\n collector.responses.set(requestId, message);\n this.settleJsonResponse(streamId, collector);\n }\n return;\n }\n\n const writer = this._streamMapping.get(streamId);\n // With an event store the message must be persisted even if the client\n // has already disconnected, so a reconnect with Last-Event-Id can replay\n // it. The live write to the SSE stream is best-effort on top of that.\n const store = this.shouldPersist(streamId, writer)\n ? this._eventStore\n : undefined;\n\n if (writer || store) {\n try {\n let eventId: string | undefined;\n if (store) {\n eventId = await store.storeEvent(streamId, message);\n }\n if (writer) {\n if (eventId === undefined) {\n await this.writeSSEEvent(writer, message);\n } else {\n await this.writeSSEEventWithId(writer, eventId, message);\n }\n }\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n\n // Close the POST stream once all of its requests are answered. Drained\n // whether or not the store and the socket cooperated: with an event\n // store configured `trackStream` deliberately leaves routing entries\n // alone on disconnect, so this is the only thing that reclaims them,\n // and giving up on a failed write strands the entry until the session\n // ends.\n if (requestId !== undefined && isResponse) {\n this._requestToStreamMapping.delete(requestId);\n const streamInUse = Array.from(\n this._requestToStreamMapping.values(),\n ).includes(streamId);\n if (!streamInUse) {\n this._streamMapping.delete(streamId);\n if (writer) {\n try {\n await writer.close();\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n }\n }\n }\n }\n\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n /**\n * Create an error response\n */\n private createErrorResponse(\n status: number,\n code: number,\n message: string,\n ): Response {\n return new Response(\n JSON.stringify({\n error: { code, message },\n id: null,\n jsonrpc: \"2.0\",\n }),\n {\n headers: {\n ...this.getResponseHeaders(),\n \"Content-Type\": \"application/json\",\n },\n status,\n },\n );\n }\n\n /**\n * Get common response headers\n */\n private getResponseHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n if (this.sessionId) {\n headers[\"mcp-session-id\"] = this.sessionId;\n }\n return headers;\n }\n\n /**\n * Handles DELETE requests to terminate sessions\n */\n private async handleDeleteRequest(request: Request): Promise<Response> {\n const sessionId = request.headers.get(\"mcp-session-id\");\n\n if (this.sessionIdGenerator) {\n if (!sessionId) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n if (this.sessionId !== sessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n }\n\n // Close all streams\n for (const writer of this._streamMapping.values()) {\n try {\n await writer.close();\n } catch {\n // Ignore close errors\n }\n }\n this._streamMapping.clear();\n // Per-session, like the session id below: this instance stays usable, and\n // the next session starts having opened no standalone stream of its own.\n this._standaloneStreamOpened = false;\n this.releasePendingRequests();\n\n await this._onsessionclosed?.(this.sessionId ?? \"\");\n this.sessionId = undefined;\n\n return new Response(null, {\n headers: this.getResponseHeaders(),\n status: 204,\n });\n }\n\n /**\n * Handles GET requests for SSE stream\n */\n private async handleGetRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return this.createErrorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept text/event-stream\",\n );\n }\n\n // Validate session\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (this.sessionIdGenerator && !sessionId) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n if (this.sessionIdGenerator && this.sessionId !== sessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n\n // Check for existing standalone stream\n if (this._streamMapping.has(this._standaloneSseStreamId)) {\n return this.createErrorResponse(\n 409,\n -32000,\n \"Conflict: SSE stream already exists for this session\",\n );\n }\n\n // Handle resumability\n if (this._eventStore) {\n const lastEventId = request.headers.get(\"last-event-id\");\n if (lastEventId) {\n return this.handleReplayEvents(lastEventId);\n }\n }\n\n // Create SSE stream\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n this.trackStream(this._standaloneSseStreamId, writer);\n\n return new Response(readable, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Handles POST requests containing JSON-RPC messages\n */\n private async handlePostRequest(\n request: Request,\n parsedBody?: unknown,\n ): Promise<Response> {\n // Validate Accept header\n const acceptHeader = request.headers.get(\"accept\");\n if (\n !acceptHeader?.includes(\"application/json\") &&\n !acceptHeader?.includes(\"text/event-stream\")\n ) {\n return this.createErrorResponse(\n 406,\n -32000,\n \"Not Acceptable: Client must accept application/json or text/event-stream\",\n );\n }\n\n // Validate Content-Type\n const contentType = request.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return this.createErrorResponse(\n 415,\n -32000,\n \"Unsupported Media Type: Content-Type must be application/json\",\n );\n }\n\n // Validate Content-Length\n const contentLength = parseInt(\n request.headers.get(\"content-length\") ?? \"0\",\n 10,\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE) {\n return this.createErrorResponse(\n 413,\n -32000,\n `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE} bytes`,\n );\n }\n\n // Parse body\n let rawMessage: unknown;\n try {\n rawMessage = parsedBody ?? (await request.json());\n } catch {\n return this.createErrorResponse(400, -32700, \"Parse error: Invalid JSON\");\n }\n\n // Handle batch or single message. The original shape decides the response\n // envelope: a batch always answers with an array, even when only one\n // response survives.\n const isBatch = Array.isArray(rawMessage);\n const arrayMessage: unknown[] = Array.isArray(rawMessage)\n ? rawMessage\n : [rawMessage];\n\n if (isBatch && arrayMessage.length === 0) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Batch must contain at least one message\",\n );\n }\n\n // Validate messages\n const messages: JSONRPCMessage[] = [];\n for (const msg of arrayMessage) {\n const result = JSONRPCMessageSchema.safeParse(msg);\n if (!result.success) {\n return this.createErrorResponse(\n 400,\n -32700,\n \"Parse error: Invalid JSON-RPC message\",\n );\n }\n messages.push(result.data);\n }\n\n // Handle session ID\n const requestSessionId = request.headers.get(\"mcp-session-id\");\n const hasInitRequest = messages.some((msg) => isInitializeRequest(msg));\n\n // Validate session requirements\n if (hasInitRequest && requestSessionId) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Initialization requests must not include a sessionId\",\n );\n }\n\n if (hasInitRequest && messages.length > 1) {\n return this.createErrorResponse(\n 400,\n -32600,\n \"Invalid Request: Only one initialization request is allowed\",\n );\n }\n\n if (!hasInitRequest && !requestSessionId && this.sessionIdGenerator) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Bad Request: Mcp-Session-Id header is required\",\n );\n }\n\n // Generate or validate session ID\n if (hasInitRequest && this.sessionIdGenerator) {\n this.sessionId = this.sessionIdGenerator();\n await this._onsessioninitialized?.(this.sessionId);\n } else if (requestSessionId) {\n if (this.sessionIdGenerator && this.sessionId !== requestSessionId) {\n return this.createErrorResponse(404, -32001, \"Session not found\");\n }\n }\n\n const requestIds = messages\n .filter((msg) => isJSONRPCRequest(msg))\n .map((msg) => msg.id);\n const useJsonResponse =\n this._enableJsonResponse &&\n Boolean(acceptHeader?.includes(\"application/json\"));\n\n // Register the response sink before dispatching: the SDK produces\n // responses asynchronously and send() routes them back by request id.\n let jsonResponses: Promise<JSONRPCMessage[]> | undefined;\n let sseReadable: ReadableStream<Uint8Array> | undefined;\n if (requestIds.length > 0) {\n // Must be unique: a wall-clock id collides between two POSTs issued in\n // the same millisecond, which would cross-deliver their responses.\n const streamId = crypto.randomUUID();\n for (const id of requestIds) {\n this._requestToStreamMapping.set(id, streamId);\n }\n\n if (useJsonResponse) {\n jsonResponses = new Promise((resolve) => {\n this._jsonResponseCollectors.set(streamId, {\n expectedIds: requestIds,\n resolve,\n responses: new Map(),\n });\n });\n } else {\n const { readable, writable } = new TransformStream<Uint8Array>();\n this.trackStream(streamId, writable.getWriter());\n sseReadable = readable;\n }\n }\n\n // A cancelled request is never answered — the SDK suppresses the response\n // of a request whose abort signal fired — so send() never runs for its id\n // and nothing else would ever drop its routing entry. Release it here.\n for (const message of messages) {\n const cancelled = CancelledNotificationSchema.safeParse(message);\n if (cancelled.success) {\n await this.releaseCancelledRequest(cancelled.data.params.requestId);\n }\n }\n\n // Process messages through the transport\n for (const message of messages) {\n this.onmessage?.(message, { authInfo: undefined });\n }\n\n // Nothing to answer: the batch was only notifications and/or responses\n if (requestIds.length === 0) {\n return new Response(null, {\n headers: this.getResponseHeaders(),\n status: 202,\n });\n }\n\n // Return JSON response if enabled and client accepts it\n if (jsonResponses) {\n // Wait for the handlers to actually answer, however long they take\n const responses = await jsonResponses;\n\n const responseBody = JSON.stringify(isBatch ? responses : responses[0]);\n\n return new Response(responseBody, {\n headers: {\n ...this.getResponseHeaders(),\n \"Content-Type\": \"application/json\",\n },\n status: 200,\n });\n }\n\n // Return SSE stream\n return new Response(sseReadable ?? null, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Replay events for resumability\n */\n private async handleReplayEvents(lastEventId: string): Promise<Response> {\n if (!this._eventStore) {\n return this.createErrorResponse(\n 400,\n -32000,\n \"Resumability not supported\",\n );\n }\n\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n\n this._replaysInFlight += 1;\n try {\n const streamId = await this._eventStore.replayEventsAfter(lastEventId, {\n send: async (eventId, message) => {\n await this.writeSSEEventWithId(writer, eventId, message);\n },\n });\n this.trackStream(streamId, writer);\n } catch (error) {\n await writer.close();\n return this.createErrorResponse(500, -32000, `Replay failed: ${error}`);\n } finally {\n this._replaysInFlight -= 1;\n }\n\n return new Response(readable, {\n headers: {\n ...this.getResponseHeaders(),\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n },\n status: 200,\n });\n }\n\n /**\n * Handles unsupported HTTP methods\n */\n private handleUnsupportedRequest(): Response {\n return this.createErrorResponse(405, -32000, \"Method not allowed\");\n }\n\n /**\n * Settle the routing state of a request the client cancelled, which will\n * therefore never produce a response: the same drain `send()` performs once\n * a response has been written, minus the response. Idempotent, so it is a\n * no-op if the response won the race against the cancellation.\n *\n * JSON-mode POSTs are left alone: `_jsonResponseCollectors` owns their\n * settlement.\n */\n private async releaseCancelledRequest(requestId: RequestId): Promise<void> {\n const streamId = this._requestToStreamMapping.get(requestId);\n if (streamId === undefined || this._jsonResponseCollectors.has(streamId)) {\n return;\n }\n\n this._requestToStreamMapping.delete(requestId);\n const streamInUse = Array.from(\n this._requestToStreamMapping.values(),\n ).includes(streamId);\n if (streamInUse) {\n return;\n }\n\n // Nothing will ever be written to this stream again; close it rather than\n // leaving the client reading a stream that can only hang.\n const writer = this._streamMapping.get(streamId);\n this._streamMapping.delete(streamId);\n if (writer) {\n try {\n await writer.close();\n } catch (error) {\n this.onerror?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n }\n\n /**\n * Drop the routing state left over once every stream is gone, answering any\n * POST still waiting on a JSON response with whatever arrived rather than\n * leaving the request hanging.\n */\n private releasePendingRequests(): void {\n for (const collector of this._jsonResponseCollectors.values()) {\n collector.resolve(\n collector.expectedIds\n .map((id) => collector.responses.get(id))\n .filter((response) => response !== undefined),\n );\n }\n this._jsonResponseCollectors.clear();\n this._requestToStreamMapping.clear();\n }\n\n /**\n * Answer a JSON-mode POST once every request it carried has a response\n */\n private settleJsonResponse(\n streamId: StreamId,\n collector: PendingJsonResponse,\n ): void {\n const responses: JSONRPCMessage[] = [];\n for (const id of collector.expectedIds) {\n const response = collector.responses.get(id);\n if (!response) {\n // Still waiting on at least one of this POST's requests\n return;\n }\n responses.push(response);\n }\n\n this._jsonResponseCollectors.delete(streamId);\n for (const id of collector.expectedIds) {\n this._requestToStreamMapping.delete(id);\n }\n collector.resolve(responses);\n }\n\n /**\n * Whether an event addressed to `streamId` should go to the event store.\n *\n * Everything but the standalone stream is persisted whenever a store is\n * configured: those ids exist only because their stream did. The standalone\n * id is a constant, so it resolves whether or not a client ever opened that\n * stream, and storing before the first GET writes events nothing can reach —\n * replay is keyed off Last-Event-Id, and a client that never held the stream\n * was never handed an id to resume from.\n */\n private shouldPersist(\n streamId: StreamId,\n writer: undefined | WritableStreamDefaultWriter<Uint8Array>,\n ): boolean {\n if (this._eventStore === undefined) {\n return false;\n }\n\n if (streamId !== this._standaloneSseStreamId) {\n return true;\n }\n\n return (\n this._standaloneStreamOpened ||\n // A live writer means the stream is open now, which is stronger evidence\n // than the latch. Belt and braces: it keeps a writer reaching this point\n // without `trackStream` from producing an SSE event with no `id:`.\n writer !== undefined ||\n this._replaysInFlight > 0\n );\n }\n\n private trackStream(\n streamId: StreamId,\n writer: WritableStreamDefaultWriter<Uint8Array>,\n ): void {\n // Latched here rather than at each call site so a new way of opening the\n // standalone stream cannot forget to record it.\n if (streamId === this._standaloneSseStreamId) {\n this._standaloneStreamOpened = true;\n }\n this._streamMapping.set(streamId, writer);\n const removeStreamIfCurrent = () => {\n if (this._streamMapping.get(streamId) !== writer) {\n return;\n }\n this._streamMapping.delete(streamId);\n // With an event store, a response can still arrive after the client gave\n // up, and it must be persisted for replay. Keep the routing entry so\n // send() can resolve the stream id and store under it; send() drops the\n // entry once the response has been stored.\n if (this._eventStore) {\n return;\n }\n // No event store: nothing will be persisted for this stream, so drop the\n // routing entries now rather than leaking them. No-op for the standalone\n // GET stream, which is never a request target.\n for (const [requestId, mappedStreamId] of this._requestToStreamMapping) {\n if (mappedStreamId === streamId) {\n this._requestToStreamMapping.delete(requestId);\n }\n }\n };\n void writer.closed.then(removeStreamIfCurrent, removeStreamIfCurrent);\n }\n\n /**\n * Write an SSE event to the stream\n */\n private async writeSSEEvent(\n writer: WritableStreamDefaultWriter<Uint8Array>,\n message: JSONRPCMessage,\n ): Promise<void> {\n const data = `data: ${JSON.stringify(message)}\\n\\n`;\n await writer.write(this._encoder.encode(data));\n }\n\n /**\n * Write an SSE event with ID to the stream\n */\n private async writeSSEEventWithId(\n writer: WritableStreamDefaultWriter<Uint8Array>,\n eventId: string,\n message: JSONRPCMessage,\n ): Promise<void> {\n const data = `id: ${eventId}\\ndata: ${JSON.stringify(message)}\\n\\n`;\n await writer.write(this._encoder.encode(data));\n }\n}\n"],"mappings":";AAyBA;AAAA,EACE;AAAA,EAEA;AAAA,OACK;AAEP,SAAS,YAAY;AACrB,SAAS,wBAAwB;AACjC,SAAS,SAAS;AAClB,SAAS,uBAAuB;;;ACzBhC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OAGK;AA4DP,IAAM,uBAAuB,IAAI,OAAO;AAMjC,IAAM,mCAAN,MAA4D;AAAA,EACjE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACQ,sBAAsB;AAAA,EACtB,WAAW,IAAI,YAAY;AAAA,EAC3B;AAAA,EACA,0BAA0B,oBAAI,IAAmC;AAAA,EACjE;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB;AAAA,EAEnB,0BAA0B,oBAAI,IAAyB;AAAA,EAEvD,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzB,0BAA0B;AAAA,EAC1B,WAAW;AAAA,EACX,iBAAiB,oBAAI,IAG3B;AAAA,EACM;AAAA,EAER,YAAY,SAAkD;AAC5D,SAAK,qBAAqB,QAAQ;AAClC,SAAK,sBAAsB,QAAQ,sBAAsB;AACzD,SAAK,cAAc,QAAQ;AAC3B,SAAK,wBAAwB,QAAQ;AACrC,SAAK,mBAAmB,QAAQ;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,eAAW,UAAU,KAAK,eAAe,OAAO,GAAG;AACjD,UAAI;AACF,cAAM,OAAO,MAAM;AAAA,MACrB,QAAQ;AAAA,MAER;AAAA,IACF;AACA,SAAK,eAAe,MAAM;AAC1B,SAAK,0BAA0B;AAC/B,SAAK,uBAAuB;AAC5B,SAAK,WAAW;AAChB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cACJ,SACA,YACmB;AACnB,UAAM,SAAS,QAAQ;AAEvB,QAAI,WAAW,QAAQ;AACrB,aAAO,KAAK,kBAAkB,SAAS,UAAU;AAAA,IACnD,WAAW,WAAW,OAAO;AAC3B,aAAO,KAAK,iBAAiB,OAAO;AAAA,IACtC,WAAW,WAAW,UAAU;AAC9B,aAAO,KAAK,oBAAoB,OAAO;AAAA,IACzC,OAAO;AACL,aAAO,KAAK,yBAAyB;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KACJ,SACA,SACe;AACf,QAAI,YAAY,SAAS;AACzB,UAAM,aAAa,kBAAkB,OAAO,KAAK,eAAe,OAAO;AACvE,QAAI,YAAY;AAEd,kBAAY,QAAQ;AAAA,IACtB;AAEA,UAAM,WACJ,cAAc,SACV,KAAK,yBACL,KAAK,wBAAwB,IAAI,SAAS;AAEhD,QAAI,UAAU;AAGZ,YAAM,YAAY,KAAK,wBAAwB,IAAI,QAAQ;AAC3D,UAAI,WAAW;AACb,YAAI,cAAc,cAAc,QAAW;AACzC,oBAAU,UAAU,IAAI,WAAW,OAAO;AAC1C,eAAK,mBAAmB,UAAU,SAAS;AAAA,QAC7C;AACA;AAAA,MACF;AAEA,YAAM,SAAS,KAAK,eAAe,IAAI,QAAQ;AAI/C,YAAM,QAAQ,KAAK,cAAc,UAAU,MAAM,IAC7C,KAAK,cACL;AAEJ,UAAI,UAAU,OAAO;AACnB,YAAI;AACF,cAAI;AACJ,cAAI,OAAO;AACT,sBAAU,MAAM,MAAM,WAAW,UAAU,OAAO;AAAA,UACpD;AACA,cAAI,QAAQ;AACV,gBAAI,YAAY,QAAW;AACzB,oBAAM,KAAK,cAAc,QAAQ,OAAO;AAAA,YAC1C,OAAO;AACL,oBAAM,KAAK,oBAAoB,QAAQ,SAAS,OAAO;AAAA,YACzD;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,eAAK;AAAA,YACH,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,UAC1D;AAAA,QACF;AAQA,YAAI,cAAc,UAAa,YAAY;AACzC,eAAK,wBAAwB,OAAO,SAAS;AAC7C,gBAAM,cAAc,MAAM;AAAA,YACxB,KAAK,wBAAwB,OAAO;AAAA,UACtC,EAAE,SAAS,QAAQ;AACnB,cAAI,CAAC,aAAa;AAChB,iBAAK,eAAe,OAAO,QAAQ;AACnC,gBAAI,QAAQ;AACV,kBAAI;AACF,sBAAM,OAAO,MAAM;AAAA,cACrB,SAAS,OAAO;AACd,qBAAK;AAAA,kBACH,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,gBAC1D;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK,UAAU;AACjB,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKQ,oBACN,QACA,MACA,SACU;AACV,WAAO,IAAI;AAAA,MACT,KAAK,UAAU;AAAA,QACb,OAAO,EAAE,MAAM,QAAQ;AAAA,QACvB,IAAI;AAAA,QACJ,SAAS;AAAA,MACX,CAAC;AAAA,MACD;AAAA,QACE,SAAS;AAAA,UACP,GAAG,KAAK,mBAAmB;AAAA,UAC3B,gBAAgB;AAAA,QAClB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAA6C;AACnD,UAAM,UAAkC,CAAC;AACzC,QAAI,KAAK,WAAW;AAClB,cAAQ,gBAAgB,IAAI,KAAK;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,oBAAoB,SAAqC;AACrE,UAAM,YAAY,QAAQ,QAAQ,IAAI,gBAAgB;AAEtD,QAAI,KAAK,oBAAoB;AAC3B,UAAI,CAAC,WAAW;AACd,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI,KAAK,cAAc,WAAW;AAChC,eAAO,KAAK,oBAAoB,KAAK,QAAQ,mBAAmB;AAAA,MAClE;AAAA,IACF;AAGA,eAAW,UAAU,KAAK,eAAe,OAAO,GAAG;AACjD,UAAI;AACF,cAAM,OAAO,MAAM;AAAA,MACrB,QAAQ;AAAA,MAER;AAAA,IACF;AACA,SAAK,eAAe,MAAM;AAG1B,SAAK,0BAA0B;AAC/B,SAAK,uBAAuB;AAE5B,UAAM,KAAK,mBAAmB,KAAK,aAAa,EAAE;AAClD,SAAK,YAAY;AAEjB,WAAO,IAAI,SAAS,MAAM;AAAA,MACxB,SAAS,KAAK,mBAAmB;AAAA,MACjC,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAiB,SAAqC;AAClE,UAAM,eAAe,QAAQ,QAAQ,IAAI,QAAQ;AACjD,QAAI,CAAC,cAAc,SAAS,mBAAmB,GAAG;AAChD,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,QAAQ,QAAQ,IAAI,gBAAgB;AACtD,QAAI,KAAK,sBAAsB,CAAC,WAAW;AACzC,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,sBAAsB,KAAK,cAAc,WAAW;AAC3D,aAAO,KAAK,oBAAoB,KAAK,QAAQ,mBAAmB;AAAA,IAClE;AAGA,QAAI,KAAK,eAAe,IAAI,KAAK,sBAAsB,GAAG;AACxD,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,aAAa;AACpB,YAAM,cAAc,QAAQ,QAAQ,IAAI,eAAe;AACvD,UAAI,aAAa;AACf,eAAO,KAAK,mBAAmB,WAAW;AAAA,MAC5C;AAAA,IACF;AAGA,UAAM,EAAE,UAAU,SAAS,IAAI,IAAI,gBAA4B;AAC/D,UAAM,SAAS,SAAS,UAAU;AAClC,SAAK,YAAY,KAAK,wBAAwB,MAAM;AAEpD,WAAO,IAAI,SAAS,UAAU;AAAA,MAC5B,SAAS;AAAA,QACP,GAAG,KAAK,mBAAmB;AAAA,QAC3B,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBACZ,SACA,YACmB;AAEnB,UAAM,eAAe,QAAQ,QAAQ,IAAI,QAAQ;AACjD,QACE,CAAC,cAAc,SAAS,kBAAkB,KAC1C,CAAC,cAAc,SAAS,mBAAmB,GAC3C;AACA,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,cAAc,QAAQ,QAAQ,IAAI,cAAc;AACtD,QAAI,CAAC,aAAa,SAAS,kBAAkB,GAAG;AAC9C,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,gBAAgB;AAAA,MACpB,QAAQ,QAAQ,IAAI,gBAAgB,KAAK;AAAA,MACzC;AAAA,IACF;AACA,QAAI,gBAAgB,sBAAsB;AACxC,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA,2CAA2C,oBAAoB;AAAA,MACjE;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,mBAAa,cAAe,MAAM,QAAQ,KAAK;AAAA,IACjD,QAAQ;AACN,aAAO,KAAK,oBAAoB,KAAK,QAAQ,2BAA2B;AAAA,IAC1E;AAKA,UAAM,UAAU,MAAM,QAAQ,UAAU;AACxC,UAAM,eAA0B,MAAM,QAAQ,UAAU,IACpD,aACA,CAAC,UAAU;AAEf,QAAI,WAAW,aAAa,WAAW,GAAG;AACxC,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAA6B,CAAC;AACpC,eAAW,OAAO,cAAc;AAC9B,YAAM,SAAS,qBAAqB,UAAU,GAAG;AACjD,UAAI,CAAC,OAAO,SAAS;AACnB,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,eAAS,KAAK,OAAO,IAAI;AAAA,IAC3B;AAGA,UAAM,mBAAmB,QAAQ,QAAQ,IAAI,gBAAgB;AAC7D,UAAM,iBAAiB,SAAS,KAAK,CAAC,QAAQ,oBAAoB,GAAG,CAAC;AAGtE,QAAI,kBAAkB,kBAAkB;AACtC,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,kBAAkB,SAAS,SAAS,GAAG;AACzC,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,kBAAkB,CAAC,oBAAoB,KAAK,oBAAoB;AACnE,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,QAAI,kBAAkB,KAAK,oBAAoB;AAC7C,WAAK,YAAY,KAAK,mBAAmB;AACzC,YAAM,KAAK,wBAAwB,KAAK,SAAS;AAAA,IACnD,WAAW,kBAAkB;AAC3B,UAAI,KAAK,sBAAsB,KAAK,cAAc,kBAAkB;AAClE,eAAO,KAAK,oBAAoB,KAAK,QAAQ,mBAAmB;AAAA,MAClE;AAAA,IACF;AAEA,UAAM,aAAa,SAChB,OAAO,CAAC,QAAQ,iBAAiB,GAAG,CAAC,EACrC,IAAI,CAAC,QAAQ,IAAI,EAAE;AACtB,UAAM,kBACJ,KAAK,uBACL,QAAQ,cAAc,SAAS,kBAAkB,CAAC;AAIpD,QAAI;AACJ,QAAI;AACJ,QAAI,WAAW,SAAS,GAAG;AAGzB,YAAM,WAAW,OAAO,WAAW;AACnC,iBAAW,MAAM,YAAY;AAC3B,aAAK,wBAAwB,IAAI,IAAI,QAAQ;AAAA,MAC/C;AAEA,UAAI,iBAAiB;AACnB,wBAAgB,IAAI,QAAQ,CAAC,YAAY;AACvC,eAAK,wBAAwB,IAAI,UAAU;AAAA,YACzC,aAAa;AAAA,YACb;AAAA,YACA,WAAW,oBAAI,IAAI;AAAA,UACrB,CAAC;AAAA,QACH,CAAC;AAAA,MACH,OAAO;AACL,cAAM,EAAE,UAAU,SAAS,IAAI,IAAI,gBAA4B;AAC/D,aAAK,YAAY,UAAU,SAAS,UAAU,CAAC;AAC/C,sBAAc;AAAA,MAChB;AAAA,IACF;AAKA,eAAW,WAAW,UAAU;AAC9B,YAAM,YAAY,4BAA4B,UAAU,OAAO;AAC/D,UAAI,UAAU,SAAS;AACrB,cAAM,KAAK,wBAAwB,UAAU,KAAK,OAAO,SAAS;AAAA,MACpE;AAAA,IACF;AAGA,eAAW,WAAW,UAAU;AAC9B,WAAK,YAAY,SAAS,EAAE,UAAU,OAAU,CAAC;AAAA,IACnD;AAGA,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO,IAAI,SAAS,MAAM;AAAA,QACxB,SAAS,KAAK,mBAAmB;AAAA,QACjC,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAGA,QAAI,eAAe;AAEjB,YAAM,YAAY,MAAM;AAExB,YAAM,eAAe,KAAK,UAAU,UAAU,YAAY,UAAU,CAAC,CAAC;AAEtE,aAAO,IAAI,SAAS,cAAc;AAAA,QAChC,SAAS;AAAA,UACP,GAAG,KAAK,mBAAmB;AAAA,UAC3B,gBAAgB;AAAA,QAClB;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAGA,WAAO,IAAI,SAAS,eAAe,MAAM;AAAA,MACvC,SAAS;AAAA,QACP,GAAG,KAAK,mBAAmB;AAAA,QAC3B,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBAAmB,aAAwC;AACvE,QAAI,CAAC,KAAK,aAAa;AACrB,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,EAAE,UAAU,SAAS,IAAI,IAAI,gBAA4B;AAC/D,UAAM,SAAS,SAAS,UAAU;AAElC,SAAK,oBAAoB;AACzB,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,YAAY,kBAAkB,aAAa;AAAA,QACrE,MAAM,OAAO,SAAS,YAAY;AAChC,gBAAM,KAAK,oBAAoB,QAAQ,SAAS,OAAO;AAAA,QACzD;AAAA,MACF,CAAC;AACD,WAAK,YAAY,UAAU,MAAM;AAAA,IACnC,SAAS,OAAO;AACd,YAAM,OAAO,MAAM;AACnB,aAAO,KAAK,oBAAoB,KAAK,OAAQ,kBAAkB,KAAK,EAAE;AAAA,IACxE,UAAE;AACA,WAAK,oBAAoB;AAAA,IAC3B;AAEA,WAAO,IAAI,SAAS,UAAU;AAAA,MAC5B,SAAS;AAAA,QACP,GAAG,KAAK,mBAAmB;AAAA,QAC3B,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,2BAAqC;AAC3C,WAAO,KAAK,oBAAoB,KAAK,OAAQ,oBAAoB;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,wBAAwB,WAAqC;AACzE,UAAM,WAAW,KAAK,wBAAwB,IAAI,SAAS;AAC3D,QAAI,aAAa,UAAa,KAAK,wBAAwB,IAAI,QAAQ,GAAG;AACxE;AAAA,IACF;AAEA,SAAK,wBAAwB,OAAO,SAAS;AAC7C,UAAM,cAAc,MAAM;AAAA,MACxB,KAAK,wBAAwB,OAAO;AAAA,IACtC,EAAE,SAAS,QAAQ;AACnB,QAAI,aAAa;AACf;AAAA,IACF;AAIA,UAAM,SAAS,KAAK,eAAe,IAAI,QAAQ;AAC/C,SAAK,eAAe,OAAO,QAAQ;AACnC,QAAI,QAAQ;AACV,UAAI;AACF,cAAM,OAAO,MAAM;AAAA,MACrB,SAAS,OAAO;AACd,aAAK;AAAA,UACH,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,yBAA+B;AACrC,eAAW,aAAa,KAAK,wBAAwB,OAAO,GAAG;AAC7D,gBAAU;AAAA,QACR,UAAU,YACP,IAAI,CAAC,OAAO,UAAU,UAAU,IAAI,EAAE,CAAC,EACvC,OAAO,CAAC,aAAa,aAAa,MAAS;AAAA,MAChD;AAAA,IACF;AACA,SAAK,wBAAwB,MAAM;AACnC,SAAK,wBAAwB,MAAM;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKQ,mBACN,UACA,WACM;AACN,UAAM,YAA8B,CAAC;AACrC,eAAW,MAAM,UAAU,aAAa;AACtC,YAAM,WAAW,UAAU,UAAU,IAAI,EAAE;AAC3C,UAAI,CAAC,UAAU;AAEb;AAAA,MACF;AACA,gBAAU,KAAK,QAAQ;AAAA,IACzB;AAEA,SAAK,wBAAwB,OAAO,QAAQ;AAC5C,eAAW,MAAM,UAAU,aAAa;AACtC,WAAK,wBAAwB,OAAO,EAAE;AAAA,IACxC;AACA,cAAU,QAAQ,SAAS;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,cACN,UACA,QACS;AACT,QAAI,KAAK,gBAAgB,QAAW;AAClC,aAAO;AAAA,IACT;AAEA,QAAI,aAAa,KAAK,wBAAwB;AAC5C,aAAO;AAAA,IACT;AAEA,WACE,KAAK;AAAA;AAAA;AAAA,IAIL,WAAW,UACX,KAAK,mBAAmB;AAAA,EAE5B;AAAA,EAEQ,YACN,UACA,QACM;AAGN,QAAI,aAAa,KAAK,wBAAwB;AAC5C,WAAK,0BAA0B;AAAA,IACjC;AACA,SAAK,eAAe,IAAI,UAAU,MAAM;AACxC,UAAM,wBAAwB,MAAM;AAClC,UAAI,KAAK,eAAe,IAAI,QAAQ,MAAM,QAAQ;AAChD;AAAA,MACF;AACA,WAAK,eAAe,OAAO,QAAQ;AAKnC,UAAI,KAAK,aAAa;AACpB;AAAA,MACF;AAIA,iBAAW,CAAC,WAAW,cAAc,KAAK,KAAK,yBAAyB;AACtE,YAAI,mBAAmB,UAAU;AAC/B,eAAK,wBAAwB,OAAO,SAAS;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AACA,SAAK,OAAO,OAAO,KAAK,uBAAuB,qBAAqB;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cACZ,QACA,SACe;AACf,UAAM,OAAO,SAAS,KAAK,UAAU,OAAO,CAAC;AAAA;AAAA;AAC7C,UAAM,OAAO,MAAM,KAAK,SAAS,OAAO,IAAI,CAAC;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,oBACZ,QACA,SACA,SACe;AACf,UAAM,OAAO,OAAO,OAAO;AAAA,QAAW,KAAK,UAAU,OAAO,CAAC;AAAA;AAAA;AAC7D,UAAM,OAAO,MAAM,KAAK,SAAS,OAAO,IAAI,CAAC;AAAA,EAC/C;AACF;;;ADlrBO,IAAM,cAAN,MAAkB;AAAA,EACvB,WAAW,IAAI,KAAK;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAyB,CAAC;AAAA,EAC1B,aAA6B,CAAC;AAAA,EAC9B,SAAqB,CAAC;AAAA,EACtB;AAAA,EAEA,YAAY,SAA6B;AACvC,SAAK,QAAQ,QAAQ;AACrB,SAAK,WAAW,QAAQ;AACxB,SAAK,UAAU,QAAQ,UAAU;AACjC,SAAK,WAAW,QAAQ,WAAW;AAEnC,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,QAA0B;AAClC,SAAK,SAAS,KAAK,MAAM;AACzB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,UAA8B;AACxC,SAAK,WAAW,KAAK,QAAQ;AAC7B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAiB,MAA+B;AAC9C,SAAK,OAAO,KAAK,IAAgB;AACjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,SAAqC;AAC/C,WAAO,KAAK,SAAS,MAAM,OAAO;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,SAAe;AACb,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,QAAgB,MAAc,SAA2B;AACtE,WAAO,IAAI;AAAA,MACT,KAAK,UAAU;AAAA,QACb,OAAO,EAAE,MAAM,QAAQ;AAAA,QACvB,IAAI;AAAA,QACJ,SAAS;AAAA,MACX,CAAC;AAAA,MACD;AAAA,QACE,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,IAAqC;AACrD,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,cAAc;AAAA,UACZ,SAAS,KAAK,SAAS,SAAS,IAAI,CAAC,IAAI;AAAA,UACzC,WAAW,KAAK,WAAW,SAAS,IAAI,CAAC,IAAI;AAAA,UAC7C,OAAO,KAAK,OAAO,SAAS,IAAI,CAAC,IAAI;AAAA,QACvC;AAAA,QACA,iBAAiB;AAAA,QACjB,YAAY;AAAA,UACV,MAAM,KAAK;AAAA,UACX,SAAS,KAAK;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAkB,SAAqC;AAE3D,UAAM,eAAe,QAAQ,QAAQ,IAAI,QAAQ;AACjD,QACE,CAAC,cAAc,SAAS,kBAAkB,KAC1C,CAAC,cAAc,SAAS,mBAAmB,GAC3C;AACA,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,cAAc,QAAQ,QAAQ,IAAI,cAAc;AACtD,QAAI,CAAC,aAAa,SAAS,kBAAkB,GAAG;AAC9C,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,QAAQ,KAAK;AAAA,IAC5B,QAAQ;AACN,aAAO,KAAK,eAAe,KAAK,QAAQ,2BAA2B;AAAA,IACrE;AAGA,UAAM,UAAU,MAAM,QAAQ,IAAI;AAClC,UAAM,WAAW,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AAEnD,QAAI,WAAW,SAAS,WAAW,GAAG;AACpC,aAAO,KAAK;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAA8B,CAAC;AAErC,eAAW,WAAW,UAAU;AAC9B,YAAM,WAAW,MAAM,KAAK,eAAe,OAAO;AAClD,UAAI,UAAU;AACZ,kBAAU,KAAK,QAAQ;AAAA,MACzB;AAAA,IACF;AAGA,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C;AAEA,UAAM,eAAe,KAAK,UAAU,UAAU,YAAY,UAAU,CAAC,CAAC;AAEtE,WAAO,IAAI,SAAS,cAAc;AAAA,MAChC,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAqB,SAAqC;AAC9D,UAAM,eAAe,QAAQ,QAAQ,IAAI,QAAQ;AACjD,QAAI,CAAC,cAAc,SAAS,mBAAmB,GAAG;AAChD,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,SAAkD;AACrE,QAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,aAAO,KAAK,UAAU,MAAM,QAAQ,8BAA8B;AAAA,IACpE;AAEA,UAAM,MAAM;AAOZ,QAAI,IAAI,YAAY,OAAO;AACzB,aAAO,KAAK;AAAA,QACV,IAAI,MAAM;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,QAAI,EAAE,QAAQ,QAAQ,IAAI,OAAO,QAAW;AAC1C,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,IAAI;AACnB,UAAM,KAAK,IAAI;AACf,UAAM,SAAS,IAAI;AAEnB,QAAI;AACF,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,iBAAO,KAAK,kBAAkB,EAAE;AAAA,QAElC,KAAK;AACH,iBAAO,EAAE,IAAI,SAAS,OAAO,QAAQ,CAAC,EAAE;AAAA,QAE1C,KAAK;AACH,iBAAO,KAAK,kBAAkB,IAAI,MAAM;AAAA,QAE1C,KAAK;AACH,iBAAO,KAAK,mBAAmB,EAAE;AAAA,QAEnC,KAAK;AACH,iBAAO,KAAK,qBAAqB,EAAE;AAAA,QAErC,KAAK;AACH,iBAAO,KAAK,qBAAqB,IAAI,MAAM;AAAA,QAE7C,KAAK;AACH,iBAAO,KAAK,iBAAiB,IAAI,MAAM;AAAA,QAEzC,KAAK;AACH,iBAAO,KAAK,iBAAiB,EAAE;AAAA,QAEjC;AACE,iBAAO,KAAK,UAAU,IAAI,QAAQ,qBAAqB,MAAM,EAAE;AAAA,MACnE;AAAA,IACF,SAAS,OAAO;AACd,WAAK,QAAQ,MAAM,kBAAkB,MAAM,KAAK,KAAK;AACrD,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBACJ,IACA,QACyB;AACzB,UAAM,aAAa,QAAQ;AAC3B,UAAM,aAAa,QAAQ;AAE3B,UAAM,SAAS,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,UAAU;AAC9D,QAAI,CAAC,QAAQ;AACX,aAAO,KAAK;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV,qBAAqB,UAAU;AAAA,MACjC;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,KAAK,cAAc,CAAC,CAAC;AACjD,YAAM,WACJ,OAAO,WAAW,WACd,CAAC,EAAE,SAAS,EAAE,MAAM,QAAQ,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAC1D,OAAO;AAEb,aAAO;AAAA,QACL;AAAA,QACA,SAAS;AAAA,QACT,QAAQ,EAAE,SAAS;AAAA,MACrB;AAAA,IACF,SAAS,OAAO;AACd,aAAO,KAAK;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,IAAqC;AACtD,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,SAAS,KAAK,SAAS,IAAI,CAAC,OAAO;AAAA,UACjC,WAAW,EAAE;AAAA,UACb,aAAa,EAAE;AAAA,UACf,MAAM,EAAE;AAAA,QACV,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,IAAqC;AACxD,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,WAAW,KAAK,WAAW,IAAI,CAAC,OAAO;AAAA,UACrC,aAAa,EAAE;AAAA,UACf,UAAU,EAAE;AAAA,UACZ,MAAM,EAAE;AAAA,UACR,KAAK,EAAE;AAAA,QACT,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBACJ,IACA,QACyB;AACzB,UAAM,MAAM,QAAQ;AACpB,UAAM,WAAW,KAAK,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAE1D,QAAI,CAAC,UAAU;AACb,aAAO,KAAK;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV,uBAAuB,GAAG;AAAA,MAC5B;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,SAAS,KAAK;AACnC,YAAM,UACJ,OAAO,WAAW,WACd,EAAE,UAAU,SAAS,YAAY,cAAc,MAAM,QAAQ,IAAI,IACjE,EAAE,KAAK,GAAG,OAAO;AAEvB,aAAO;AAAA,QACL;AAAA,QACA,SAAS;AAAA,QACT,QAAQ,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,MAChC;AAAA,IACF,SAAS,OAAO;AACd,aAAO,KAAK;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV,yBAAyB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBACJ,IACA,QACyB;AACzB,UAAM,WAAW,QAAQ;AACzB,UAAM,WAAW,QAAQ;AAEzB,UAAM,OAAO,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AACxD,QAAI,CAAC,MAAM;AACT,aAAO,KAAK;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV,mBAAmB,QAAQ;AAAA,MAC7B;AAAA,IACF;AAEA,QAAI,OAAgB,YAAY,CAAC;AAEjC,QAAI,KAAK,YAAY;AACnB,UAAI;AAEJ,UAAI;AACF,iBAAS,MAAM,KAAK,WAAW,WAAW,EAAE,SAAS,QAAQ;AAAA,MAC/D,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,UACV;AAAA,UACA,UAAU;AAAA,UACV,SAAS,QAAQ,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAC3G;AAAA,MACF;AAEA,UAAI,OAAO,QAAQ;AACjB,cAAM,iBAAiB,OAAO,OAC3B,IAAI,CAAC,UAAU;AACd,gBAAM,OAAO,MAAM,MAAM,KAAK,GAAG,KAAK;AACtC,iBAAO,GAAG,IAAI,KAAK,MAAM,OAAO;AAAA,QAClC,CAAC,EACA,KAAK,IAAI;AAEZ,eAAO,KAAK;AAAA,UACV;AAAA,UACA,UAAU;AAAA,UACV,SAAS,QAAQ,kCAAkC,cAAc;AAAA,QACnE;AAAA,MACF;AAEA,aAAO,OAAO;AAAA,IAChB;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,QAAQ,IAAI;AAGtC,YAAM,UACJ,OAAO,WAAW,WACd,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC,IAC/B,OAAO;AAEb,aAAO;AAAA,QACL;AAAA,QACA,SAAS;AAAA,QACT,QAAQ,EAAE,QAAQ;AAAA,MACpB;AAAA,IACF,SAAS,OAAO;AACd,aAAO,KAAK;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,IAAqC;AACpD,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,OAAO,KAAK,OAAO,IAAI,CAAC,UAAU;AAAA,UAChC,aAAa,KAAK;AAAA,UAClB,aAAa,KAAK,aACd,KAAK,oBAAoB,KAAK,UAAU,IACxC,EAAE,MAAM,SAAS;AAAA,UACrB,MAAM,KAAK;AAAA,QACb,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UACE,IACA,MACA,SACgB;AAChB,WAAO;AAAA,MACL,OAAO,EAAE,MAAM,QAAQ;AAAA,MACvB;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBACE,QACyB;AACzB,QAAI;AAGF,UAAI,OAAQ,EAAU,iBAAiB,YAAY;AACjD,eAAO;AAAA,UACJ,EAAU,aAAa,MAAM;AAAA,QAChC;AAAA,MACF;AAIA,UAAI,UAAW,UAAkB,kBAAkB,EAAE,SAAS;AAC5D,eAAO;AAAA,UACL,gBAAgB,QAAe,EAAE,QAAQ,WAAW,CAAC;AAAA,QAIvD;AAAA,MACF;AAGA,aAAO,EAAE,MAAM,SAAS;AAAA,IAC1B,QAAQ;AACN,aAAO,EAAE,MAAM,SAAS;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAqB;AAEnB,SAAK,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,KAAK,WAAM,CAAC;AAGlD,SAAK,SAAS,KAAK,KAAK,UAAU,OAAO,MAAM;AAC7C,aAAO,KAAK,kBAAkB,EAAE,IAAI,GAAG;AAAA,IACzC,CAAC;AAGD,SAAK,SAAS,IAAI,KAAK,UAAU,OAAO,MAAM;AAC5C,aAAO,KAAK,qBAAqB,EAAE,IAAI,GAAG;AAAA,IAC5C,CAAC;AAGD,SAAK,SAAS,OAAO,KAAK,UAAU,YAAY;AAC9C,aAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C,CAAC;AAAA,EACH;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastmcp",
3
- "version": "4.16.2",
3
+ "version": "4.16.3",
4
4
  "main": "dist/FastMCP.js",
5
5
  "scripts": {
6
6
  "build": "tsup",