@mastra/mcp 0.5.0-alpha.2 → 0.5.0-alpha.4

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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/mcp@0.5.0-alpha.2 build /home/runner/work/mastra/mastra/packages/mcp
2
+ > @mastra/mcp@0.5.0-alpha.4 build /home/runner/work/mastra/mastra/packages/mcp
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.4.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 18478ms
9
+ TSC ⚡️ Build success in 17734ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/packages/mcp/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/packages/mcp/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 12208ms
16
+ DTS ⚡️ Build success in 13432ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- ESM dist/index.js 25.82 KB
21
- ESM ⚡️ Build success in 1060ms
22
- CJS dist/index.cjs 26.18 KB
23
- CJS ⚡️ Build success in 1060ms
20
+ CJS dist/index.cjs 32.44 KB
21
+ CJS ⚡️ Build success in 1027ms
22
+ ESM dist/index.js 32.14 KB
23
+ ESM ⚡️ Build success in 1029ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @mastra/mcp
2
2
 
3
+ ## 0.5.0-alpha.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 396be50: updated mcp server routes for MCP SSE for use with hono server
8
+ - da082f8: Switch from serializing json schema string as a function to a library that creates a zod object in memory from the json schema. This reduces the errors we were seeing from zod schema code that could not be serialized.
9
+ - Updated dependencies [396be50]
10
+ - Updated dependencies [c3bd795]
11
+ - Updated dependencies [da082f8]
12
+ - Updated dependencies [a5810ce]
13
+ - @mastra/core@0.9.4-alpha.3
14
+
15
+ ## 0.5.0-alpha.3
16
+
17
+ ### Patch Changes
18
+
19
+ - bb1e2c8: Make sure mcp handlers can only be registered once
20
+
3
21
  ## 0.5.0-alpha.2
4
22
 
5
23
  ### Patch Changes
@@ -4,11 +4,14 @@ import type * as http from 'node:http';
4
4
  import { LoggingLevel } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { MastraBase } from '@mastra/core/base';
6
6
  import { MCPServerBase } from '@mastra/core/mcp';
7
+ import type { MCPServerHonoSSEOptions } from '@mastra/core/mcp';
7
8
  import type { MCPServerSSEOptions } from '@mastra/core/mcp';
8
9
  import type { Protocol } from '@modelcontextprotocol/sdk/shared/protocol.js';
9
10
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
10
11
  import type { SSEClientTransportOptions } from '@modelcontextprotocol/sdk/client/sse.js';
11
12
  import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
