@eaperezc/mcpgen 0.1.0 → 0.1.1

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.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { I as InlineToolDefinition, c as InlineResourceDefinition, d as InlinePromptDefinition, T as TransportConfig, e as AuthConfig, L as LogLevel, S as ServerHooks, M as McpServer, f as Logger, R as RequestContextData, A as AuthContext, g as Transport, H as HttpTransportConfig } from './types-B9yzEar_.js';
2
- export { k as ApiKeyConfig, l as ApiKeyValidationResult, b as BasePrompt, a as BaseResource, B as BaseTool, U as ContextKey, Y as CorsConfig, K as LogEntry, Q as LogTransport, N as LoggerConfig, O as OAuthConfig, F as PromptArgumentMetadata, C as PromptDefinition, E as PromptHandler, z as PromptMessage, G as PromptMetadata, P as PromptRegistry, D as PromptResult, y as PromptRole, s as ResourceContent, t as ResourceDefinition, v as ResourceHandler, w as ResourceMetadata, r as ResourceRegistry, u as ResourceResult, x as ResourceTemplate, j as ServerCapabilities, h as ServerConfig, i as ServerInfo, X as SseTransportConfig, W as StdioTransportConfig, Z as TlsConfig, n as ToolDefinition, p as ToolHandler, q as ToolMetadata, m as ToolRegistry, o as ToolResult, V as TransportType, J as logger } from './types-B9yzEar_.js';
1
+ import { I as InlineToolDefinition, c as InlineResourceDefinition, d as InlinePromptDefinition, T as TransportConfig, e as AuthConfig, L as LogLevel, S as ServerHooks, M as McpServer, f as Logger, R as RequestContextData, A as AuthContext, g as Transport, H as HttpTransportConfig } from './types-Bu1xVhfb.js';
2
+ export { k as ApiKeyConfig, l as ApiKeyValidationResult, b as BasePrompt, a as BaseResource, B as BaseTool, U as ContextKey, Y as CorsConfig, K as LogEntry, Q as LogTransport, N as LoggerConfig, O as OAuthConfig, F as PromptArgumentMetadata, C as PromptDefinition, E as PromptHandler, z as PromptMessage, G as PromptMetadata, P as PromptRegistry, D as PromptResult, y as PromptRole, s as ResourceContent, t as ResourceDefinition, v as ResourceHandler, w as ResourceMetadata, r as ResourceRegistry, u as ResourceResult, x as ResourceTemplate, j as ServerCapabilities, h as ServerConfig, i as ServerInfo, X as SseTransportConfig, W as StdioTransportConfig, Z as TlsConfig, n as ToolDefinition, p as ToolHandler, q as ToolMetadata, m as ToolRegistry, o as ToolResult, V as TransportType, J as logger } from './types-Bu1xVhfb.js';
3
3
  import { z } from 'zod';
4
4
  export { z } from 'zod';
5
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
6
5
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
6
 
8
7
  /**
@@ -241,33 +240,22 @@ declare class McpError extends Error {
241
240
  }
242
241
 
243
242
  /**
244
- * HTTP Transport for MCP servers
245
- *
246
- * Implements the MCP Streamable HTTP transport specification,
247
- * supporting both SSE streaming and direct HTTP responses.
248
- *
249
- * @example
250
- * ```typescript
251
- * const transport = new HttpTransport({
252
- * type: 'http',
253
- * port: 3000,
254
- * cors: { origin: ['https://myapp.com'] },
255
- * });
256
- *
257
- * await transport.start(mcpServer);
258
- * ```
243
+ * Factory function to create a configured MCP Server instance
259
244
  */
