mcp-proxy 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import {
3
3
  InMemoryEventStore,
4
4
  proxyServer,
5
5
  startHTTPServer
6
- } from "../chunk-L6JN33YZ.js";
6
+ } from "../chunk-JE5DUWZ2.js";
7
7
 
8
8
  // src/bin/mcp-proxy.ts
9
9
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
@@ -201,7 +201,9 @@ var handleStreamRequest = async ({
201
201
  transport.onclose = async () => {
202
202
  const sid = transport.sessionId;
203
203
  if (sid && activeTransports[sid]) {
204
- onClose?.(server);
204
+ if (onClose) {
205
+ await onClose(server);
206
+ }
205
207
  try {
206
208
  await server.close();
207
209
  } catch (error) {
@@ -221,7 +223,9 @@ var handleStreamRequest = async ({
221
223
  return true;
222
224
  }
223
225
  server.connect(transport);
224
- onConnect?.(server);
226
+ if (onConnect) {
227
+ await onConnect(server);
228
+ }
225
229
  await transport.handleRequest(req, res, body);
226
230
  return true;
227
231
  } else {
@@ -288,7 +292,9 @@ var handleStreamRequest = async ({
288
292
  }
289
293
  try {
290
294
  await activeTransport.transport.handleRequest(req, res);
291
- onClose?.(activeTransport.server);
295
+ if (onClose) {
296
+ await onClose(activeTransport.server);
297
+ }
292
298
  } catch (error) {
293
299
  console.error("Error handling delete request:", error);
294
300
  res.writeHead(500).end("Error handling delete request");
@@ -329,7 +335,7 @@ var handleSSERequest = async ({
329
335
  console.error("Error closing server:", error);
330
336
  }
331
337
  delete activeTransports[transport.sessionId];
332
- onClose?.(server);
338
+ await onClose?.(server);
333
339
  });
334
340
  try {
335
341
  await server.connect(transport);
@@ -338,7 +344,9 @@ var handleSSERequest = async ({
338
344
  method: "sse/connection",
339
345
  params: { message: "SSE Connection established" }
340
346
  });
341
- onConnect?.(server);
347
+ if (onConnect) {
348
+ await onConnect(server);
349
+ }
342
350
  } catch (error) {
343
351
  if (!closed) {
344
352
  console.error("Error connecting to server:", error);
@@ -459,4 +467,4 @@ export {
459
467
  proxyServer,
460
468
  startHTTPServer
461
469
  };
462
- //# sourceMappingURL=chunk-L6JN33YZ.js.map
470
+ //# sourceMappingURL=chunk-JE5DUWZ2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/InMemoryEventStore.ts","../src/proxyServer.ts","../src/startHTTPServer.ts"],"sourcesContent":["/**\n * This is a copy of the InMemoryEventStore from the typescript-sdk\n * https://github.com/modelcontextprotocol/typescript-sdk/blob/main/src/inMemoryEventStore.ts\n */\n\nimport type { EventStore } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\n\n/**\n * Simple in-memory implementation of the EventStore interface for resumability\n * This is primarily intended for examples and testing, not for production use\n * where a persistent storage solution would be more appropriate.\n */\nexport class InMemoryEventStore implements EventStore {\n private events: Map<string, { message: JSONRPCMessage; streamId: string }> =\n new Map();\n\n /**\n * Replays events that occurred after a specific event ID\n * Implements EventStore.replayEventsAfter\n */\n async replayEventsAfter(\n lastEventId: string,\n {\n send,\n }: { send: (eventId: string, message: JSONRPCMessage) => Promise<void> },\n ): Promise<string> {\n if (!lastEventId || !this.events.has(lastEventId)) {\n return \"\";\n }\n\n // Extract the stream ID from the event ID\n const streamId = this.getStreamIdFromEventId(lastEventId);\n if (!streamId) {\n return \"\";\n }\n\n let foundLastEvent = false;\n\n // Sort events by eventId for chronological ordering\n const sortedEvents = [...this.events.entries()].sort((a, b) =>\n a[0].localeCompare(b[0]),\n );\n\n for (const [\n eventId,\n { message, streamId: eventStreamId },\n ] of sortedEvents) {\n // Only include events from the same stream\n if (eventStreamId !== streamId) {\n continue;\n }\n\n // Start sending events after we find the lastEventId\n if (eventId === lastEventId) {\n foundLastEvent = true;\n continue;\n }\n\n if (foundLastEvent) {\n await send(eventId, message);\n }\n }\n return streamId;\n }\n\n /**\n * Stores an event with a generated event ID\n * Implements EventStore.storeEvent\n */\n async storeEvent(streamId: string, message: JSONRPCMessage): Promise<string> {\n const eventId = this.generateEventId(streamId);\n this.events.set(eventId, { message, streamId });\n return eventId;\n }\n\n /**\n * Generates a unique event ID for a given stream ID\n */\n private generateEventId(streamId: string): string {\n return `${streamId}_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n }\n\n /**\n * Extracts the stream ID from an event ID\n */\n private getStreamIdFromEventId(eventId: string): string {\n const parts = eventId.split(\"_\");\n return parts.length > 0 ? parts[0] : \"\";\n }\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n CallToolRequestSchema,\n CompleteRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourcesRequestSchema,\n ListResourceTemplatesRequestSchema,\n ListToolsRequestSchema,\n LoggingMessageNotificationSchema,\n ReadResourceRequestSchema,\n ResourceUpdatedNotificationSchema,\n ServerCapabilities,\n SubscribeRequestSchema,\n UnsubscribeRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nexport const proxyServer = async ({\n client,\n server,\n serverCapabilities,\n}: {\n client: Client;\n server: Server;\n serverCapabilities: ServerCapabilities;\n}): Promise<void> => {\n if (serverCapabilities?.logging) {\n server.setNotificationHandler(\n LoggingMessageNotificationSchema,\n async (args) => {\n return client.notification(args);\n },\n );\n client.setNotificationHandler(\n LoggingMessageNotificationSchema,\n async (args) => {\n return server.notification(args);\n },\n );\n }\n\n if (serverCapabilities?.prompts) {\n server.setRequestHandler(GetPromptRequestSchema, async (args) => {\n return client.getPrompt(args.params);\n });\n\n server.setRequestHandler(ListPromptsRequestSchema, async (args) => {\n return client.listPrompts(args.params);\n });\n }\n\n if (serverCapabilities?.resources) {\n server.setRequestHandler(ListResourcesRequestSchema, async (args) => {\n return client.listResources(args.params);\n });\n\n server.setRequestHandler(\n ListResourceTemplatesRequestSchema,\n async (args) => {\n return client.listResourceTemplates(args.params);\n },\n );\n\n server.setRequestHandler(ReadResourceRequestSchema, async (args) => {\n return client.readResource(args.params);\n });\n\n if (serverCapabilities?.resources.subscribe) {\n server.setNotificationHandler(\n ResourceUpdatedNotificationSchema,\n async (args) => {\n return client.notification(args);\n },\n );\n\n server.setRequestHandler(SubscribeRequestSchema, async (args) => {\n return client.subscribeResource(args.params);\n });\n\n server.setRequestHandler(UnsubscribeRequestSchema, async (args) => {\n return client.unsubscribeResource(args.params);\n });\n }\n }\n\n if (serverCapabilities?.tools) {\n server.setRequestHandler(CallToolRequestSchema, async (args) => {\n return client.callTool(args.params);\n });\n\n server.setRequestHandler(ListToolsRequestSchema, async (args) => {\n return client.listTools(args.params);\n });\n }\n\n server.setRequestHandler(CompleteRequestSchema, async (args) => {\n return client.complete(args.params);\n });\n};\n","import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { SSEServerTransport } from \"@modelcontextprotocol/sdk/server/sse.js\";\nimport {\n EventStore,\n StreamableHTTPServerTransport,\n} from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { isInitializeRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport http from \"http\";\nimport { randomUUID } from \"node:crypto\";\n\nimport { InMemoryEventStore } from \"./InMemoryEventStore.js\";\n\nexport type SSEServer = {\n close: () => Promise<void>;\n};\n\ntype ServerLike = {\n close: Server[\"close\"];\n connect: Server[\"connect\"];\n};\n\nconst getBody = (request: http.IncomingMessage) => {\n return new Promise((resolve) => {\n const bodyParts: Buffer[] = [];\n let body: string;\n request\n .on(\"data\", (chunk) => {\n bodyParts.push(chunk);\n })\n .on(\"end\", () => {\n body = Buffer.concat(bodyParts).toString();\n try {\n resolve(JSON.parse(body));\n } catch(error) {\n console.error(\"Error parsing body:\", error);\n resolve(null);\n }\n });\n });\n};\n\nconst handleStreamRequest = async <T extends ServerLike>({\n activeTransports,\n createServer,\n endpoint,\n eventStore,\n onClose,\n onConnect,\n req,\n res,\n}: {\n activeTransports: Record<\n string,\n { server: T; transport: StreamableHTTPServerTransport }\n >;\n createServer: (request: http.IncomingMessage) => Promise<T>;\n endpoint: string;\n eventStore?: EventStore;\n onClose?: (server: T) => Promise<void>;\n onConnect?: (server: T) => Promise<void>;\n req: http.IncomingMessage;\n res: http.ServerResponse;\n}) => {\n if (\n req.method === \"POST\" &&\n new URL(req.url!, \"http://localhost\").pathname === endpoint\n ) {\n try {\n const sessionId = Array.isArray(req.headers[\"mcp-session-id\"])\n ? req.headers[\"mcp-session-id\"][0]\n : req.headers[\"mcp-session-id\"];\n\n let transport: StreamableHTTPServerTransport;\n \n let server: T;\n\n const body = await getBody(req);\n\n if (sessionId && activeTransports[sessionId]) {\n transport = activeTransports[sessionId].transport;\n server = activeTransports[sessionId].server;\n } else if (!sessionId && isInitializeRequest(body)) {\n // Create a new transport for the session\n transport = new StreamableHTTPServerTransport({\n eventStore: eventStore || new InMemoryEventStore(),\n onsessioninitialized: (_sessionId) => {\n // add only when the id Sesison id is generated\n activeTransports[_sessionId] = {\n server,\n transport,\n };\n },\n sessionIdGenerator: randomUUID,\n });\n\n // Handle the server close event\n transport.onclose = async () => {\n const sid = transport.sessionId;\n if (sid && activeTransports[sid]) {\n if (onClose) {\n await onClose(server);\n }\n\n try {\n await server.close();\n } catch (error) {\n console.error(\"Error closing server:\", error);\n }\n\n delete activeTransports[sid];\n }\n };\n\n try {\n server = await createServer(req);\n } catch (error) {\n if (error instanceof Response) {\n res.writeHead(error.status).end(error.statusText);\n\n return true;\n }\n\n res.writeHead(500).end(\"Error creating server\");\n\n return true;\n }\n\n server.connect(transport);\n\n if (onConnect) {\n await onConnect(server);\n }\n\n await transport.handleRequest(req, res, body);\n\n return true;\n } else {\n // Error if the server is not created but the request is not an initialize request\n res.setHeader(\"Content-Type\", \"application/json\");\n\n res.writeHead(400).end(\n JSON.stringify({\n error: {\n code: -32000,\n message: \"Bad Request: No valid session ID provided\",\n },\n id: null,\n jsonrpc: \"2.0\",\n }),\n );\n\n return true;\n }\n\n // Handle the request if the server is already created\n await transport.handleRequest(req, res, body);\n\n return true;\n } catch (error) {\n console.error(\"Error handling request:\", error);\n\n res.setHeader(\"Content-Type\", \"application/json\");\n\n res.writeHead(500).end(\n JSON.stringify({\n error: { code: -32603, message: \"Internal Server Error\" },\n id: null,\n jsonrpc: \"2.0\",\n }),\n );\n }\n return true;\n }\n\n if (\n req.method === \"GET\" &&\n new URL(req.url!, \"http://localhost\").pathname === endpoint\n ) {\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n const activeTransport:\n | {\n server: T;\n transport: StreamableHTTPServerTransport;\n }\n | undefined = sessionId ? activeTransports[sessionId] : undefined;\n\n if (!sessionId) {\n res.writeHead(400).end(\"No sessionId\");\n\n return true;\n }\n\n if (!activeTransport) {\n res.writeHead(400).end(\"No active transport\");\n\n return true;\n }\n\n const lastEventId = req.headers[\"last-event-id\"] as string | undefined;\n\n if (lastEventId) {\n console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`);\n } else {\n console.log(`Establishing new SSE stream for session ${sessionId}`);\n }\n\n await activeTransport.transport.handleRequest(req, res);\n\n return true;\n }\n\n if (\n req.method === \"DELETE\" &&\n new URL(req.url!, \"http://localhost\").pathname === endpoint\n ) {\n console.log(\"received delete request\");\n\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n if (!sessionId) {\n res.writeHead(400).end(\"Invalid or missing sessionId\");\n\n return true;\n }\n\n console.log(\"received delete request for session\", sessionId);\n\n const activeTransport = activeTransports[sessionId];\n\n if (!activeTransport) {\n res.writeHead(400).end(\"No active transport\");\n return true;\n }\n\n try {\n await activeTransport.transport.handleRequest(req, res);\n\n if (onClose) {\n await onClose(activeTransport.server);\n }\n } catch (error) {\n console.error(\"Error handling delete request:\", error);\n\n res.writeHead(500).end(\"Error handling delete request\");\n }\n\n return true;\n }\n\n return false;\n};\n\nconst handleSSERequest = async <T extends ServerLike>({\n activeTransports,\n createServer,\n endpoint,\n onClose,\n onConnect,\n req,\n res,\n}: {\n activeTransports: Record<string, SSEServerTransport>;\n createServer: (request: http.IncomingMessage) => Promise<T>;\n endpoint: string;\n onClose?: (server: T) => void;\n onConnect?: (server: T) => void;\n req: http.IncomingMessage;\n res: http.ServerResponse;\n}) => {\n if (\n req.method === \"GET\" &&\n new URL(req.url!, \"http://localhost\").pathname === endpoint\n ) {\n const transport = new SSEServerTransport(\"/messages\", res);\n\n let server: T;\n\n try {\n server = await createServer(req);\n } catch (error) {\n if (error instanceof Response) {\n res.writeHead(error.status).end(error.statusText);\n\n return true;\n }\n\n res.writeHead(500).end(\"Error creating server\");\n\n return true;\n }\n\n activeTransports[transport.sessionId] = transport;\n\n let closed = false;\n\n res.on(\"close\", async () => {\n closed = true;\n\n try {\n await server.close();\n } catch (error) {\n console.error(\"Error closing server:\", error);\n }\n\n delete activeTransports[transport.sessionId];\n\n await onClose?.(server);\n });\n\n try {\n await server.connect(transport);\n\n await transport.send({\n jsonrpc: \"2.0\",\n method: \"sse/connection\",\n params: { message: \"SSE Connection established\" },\n });\n\n if (onConnect) {\n await onConnect(server);\n }\n } catch (error) {\n if (!closed) {\n console.error(\"Error connecting to server:\", error);\n\n res.writeHead(500).end(\"Error connecting to server\");\n }\n }\n\n return true;\n }\n\n if (req.method === \"POST\" && req.url?.startsWith(\"/messages\")) {\n const sessionId = new URL(req.url, \"https://example.com\").searchParams.get(\n \"sessionId\",\n );\n\n if (!sessionId) {\n res.writeHead(400).end(\"No sessionId\");\n\n return true;\n }\n\n const activeTransport: SSEServerTransport | undefined =\n activeTransports[sessionId];\n\n if (!activeTransport) {\n res.writeHead(400).end(\"No active transport\");\n\n return true;\n }\n\n await activeTransport.handlePostMessage(req, res);\n\n return true;\n }\n\n return false;\n};\n\nexport const startHTTPServer = async <T extends ServerLike>({\n createServer,\n eventStore,\n onClose,\n onConnect,\n onUnhandledRequest,\n port,\n sseEndpoint,\n streamEndpoint,\n}: {\n createServer: (request: http.IncomingMessage) => Promise<T>;\n eventStore?: EventStore;\n onClose?: (server: T) => Promise<void>;\n onConnect?: (server: T) => Promise<void>;\n onUnhandledRequest?: (\n req: http.IncomingMessage,\n res: http.ServerResponse,\n ) => Promise<void>;\n port: number;\n sseEndpoint?: null | string;\n streamEndpoint?: null | string;\n}): Promise<SSEServer> => {\n const activeSSETransports: Record<string, SSEServerTransport> = {};\n\n const activeStreamTransports: Record<\n string,\n {\n server: T;\n transport: StreamableHTTPServerTransport;\n }\n > = {};\n\n /**\n * @author https://dev.classmethod.jp/articles/mcp-sse/\n */\n const httpServer = http.createServer(async (req, res) => {\n if (req.headers.origin) {\n try {\n const origin = new URL(req.headers.origin);\n\n res.setHeader(\"Access-Control-Allow-Origin\", origin.origin);\n res.setHeader(\"Access-Control-Allow-Credentials\", \"true\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"*\");\n res.setHeader(\"Access-Control-Expose-Headers\", \"mcp-session-id\");\n } catch (error) {\n console.error(\"Error parsing origin:\", error);\n }\n }\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (req.method === \"GET\" && req.url === `/ping`) {\n res.writeHead(200).end(\"pong\");\n return;\n }\n\n if (\n sseEndpoint !== null &&\n await handleSSERequest({\n activeTransports: activeSSETransports,\n createServer,\n endpoint: sseEndpoint ?? \"/sse\",\n onClose,\n onConnect,\n req,\n res,\n })\n ) {\n return;\n }\n\n if (\n streamEndpoint !== null &&\n await handleStreamRequest({\n activeTransports: activeStreamTransports,\n createServer,\n endpoint: streamEndpoint ?? \"/mcp\",\n eventStore,\n onClose,\n onConnect,\n req,\n res,\n })\n ) {\n return;\n }\n\n if (onUnhandledRequest) {\n await onUnhandledRequest(req, res);\n } else {\n res.writeHead(404).end();\n }\n });\n\n await new Promise((resolve) => {\n httpServer.listen(port, \"::\", () => {\n resolve(undefined);\n });\n });\n\n return {\n close: async () => {\n for (const transport of Object.values(activeSSETransports)) {\n await transport.close();\n }\n\n for (const transport of Object.values(activeStreamTransports)) {\n await transport.transport.close();\n }\n\n return new Promise((resolve, reject) => {\n httpServer.close((error) => {\n if (error) {\n reject(error);\n\n return;\n }\n\n resolve();\n });\n });\n },\n };\n};\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -57,8 +57,8 @@ type ServerLike = {
57
57
  declare const startHTTPServer: <T extends ServerLike>({ createServer, eventStore, onClose, onConnect, onUnhandledRequest, port, sseEndpoint, streamEndpoint, }: {
58
58
  createServer: (request: http.IncomingMessage) => Promise<T>;
59
59
  eventStore?: EventStore;
60
- onClose?: (server: T) => void;
61
- onConnect?: (server: T) => void;
60
+ onClose?: (server: T) => Promise<void>;
61
+ onConnect?: (server: T) => Promise<void>;
62
62
  onUnhandledRequest?: (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
63
63
  port: number;
64
64
  sseEndpoint?: null | string;
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  InMemoryEventStore,
3
3
  proxyServer,
4
4
  startHTTPServer
5
- } from "./chunk-L6JN33YZ.js";
5
+ } from "./chunk-JE5DUWZ2.js";
6
6
 
7
7
  // src/startStdioServer.ts
8
8
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
package/jsr.json CHANGED
@@ -3,5 +3,5 @@
3
3
  "include": ["src/index.ts", "src/bin/mcp-proxy.ts"],
4
4
  "license": "MIT",
5
5
  "name": "@punkpeye/mcp-proxy",
6
- "version": "4.0.0"
6
+ "version": "5.0.0"
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-proxy",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "main": "dist/index.js",
5
5
  "scripts": {
6
6
  "build": "tsup",
@@ -45,8 +45,8 @@ it("proxies messages between HTTP stream and stdio servers", async () => {
45
45
 
46
46
  const port = await getRandomPort();
47
47
 
48
- const onConnect = vi.fn();
49
- const onClose = vi.fn();
48
+ const onConnect = vi.fn().mockResolvedValue(undefined);
49
+ const onClose = vi.fn().mockResolvedValue(undefined);
50
50
 
51
51
  await startHTTPServer({
52
52
  createServer: async () => {
@@ -56,8 +56,8 @@ const handleStreamRequest = async <T extends ServerLike>({
56
56
  createServer: (request: http.IncomingMessage) => Promise<T>;
57
57
  endpoint: string;
58
58
  eventStore?: EventStore;
59
- onClose?: (server: T) => void;
60
- onConnect?: (server: T) => void;
59
+ onClose?: (server: T) => Promise<void>;
60
+ onConnect?: (server: T) => Promise<void>;
61
61
  req: http.IncomingMessage;
62
62
  res: http.ServerResponse;
63
63
  }) => {
@@ -97,7 +97,9 @@ const handleStreamRequest = async <T extends ServerLike>({
97
97
  transport.onclose = async () => {
98
98
  const sid = transport.sessionId;
99
99
  if (sid && activeTransports[sid]) {
100
- onClose?.(server);
100
+ if (onClose) {
101
+ await onClose(server);
102
+ }
101
103
 
102
104
  try {
103
105
  await server.close();
@@ -125,7 +127,9 @@ const handleStreamRequest = async <T extends ServerLike>({
125
127
 
126
128
  server.connect(transport);
127
129
 
128
- onConnect?.(server);
130
+ if (onConnect) {
131
+ await onConnect(server);
132
+ }
129
133
 
130
134
  await transport.handleRequest(req, res, body);
131
135
 
@@ -231,7 +235,9 @@ const handleStreamRequest = async <T extends ServerLike>({
231
235
  try {
232
236
  await activeTransport.transport.handleRequest(req, res);
233
237
 
234
- onClose?.(activeTransport.server);
238
+ if (onClose) {
239
+ await onClose(activeTransport.server);
240
+ }
235
241
  } catch (error) {
236
242
  console.error("Error handling delete request:", error);
237
243
 
@@ -298,7 +304,7 @@ const handleSSERequest = async <T extends ServerLike>({
298
304
 
299
305
  delete activeTransports[transport.sessionId];
300
306
 
301
- onClose?.(server);
307
+ await onClose?.(server);
302
308
  });
303
309
 
304
310
  try {
@@ -310,7 +316,9 @@ const handleSSERequest = async <T extends ServerLike>({
310
316
  params: { message: "SSE Connection established" },
311
317
  });
312
318
 
313
- onConnect?.(server);
319
+ if (onConnect) {
320
+ await onConnect(server);
321
+ }
314
322
  } catch (error) {
315
323
  if (!closed) {
316
324
  console.error("Error connecting to server:", error);
@@ -362,8 +370,8 @@ export const startHTTPServer = async <T extends ServerLike>({
362
370
  }: {
363
371
  createServer: (request: http.IncomingMessage) => Promise<T>;
364
372
  eventStore?: EventStore;
365
- onClose?: (server: T) => void;
366
- onConnect?: (server: T) => void;
373
+ onClose?: (server: T) => Promise<void>;
374
+ onConnect?: (server: T) => Promise<void>;
367
375
  onUnhandledRequest?: (
368
376
  req: http.IncomingMessage,
369
377
  res: http.ServerResponse,
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/InMemoryEventStore.ts","../src/proxyServer.ts","../src/startHTTPServer.ts"],"sourcesContent":["/**\n * This is a copy of the InMemoryEventStore from the typescript-sdk\n * https://github.com/modelcontextprotocol/typescript-sdk/blob/main/src/inMemoryEventStore.ts\n */\n\nimport type { EventStore } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\n\n/**\n * Simple in-memory implementation of the EventStore interface for resumability\n * This is primarily intended for examples and testing, not for production use\n * where a persistent storage solution would be more appropriate.\n */\nexport class InMemoryEventStore implements EventStore {\n private events: Map<string, { message: JSONRPCMessage; streamId: string }> =\n new Map();\n\n /**\n * Replays events that occurred after a specific event ID\n * Implements EventStore.replayEventsAfter\n */\n async replayEventsAfter(\n lastEventId: string,\n {\n send,\n }: { send: (eventId: string, message: JSONRPCMessage) => Promise<void> },\n ): Promise<string> {\n if (!lastEventId || !this.events.has(lastEventId)) {\n return \"\";\n }\n\n // Extract the stream ID from the event ID\n const streamId = this.getStreamIdFromEventId(lastEventId);\n if (!streamId) {\n return \"\";\n }\n\n let foundLastEvent = false;\n\n // Sort events by eventId for chronological ordering\n const sortedEvents = [...this.events.entries()].sort((a, b) =>\n a[0].localeCompare(b[0]),\n );\n\n for (const [\n eventId,\n { message, streamId: eventStreamId },\n ] of sortedEvents) {\n // Only include events from the same stream\n if (eventStreamId !== streamId) {\n continue;\n }\n\n // Start sending events after we find the lastEventId\n if (eventId === lastEventId) {\n foundLastEvent = true;\n continue;\n }\n\n if (foundLastEvent) {\n await send(eventId, message);\n }\n }\n return streamId;\n }\n\n /**\n * Stores an event with a generated event ID\n * Implements EventStore.storeEvent\n */\n async storeEvent(streamId: string, message: JSONRPCMessage): Promise<string> {\n const eventId = this.generateEventId(streamId);\n this.events.set(eventId, { message, streamId });\n return eventId;\n }\n\n /**\n * Generates a unique event ID for a given stream ID\n */\n private generateEventId(streamId: string): string {\n return `${streamId}_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n }\n\n /**\n * Extracts the stream ID from an event ID\n */\n private getStreamIdFromEventId(eventId: string): string {\n const parts = eventId.split(\"_\");\n return parts.length > 0 ? parts[0] : \"\";\n }\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n CallToolRequestSchema,\n CompleteRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourcesRequestSchema,\n ListResourceTemplatesRequestSchema,\n ListToolsRequestSchema,\n LoggingMessageNotificationSchema,\n ReadResourceRequestSchema,\n ResourceUpdatedNotificationSchema,\n ServerCapabilities,\n SubscribeRequestSchema,\n UnsubscribeRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nexport const proxyServer = async ({\n client,\n server,\n serverCapabilities,\n}: {\n client: Client;\n server: Server;\n serverCapabilities: ServerCapabilities;\n}): Promise<void> => {\n if (serverCapabilities?.logging) {\n server.setNotificationHandler(\n LoggingMessageNotificationSchema,\n async (args) => {\n return client.notification(args);\n },\n );\n client.setNotificationHandler(\n LoggingMessageNotificationSchema,\n async (args) => {\n return server.notification(args);\n },\n );\n }\n\n if (serverCapabilities?.prompts) {\n server.setRequestHandler(GetPromptRequestSchema, async (args) => {\n return client.getPrompt(args.params);\n });\n\n server.setRequestHandler(ListPromptsRequestSchema, async (args) => {\n return client.listPrompts(args.params);\n });\n }\n\n if (serverCapabilities?.resources) {\n server.setRequestHandler(ListResourcesRequestSchema, async (args) => {\n return client.listResources(args.params);\n });\n\n server.setRequestHandler(\n ListResourceTemplatesRequestSchema,\n async (args) => {\n return client.listResourceTemplates(args.params);\n },\n );\n\n server.setRequestHandler(ReadResourceRequestSchema, async (args) => {\n return client.readResource(args.params);\n });\n\n if (serverCapabilities?.resources.subscribe) {\n server.setNotificationHandler(\n ResourceUpdatedNotificationSchema,\n async (args) => {\n return client.notification(args);\n },\n );\n\n server.setRequestHandler(SubscribeRequestSchema, async (args) => {\n return client.subscribeResource(args.params);\n });\n\n server.setRequestHandler(UnsubscribeRequestSchema, async (args) => {\n return client.unsubscribeResource(args.params);\n });\n }\n }\n\n if (serverCapabilities?.tools) {\n server.setRequestHandler(CallToolRequestSchema, async (args) => {\n return client.callTool(args.params);\n });\n\n server.setRequestHandler(ListToolsRequestSchema, async (args) => {\n return client.listTools(args.params);\n });\n }\n\n server.setRequestHandler(CompleteRequestSchema, async (args) => {\n return client.complete(args.params);\n });\n};\n","import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { SSEServerTransport } from \"@modelcontextprotocol/sdk/server/sse.js\";\nimport {\n EventStore,\n StreamableHTTPServerTransport,\n} from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { isInitializeRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport http from \"http\";\nimport { randomUUID } from \"node:crypto\";\n\nimport { InMemoryEventStore } from \"./InMemoryEventStore.js\";\n\nexport type SSEServer = {\n close: () => Promise<void>;\n};\n\ntype ServerLike = {\n close: Server[\"close\"];\n connect: Server[\"connect\"];\n};\n\nconst getBody = (request: http.IncomingMessage) => {\n return new Promise((resolve) => {\n const bodyParts: Buffer[] = [];\n let body: string;\n request\n .on(\"data\", (chunk) => {\n bodyParts.push(chunk);\n })\n .on(\"end\", () => {\n body = Buffer.concat(bodyParts).toString();\n try {\n resolve(JSON.parse(body));\n } catch(error) {\n console.error(\"Error parsing body:\", error);\n resolve(null);\n }\n });\n });\n};\n\nconst handleStreamRequest = async <T extends ServerLike>({\n activeTransports,\n createServer,\n endpoint,\n eventStore,\n onClose,\n onConnect,\n req,\n res,\n}: {\n activeTransports: Record<\n string,\n { server: T; transport: StreamableHTTPServerTransport }\n >;\n createServer: (request: http.IncomingMessage) => Promise<T>;\n endpoint: string;\n eventStore?: EventStore;\n onClose?: (server: T) => void;\n onConnect?: (server: T) => void;\n req: http.IncomingMessage;\n res: http.ServerResponse;\n}) => {\n if (\n req.method === \"POST\" &&\n new URL(req.url!, \"http://localhost\").pathname === endpoint\n ) {\n try {\n const sessionId = Array.isArray(req.headers[\"mcp-session-id\"])\n ? req.headers[\"mcp-session-id\"][0]\n : req.headers[\"mcp-session-id\"];\n\n let transport: StreamableHTTPServerTransport;\n \n let server: T;\n\n const body = await getBody(req);\n\n if (sessionId && activeTransports[sessionId]) {\n transport = activeTransports[sessionId].transport;\n server = activeTransports[sessionId].server;\n } else if (!sessionId && isInitializeRequest(body)) {\n // Create a new transport for the session\n transport = new StreamableHTTPServerTransport({\n eventStore: eventStore || new InMemoryEventStore(),\n onsessioninitialized: (_sessionId) => {\n // add only when the id Sesison id is generated\n activeTransports[_sessionId] = {\n server,\n transport,\n };\n },\n sessionIdGenerator: randomUUID,\n });\n\n // Handle the server close event\n transport.onclose = async () => {\n const sid = transport.sessionId;\n if (sid && activeTransports[sid]) {\n onClose?.(server);\n\n try {\n await server.close();\n } catch (error) {\n console.error(\"Error closing server:\", error);\n }\n\n delete activeTransports[sid];\n }\n };\n\n try {\n server = await createServer(req);\n } catch (error) {\n if (error instanceof Response) {\n res.writeHead(error.status).end(error.statusText);\n\n return true;\n }\n\n res.writeHead(500).end(\"Error creating server\");\n\n return true;\n }\n\n server.connect(transport);\n\n onConnect?.(server);\n\n await transport.handleRequest(req, res, body);\n\n return true;\n } else {\n // Error if the server is not created but the request is not an initialize request\n res.setHeader(\"Content-Type\", \"application/json\");\n\n res.writeHead(400).end(\n JSON.stringify({\n error: {\n code: -32000,\n message: \"Bad Request: No valid session ID provided\",\n },\n id: null,\n jsonrpc: \"2.0\",\n }),\n );\n\n return true;\n }\n\n // Handle the request if the server is already created\n await transport.handleRequest(req, res, body);\n\n return true;\n } catch (error) {\n console.error(\"Error handling request:\", error);\n\n res.setHeader(\"Content-Type\", \"application/json\");\n\n res.writeHead(500).end(\n JSON.stringify({\n error: { code: -32603, message: \"Internal Server Error\" },\n id: null,\n jsonrpc: \"2.0\",\n }),\n );\n }\n return true;\n }\n\n if (\n req.method === \"GET\" &&\n new URL(req.url!, \"http://localhost\").pathname === endpoint\n ) {\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n const activeTransport:\n | {\n server: T;\n transport: StreamableHTTPServerTransport;\n }\n | undefined = sessionId ? activeTransports[sessionId] : undefined;\n\n if (!sessionId) {\n res.writeHead(400).end(\"No sessionId\");\n\n return true;\n }\n\n if (!activeTransport) {\n res.writeHead(400).end(\"No active transport\");\n\n return true;\n }\n\n const lastEventId = req.headers[\"last-event-id\"] as string | undefined;\n\n if (lastEventId) {\n console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`);\n } else {\n console.log(`Establishing new SSE stream for session ${sessionId}`);\n }\n\n await activeTransport.transport.handleRequest(req, res);\n\n return true;\n }\n\n if (\n req.method === \"DELETE\" &&\n new URL(req.url!, \"http://localhost\").pathname === endpoint\n ) {\n console.log(\"received delete request\");\n\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n if (!sessionId) {\n res.writeHead(400).end(\"Invalid or missing sessionId\");\n\n return true;\n }\n\n console.log(\"received delete request for session\", sessionId);\n\n const activeTransport = activeTransports[sessionId];\n\n if (!activeTransport) {\n res.writeHead(400).end(\"No active transport\");\n return true;\n }\n\n try {\n await activeTransport.transport.handleRequest(req, res);\n\n onClose?.(activeTransport.server);\n } catch (error) {\n console.error(\"Error handling delete request:\", error);\n\n res.writeHead(500).end(\"Error handling delete request\");\n }\n\n return true;\n }\n\n return false;\n};\n\nconst handleSSERequest = async <T extends ServerLike>({\n activeTransports,\n createServer,\n endpoint,\n onClose,\n onConnect,\n req,\n res,\n}: {\n activeTransports: Record<string, SSEServerTransport>;\n createServer: (request: http.IncomingMessage) => Promise<T>;\n endpoint: string;\n onClose?: (server: T) => void;\n onConnect?: (server: T) => void;\n req: http.IncomingMessage;\n res: http.ServerResponse;\n}) => {\n if (\n req.method === \"GET\" &&\n new URL(req.url!, \"http://localhost\").pathname === endpoint\n ) {\n const transport = new SSEServerTransport(\"/messages\", res);\n\n let server: T;\n\n try {\n server = await createServer(req);\n } catch (error) {\n if (error instanceof Response) {\n res.writeHead(error.status).end(error.statusText);\n\n return true;\n }\n\n res.writeHead(500).end(\"Error creating server\");\n\n return true;\n }\n\n activeTransports[transport.sessionId] = transport;\n\n let closed = false;\n\n res.on(\"close\", async () => {\n closed = true;\n\n try {\n await server.close();\n } catch (error) {\n console.error(\"Error closing server:\", error);\n }\n\n delete activeTransports[transport.sessionId];\n\n onClose?.(server);\n });\n\n try {\n await server.connect(transport);\n\n await transport.send({\n jsonrpc: \"2.0\",\n method: \"sse/connection\",\n params: { message: \"SSE Connection established\" },\n });\n\n onConnect?.(server);\n } catch (error) {\n if (!closed) {\n console.error(\"Error connecting to server:\", error);\n\n res.writeHead(500).end(\"Error connecting to server\");\n }\n }\n\n return true;\n }\n\n if (req.method === \"POST\" && req.url?.startsWith(\"/messages\")) {\n const sessionId = new URL(req.url, \"https://example.com\").searchParams.get(\n \"sessionId\",\n );\n\n if (!sessionId) {\n res.writeHead(400).end(\"No sessionId\");\n\n return true;\n }\n\n const activeTransport: SSEServerTransport | undefined =\n activeTransports[sessionId];\n\n if (!activeTransport) {\n res.writeHead(400).end(\"No active transport\");\n\n return true;\n }\n\n await activeTransport.handlePostMessage(req, res);\n\n return true;\n }\n\n return false;\n};\n\nexport const startHTTPServer = async <T extends ServerLike>({\n createServer,\n eventStore,\n onClose,\n onConnect,\n onUnhandledRequest,\n port,\n sseEndpoint,\n streamEndpoint,\n}: {\n createServer: (request: http.IncomingMessage) => Promise<T>;\n eventStore?: EventStore;\n onClose?: (server: T) => void;\n onConnect?: (server: T) => void;\n onUnhandledRequest?: (\n req: http.IncomingMessage,\n res: http.ServerResponse,\n ) => Promise<void>;\n port: number;\n sseEndpoint?: null | string;\n streamEndpoint?: null | string;\n}): Promise<SSEServer> => {\n const activeSSETransports: Record<string, SSEServerTransport> = {};\n\n const activeStreamTransports: Record<\n string,\n {\n server: T;\n transport: StreamableHTTPServerTransport;\n }\n > = {};\n\n /**\n * @author https://dev.classmethod.jp/articles/mcp-sse/\n */\n const httpServer = http.createServer(async (req, res) => {\n if (req.headers.origin) {\n try {\n const origin = new URL(req.headers.origin);\n\n res.setHeader(\"Access-Control-Allow-Origin\", origin.origin);\n res.setHeader(\"Access-Control-Allow-Credentials\", \"true\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"*\");\n res.setHeader(\"Access-Control-Expose-Headers\", \"mcp-session-id\");\n } catch (error) {\n console.error(\"Error parsing origin:\", error);\n }\n }\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (req.method === \"GET\" && req.url === `/ping`) {\n res.writeHead(200).end(\"pong\");\n return;\n }\n\n if (\n sseEndpoint !== null &&\n await handleSSERequest({\n activeTransports: activeSSETransports,\n createServer,\n endpoint: sseEndpoint ?? \"/sse\",\n onClose,\n onConnect,\n req,\n res,\n })\n ) {\n return;\n }\n\n if (\n streamEndpoint !== null &&\n await handleStreamRequest({\n activeTransports: activeStreamTransports,\n createServer,\n endpoint: streamEndpoint ?? \"/mcp\",\n eventStore,\n onClose,\n onConnect,\n req,\n res,\n })\n ) {\n return;\n }\n\n if (onUnhandledRequest) {\n await onUnhandledRequest(req, res);\n } else {\n res.writeHead(404).end();\n }\n });\n\n await new Promise((resolve) => {\n httpServer.listen(port, \"::\", () => {\n resolve(undefined);\n });\n });\n\n return {\n close: async () => {\n for (const transport of Object.values(activeSSETransports)) {\n await transport.close();\n }\n\n for (const transport of Object.values(activeStreamTransports)) {\n await transport.transport.close();\n }\n\n return new Promise((resolve, reject) => {\n httpServer.close((error) => {\n if (error) {\n reject(error);\n\n return;\n }\n\n resolve();\n });\n });\n },\n };\n};\n"],"mappings":"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","names":[]}