13
+ import type { SSEStreamingApi } from 'hono/streaming';
14
+ import { SSETransport } from 'hono-mcp-server-sse-transport';
12
15
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
16
  import type { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
14
17
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
@@ -18,6 +21,8 @@ import { ToolExecutionContext } from '@mastra/core';
18
21
  import type { ToolsInput } from '@mastra/core/agent';
19
22
  import { z } from 'zod';
20
23
 
24
+ export declare const allTools: ToolsInput;
25
+
21
26
  declare type BaseServerOptions = {
22
27
  logger?: LogHandler;
23
28
  timeout?: number;
@@ -188,7 +193,10 @@ declare class MCPServer extends MCPServerBase {
188
193
  private server;
189
194
  private stdioTransport?;
190
195
  private sseTransport?;
196
+ private sseHonoTransports;
191
197
  private streamableHTTPTransport?;
198
+ private listToolsHandlerIsRegistered;
199
+ private callToolHandlerIsRegistered;
192
200
  /**
193
201
  * Get the current stdio transport.
194
202
  */
@@ -197,6 +205,10 @@ declare class MCPServer extends MCPServerBase {
197
205
  * Get the current SSE transport.
198
206
  */
199
207
  getSseTransport(): SSEServerTransport | undefined;
208
+ /**
209
+ * Get the current SSE Hono transport.
210
+ */
211
+ getSseHonoTransport(sessionId: string): SSETransport | undefined;
200
212
  /**
201
213
  * Get the current streamable HTTP transport.
202
214
  */
@@ -241,6 +253,16 @@ declare class MCPServer extends MCPServerBase {
241
253
  * @param res HTTP response (must support .write/.end)
242
254
  */
243
255
  startSSE({ url, ssePath, messagePath, req, res }: MCPServerSSEOptions): Promise<void>;
256
+ /**
257
+ * Handles MCP-over-SSE protocol for user-provided HTTP servers.
258
+ * Call this from your HTTP server for both the SSE and message endpoints.
259
+ *
260
+ * @param url Parsed URL of the incoming request
261
+ * @param ssePath Path for establishing the SSE connection (e.g. '/sse')
262
+ * @param messagePath Path for POSTing client messages (e.g. '/message')
263
+ * @param context Incoming Hono context
264
+ */
265
+ startHonoSSE({ url, ssePath, messagePath, context }: MCPServerHonoSSEOptions): Promise<Response>;
244
266
  /**
245
267
  * Handles MCP-over-StreamableHTTP protocol for user-provided HTTP servers.
246
268
  * Call this from your HTTP server for the streamable HTTP endpoint.
@@ -258,11 +280,14 @@ declare class MCPServer extends MCPServerBase {
258
280
  res: http.ServerResponse<http.IncomingMessage>;
259
281
  options?: StreamableHTTPServerTransportOptions;
260
282
  }): Promise<void>;
261
- handlePostMessage(req: http.IncomingMessage, res: http.ServerResponse<http.IncomingMessage>): Promise<void>;
262
283
  connectSSE({ messagePath, res, }: {
263
284
  messagePath: string;
264
285
  res: http.ServerResponse<http.IncomingMessage>;
265
286
  }): Promise<void>;
287
+ connectHonoSSE({ messagePath, stream }: {
288
+ messagePath: string;
289
+ stream: SSEStreamingApi;
290
+ }): Promise<void>;
266
291
  /**
267
292
  * Close the MCP server and all its connections
268
293
  */
@@ -271,6 +296,8 @@ declare class MCPServer extends MCPServerBase {
271
296
  export { MCPServer }
272
297
  export { MCPServer as MCPServer_alias_1 }
273
298
 
299
+ export declare const mcpServerName = "firecrawl-mcp-fixture";
300
+
274
301
  export declare const server: Server<{
275
302
  method: string;
276
303
  params?: {
@@ -4,11 +4,14 @@ import type * as http from 'node:http';
4
4
  import { LoggingLevel } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { MastraBase } from '@mastra/core/base';
6
6
  import { MCPServerBase } from '@mastra/core/mcp';
7
+ import type { MCPServerHonoSSEOptions } from '@mastra/core/mcp';
7
8
  import type { MCPServerSSEOptions } from '@mastra/core/mcp';
8
9
  import type { Protocol } from '@modelcontextprotocol/sdk/shared/protocol.js';
9
10
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
10
11
  import type { SSEClientTransportOptions } from '@modelcontextprotocol/sdk/client/sse.js';
11
12
  import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
13
+ import type { SSEStreamingApi } from 'hono/streaming';
14
+ import { SSETransport } from 'hono-mcp-server-sse-transport';
12
15
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
16
  import type { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
14
17
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
@@ -18,6 +21,8 @@ import { ToolExecutionContext } from '@mastra/core';
18
21
  import type { ToolsInput } from '@mastra/core/agent';
19
22
  import { z } from 'zod';
20
23
 
24
+ export declare const allTools: ToolsInput;
25
+
21
26
  declare type BaseServerOptions = {
22
27
  logger?: LogHandler;
23
28
  timeout?: number;
@@ -188,7 +193,10 @@ declare class MCPServer extends MCPServerBase {
188
193
  private server;
189
194
  private stdioTransport?;
190
195
  private sseTransport?;
196
+ private sseHonoTransports;
191
197
  private streamableHTTPTransport?;
198
+ private listToolsHandlerIsRegistered;
199
+ private callToolHandlerIsRegistered;
192
200
  /**
193
201
  * Get the current stdio transport.
194
202
  */
@@ -197,6 +205,10 @@ declare class MCPServer extends MCPServerBase {
197
205
  * Get the current SSE transport.
198
206
  */
199
207
  getSseTransport(): SSEServerTransport | undefined;
208
+ /**
209
+ * Get the current SSE Hono transport.
210
+ */
211
+ getSseHonoTransport(sessionId: string): SSETransport | undefined;
200
212
  /**
201
213
  * Get the current streamable HTTP transport.
202
214
  */
@@ -241,6 +253,16 @@ declare class MCPServer extends MCPServerBase {
241
253
  * @param res HTTP response (must support .write/.end)
242
254
  */
243
255
  startSSE({ url, ssePath, messagePath, req, res }: MCPServerSSEOptions): Promise<void>;
256
+ /**
257
+ * Handles MCP-over-SSE protocol for user-provided HTTP servers.
258
+ * Call this from your HTTP server for both the SSE and message endpoints.
259
+ *
260
+ * @param url Parsed URL of the incoming request
261
+ * @param ssePath Path for establishing the SSE connection (e.g. '/sse')
262
+ * @param messagePath Path for POSTing client messages (e.g. '/message')
263
+ * @param context Incoming Hono context
264
+ */
265
+ startHonoSSE({ url, ssePath, messagePath, context }: MCPServerHonoSSEOptions): Promise<Response>;
244
266
  /**
245
267
  * Handles MCP-over-StreamableHTTP protocol for user-provided HTTP servers.
246
268
  * Call this from your HTTP server for the streamable HTTP endpoint.
@@ -258,11 +280,14 @@ declare class MCPServer extends MCPServerBase {
258
280
  res: http.ServerResponse<http.IncomingMessage>;
259
281
  options?: StreamableHTTPServerTransportOptions;
260
282
  }): Promise<void>;
261
- handlePostMessage(req: http.IncomingMessage, res: http.ServerResponse<http.IncomingMessage>): Promise<void>;
262
283
  connectSSE({ messagePath, res, }: {
263
284
  messagePath: string;
264
285
  res: http.ServerResponse<http.IncomingMessage>;
265
286
  }): Promise<void>;
287
+ connectHonoSSE({ messagePath, stream }: {
288
+ messagePath: string;
289
+ stream: SSEStreamingApi;
290
+ }): Promise<void>;
266
291
  /**
267
292
  * Close the MCP server and all its connections
268
293
  */
@@ -271,6 +296,8 @@ declare class MCPServer extends MCPServerBase {
271
296
  export { MCPServer }
272
297
  export { MCPServer as MCPServer_alias_1 }
273
298
 
299
+ export declare const mcpServerName = "firecrawl-mcp-fixture";
300
+
274
301
  export declare const server: Server<{
275
302
  method: string;
276
303
  params?: {
package/dist/index.cjs CHANGED
@@ -10,11 +10,11 @@ var streamableHttp_js$1 = require('@modelcontextprotocol/sdk/client/streamableHt
10
10
  var protocol_js = require('@modelcontextprotocol/sdk/shared/protocol.js');
11
11
  var types_js = require('@modelcontextprotocol/sdk/types.js');
12
12
  var exitHook = require('exit-hook');
13
- var jsonSchemaToZod = require('json-schema-to-zod');
14
13
  var zod = require('zod');
14
+ var zodFromJsonSchema = require('zod-from-json-schema');
15
15
  var equal = require('fast-deep-equal');
16
16
  var uuid = require('uuid');
17
- var crypto = require('crypto');
17
+ var crypto$1 = require('crypto');
18
18
  var core = require('@mastra/core');
19
19
  var mcp = require('@mastra/core/mcp');
20
20
  var runtimeContext = require('@mastra/core/runtime-context');
@@ -22,10 +22,10 @@ var index_js = require('@modelcontextprotocol/sdk/server/index.js');
22
22
  var sse_js = require('@modelcontextprotocol/sdk/server/sse.js');
23
23
  var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
24
24
  var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
25
+ var streaming = require('hono/streaming');
25
26
 
26
27
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
27
28
 
28
- var jsonSchemaToZod__default = /*#__PURE__*/_interopDefault(jsonSchemaToZod);
29
29
  var equal__default = /*#__PURE__*/_interopDefault(equal);
30
30
 
31
31
  // src/client.ts
@@ -238,7 +238,29 @@ var InternalMastraMCPClient = class extends base.MastraBase {
238
238
  });
239
239
  }
240
240
  convertInputSchema(inputSchema) {
241
- return utils.isZodType(inputSchema) ? inputSchema : utils.resolveSerializedZodOutput(jsonSchemaToZod__default.default(inputSchema));
241
+ if (utils.isZodType(inputSchema)) {
242
+ return inputSchema;
243
+ }
244
+ try {
245
+ const rawShape = zodFromJsonSchema.jsonSchemaObjectToZodRawShape(inputSchema);
246
+ return zod.z.object(rawShape);
247
+ } catch (error) {
248
+ let errorDetails;
249
+ if (error instanceof Error) {
250
+ errorDetails = error.stack;
251
+ } else {
252
+ try {
253
+ errorDetails = JSON.stringify(error);
254
+ } catch {
255
+ errorDetails = String(error);
256
+ }
257
+ }
258
+ this.log("error", "Failed to convert JSON schema to Zod schema using zodFromJsonSchema", {
259
+ error: errorDetails,
260
+ originalJsonSchema: inputSchema
261
+ });
262
+ throw new Error(errorDetails);
263
+ }
242
264
  }
243
265
  async tools() {
244
266
  this.log("debug", `Requesting tools from MCP server`);
@@ -246,36 +268,43 @@ var InternalMastraMCPClient = class extends base.MastraBase {
246
268
  const toolsRes = {};
247
269
  tools$1.forEach((tool) => {
248
270
  this.log("debug", `Processing tool: ${tool.name}`);
249
- const mastraTool = tools.createTool({
250
- id: `${this.name}_${tool.name}`,
251
- description: tool.description || "",
252
- inputSchema: this.convertInputSchema(tool.inputSchema),
253
- execute: async ({ context }) => {
254
- try {
255
- this.log("debug", `Executing tool: ${tool.name}`, { toolArgs: context });
256
- const res = await this.client.callTool(
257
- {
258
- name: tool.name,
259
- arguments: context
260
- },
261
- types_js.CallToolResultSchema,
262
- {
263
- timeout: this.timeout
264
- }
265
- );
266
- this.log("debug", `Tool executed successfully: ${tool.name}`);
267
- return res;
268
- } catch (e) {
269
- this.log("error", `Error calling tool: ${tool.name}`, {
270
- error: e instanceof Error ? e.stack : JSON.stringify(e, null, 2),
271
- toolArgs: context
272
- });
273
- throw e;
271
+ try {
272
+ const mastraTool = tools.createTool({
273
+ id: `${this.name}_${tool.name}`,
274
+ description: tool.description || "",
275
+ inputSchema: this.convertInputSchema(tool.inputSchema),
276
+ execute: async ({ context }) => {
277
+ try {
278
+ this.log("debug", `Executing tool: ${tool.name}`, { toolArgs: context });
279
+ const res = await this.client.callTool(
280
+ {
281
+ name: tool.name,
282
+ arguments: context
283
+ },
284
+ types_js.CallToolResultSchema,
285
+ {
286
+ timeout: this.timeout
287
+ }
288
+ );
289
+ this.log("debug", `Tool executed successfully: ${tool.name}`);
290
+ return res;
291
+ } catch (e) {
292
+ this.log("error", `Error calling tool: ${tool.name}`, {
293
+ error: e instanceof Error ? e.stack : JSON.stringify(e, null, 2),
294
+ toolArgs: context
295
+ });
296
+ throw e;
297
+ }
274
298
  }
299
+ });
300
+ if (tool.name) {
301
+ toolsRes[tool.name] = mastraTool;
275
302
  }
276
- });
277
- if (tool.name) {
278
- toolsRes[tool.name] = mastraTool;
303
+ } catch (toolCreationError) {
304
+ this.log("error", `Failed to create Mastra tool wrapper for MCP tool: ${tool.name}`, {
305
+ error: toolCreationError instanceof Error ? toolCreationError.stack : String(toolCreationError),
306
+ mcpToolDefinition: tool
307
+ });
279
308
  }
280
309
  });
281
310
  return toolsRes;
@@ -477,11 +506,98 @@ var MCPConfiguration = class extends MCPClient {
477
506
  );
478
507
  }
479
508
  };
509
+ var MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024;
510
+ var SSETransport = class {
511
+ messageUrl;
512
+ stream;
513
+ _sessionId;
514
+ onclose;
515
+ onerror;
516
+ onmessage;
517
+ /**
518
+ * Creates a new SSETransport, which will direct the MPC client to POST messages to messageUrl
519
+ */
520
+ constructor(messageUrl, stream) {
521
+ this.messageUrl = messageUrl;
522
+ this.stream = stream;
523
+ this._sessionId = crypto.randomUUID();
524
+ this.stream.onAbort(() => {
525
+ void this.close();
526
+ });
527
+ }
528
+ get sessionId() {
529
+ return this._sessionId;
530
+ }
531
+ // start() is automatically called after MCP Server connects to the transport
532
+ async start() {
533
+ if (this.stream == null) {
534
+ throw new Error("Stream not initialized");
535
+ }
536
+ if (this.stream.closed) {
537
+ throw new Error("SSE transport already closed!");
538
+ }
539
+ await this.stream.writeSSE({
540
+ event: "endpoint",
541
+ data: `${this.messageUrl}?sessionId=${this.sessionId}`
542
+ });
543
+ }
544
+ async handlePostMessage(context) {
545
+ if (this.stream?.closed == null) {
546
+ return context.text("SSE connection not established", 500);
547
+ }
548
+ try {
549
+ const contentType = context.req.header("content-type") || "";
550
+ if (!contentType.includes("application/json")) {
551
+ throw new Error(`Unsupported content-type: ${contentType}`);
552
+ }
553
+ const contentLength = Number.parseInt(context.req.header("content-length") || "0", 10);
554
+ if (contentLength > MAXIMUM_MESSAGE_SIZE) {
555
+ throw new Error(`Request body too large: ${contentLength} bytes`);
556
+ }
557
+ const body = await context.req.json();
558
+ await this.handleMessage(body);
559
+ return context.text("Accepted", 202);
560
+ } catch (error) {
561
+ this.onerror?.(error);
562
+ return context.text("Error", 400);
563
+ }
564
+ }
565
+ /**
566
+ * Handle a client message, regardless of how it arrived. This can be used to inform the server of messages that arrive via a means different than HTTP POST.
567
+ */
568
+ async handleMessage(message) {
569
+ let parsedMessage;
570
+ try {
571
+ parsedMessage = types_js.JSONRPCMessageSchema.parse(message);
572
+ } catch (error) {
573
+ this.onerror?.(error);
574
+ throw error;
575
+ }
576
+ this.onmessage?.(parsedMessage);
577
+ }
578
+ async close() {
579
+ if (this.stream?.closed) {
580
+ this.stream.abort();
581
+ }
582
+ }
583
+ async send(message) {
584
+ if (this.stream?.closed) {
585
+ throw new Error("Not connected");
586
+ }
587
+ await this.stream.writeSSE({
588
+ event: "message",
589
+ data: JSON.stringify(message)
590
+ });
591
+ }
592
+ };
480
593
  var MCPServer = class extends mcp.MCPServerBase {
481
594
  server;
482
595
  stdioTransport;
483
596
  sseTransport;
597
+ sseHonoTransports;
484
598
  streamableHTTPTransport;
599
+ listToolsHandlerIsRegistered = false;
600
+ callToolHandlerIsRegistered = false;
485
601
  /**
486
602
  * Get the current stdio transport.
487
603
  */
@@ -494,6 +610,12 @@ var MCPServer = class extends mcp.MCPServerBase {
494
610
  getSseTransport() {
495
611
  return this.sseTransport;
496
612
  }
613
+ /**
614
+ * Get the current SSE Hono transport.
615
+ */
616
+ getSseHonoTransport(sessionId) {
617
+ return this.sseHonoTransports.get(sessionId);
618
+ }
497
619
  /**
498
620
  * Get the current streamable HTTP transport.
499
621
  */
@@ -512,6 +634,7 @@ var MCPServer = class extends mcp.MCPServerBase {
512
634
  this.logger.info(
513
635
  `Initialized MCPServer '${name}' v${version} with tools: ${Object.keys(this.convertedTools).join(", ")}`
514
636
  );
637
+ this.sseHonoTransports = /* @__PURE__ */ new Map();
515
638
  this.registerListToolsHandler();
516
639
  this.registerCallToolHandler();
517
640
  }
@@ -555,6 +678,10 @@ var MCPServer = class extends mcp.MCPServerBase {
555
678
  * Register the ListTools handler for listing all available tools.
556
679
  */
557
680
  registerListToolsHandler() {
681
+ if (this.listToolsHandlerIsRegistered) {
682
+ return;
683
+ }
684
+ this.listToolsHandlerIsRegistered = true;
558
685
  this.server.setRequestHandler(types_js.ListToolsRequestSchema, async () => {
559
686
  this.logger.debug("Handling ListTools request");
560
687
  return {
@@ -570,6 +697,10 @@ var MCPServer = class extends mcp.MCPServerBase {
570
697
  * Register the CallTool handler for executing a tool by name.
571
698
  */
572
699
  registerCallToolHandler() {
700
+ if (this.callToolHandlerIsRegistered) {
701
+ return;
702
+ }
703
+ this.callToolHandlerIsRegistered = true;
573
704
  this.server.setRequestHandler(types_js.CallToolRequestSchema, async (request) => {
574
705
  const startTime = Date.now();
575
706
  try {
@@ -675,6 +806,43 @@ var MCPServer = class extends mcp.MCPServerBase {
675
806
  res.end();
676
807
  }
677
808
  }
809
+ /**
810
+ * Handles MCP-over-SSE protocol for user-provided HTTP servers.
811
+ * Call this from your HTTP server for both the SSE and message endpoints.
812
+ *
813
+ * @param url Parsed URL of the incoming request
814
+ * @param ssePath Path for establishing the SSE connection (e.g. '/sse')
815
+ * @param messagePath Path for POSTing client messages (e.g. '/message')
816
+ * @param context Incoming Hono context
817
+ */
818
+ async startHonoSSE({ url, ssePath, messagePath, context }) {
819
+ if (url.pathname === ssePath) {
820
+ return streaming.streamSSE(context, async (stream) => {
821
+ await this.connectHonoSSE({
822
+ messagePath,
823
+ stream
824
+ });
825
+ });
826
+ } else if (url.pathname === messagePath) {
827
+ this.logger.debug("Received message");
828
+ const sessionId = context.req.query("sessionId");
829
+ this.logger.debug("Received message for sessionId", { sessionId });
830
+ if (!sessionId) {
831
+ return context.text("No sessionId provided", 400);
832
+ }
833
+ if (!this.sseHonoTransports.has(sessionId)) {
834
+ return context.text(`No transport found for sessionId ${sessionId}`, 400);
835
+ }
836
+ const message = await this.sseHonoTransports.get(sessionId)?.handlePostMessage(context);
837
+ if (!message) {
838
+ return context.text("Transport not found", 400);
839
+ }
840
+ return message;
841
+ } else {
842
+ this.logger.debug("Unknown path:", { path: url.pathname });
843
+ return context.text("Unknown path", 404);
844
+ }
845
+ }
678
846
  /**
679
847
  * Handles MCP-over-StreamableHTTP protocol for user-provided HTTP servers.
680
848
  * Call this from your HTTP server for the streamable HTTP endpoint.
@@ -690,7 +858,7 @@ var MCPServer = class extends mcp.MCPServerBase {
690
858
  httpPath,
691
859
  req,
692
860
  res,
693
- options = { sessionIdGenerator: () => crypto.randomUUID() }
861
+ options = { sessionIdGenerator: () => crypto$1.randomUUID() }
694
862
  }) {
695
863
  if (url.pathname === httpPath) {
696
864
  this.streamableHTTPTransport = new streamableHttp_js.StreamableHTTPServerTransport(options);
@@ -722,14 +890,6 @@ var MCPServer = class extends mcp.MCPServerBase {
722
890
  res.end();
723
891
  }
724
892
  }
725
- async handlePostMessage(req, res) {
726
- if (!this.sseTransport) {
727
- res.writeHead(503);
728
- res.end("SSE connection not established");
729
- return;
730
- }
731
- await this.sseTransport.handlePostMessage(req, res);
732
- }
733
893
  async connectSSE({
734
894
  messagePath,
735
895
  res
@@ -745,10 +905,35 @@ var MCPServer = class extends mcp.MCPServerBase {
745
905
  this.sseTransport = void 0;
746
906
  });
747
907
  }
908
+ async connectHonoSSE({ messagePath, stream }) {
909
+ this.logger.debug("Received SSE connection");
910
+ const sseTransport = new SSETransport(messagePath, stream);
911
+ const sessionId = sseTransport.sessionId;
912
+ this.logger.debug("SSE Transport created with sessionId:", { sessionId });
913
+ this.sseHonoTransports.set(sessionId, sseTransport);
914
+ stream.onAbort(() => {
915
+ this.logger.debug("SSE Transport aborted with sessionId:", { sessionId });
916
+ this.sseHonoTransports.delete(sessionId);
917
+ });
918
+ await this.server.connect(sseTransport);
919
+ this.server.onclose = async () => {
920
+ this.logger.debug("SSE Transport closed with sessionId:", { sessionId });
921
+ this.sseHonoTransports.delete(sessionId);
922
+ await this.server.close();
923
+ };
924
+ while (true) {
925
+ const sessionIds = Array.from(this.sseHonoTransports.keys() || []);
926
+ this.logger.debug("Active Hono SSE sessions:", { sessionIds });
927
+ await stream.write(":keep-alive\n\n");
928
+ await stream.sleep(6e4);
929
+ }
930
+ }
748
931
  /**
749
932
  * Close the MCP server and all its connections
750
933
  */
751
934
  async close() {
935
+ this.callToolHandlerIsRegistered = false;
936
+ this.listToolsHandlerIsRegistered = false;
752
937
  try {
753
938
  if (this.stdioTransport) {
754
939
  await this.stdioTransport.close?.();
@@ -758,6 +943,12 @@ var MCPServer = class extends mcp.MCPServerBase {
758
943
  await this.sseTransport.close?.();
759
944
  this.sseTransport = void 0;
760
945
  }
946
+ if (this.sseHonoTransports) {
947
+ for (const transport of this.sseHonoTransports.values()) {
948
+ await transport.close?.();
949
+ }
950
+ this.sseHonoTransports.clear();
951
+ }
761
952
  if (this.streamableHTTPTransport) {
762
953
  await this.streamableHTTPTransport.close?.();
763
954
  this.streamableHTTPTransport = void 0;