245
+ type ServerFactory = () => Server;
260
246
  declare class HttpTransport implements Transport {
261
247
  private config;
262
248
  private logger;
263
249
  private httpServer;
264
- private mcpTransport;
265
250
  private running;
251
+ private serverFactory;
252
+ private sessions;
266
253
  constructor(config: HttpTransportConfig, logger?: Logger);
267
254
  /**
268
255
  * Start the HTTP transport
256
+ * @param serverFactory - Factory function to create new Server instances per session
269
257
  */
270
- start(mcpServer?: Server): Promise<void>;
258
+ start(serverFactory?: ServerFactory): Promise<void>;
271
259
  /**
272
260
  * Stop the HTTP transport
273
261
  */
@@ -277,9 +265,13 @@ declare class HttpTransport implements Transport {
277
265
  */
278
266
  isRunning(): boolean;
279
267
  /**
280
- * Get the underlying MCP transport (for advanced use cases)
268
+ * Get all active sessions (for debugging/monitoring)
269
+ */
270
+ getActiveSessions(): string[];
271
+ /**
272
+ * Get or create a session for the given session ID
281
273
  */
282
- getMcpTransport(): StreamableHTTPServerTransport | null;
274
+ private getOrCreateSession;
283
275
  /**
284
276
  * Handle incoming HTTP request
285
277
  */
package/dist/index.js CHANGED
@@ -873,8 +873,9 @@ var HttpTransport = class {
873
873
  config;
874
874
  logger;
875
875
  httpServer = null;
876
- mcpTransport = null;
877
876
  running = false;
877
+ serverFactory = null;
878
+ sessions = /* @__PURE__ */ new Map();
878
879
  constructor(config, logger2) {
879
880
  this.config = {
880
881
  ...config,
@@ -886,17 +887,13 @@ var HttpTransport = class {
886
887
  }
887
888
  /**
888
889
  * Start the HTTP transport
890
+ * @param serverFactory - Factory function to create new Server instances per session
889
891
  */
890
- async start(mcpServer) {
892
+ async start(serverFactory) {
891
893
  if (this.running) {
892
894
  throw new Error("Transport is already running");
893
895
  }
894
- this.mcpTransport = new StreamableHTTPServerTransport({
895
- sessionIdGenerator: () => randomUUID()
896
- });
897
- if (mcpServer) {
898
- await mcpServer.connect(this.mcpTransport);
899
- }
896
+ this.serverFactory = serverFactory ?? null;
900
897
  this.httpServer = createServer((req, res) => {
901
898
  this.handleRequest(req, res);
902
899
  });
@@ -924,10 +921,15 @@ var HttpTransport = class {
924
921
  if (!this.running) {
925
922
  return;
926
923
  }
927
- if (this.mcpTransport) {
928
- await this.mcpTransport.close();
929
- this.mcpTransport = null;
924
+ for (const [sessionId, session] of this.sessions) {
925
+ try {
926
+ await session.transport.close();
927
+ await session.server.close();
928
+ } catch (error) {
929
+ this.logger.error(`Error closing session ${sessionId}`, error instanceof Error ? error : void 0);
930
+ }
930
931
  }
932
+ this.sessions.clear();
931
933
  if (this.httpServer) {
932
934
  return new Promise((resolve, reject) => {
933
935
  this.httpServer.close((error) => {
@@ -951,10 +953,34 @@ var HttpTransport = class {
951
953
  return this.running;
952
954
  }
953
955
  /**
954
- * Get the underlying MCP transport (for advanced use cases)
956
+ * Get all active sessions (for debugging/monitoring)
957
+ */
958
+ getActiveSessions() {
959
+ return Array.from(this.sessions.keys());
960
+ }
961
+ /**
962
+ * Get or create a session for the given session ID
955
963
  */
956
- getMcpTransport() {
957
- return this.mcpTransport;
964
+ async getOrCreateSession(sessionId) {
965
+ let session = this.sessions.get(sessionId);
966
+ if (!session) {
967
+ if (!this.serverFactory) {
968
+ throw new Error("No server factory configured");
969
+ }
970
+ const transport = new StreamableHTTPServerTransport({
971
+ sessionIdGenerator: () => sessionId
972
+ });
973
+ const server = this.serverFactory();
974
+ await server.connect(transport);
975
+ session = {
976
+ transport,
977
+ server,
978
+ createdAt: Date.now()
979
+ };
980
+ this.sessions.set(sessionId, session);
981
+ this.logger.debug("Created new session", { sessionId });
982
+ }
983
+ return session;
958
984
  }
959
985
  /**
960
986
  * Handle incoming HTTP request
@@ -975,9 +1001,9 @@ var HttpTransport = class {
975
1001
  return;
976
1002
  }
977
1003
  if (path === this.config.basePath || path === `${this.config.basePath}/`) {
978
- if (!this.mcpTransport) {
1004
+ if (!this.serverFactory) {
979
1005
  res.writeHead(503, { "Content-Type": "application/json" });
980
- res.end(JSON.stringify({ error: "Transport not initialized" }));
1006
+ res.end(JSON.stringify({ error: "Server factory not configured" }));
981
1007
  return;
982
1008
  }
983
1009
  try {
@@ -985,7 +1011,12 @@ var HttpTransport = class {
985
1011
  if (req.method === "POST") {
986
1012
  body = await this.parseBody(req);
987
1013
  }
988
- await this.mcpTransport.handleRequest(req, res, body);
1014
+ let sessionId = req.headers["mcp-session-id"];
1015
+ if (!sessionId) {
1016
+ sessionId = randomUUID();
1017
+ }
1018
+ const session = await this.getOrCreateSession(sessionId);
1019
+ await session.transport.handleRequest(req, res, body);
989
1020
  } catch (error) {
990
1021
  this.logger.error("Error handling MCP request", error instanceof Error ? error : void 0);
991
1022
  if (!res.headersSent) {
@@ -1102,10 +1133,17 @@ var McpServer = class {
1102
1133
  };
1103
1134
  }
1104
1135
  /**
1105
- * Set up MCP request handlers
1136
+ * Set up MCP request handlers on a server instance
1106
1137
  */
1107
1138
  setupHandlers() {
1108
- this.server.setRequestHandler(ListToolsRequestSchema, async () => {
1139
+ this.setupHandlersOnServer(this.server);
1140
+ }
1141
+ /**
1142
+ * Configure handlers on a given Server instance
1143
+ * This is used both for the main server (stdio) and for per-session servers (http)
1144
+ */
1145
+ setupHandlersOnServer(server) {
1146
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
1109
1147
  return runInRequestContextAsync(async () => {
1110
1148
  const tools = this.toolRegistry.getAll();
1111
1149
  return {
@@ -1117,7 +1155,7 @@ var McpServer = class {
1117
1155
  };
1118
1156
  });
1119
1157
  });
1120
- this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
1158
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1121
1159
  return runInRequestContextAsync(async () => {
1122
1160
  const { name, arguments: args } = request.params;
1123
1161
  const tool = this.toolRegistry.get(name);
@@ -1136,7 +1174,7 @@ var McpServer = class {
1136
1174
  };
1137
1175
  });
1138
1176
  });
1139
- this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
1177
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
1140
1178
  return runInRequestContextAsync(async () => {
1141
1179
  const resources = this.resourceRegistry.getAll();
1142
1180
  return {
@@ -1149,7 +1187,7 @@ var McpServer = class {
1149
1187
  };
1150
1188
  });
1151
1189
  });
1152
- this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
1190
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
1153
1191
  return runInRequestContextAsync(async () => {
1154
1192
  const { uri } = request.params;
1155
1193
  const resource = this.resourceRegistry.get(uri);
@@ -1165,7 +1203,7 @@ var McpServer = class {
1165
1203
  };
1166
1204
  });
1167
1205
  });
1168
- this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
1206
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
1169
1207
  return runInRequestContextAsync(async () => {
1170
1208
  const prompts = this.promptRegistry.getAll();
1171
1209
  return {
@@ -1184,7 +1222,7 @@ var McpServer = class {
1184
1222
  };
1185
1223
  });
1186
1224
  });
1187
- this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
1225
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
1188
1226
  return runInRequestContextAsync(async () => {
1189
1227
  const { name, arguments: args } = request.params;
1190
1228
  const prompt = this.promptRegistry.get(name);
@@ -1202,6 +1240,24 @@ var McpServer = class {
1202
1240
  });
1203
1241
  });
1204
1242
  }
1243
+ /**
1244
+ * Create a server factory for HTTP transport (creates per-session servers)
1245
+ */
1246
+ createServerFactory() {
1247
+ return () => {
1248
+ const server = new Server(
1249
+ {
1250
+ name: this.config.name,
1251
+ version: this.config.version
1252
+ },
1253
+ {
1254
+ capabilities: this.getCapabilities()
1255
+ }
1256
+ );
1257
+ this.setupHandlersOnServer(server);
1258
+ return server;
1259
+ };
1260
+ }
1205
1261
  tool(toolOrName, definition) {
1206
1262
  if (typeof toolOrName === "string" && definition) {
1207
1263
  this.toolRegistry.registerInline(toolOrName, definition);
@@ -1245,14 +1301,6 @@ var McpServer = class {
1245
1301
  }
1246
1302
  const transportConfig = this.config.transport ?? "stdio";
1247
1303
  const transportType = typeof transportConfig === "string" ? transportConfig : transportConfig.type;
1248
- this.logger.info("Starting MCP server", {
1249
- name: this.config.name,
1250
- version: this.config.version,
1251
- transport: transportType,
1252
- tools: this.toolRegistry.size,
1253
- resources: this.resourceRegistry.size,
1254
- prompts: this.promptRegistry.size
1255
- });
1256
1304
  try {
1257
1305
  await this.hooks.onBeforeStart?.();
1258
1306
  if (transportType === "stdio") {
@@ -1261,7 +1309,7 @@ var McpServer = class {
1261
1309
  } else if (transportType === "http") {
1262
1310
  const httpConfig = transportConfig;
1263
1311
  this.httpTransport = new HttpTransport(httpConfig, this.logger);
1264
- await this.httpTransport.start(this.server);
1312
+ await this.httpTransport.start(this.createServerFactory());
1265
1313
  } else if (transportType === "sse") {
1266
1314
  throw new McpError({
1267
1315
  code: "NOT_IMPLEMENTED" /* NOT_IMPLEMENTED */,
@@ -1270,8 +1318,12 @@ var McpServer = class {
1270
1318
  }
1271
1319
  this.running = true;
1272
1320
  await this.hooks.onAfterStart?.();
1273
- this.logger.info("MCP server started successfully", {
1321
+ this.logger.info("MCP server started", {
1322
+ version: this.config.version,
1274
1323
  transport: transportType,
1324
+ tools: this.toolRegistry.size,
1325
+ resources: this.resourceRegistry.size,
1326
+ prompts: this.promptRegistry.size,
1275
1327
  ...transportType === "http" && {
1276
1328
  port: transportConfig.port,
1277
1329
  host: transportConfig.host ?? "0.0.0.0"