@frontmcp/sdk 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/package.json +8 -19
- package/src/adapter/adapter.instance.js +5 -0
- package/src/adapter/adapter.instance.js.map +1 -1
- package/src/auth/authorization/authorization.class.d.ts +1 -4
- package/src/auth/authorization/authorization.class.js +6 -13
- package/src/auth/authorization/authorization.class.js.map +1 -1
- package/src/auth/flows/session.verify.flow.d.ts +1 -0
- package/src/auth/flows/session.verify.flow.js +11 -1
- package/src/auth/flows/session.verify.flow.js.map +1 -1
- package/src/auth/flows/well-known.jwks.flow.js +2 -2
- package/src/auth/flows/well-known.jwks.flow.js.map +1 -1
- package/src/auth/jwks/dev-key-persistence.d.ts +63 -0
- package/src/auth/jwks/dev-key-persistence.js +219 -0
- package/src/auth/jwks/dev-key-persistence.js.map +1 -0
- package/src/auth/jwks/index.d.ts +1 -0
- package/src/auth/jwks/index.js +1 -0
- package/src/auth/jwks/index.js.map +1 -1
- package/src/auth/jwks/jwks.service.d.ts +7 -4
- package/src/auth/jwks/jwks.service.js +81 -12
- package/src/auth/jwks/jwks.service.js.map +1 -1
- package/src/auth/jwks/jwks.types.d.ts +7 -0
- package/src/auth/jwks/jwks.types.js.map +1 -1
- package/src/auth/machine-id.d.ts +5 -0
- package/src/auth/machine-id.js +32 -0
- package/src/auth/machine-id.js.map +1 -0
- package/src/auth/session/index.d.ts +1 -0
- package/src/auth/session/index.js +3 -1
- package/src/auth/session/index.js.map +1 -1
- package/src/auth/session/record/session.base.js +5 -3
- package/src/auth/session/record/session.base.js.map +1 -1
- package/src/auth/session/record/session.stateless.d.ts +2 -2
- package/src/auth/session/record/session.stateless.js +5 -3
- package/src/auth/session/record/session.stateless.js.map +1 -1
- package/src/auth/session/redis-session.store.d.ts +64 -0
- package/src/auth/session/redis-session.store.js +204 -0
- package/src/auth/session/redis-session.store.js.map +1 -0
- package/src/auth/session/session.service.d.ts +0 -2
- package/src/auth/session/session.service.js +1 -7
- package/src/auth/session/session.service.js.map +1 -1
- package/src/auth/session/transport-session.manager.js +3 -5
- package/src/auth/session/transport-session.manager.js.map +1 -1
- package/src/auth/session/transport-session.types.d.ts +4 -0
- package/src/auth/session/transport-session.types.js +4 -3
- package/src/auth/session/transport-session.types.js.map +1 -1
- package/src/auth/session/utils/session-id.utils.d.ts +12 -1
- package/src/auth/session/utils/session-id.utils.js +48 -9
- package/src/auth/session/utils/session-id.utils.js.map +1 -1
- package/src/auth/ui/base-layout.d.ts +0 -8
- package/src/auth/ui/base-layout.js +1 -14
- package/src/auth/ui/base-layout.js.map +1 -1
- package/src/auth/ui/index.d.ts +3 -4
- package/src/auth/ui/index.js +10 -11
- package/src/auth/ui/index.js.map +1 -1
- package/src/auth/ui/{htmx-templates.d.ts → templates.d.ts} +5 -6
- package/src/auth/ui/{htmx-templates.js → templates.js} +8 -15
- package/src/auth/ui/templates.js.map +1 -0
- package/src/common/decorators/decorator-utils.js.map +1 -1
- package/src/common/decorators/front-mcp.decorator.js +28 -2
- package/src/common/decorators/front-mcp.decorator.js.map +1 -1
- package/src/common/index.d.ts +0 -1
- package/src/common/index.js +0 -1
- package/src/common/index.js.map +1 -1
- package/src/common/interfaces/adapter.interface.d.ts +6 -0
- package/src/common/interfaces/adapter.interface.js.map +1 -1
- package/src/common/interfaces/execution-context.interface.d.ts +52 -3
- package/src/common/interfaces/execution-context.interface.js +88 -3
- package/src/common/interfaces/execution-context.interface.js.map +1 -1
- package/src/common/interfaces/flow.interface.d.ts +13 -0
- package/src/common/interfaces/flow.interface.js +24 -0
- package/src/common/interfaces/flow.interface.js.map +1 -1
- package/src/common/interfaces/server.interface.d.ts +9 -0
- package/src/common/interfaces/server.interface.js.map +1 -1
- package/src/common/metadata/app.metadata.d.ts +108 -0
- package/src/common/metadata/front-mcp.metadata.d.ts +659 -2
- package/src/common/metadata/front-mcp.metadata.js +3 -1
- package/src/common/metadata/front-mcp.metadata.js.map +1 -1
- package/src/common/metadata/provider.metadata.d.ts +14 -0
- package/src/common/metadata/provider.metadata.js +18 -2
- package/src/common/metadata/provider.metadata.js.map +1 -1
- package/src/common/metadata/tool.metadata.d.ts +33 -1
- package/src/common/metadata/tool.metadata.js.map +1 -1
- package/src/common/migrate/auth-transport.migrate.d.ts +62 -0
- package/src/common/migrate/auth-transport.migrate.js +140 -0
- package/src/common/migrate/auth-transport.migrate.js.map +1 -0
- package/src/common/migrate/index.d.ts +1 -0
- package/src/common/migrate/index.js +6 -0
- package/src/common/migrate/index.js.map +1 -0
- package/src/common/schemas/http-output.schema.d.ts +10 -2
- package/src/common/schemas/index.d.ts +1 -0
- package/src/common/schemas/index.js +1 -0
- package/src/common/schemas/index.js.map +1 -1
- package/src/common/schemas/session-header.schema.d.ts +16 -0
- package/src/common/schemas/session-header.schema.js +42 -0
- package/src/common/schemas/session-header.schema.js.map +1 -0
- package/src/common/tokens/front-mcp.tokens.js +3 -1
- package/src/common/tokens/front-mcp.tokens.js.map +1 -1
- package/src/common/types/options/auth.options.d.ts +233 -3
- package/src/common/types/options/auth.options.js +29 -40
- package/src/common/types/options/auth.options.js.map +1 -1
- package/src/common/types/options/index.d.ts +2 -0
- package/src/common/types/options/index.js +2 -0
- package/src/common/types/options/index.js.map +1 -1
- package/src/common/types/options/redis.options.d.ts +22 -0
- package/src/common/types/options/redis.options.js +45 -0
- package/src/common/types/options/redis.options.js.map +1 -0
- package/src/common/types/options/transport.options.d.ts +84 -0
- package/src/common/types/options/transport.options.js +121 -0
- package/src/common/types/options/transport.options.js.map +1 -0
- package/src/completion/flows/complete.flow.d.ts +17 -2
- package/src/context/frontmcp-context-storage.d.ts +94 -0
- package/src/context/frontmcp-context-storage.js +183 -0
- package/src/context/frontmcp-context-storage.js.map +1 -0
- package/src/context/frontmcp-context.d.ts +269 -0
- package/src/context/frontmcp-context.js +360 -0
- package/src/context/frontmcp-context.js.map +1 -0
- package/src/context/frontmcp-context.provider.d.ts +43 -0
- package/src/context/frontmcp-context.provider.js +61 -0
- package/src/context/frontmcp-context.provider.js.map +1 -0
- package/src/context/index.d.ts +34 -0
- package/src/context/index.js +64 -0
- package/src/context/index.js.map +1 -0
- package/src/context/request-context-storage.d.ts +89 -0
- package/src/context/request-context-storage.js +183 -0
- package/src/context/request-context-storage.js.map +1 -0
- package/src/context/request-context.d.ts +184 -0
- package/src/context/request-context.js +209 -0
- package/src/context/request-context.js.map +1 -0
- package/src/context/request-context.provider.d.ts +37 -0
- package/src/context/request-context.provider.js +51 -0
- package/src/context/request-context.provider.js.map +1 -0
- package/src/context/session-key.provider.d.ts +45 -0
- package/src/context/session-key.provider.js +65 -0
- package/src/context/session-key.provider.js.map +1 -0
- package/src/context/trace-context.d.ts +43 -0
- package/src/context/trace-context.js +142 -0
- package/src/context/trace-context.js.map +1 -0
- package/src/errors/index.d.ts +1 -1
- package/src/errors/index.js +3 -1
- package/src/errors/index.js.map +1 -1
- package/src/errors/mcp.error.d.ts +7 -0
- package/src/errors/mcp.error.js +11 -1
- package/src/errors/mcp.error.js.map +1 -1
- package/src/flows/flow.instance.d.ts +16 -0
- package/src/flows/flow.instance.js +166 -80
- package/src/flows/flow.instance.js.map +1 -1
- package/src/flows/flow.registry.d.ts +5 -0
- package/src/flows/flow.registry.js +45 -3
- package/src/flows/flow.registry.js.map +1 -1
- package/src/front-mcp/front-mcp.d.ts +12 -0
- package/src/front-mcp/front-mcp.js +22 -3
- package/src/front-mcp/front-mcp.js.map +1 -1
- package/src/front-mcp/front-mcp.providers.d.ts +266 -1
- package/src/front-mcp/front-mcp.providers.js +2 -1
- package/src/front-mcp/front-mcp.providers.js.map +1 -1
- package/src/front-mcp/serverless-handler.d.ts +28 -0
- package/src/front-mcp/serverless-handler.js +61 -0
- package/src/front-mcp/serverless-handler.js.map +1 -0
- package/src/hooks/hooks.utils.d.ts +1 -1
- package/src/hooks/hooks.utils.js +10 -3
- package/src/hooks/hooks.utils.js.map +1 -1
- package/src/index.d.ts +8 -4
- package/src/index.js +20 -1
- package/src/index.js.map +1 -1
- package/src/logger/instances/instance.logger.js +0 -1
- package/src/logger/instances/instance.logger.js.map +1 -1
- package/src/logging/flows/set-level.flow.d.ts +17 -2
- package/src/notification/notification.service.js +5 -1
- package/src/notification/notification.service.js.map +1 -1
- package/src/prompt/flows/get-prompt.flow.d.ts +97 -2
- package/src/prompt/flows/prompts-list.flow.d.ts +12 -1
- package/src/provider/provider.registry.d.ts +97 -5
- package/src/provider/provider.registry.js +306 -9
- package/src/provider/provider.registry.js.map +1 -1
- package/src/provider/provider.types.d.ts +21 -3
- package/src/provider/provider.types.js.map +1 -1
- package/src/resource/flows/read-resource.flow.d.ts +22 -3
- package/src/resource/flows/resource-templates-list.flow.d.ts +20 -1
- package/src/resource/flows/resources-list.flow.d.ts +20 -1
- package/src/resource/flows/subscribe-resource.flow.d.ts +17 -2
- package/src/resource/flows/unsubscribe-resource.flow.d.ts +17 -2
- package/src/scope/flows/http.request.flow.js +43 -7
- package/src/scope/flows/http.request.flow.js.map +1 -1
- package/src/scope/scope.instance.js +12 -5
- package/src/scope/scope.instance.js.map +1 -1
- package/src/server/adapters/base.host.adapter.d.ts +9 -0
- package/src/server/adapters/base.host.adapter.js.map +1 -1
- package/src/server/adapters/express.host.adapter.d.ts +12 -0
- package/src/server/adapters/express.host.adapter.js +21 -1
- package/src/server/adapters/express.host.adapter.js.map +1 -1
- package/src/server/server.instance.d.ts +3 -0
- package/src/server/server.instance.js +14 -7
- package/src/server/server.instance.js.map +1 -1
- package/src/tool/flows/call-tool.flow.d.ts +118 -13
- package/src/tool/flows/call-tool.flow.js +240 -194
- package/src/tool/flows/call-tool.flow.js.map +1 -1
- package/src/tool/flows/tools-list.flow.d.ts +25 -11
- package/src/tool/flows/tools-list.flow.js +82 -31
- package/src/tool/flows/tools-list.flow.js.map +1 -1
- package/src/tool/tool.instance.d.ts +1 -4
- package/src/transport/adapters/transport.streamable-http.adapter.js +1 -0
- package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
- package/src/transport/flows/handle.sse.flow.js +9 -2
- package/src/transport/flows/handle.sse.flow.js.map +1 -1
- package/src/transport/flows/handle.streamable-http.flow.js +63 -6
- package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
- package/src/transport/mcp-handlers/complete-request.handler.d.ts +27 -1
- package/src/transport/mcp-handlers/get-prompt-request.handler.d.ts +52 -1
- package/src/transport/mcp-handlers/index.d.ts +413 -7
- package/src/transport/mcp-handlers/initialize-request.handler.js +12 -2
- package/src/transport/mcp-handlers/initialize-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/list-prompts-request.handler.d.ts +27 -1
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.d.ts +32 -1
- package/src/transport/mcp-handlers/list-resources-request.handler.d.ts +32 -1
- package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +30 -1
- package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +20 -0
- package/src/transport/mcp-handlers/read-resource-request.handler.d.ts +27 -1
- package/src/transport/mcp-handlers/subscribe-request.handler.d.ts +20 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.d.ts +20 -0
- package/src/transport/transport.registry.d.ts +68 -4
- package/src/transport/transport.registry.js +313 -11
- package/src/transport/transport.registry.js.map +1 -1
- package/src/auth/ui/htmx-templates.js.map +0 -1
- package/src/common/providers/session.provider.d.ts +0 -13
- package/src/common/providers/session.provider.js +0 -27
- package/src/common/providers/session.provider.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.request.flow.js","sourceRoot":"","sources":["../../../../src/scope/flows/http.request.flow.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Flow,\n httpInputSchema,\n FlowRunOptions,\n httpOutputSchema,\n FlowPlan,\n FlowBase,\n ScopeEntry,\n FlowHooksOf,\n ServerRequest,\n ServerRequestTokens,\n httpRespond,\n decideIntent,\n decisionSchema,\n intentSchema,\n normalizeEntryPrefix,\n normalizeScopeBase,\n FlowControl,\n} from '../../common';\nimport { z } from 'zod';\nimport { sessionVerifyOutputSchema } from '../../auth/flows/session.verify.flow';\n\nconst plan = {\n pre: [\n // request tracing\n 'traceRequest',\n // rate limiting / concurrency\n 'acquireQuota',\n 'acquireSemaphore',\n // route request to the correct flow\n 'checkAuthorization',\n 'router',\n ],\n execute: [\n 'handleLegacySse',\n 'handleSse',\n 'handleStreamableHttp',\n 'handleStatefulHttp',\n 'handleStatelessHttp',\n 'handleDeleteSession',\n ],\n finalize: [\n // audit/metrics\n 'audit',\n 'metrics',\n\n // cleanup\n 'releaseSemaphore',\n 'releaseQuota',\n 'finalize',\n ],\n error: [],\n} as const satisfies FlowPlan<string>;\n\nexport const httpRequestStateSchema = z.object({\n decision: decisionSchema,\n intent: intentSchema,\n verifyResult: sessionVerifyOutputSchema,\n});\n\nconst name = 'http:request' as const;\nconst { Stage } = FlowHooksOf('http:request');\n\ndeclare global {\n interface ExtendFlows {\n 'http:request': FlowRunOptions<\n HttpRequestFlow,\n typeof plan,\n typeof httpInputSchema,\n typeof httpOutputSchema,\n typeof httpRequestStateSchema\n >;\n }\n}\n\n@Flow({\n name,\n plan,\n access: 'public',\n inputSchema: httpInputSchema,\n outputSchema: httpOutputSchema,\n middleware: {\n path: '/',\n },\n})\nexport default class HttpRequestFlow extends FlowBase<typeof name> {\n logger = this.scope.logger.child('HttpRequestFlow');\n private requestStartTime = 0;\n private requestId = '';\n\n static canActivate(request: ServerRequest, scope: ScopeEntry) {\n const requestPath = normalizeEntryPrefix(request.path);\n const prefix = normalizeEntryPrefix(scope.entryPath);\n const scopePath = normalizeScopeBase(scope.routeBase);\n const basePath = `${prefix}${scopePath}`;\n\n return (\n requestPath === basePath || // Modern transports: /\n requestPath === `${basePath}/sse` || // Legacy SSE: /sse\n requestPath === `${basePath}/message` // Legacy SSE: /message\n );\n }\n\n @Stage('traceRequest')\n async traceRequest() {\n const { request } = this.rawInput;\n this.requestStartTime = Date.now();\n this.requestId = `req-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n // Extract useful tracing info\n const userAgent = request.headers?.['user-agent'] as string | undefined;\n const sessionId = request.headers?.['mcp-session-id'] as string | undefined;\n const contentType = request.headers?.['content-type'] as string | undefined;\n const accept = request.headers?.['accept'] as string | undefined;\n\n const body = request.body as Record<string, unknown> | undefined;\n this.logger.info(`[${this.requestId}] ▶ ${request.method} ${request.path}`, {\n requestId: this.requestId,\n method: request.method,\n path: request.path,\n userAgent: userAgent?.slice(0, 50),\n sessionId: sessionId?.slice(0, 20),\n contentType,\n accept,\n hasBody: !!request.body,\n bodyMethod: body?.['method'],\n });\n\n // Log sanitized headers for debugging connection issues\n const headers = request.headers ?? {};\n const sanitizedHeaders = Object.fromEntries(\n Object.entries(headers).map(([key, value]) => {\n // Redact clearly sensitive headers\n if (/^(authorization|proxy-authorization|cookie|set-cookie|x-api-key)$/i.test(key)) {\n return [key, '[REDACTED]'];\n }\n // Truncate session identifiers instead of logging full values\n if (key === 'mcp-session-id') {\n return [key, String(value).slice(0, 8) + '...'];\n }\n return [key, value];\n }),\n );\n this.logger.debug(`[${this.requestId}] HEADERS`, { headers: sanitizedHeaders });\n }\n\n @Stage('checkAuthorization')\n async checkAuthorization() {\n const { request } = this.rawInput;\n this.logger.verbose(`[${this.requestId}] checkAuthorization: verifying session`);\n\n try {\n const result = await this.scope.runFlow('session:verify', { request });\n if (!result) {\n this.logger.error(`[${this.requestId}] failed to verify session`);\n throw new Error('Session verification failed');\n }\n this.state.set({\n verifyResult: result,\n });\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'checkAuthorization');\n }\n throw error;\n }\n }\n\n @Stage('router')\n async router() {\n try {\n const { request } = this.rawInput;\n this.logger.verbose(`[${this.requestId}] router: check request decision`);\n\n // Use transport config directly from auth (already parsed with defaults by Zod)\n const transport = this.scope.auth.transport;\n const decision = decideIntent(request, { ...transport, tolerateMissingAccept: true });\n\n // Handle DELETE method immediately - it's for session termination\n // regardless of what protocol the session was created with\n if (request.method.toUpperCase() === 'DELETE') {\n this.logger.verbose(`[${this.requestId}] DELETE request, using decision intent: ${decision.intent}`);\n if (decision.intent === 'unknown') {\n // DELETE without session ID - forward to next middleware\n // to allow custom DELETE handlers by developers\n this.logger.verbose(`[${this.requestId}] DELETE with unknown intent, forwarding to next middleware`);\n this.next();\n return;\n }\n this.state.set('intent', decision.intent);\n return;\n }\n\n const { verifyResult } = this.state.required;\n if (verifyResult.kind === 'authorized') {\n const { authorization } = verifyResult;\n request[ServerRequestTokens.auth] = authorization;\n if (authorization.session) {\n const sessionId = authorization.session.id;\n request[ServerRequestTokens.sessionId] = sessionId;\n\n // Check if the session has been terminated (via DELETE)\n // Per MCP spec, requests to terminated sessions should return 404\n if (this.scope.notifications.isSessionTerminated(sessionId)) {\n this.logger.warn(`[${this.requestId}] Request to terminated session: ${sessionId.slice(0, 20)}...`);\n this.respond(httpRespond.notFound('Session not found'));\n return;\n }\n\n // Safely access payload.protocol with null check\n const protocol = authorization.session.payload?.protocol;\n if (protocol) {\n this.logger.info(`[${this.requestId}] decision from session: ${protocol}`);\n this.state.set('intent', protocol);\n return;\n }\n }\n\n if (decision.intent === 'unknown') {\n // continue to other middleware\n // with authentication (public/authorized routes)\n this.logger.verbose(`[${this.requestId}] decision is unknown, continue to next http middleware`);\n this.next();\n return; // Explicit return for clarity (this.next() throws FlowControl)\n }\n\n // register decision intent to state\n // and move to next stage\n this.logger.verbose(`[${this.requestId}] decision is request info: ${decision.intent}`);\n this.state.set('intent', decision.intent);\n } else {\n this.logger.verbose(`[${this.requestId}] not authorized request, check decision intent: ${decision.intent}`);\n if (decision.intent === 'unknown') {\n this.logger.verbose(`[${this.requestId}] decision is unknown, continue to other public http middleware`);\n // continue to other middleware\n // without authentication (public routes)\n this.next();\n return; // Explicit return for clarity (this.next() throws FlowControl)\n }\n\n this.logger.warn(`[${this.requestId}] decision is ${decision.intent}, but not authorized, respond with 401`);\n // if the decision is specific mcp transport and no auth\n // then respond with 401\n this.respond(\n httpRespond.unauthorized({\n headers: {\n 'WWW-Authenticate': verifyResult.prmMetadataHeader,\n },\n }),\n );\n }\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'router');\n }\n throw error;\n }\n }\n\n @Stage('handleLegacySse', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'legacy-sse',\n })\n async handleLegacySse() {\n try {\n const response = await this.scope.runFlow('handle:legacy-sse', this.rawInput);\n if (response) {\n this.respond(response);\n }\n this.handled();\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleLegacySse');\n }\n throw error;\n }\n }\n\n @Stage('handleSse', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'sse',\n })\n async handleSse() {\n try {\n const response = await this.scope.runFlow('handle:streamable-http', this.rawInput);\n if (response) {\n this.respond(response);\n }\n this.next();\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleSse');\n }\n throw error;\n }\n }\n\n @Stage('handleStreamableHttp', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'streamable-http',\n })\n async handleStreamableHttp() {\n try {\n const response = await this.scope.runFlow('handle:streamable-http', this.rawInput);\n if (response) {\n this.respond(response);\n }\n this.next();\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleStreamableHttp');\n }\n throw error;\n }\n }\n\n @Stage('handleStatefulHttp', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'stateful-http',\n })\n async handleStatefulHttp() {\n // this.scope.runFlow('mcp:transport:stateful-http', this.rawInput);\n this.next();\n }\n\n @Stage('handleStatelessHttp', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'stateless-http',\n })\n async handleStatelessHttp() {\n try {\n const response = await this.scope.runFlow('handle:stateless-http', this.rawInput);\n if (response) {\n this.respond(response);\n }\n this.handled();\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleStatelessHttp');\n }\n throw error;\n }\n }\n\n @Stage('handleDeleteSession', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'delete-session',\n })\n async handleDeleteSession() {\n try {\n const { request } = this.rawInput;\n // Headers are normalized to lowercase by the adapter\n const sessionId = request[ServerRequestTokens.sessionId] ?? request.headers['mcp-session-id'];\n\n if (!sessionId || typeof sessionId !== 'string') {\n this.logger.warn(`[${this.requestId}] DELETE request without valid session ID`);\n this.respond(httpRespond.rpcError('No valid session ID provided'));\n return;\n }\n\n this.logger.info(`[${this.requestId}] DELETE session: ${sessionId}`);\n\n // Terminate the session - this unregisters the server AND adds to terminated set\n // This prevents future requests with this session ID from being accepted\n const wasRegistered = this.scope.notifications.terminateSession(sessionId);\n\n if (!wasRegistered) {\n // Session not found - per MCP spec, return 404\n // Note: We still added it to terminated set to prevent future use\n this.logger.warn(`[${this.requestId}] Session not found for DELETE: ${sessionId}`);\n this.respond(httpRespond.notFound('Session not found'));\n return;\n }\n\n this.logger.info(`[${this.requestId}] Session terminated: ${sessionId}`);\n this.respond(httpRespond.noContent());\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleDeleteSession');\n }\n throw error;\n }\n }\n\n @Stage('finalize')\n async finalize() {\n const { request } = this.rawInput;\n const duration = Date.now() - this.requestStartTime;\n const intent = this.state.get('intent') ?? 'unknown';\n\n this.logger.info(`[${this.requestId}] ◀ ${request.method} ${request.path} completed in ${duration}ms`, {\n requestId: this.requestId,\n method: request.method,\n path: request.path,\n duration,\n intent,\n });\n }\n\n /**\n * Log an error that occurred during request processing.\n * Called from stage handlers that catch errors.\n */\n private logError(error: unknown, context?: string) {\n const { request } = this.rawInput;\n const duration = Date.now() - this.requestStartTime;\n\n // Extract error details - handle various error shapes\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorName = error instanceof Error ? error.name : 'UnknownError';\n const errorStack = error instanceof Error ? error.stack : undefined;\n const body = request.body as Record<string, unknown> | undefined;\n\n // For errors with empty messages, try to extract more info\n const errorCode = (error as { code?: string | number })?.code;\n const errorCause = (error as { cause?: unknown })?.cause;\n\n // Log comprehensive error info including stack trace\n this.logger.error(\n `[${this.requestId}] ✖ ${request.method} ${request.path} failed${\n context ? ` in ${context}` : ''\n } after ${duration}ms: ${errorMessage || '(no message)'}`,\n {\n requestId: this.requestId,\n method: request.method,\n path: request.path,\n duration,\n context,\n error: {\n name: errorName,\n message: errorMessage || '(no message)',\n code: errorCode,\n cause: errorCause instanceof Error ? errorCause.message : errorCause,\n stack: errorStack,\n },\n request: {\n userAgent: (request.headers?.['user-agent'] as string)?.slice(0, 50),\n sessionId: (request.headers?.['mcp-session-id'] as string)?.slice(0, 20),\n contentType: request.headers?.['content-type'],\n bodyMethod: body?.['method'],\n bodyId: body?.['id'],\n },\n state: {\n intent: this.state.get('intent'),\n hasVerifyResult: !!this.state.get('verifyResult'),\n },\n },\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"http.request.flow.js","sourceRoot":"","sources":["../../../../src/scope/flows/http.request.flow.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Flow,\n httpInputSchema,\n FlowRunOptions,\n httpOutputSchema,\n FlowPlan,\n FlowBase,\n ScopeEntry,\n FlowHooksOf,\n ServerRequest,\n ServerRequestTokens,\n httpRespond,\n decideIntent,\n decisionSchema,\n intentSchema,\n normalizeEntryPrefix,\n normalizeScopeBase,\n FlowControl,\n} from '../../common';\nimport { z } from 'zod';\nimport { sessionVerifyOutputSchema } from '../../auth/flows/session.verify.flow';\nimport { randomUUID } from 'node:crypto';\n\nconst plan = {\n pre: [\n // request tracing\n 'traceRequest',\n // rate limiting / concurrency\n 'acquireQuota',\n 'acquireSemaphore',\n // route request to the correct flow\n 'checkAuthorization',\n 'router',\n ],\n execute: [\n 'handleLegacySse',\n 'handleSse',\n 'handleStreamableHttp',\n 'handleStatefulHttp',\n 'handleStatelessHttp',\n 'handleDeleteSession',\n ],\n finalize: [\n // audit/metrics\n 'audit',\n 'metrics',\n\n // cleanup\n 'releaseSemaphore',\n 'releaseQuota',\n 'finalize',\n ],\n error: [],\n} as const satisfies FlowPlan<string>;\n\nexport const httpRequestStateSchema = z.object({\n decision: decisionSchema,\n intent: intentSchema,\n verifyResult: sessionVerifyOutputSchema,\n});\n\nconst name = 'http:request' as const;\nconst { Stage } = FlowHooksOf('http:request');\n\ndeclare global {\n interface ExtendFlows {\n 'http:request': FlowRunOptions<\n HttpRequestFlow,\n typeof plan,\n typeof httpInputSchema,\n typeof httpOutputSchema,\n typeof httpRequestStateSchema\n >;\n }\n}\n\n@Flow({\n name,\n plan,\n access: 'public',\n inputSchema: httpInputSchema,\n outputSchema: httpOutputSchema,\n middleware: {\n path: '/',\n },\n})\nexport default class HttpRequestFlow extends FlowBase<typeof name> {\n logger = this.scope.logger.child('HttpRequestFlow');\n private requestStartTime = 0;\n private requestId = '';\n\n static canActivate(request: ServerRequest, scope: ScopeEntry) {\n const requestPath = normalizeEntryPrefix(request.path);\n const prefix = normalizeEntryPrefix(scope.entryPath);\n const scopePath = normalizeScopeBase(scope.routeBase);\n const basePath = `${prefix}${scopePath}`;\n\n return (\n requestPath === basePath || // Modern transports: /\n requestPath === `${basePath}/sse` || // Legacy SSE: /sse\n requestPath === `${basePath}/message` // Legacy SSE: /message\n );\n }\n\n @Stage('traceRequest')\n async traceRequest() {\n const { request } = this.rawInput;\n this.requestStartTime = Date.now();\n\n // Get FrontMcpContext from AsyncLocalStorage (already initialized by FlowInstance.runWithContext)\n const ctx = this.tryGetContext();\n // Use randomUUID() for fallback instead of Math.random() to avoid collisions under load\n this.requestId = ctx?.requestId ?? `req-${randomUUID()}`;\n\n // Extract request details for logging\n const headers = request.headers ?? {};\n const body = request.body as Record<string, unknown> | undefined;\n const userAgent = headers['user-agent'] as string | undefined;\n const contentType = headers['content-type'] as string | undefined;\n const accept = headers['accept'] as string | undefined;\n // Use sessionId from context (which generates unique anon IDs) or header\n // 'no-session' is a logging fallback only, not used for SESSION providers\n const sessionId = ctx?.sessionId ?? (headers['mcp-session-id'] as string) ?? 'no-session';\n\n this.logger.info(`[${this.requestId}] ▶ ${request.method} ${request.path}`, {\n requestId: this.requestId,\n traceId: ctx?.traceContext.traceId?.slice(0, 16),\n method: request.method,\n path: request.path,\n userAgent: userAgent?.slice(0, 50),\n sessionId: sessionId?.slice(0, 20),\n contentType,\n accept,\n hasBody: !!request.body,\n bodyMethod: body?.['method'],\n });\n\n // Log sanitized headers for debugging connection issues\n const sanitizedHeaders = Object.fromEntries(\n Object.entries(headers).map(([key, value]) => {\n // Redact clearly sensitive headers\n if (/^(authorization|proxy-authorization|cookie|set-cookie|x-api-key)$/i.test(key)) {\n return [key, '[REDACTED]'];\n }\n // Truncate session identifiers instead of logging full values\n if (key === 'mcp-session-id') {\n return [key, String(value).slice(0, 8) + '...'];\n }\n return [key, value];\n }),\n );\n this.logger.debug(`[${this.requestId}] HEADERS`, { headers: sanitizedHeaders });\n }\n\n @Stage('checkAuthorization')\n async checkAuthorization() {\n const { request } = this.rawInput;\n this.logger.verbose(`[${this.requestId}] checkAuthorization: verifying session`);\n\n try {\n const result = await this.scope.runFlow('session:verify', { request });\n if (!result) {\n this.logger.error(`[${this.requestId}] failed to verify session`);\n throw new Error('Session verification failed');\n }\n this.state.set({\n verifyResult: result,\n });\n\n // Update FrontMcpContext with verified auth info if available\n // This allows all subsequent stages to access the auth info via context\n if (result.kind === 'authorized' && result.authorization) {\n const ctx = this.tryGetContext();\n if (ctx) {\n // Build AuthInfo from the authorization object\n // AuthInfo is the MCP SDK's auth type with token, clientId, scopes, etc.\n const { token, user, session } = result.authorization;\n ctx.updateAuthInfo({\n token,\n clientId: user.sub,\n scopes: [],\n // JWT exp is in seconds, SDK uses milliseconds throughout (e.g., Date.now())\n expiresAt: user.exp ? user.exp * 1000 : undefined,\n extra: {\n user,\n sessionId: session?.id,\n sessionPayload: session?.payload,\n },\n });\n }\n }\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'checkAuthorization');\n }\n throw error;\n }\n }\n\n @Stage('router')\n async router() {\n try {\n const { request } = this.rawInput;\n this.logger.verbose(`[${this.requestId}] router: check request decision`);\n\n // Use transport config directly from auth (already parsed with defaults by Zod)\n const transport = this.scope.auth.transport;\n const decision = decideIntent(request, { ...transport, tolerateMissingAccept: true });\n\n // Handle DELETE method immediately - it's for session termination\n // regardless of what protocol the session was created with\n if (request.method.toUpperCase() === 'DELETE') {\n this.logger.verbose(`[${this.requestId}] DELETE request, using decision intent: ${decision.intent}`);\n if (decision.intent === 'unknown') {\n // DELETE without session ID - forward to next middleware\n // to allow custom DELETE handlers by developers\n this.logger.verbose(`[${this.requestId}] DELETE with unknown intent, forwarding to next middleware`);\n this.next();\n return;\n }\n this.state.set('intent', decision.intent);\n return;\n }\n\n const { verifyResult } = this.state.required;\n if (verifyResult.kind === 'authorized') {\n const { authorization } = verifyResult;\n request[ServerRequestTokens.auth] = authorization;\n\n // Update FrontMcpContext session metadata (auth info already set in checkAuthorization)\n if (authorization.session?.payload) {\n const ctx = this.tryGetContext();\n if (ctx) {\n ctx.updateSessionMetadata(authorization.session.payload);\n }\n }\n\n if (authorization.session) {\n const sessionId = authorization.session.id;\n request[ServerRequestTokens.sessionId] = sessionId;\n\n // Check if the session has been terminated (via DELETE)\n // Per MCP spec, requests to terminated sessions should return 404\n if (this.scope.notifications.isSessionTerminated(sessionId)) {\n this.logger.warn(`[${this.requestId}] Request to terminated session: ${sessionId.slice(0, 20)}...`);\n this.respond(httpRespond.notFound('Session not found'));\n return;\n }\n\n // Safely access payload.protocol with null check\n const protocol = authorization.session.payload?.protocol;\n if (protocol) {\n this.logger.info(`[${this.requestId}] decision from session: ${protocol}`);\n this.state.set('intent', protocol);\n return;\n }\n }\n\n if (decision.intent === 'unknown') {\n // continue to other middleware\n // with authentication (public/authorized routes)\n this.logger.verbose(`[${this.requestId}] decision is unknown, continue to next http middleware`);\n this.next();\n return; // Explicit return for clarity (this.next() throws FlowControl)\n }\n\n // register decision intent to state\n // and move to next stage\n this.logger.verbose(`[${this.requestId}] decision is request info: ${decision.intent}`);\n this.state.set('intent', decision.intent);\n } else {\n this.logger.verbose(`[${this.requestId}] not authorized request, check decision intent: ${decision.intent}`);\n if (decision.intent === 'unknown') {\n this.logger.verbose(`[${this.requestId}] decision is unknown, continue to other public http middleware`);\n // continue to other middleware\n // without authentication (public routes)\n this.next();\n return; // Explicit return for clarity (this.next() throws FlowControl)\n }\n\n this.logger.warn(`[${this.requestId}] decision is ${decision.intent}, but not authorized, respond with 401`);\n // if the decision is specific mcp transport and no auth\n // then respond with 401\n this.respond(\n httpRespond.unauthorized({\n headers: {\n 'WWW-Authenticate': verifyResult.prmMetadataHeader,\n },\n }),\n );\n }\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'router');\n }\n throw error;\n }\n }\n\n @Stage('handleLegacySse', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'legacy-sse',\n })\n async handleLegacySse() {\n try {\n const response = await this.scope.runFlow('handle:legacy-sse', this.rawInput);\n if (response) {\n this.respond(response);\n }\n this.handled();\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleLegacySse');\n }\n throw error;\n }\n }\n\n @Stage('handleSse', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'sse',\n })\n async handleSse() {\n try {\n const response = await this.scope.runFlow('handle:streamable-http', this.rawInput);\n if (response) {\n this.respond(response);\n }\n this.next();\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleSse');\n }\n throw error;\n }\n }\n\n @Stage('handleStreamableHttp', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'streamable-http',\n })\n async handleStreamableHttp() {\n try {\n const response = await this.scope.runFlow('handle:streamable-http', this.rawInput);\n if (response) {\n this.respond(response);\n }\n this.next();\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleStreamableHttp');\n }\n throw error;\n }\n }\n\n @Stage('handleStatefulHttp', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'stateful-http',\n })\n async handleStatefulHttp() {\n // this.scope.runFlow('mcp:transport:stateful-http', this.rawInput);\n this.next();\n }\n\n @Stage('handleStatelessHttp', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'stateless-http',\n })\n async handleStatelessHttp() {\n try {\n const response = await this.scope.runFlow('handle:stateless-http', this.rawInput);\n if (response) {\n this.respond(response);\n }\n this.handled();\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleStatelessHttp');\n }\n throw error;\n }\n }\n\n @Stage('handleDeleteSession', {\n filter: ({\n state: {\n required: { intent },\n },\n }) => intent === 'delete-session',\n })\n async handleDeleteSession() {\n try {\n const { request } = this.rawInput;\n // Headers are normalized to lowercase by the adapter\n const sessionId = request[ServerRequestTokens.sessionId] ?? request.headers['mcp-session-id'];\n\n if (!sessionId || typeof sessionId !== 'string') {\n this.logger.warn(`[${this.requestId}] DELETE request without valid session ID`);\n this.respond(httpRespond.rpcError('No valid session ID provided'));\n return;\n }\n\n this.logger.info(`[${this.requestId}] DELETE session: ${sessionId}`);\n\n // Terminate the session - this unregisters the server AND adds to terminated set\n // This prevents future requests with this session ID from being accepted\n const wasRegistered = this.scope.notifications.terminateSession(sessionId);\n\n if (!wasRegistered) {\n // Session not found - per MCP spec, return 404\n // Note: We still added it to terminated set to prevent future use\n this.logger.warn(`[${this.requestId}] Session not found for DELETE: ${sessionId}`);\n this.respond(httpRespond.notFound('Session not found'));\n return;\n }\n\n this.logger.info(`[${this.requestId}] Session terminated: ${sessionId}`);\n this.respond(httpRespond.noContent());\n } catch (error) {\n // FlowControl is expected control flow, not an error\n if (!(error instanceof FlowControl)) {\n this.logError(error, 'handleDeleteSession');\n }\n throw error;\n }\n }\n\n @Stage('finalize')\n async finalize() {\n const { request } = this.rawInput;\n const duration = Date.now() - this.requestStartTime;\n const intent = this.state.get('intent') ?? 'unknown';\n\n this.logger.info(`[${this.requestId}] ◀ ${request.method} ${request.path} completed in ${duration}ms`, {\n requestId: this.requestId,\n method: request.method,\n path: request.path,\n duration,\n intent,\n });\n }\n\n /**\n * Log an error that occurred during request processing.\n * Called from stage handlers that catch errors.\n */\n private logError(error: unknown, context?: string) {\n const { request } = this.rawInput;\n const duration = Date.now() - this.requestStartTime;\n\n // Extract error details - handle various error shapes\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorName = error instanceof Error ? error.name : 'UnknownError';\n const errorStack = error instanceof Error ? error.stack : undefined;\n const body = request.body as Record<string, unknown> | undefined;\n\n // For errors with empty messages, try to extract more info\n const errorCode = (error as { code?: string | number })?.code;\n const errorCause = (error as { cause?: unknown })?.cause;\n\n // Log comprehensive error info including stack trace\n this.logger.error(\n `[${this.requestId}] ✖ ${request.method} ${request.path} failed${\n context ? ` in ${context}` : ''\n } after ${duration}ms: ${errorMessage || '(no message)'}`,\n {\n requestId: this.requestId,\n method: request.method,\n path: request.path,\n duration,\n context,\n error: {\n name: errorName,\n message: errorMessage || '(no message)',\n code: errorCode,\n cause: errorCause instanceof Error ? errorCause.message : errorCause,\n stack: errorStack,\n },\n request: {\n userAgent: (request.headers?.['user-agent'] as string)?.slice(0, 50),\n sessionId: (request.headers?.['mcp-session-id'] as string)?.slice(0, 20),\n contentType: request.headers?.['content-type'],\n bodyMethod: body?.['method'],\n bodyId: body?.['id'],\n },\n state: {\n intent: this.state.get('intent'),\n hasVerifyResult: !!this.state.get('verifyResult'),\n },\n },\n );\n }\n}\n"]}
|
|
@@ -4,6 +4,7 @@ exports.Scope = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
require("reflect-metadata");
|
|
6
6
|
const common_1 = require("../common");
|
|
7
|
+
const context_1 = require("../context");
|
|
7
8
|
const app_registry_1 = tslib_1.__importDefault(require("../app/app.registry"));
|
|
8
9
|
const provider_registry_1 = tslib_1.__importDefault(require("../provider/provider.registry"));
|
|
9
10
|
const auth_registry_1 = require("../auth/auth.registry");
|
|
@@ -61,7 +62,9 @@ class Scope extends common_1.ScopeEntry {
|
|
|
61
62
|
await this.scopeHooks.ready;
|
|
62
63
|
this.scopeFlows = new flow_registry_1.default(scopeProviders, [http_request_flow_1.default]);
|
|
63
64
|
await this.scopeFlows.ready;
|
|
64
|
-
|
|
65
|
+
// Pass transport persistence config to TransportService
|
|
66
|
+
const transportConfig = this.metadata.transport;
|
|
67
|
+
this.transportService = new transport_registry_1.TransportService(this, transportConfig?.persistence);
|
|
65
68
|
this.scopeAuth = new auth_registry_1.AuthRegistry(this, scopeProviders, [], scopeRef, this.metadata.auth);
|
|
66
69
|
await this.scopeAuth.ready;
|
|
67
70
|
this.scopeApps = new app_registry_1.default(this.scopeProviders, this.metadata.apps, scopeRef);
|
|
@@ -200,12 +203,16 @@ class Scope extends common_1.ScopeEntry {
|
|
|
200
203
|
provide: common_1.FrontMcpLogger,
|
|
201
204
|
useValue: this.logger,
|
|
202
205
|
},
|
|
206
|
+
// RequestContextStorage is GLOBAL because it manages the AsyncLocalStorage,
|
|
207
|
+
// not the per-request data. Access the actual RequestContext via REQUEST_CONTEXT token.
|
|
203
208
|
{
|
|
204
|
-
scope: common_1.ProviderScope.
|
|
205
|
-
name: '
|
|
206
|
-
provide:
|
|
207
|
-
useClass:
|
|
209
|
+
scope: common_1.ProviderScope.GLOBAL,
|
|
210
|
+
name: 'RequestContextStorage',
|
|
211
|
+
provide: context_1.RequestContextStorage,
|
|
212
|
+
useClass: context_1.RequestContextStorage,
|
|
208
213
|
},
|
|
214
|
+
// RequestContextProvider is a factory that retrieves from AsyncLocalStorage
|
|
215
|
+
context_1.RequestContextProvider,
|
|
209
216
|
];
|
|
210
217
|
}
|
|
211
218
|
get auth() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.instance.js","sourceRoot":"","sources":["../../../src/scope/scope.instance.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport {\n EntryOwnerRef,\n FlowInputOf,\n FlowName,\n FlowOutputOf,\n FlowType,\n FrontMcpAuth,\n FrontMcpLogger,\n FrontMcpServer,\n HookRegistryInterface,\n ProviderScope,\n ScopeEntry,\n ScopeRecord,\n SessionProvider,\n Token,\n Type,\n} from '../common';\nimport AppRegistry from '../app/app.registry';\nimport ProviderRegistry from '../provider/provider.registry';\nimport { AuthRegistry } from '../auth/auth.registry';\nimport FlowRegistry from '../flows/flow.registry';\nimport HttpRequestFlow from './flows/http.request.flow';\nimport { TransportService } from '../transport/transport.registry';\nimport ToolRegistry from '../tool/tool.registry';\nimport ResourceRegistry from '../resource/resource.registry';\nimport HookRegistry from '../hooks/hook.registry';\nimport PromptRegistry from '../prompt/prompt.registry';\nimport { NotificationService } from '../notification';\nimport SetLevelFlow from '../logging/flows/set-level.flow';\nimport CompleteFlow from '../completion/flows/complete.flow';\nimport { ToolUIRegistry, StaticWidgetResourceTemplate, hasUIConfig } from '../tool/ui';\n\nexport class Scope extends ScopeEntry {\n readonly id: string;\n private readonly globalProviders: ProviderRegistry;\n readonly logger: FrontMcpLogger;\n\n private readonly scopeProviders: ProviderRegistry;\n private scopeAuth: AuthRegistry;\n private scopeFlows: FlowRegistry;\n private scopeApps: AppRegistry;\n private scopeHooks: HookRegistry;\n private scopeTools: ToolRegistry;\n private scopeResources: ResourceRegistry;\n private scopePrompts: PromptRegistry;\n\n transportService: TransportService; // TODO: migrate transport service to transport.registry\n notificationService: NotificationService;\n private toolUIRegistry: ToolUIRegistry;\n readonly entryPath: string;\n readonly routeBase: string;\n readonly orchestrated: boolean = false;\n\n readonly server: FrontMcpServer;\n\n constructor(rec: ScopeRecord, globalProviders: ProviderRegistry) {\n super(rec, rec.provide);\n this.id = rec.metadata.id;\n this.logger = globalProviders.get(FrontMcpLogger).child('FrontMcp.MultiAppScope');\n this.globalProviders = globalProviders;\n this.server = this.globalProviders.get(FrontMcpServer);\n this.entryPath = rec.metadata.http?.entryPath ?? '';\n\n if (rec.kind === 'SPLIT_BY_APP') {\n this.routeBase = `/${rec.metadata.id}`;\n } else {\n this.routeBase = '';\n }\n\n this.scopeProviders = new ProviderRegistry(this.defaultScopeProviders, globalProviders);\n this.ready = this.initialize();\n }\n\n protected async initialize(): Promise<void> {\n await this.scopeProviders.ready;\n\n const scopeRef: EntryOwnerRef = { kind: 'scope', id: this.id, ref: Scope };\n const scopeProviders = this.scopeProviders;\n\n this.scopeHooks = new HookRegistry(scopeProviders, []);\n await this.scopeHooks.ready;\n\n this.scopeFlows = new FlowRegistry(scopeProviders, [HttpRequestFlow]);\n await this.scopeFlows.ready;\n\n this.transportService = new TransportService(this);\n\n this.scopeAuth = new AuthRegistry(this, scopeProviders, [], scopeRef, this.metadata.auth);\n await this.scopeAuth.ready;\n\n this.scopeApps = new AppRegistry(this.scopeProviders, this.metadata.apps, scopeRef);\n await this.scopeApps.ready;\n\n this.scopeTools = new ToolRegistry(this.scopeProviders, [], scopeRef);\n await this.scopeTools.ready;\n\n this.toolUIRegistry = new ToolUIRegistry();\n\n this.scopeResources = new ResourceRegistry(this.scopeProviders, [], scopeRef);\n await this.scopeResources.ready;\n\n // Register UI resource templates if any tools have UI configs\n // This enables resource capabilities to be advertised when tools have UI\n const toolsWithUI = this.scopeTools.getTools(true).filter((t) => hasUIConfig(t.metadata));\n if (toolsWithUI.length > 0) {\n // Register static widget template for OpenAI discovery (ui://widget/{toolName}.html)\n this.scopeResources.registerDynamicResource(StaticWidgetResourceTemplate);\n this.logger.verbose(`Registered UI resource template for ${toolsWithUI.length} tool(s) with UI configs`);\n\n // Pre-compile static widgets for tools with servingMode: 'static'\n // This is done at server startup so that the static widget HTML is immediately\n // available when OpenAI fetches it via resources/read (at tools/list time).\n // The static widget reads data from the FrontMCP Bridge at runtime.\n const staticModeTools = toolsWithUI.filter(\n (t) => t.metadata.ui && t.metadata.ui.servingMode === 'static' && t.metadata.ui.template,\n );\n\n if (staticModeTools.length > 0) {\n // Compile all static widgets in parallel\n let staticCompiledCount = 0;\n await Promise.all(\n staticModeTools.map(async (tool) => {\n const uiConfig = tool.metadata.ui;\n if (!uiConfig?.template) {\n this.logger.warn(\n `Skipping static widget pre-compile for tool \"${tool.metadata.name}\" due to missing ui.template`,\n );\n return;\n }\n try {\n await this.toolUIRegistry.compileStaticWidgetAsync({\n toolName: tool.metadata.name,\n template: uiConfig.template,\n uiConfig,\n });\n staticCompiledCount++;\n this.logger.verbose(`Compiled static widget for tool: ${tool.metadata.name}`);\n } catch (error) {\n // Log error but don't fail server startup\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger.error(`Failed to compile static widget for tool \"${tool.metadata.name}\": ${errorMessage}`);\n }\n }),\n );\n this.logger.info(\n `Pre-compiled ${staticCompiledCount}/${staticModeTools.length} static widget(s) for static mode tools`,\n );\n }\n\n // Pre-compile lean widget shells for inline mode tools\n // These are minimal HTML shells (no React/JS) that OpenAI caches at discovery\n // The actual React widget comes in each tool response with embedded data\n const inlineTools = toolsWithUI.filter(\n (t) =>\n t.metadata.ui &&\n (t.metadata.ui.servingMode === 'inline' || !t.metadata.ui.servingMode) &&\n t.metadata.ui.template,\n );\n\n if (inlineTools.length > 0) {\n let inlineCompiledCount = 0;\n await Promise.all(\n inlineTools.map(async (tool) => {\n const uiConfig = tool.metadata.ui;\n if (!uiConfig) {\n this.logger.warn(\n `Skipping lean widget pre-compile for tool \"${tool.metadata.name}\" due to missing ui config`,\n );\n return;\n }\n try {\n await this.toolUIRegistry.compileLeanWidgetAsync({\n toolName: tool.metadata.name,\n uiConfig,\n });\n inlineCompiledCount++;\n this.logger.verbose(`Compiled lean widget shell for tool: ${tool.metadata.name}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger.error(\n `Failed to compile lean widget shell for tool \"${tool.metadata.name}\": ${errorMessage}`,\n );\n }\n }),\n );\n this.logger.info(\n `Pre-compiled ${inlineCompiledCount}/${inlineTools.length} lean widget shell(s) for inline mode tools`,\n );\n }\n\n // Pre-compile hybrid widget shells for hybrid mode tools\n // These contain React runtime + Bridge + dynamic renderer, but NO component code\n // The component code is delivered per-request in _meta['ui/component']\n const hybridTools = toolsWithUI.filter(\n (t) => t.metadata.ui && t.metadata.ui.servingMode === 'hybrid' && t.metadata.ui.template,\n );\n\n if (hybridTools.length > 0) {\n let hybridCompiledCount = 0;\n await Promise.all(\n hybridTools.map(async (tool) => {\n const uiConfig = tool.metadata.ui;\n if (!uiConfig) {\n this.logger.warn(\n `Skipping hybrid widget pre-compile for tool \"${tool.metadata.name}\" due to missing ui config`,\n );\n return;\n }\n try {\n await this.toolUIRegistry.compileHybridWidgetAsync({\n toolName: tool.metadata.name,\n uiConfig,\n });\n hybridCompiledCount++;\n this.logger.verbose(`Compiled hybrid widget shell for tool: ${tool.metadata.name}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger.error(\n `Failed to compile hybrid widget shell for tool \"${tool.metadata.name}\": ${errorMessage}`,\n );\n }\n }),\n );\n this.logger.info(\n `Pre-compiled ${hybridCompiledCount}/${hybridTools.length} hybrid widget shell(s) for hybrid mode tools`,\n );\n }\n }\n\n this.scopePrompts = new PromptRegistry(this.scopeProviders, [], scopeRef);\n await this.scopePrompts.ready;\n\n // Initialize notification service after all registries are ready\n this.notificationService = new NotificationService(this);\n await this.notificationService.initialize();\n\n // Register logging and completion flows\n await this.scopeFlows.registryFlows([SetLevelFlow, CompleteFlow]);\n\n await this.auth.ready;\n this.logger.info('Initializing multi-app scope', this.metadata);\n if (!this.metadata.auth) {\n // log a large warning about using FrontMcp without authentication\n this.logger.warn(\n `\\n\\n*******************************\\n WARNING: FrontMcp is running without authentication. \\n This is a security risk and should only be used in development environments. \\n*******************************\\n\\n`,\n );\n }\n }\n\n private get defaultScopeProviders() {\n return [\n {\n scope: ProviderScope.GLOBAL,\n name: 'ScopeEntry',\n provide: ScopeEntry,\n useValue: this,\n },\n {\n scope: ProviderScope.GLOBAL,\n name: 'Scope',\n provide: Scope,\n useValue: this,\n },\n {\n scope: ProviderScope.GLOBAL,\n name: 'FrontMcpLogger',\n provide: FrontMcpLogger,\n useValue: this.logger,\n },\n {\n scope: ProviderScope.SESSION,\n name: 'SessionProvider',\n provide: SessionProvider,\n useClass: SessionProvider,\n },\n ];\n }\n\n get auth(): FrontMcpAuth {\n return this.scopeAuth.getPrimary();\n }\n\n get hooks(): HookRegistryInterface {\n return this.scopeHooks;\n }\n\n get authProviders(): AuthRegistry {\n return this.scopeAuth;\n }\n\n get providers() {\n return this.scopeProviders;\n }\n\n get apps(): AppRegistry {\n return this.scopeApps;\n }\n\n get tools(): ToolRegistry {\n return this.scopeTools;\n }\n\n get toolUI(): ToolUIRegistry {\n return this.toolUIRegistry;\n }\n\n get resources(): ResourceRegistry {\n return this.scopeResources;\n }\n\n get prompts(): PromptRegistry {\n return this.scopePrompts;\n }\n\n get notifications(): NotificationService {\n return this.notificationService;\n }\n\n registryFlows(...flows: FlowType[]) {\n return this.scopeFlows.registryFlows(flows);\n }\n\n runFlow<Name extends FlowName>(\n name: Name,\n input: FlowInputOf<Name>,\n deps?: Map<Token, Type>,\n ): Promise<FlowOutputOf<Name> | undefined> {\n return this.scopeFlows.runFlow(name, input, deps);\n }\n\n async runFlowForOutput<Name extends FlowName>(\n name: Name,\n input: FlowInputOf<Name>,\n deps?: Map<Token, Type>,\n ): Promise<FlowOutputOf<Name>> {\n const result = await this.scopeFlows.runFlow(name, input, deps);\n if (result) {\n return result;\n }\n throw new Error(`flow exist without output`);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scope.instance.js","sourceRoot":"","sources":["../../../src/scope/scope.instance.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport {\n EntryOwnerRef,\n FlowInputOf,\n FlowName,\n FlowOutputOf,\n FlowType,\n FrontMcpAuth,\n FrontMcpLogger,\n FrontMcpServer,\n HookRegistryInterface,\n ProviderScope,\n ScopeEntry,\n ScopeRecord,\n Token,\n Type,\n} from '../common';\nimport { RequestContextStorage, RequestContextProvider } from '../context';\nimport AppRegistry from '../app/app.registry';\nimport ProviderRegistry from '../provider/provider.registry';\nimport { AuthRegistry } from '../auth/auth.registry';\nimport FlowRegistry from '../flows/flow.registry';\nimport HttpRequestFlow from './flows/http.request.flow';\nimport { TransportService } from '../transport/transport.registry';\nimport ToolRegistry from '../tool/tool.registry';\nimport ResourceRegistry from '../resource/resource.registry';\nimport HookRegistry from '../hooks/hook.registry';\nimport PromptRegistry from '../prompt/prompt.registry';\nimport { NotificationService } from '../notification';\nimport SetLevelFlow from '../logging/flows/set-level.flow';\nimport CompleteFlow from '../completion/flows/complete.flow';\nimport { ToolUIRegistry, StaticWidgetResourceTemplate, hasUIConfig } from '../tool/ui';\n\nexport class Scope extends ScopeEntry {\n readonly id: string;\n private readonly globalProviders: ProviderRegistry;\n readonly logger: FrontMcpLogger;\n\n private readonly scopeProviders: ProviderRegistry;\n private scopeAuth: AuthRegistry;\n private scopeFlows: FlowRegistry;\n private scopeApps: AppRegistry;\n private scopeHooks: HookRegistry;\n private scopeTools: ToolRegistry;\n private scopeResources: ResourceRegistry;\n private scopePrompts: PromptRegistry;\n\n transportService: TransportService; // TODO: migrate transport service to transport.registry\n notificationService: NotificationService;\n private toolUIRegistry: ToolUIRegistry;\n readonly entryPath: string;\n readonly routeBase: string;\n readonly orchestrated: boolean = false;\n\n readonly server: FrontMcpServer;\n\n constructor(rec: ScopeRecord, globalProviders: ProviderRegistry) {\n super(rec, rec.provide);\n this.id = rec.metadata.id;\n this.logger = globalProviders.get(FrontMcpLogger).child('FrontMcp.MultiAppScope');\n this.globalProviders = globalProviders;\n this.server = this.globalProviders.get(FrontMcpServer);\n this.entryPath = rec.metadata.http?.entryPath ?? '';\n\n if (rec.kind === 'SPLIT_BY_APP') {\n this.routeBase = `/${rec.metadata.id}`;\n } else {\n this.routeBase = '';\n }\n\n this.scopeProviders = new ProviderRegistry(this.defaultScopeProviders, globalProviders);\n this.ready = this.initialize();\n }\n\n protected async initialize(): Promise<void> {\n await this.scopeProviders.ready;\n\n const scopeRef: EntryOwnerRef = { kind: 'scope', id: this.id, ref: Scope };\n const scopeProviders = this.scopeProviders;\n\n this.scopeHooks = new HookRegistry(scopeProviders, []);\n await this.scopeHooks.ready;\n\n this.scopeFlows = new FlowRegistry(scopeProviders, [HttpRequestFlow]);\n await this.scopeFlows.ready;\n\n // Pass transport persistence config to TransportService\n const transportConfig = this.metadata.transport;\n this.transportService = new TransportService(this, transportConfig?.persistence);\n\n this.scopeAuth = new AuthRegistry(this, scopeProviders, [], scopeRef, this.metadata.auth);\n await this.scopeAuth.ready;\n\n this.scopeApps = new AppRegistry(this.scopeProviders, this.metadata.apps, scopeRef);\n await this.scopeApps.ready;\n\n this.scopeTools = new ToolRegistry(this.scopeProviders, [], scopeRef);\n await this.scopeTools.ready;\n\n this.toolUIRegistry = new ToolUIRegistry();\n\n this.scopeResources = new ResourceRegistry(this.scopeProviders, [], scopeRef);\n await this.scopeResources.ready;\n\n // Register UI resource templates if any tools have UI configs\n // This enables resource capabilities to be advertised when tools have UI\n const toolsWithUI = this.scopeTools.getTools(true).filter((t) => hasUIConfig(t.metadata));\n if (toolsWithUI.length > 0) {\n // Register static widget template for OpenAI discovery (ui://widget/{toolName}.html)\n this.scopeResources.registerDynamicResource(StaticWidgetResourceTemplate);\n this.logger.verbose(`Registered UI resource template for ${toolsWithUI.length} tool(s) with UI configs`);\n\n // Pre-compile static widgets for tools with servingMode: 'static'\n // This is done at server startup so that the static widget HTML is immediately\n // available when OpenAI fetches it via resources/read (at tools/list time).\n // The static widget reads data from the FrontMCP Bridge at runtime.\n const staticModeTools = toolsWithUI.filter(\n (t) => t.metadata.ui && t.metadata.ui.servingMode === 'static' && t.metadata.ui.template,\n );\n\n if (staticModeTools.length > 0) {\n // Compile all static widgets in parallel\n let staticCompiledCount = 0;\n await Promise.all(\n staticModeTools.map(async (tool) => {\n const uiConfig = tool.metadata.ui;\n if (!uiConfig?.template) {\n this.logger.warn(\n `Skipping static widget pre-compile for tool \"${tool.metadata.name}\" due to missing ui.template`,\n );\n return;\n }\n try {\n await this.toolUIRegistry.compileStaticWidgetAsync({\n toolName: tool.metadata.name,\n template: uiConfig.template,\n uiConfig,\n });\n staticCompiledCount++;\n this.logger.verbose(`Compiled static widget for tool: ${tool.metadata.name}`);\n } catch (error) {\n // Log error but don't fail server startup\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger.error(`Failed to compile static widget for tool \"${tool.metadata.name}\": ${errorMessage}`);\n }\n }),\n );\n this.logger.info(\n `Pre-compiled ${staticCompiledCount}/${staticModeTools.length} static widget(s) for static mode tools`,\n );\n }\n\n // Pre-compile lean widget shells for inline mode tools\n // These are minimal HTML shells (no React/JS) that OpenAI caches at discovery\n // The actual React widget comes in each tool response with embedded data\n const inlineTools = toolsWithUI.filter(\n (t) =>\n t.metadata.ui &&\n (t.metadata.ui.servingMode === 'inline' || !t.metadata.ui.servingMode) &&\n t.metadata.ui.template,\n );\n\n if (inlineTools.length > 0) {\n let inlineCompiledCount = 0;\n await Promise.all(\n inlineTools.map(async (tool) => {\n const uiConfig = tool.metadata.ui;\n if (!uiConfig) {\n this.logger.warn(\n `Skipping lean widget pre-compile for tool \"${tool.metadata.name}\" due to missing ui config`,\n );\n return;\n }\n try {\n await this.toolUIRegistry.compileLeanWidgetAsync({\n toolName: tool.metadata.name,\n uiConfig,\n });\n inlineCompiledCount++;\n this.logger.verbose(`Compiled lean widget shell for tool: ${tool.metadata.name}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger.error(\n `Failed to compile lean widget shell for tool \"${tool.metadata.name}\": ${errorMessage}`,\n );\n }\n }),\n );\n this.logger.info(\n `Pre-compiled ${inlineCompiledCount}/${inlineTools.length} lean widget shell(s) for inline mode tools`,\n );\n }\n\n // Pre-compile hybrid widget shells for hybrid mode tools\n // These contain React runtime + Bridge + dynamic renderer, but NO component code\n // The component code is delivered per-request in _meta['ui/component']\n const hybridTools = toolsWithUI.filter(\n (t) => t.metadata.ui && t.metadata.ui.servingMode === 'hybrid' && t.metadata.ui.template,\n );\n\n if (hybridTools.length > 0) {\n let hybridCompiledCount = 0;\n await Promise.all(\n hybridTools.map(async (tool) => {\n const uiConfig = tool.metadata.ui;\n if (!uiConfig) {\n this.logger.warn(\n `Skipping hybrid widget pre-compile for tool \"${tool.metadata.name}\" due to missing ui config`,\n );\n return;\n }\n try {\n await this.toolUIRegistry.compileHybridWidgetAsync({\n toolName: tool.metadata.name,\n uiConfig,\n });\n hybridCompiledCount++;\n this.logger.verbose(`Compiled hybrid widget shell for tool: ${tool.metadata.name}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger.error(\n `Failed to compile hybrid widget shell for tool \"${tool.metadata.name}\": ${errorMessage}`,\n );\n }\n }),\n );\n this.logger.info(\n `Pre-compiled ${hybridCompiledCount}/${hybridTools.length} hybrid widget shell(s) for hybrid mode tools`,\n );\n }\n }\n\n this.scopePrompts = new PromptRegistry(this.scopeProviders, [], scopeRef);\n await this.scopePrompts.ready;\n\n // Initialize notification service after all registries are ready\n this.notificationService = new NotificationService(this);\n await this.notificationService.initialize();\n\n // Register logging and completion flows\n await this.scopeFlows.registryFlows([SetLevelFlow, CompleteFlow]);\n\n await this.auth.ready;\n this.logger.info('Initializing multi-app scope', this.metadata);\n if (!this.metadata.auth) {\n // log a large warning about using FrontMcp without authentication\n this.logger.warn(\n `\\n\\n*******************************\\n WARNING: FrontMcp is running without authentication. \\n This is a security risk and should only be used in development environments. \\n*******************************\\n\\n`,\n );\n }\n }\n\n private get defaultScopeProviders() {\n return [\n {\n scope: ProviderScope.GLOBAL,\n name: 'ScopeEntry',\n provide: ScopeEntry,\n useValue: this,\n },\n {\n scope: ProviderScope.GLOBAL,\n name: 'Scope',\n provide: Scope,\n useValue: this,\n },\n {\n scope: ProviderScope.GLOBAL,\n name: 'FrontMcpLogger',\n provide: FrontMcpLogger,\n useValue: this.logger,\n },\n // RequestContextStorage is GLOBAL because it manages the AsyncLocalStorage,\n // not the per-request data. Access the actual RequestContext via REQUEST_CONTEXT token.\n {\n scope: ProviderScope.GLOBAL,\n name: 'RequestContextStorage',\n provide: RequestContextStorage,\n useClass: RequestContextStorage,\n },\n // RequestContextProvider is a factory that retrieves from AsyncLocalStorage\n RequestContextProvider,\n ];\n }\n\n get auth(): FrontMcpAuth {\n return this.scopeAuth.getPrimary();\n }\n\n get hooks(): HookRegistryInterface {\n return this.scopeHooks;\n }\n\n get authProviders(): AuthRegistry {\n return this.scopeAuth;\n }\n\n get providers() {\n return this.scopeProviders;\n }\n\n get apps(): AppRegistry {\n return this.scopeApps;\n }\n\n get tools(): ToolRegistry {\n return this.scopeTools;\n }\n\n get toolUI(): ToolUIRegistry {\n return this.toolUIRegistry;\n }\n\n get resources(): ResourceRegistry {\n return this.scopeResources;\n }\n\n get prompts(): PromptRegistry {\n return this.scopePrompts;\n }\n\n get notifications(): NotificationService {\n return this.notificationService;\n }\n\n registryFlows(...flows: FlowType[]) {\n return this.scopeFlows.registryFlows(flows);\n }\n\n runFlow<Name extends FlowName>(\n name: Name,\n input: FlowInputOf<Name>,\n deps?: Map<Token, Type>,\n ): Promise<FlowOutputOf<Name> | undefined> {\n return this.scopeFlows.runFlow(name, input, deps);\n }\n\n async runFlowForOutput<Name extends FlowName>(\n name: Name,\n input: FlowInputOf<Name>,\n deps?: Map<Token, Type>,\n ): Promise<FlowOutputOf<Name>> {\n const result = await this.scopeFlows.runFlow(name, input, deps);\n if (result) {\n return result;\n }\n throw new Error(`flow exist without output`);\n }\n}\n"]}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { FrontMcpServer } from '../../common';
|
|
2
2
|
export declare abstract class HostServerAdapter extends FrontMcpServer {
|
|
3
|
+
/**
|
|
4
|
+
* Prepares the server routes without starting the HTTP listener.
|
|
5
|
+
* Used for serverless deployments (Vercel, AWS Lambda, etc.)
|
|
6
|
+
*/
|
|
7
|
+
abstract prepare(): void;
|
|
8
|
+
/**
|
|
9
|
+
* Returns the underlying HTTP handler for serverless exports.
|
|
10
|
+
*/
|
|
11
|
+
abstract getHandler(): unknown;
|
|
3
12
|
/**
|
|
4
13
|
* Start the server on the specified port
|
|
5
14
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.host.adapter.js","sourceRoot":"","sources":["../../../../src/server/adapters/base.host.adapter.ts"],"names":[],"mappings":";;;AAAA,yCAA8C;AAE9C,MAAsB,iBAAkB,SAAQ,uBAAc;
|
|
1
|
+
{"version":3,"file":"base.host.adapter.js","sourceRoot":"","sources":["../../../../src/server/adapters/base.host.adapter.ts"],"names":[],"mappings":";;;AAAA,yCAA8C;AAE9C,MAAsB,iBAAkB,SAAQ,uBAAc;CAgB7D;AAhBD,8CAgBC","sourcesContent":["import { FrontMcpServer } from '../../common';\n\nexport abstract class HostServerAdapter extends FrontMcpServer {\n /**\n * Prepares the server routes without starting the HTTP listener.\n * Used for serverless deployments (Vercel, AWS Lambda, etc.)\n */\n abstract override prepare(): void;\n\n /**\n * Returns the underlying HTTP handler for serverless exports.\n */\n abstract override getHandler(): unknown;\n\n /**\n * Start the server on the specified port\n */\n abstract override start(port: number): Promise<void> | void;\n}\n"]}
|
|
@@ -4,9 +4,21 @@ import { HttpMethod, ServerRequestHandler } from '../../common';
|
|
|
4
4
|
export declare class ExpressHostAdapter extends HostServerAdapter {
|
|
5
5
|
private app;
|
|
6
6
|
private router;
|
|
7
|
+
private prepared;
|
|
7
8
|
constructor();
|
|
8
9
|
registerRoute(method: HttpMethod, path: string, handler: ServerRequestHandler): void;
|
|
9
10
|
registerMiddleware(entryPath: string, handler: ServerRequestHandler): void;
|
|
10
11
|
enhancedHandler(handler: ServerRequestHandler): (req: express.Request, res: express.Response, next: express.NextFunction) => void | Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Prepares the Express app with routes but does NOT start the HTTP server.
|
|
14
|
+
* Used for serverless deployments (Vercel, AWS Lambda, etc.)
|
|
15
|
+
* This method is idempotent - safe to call multiple times.
|
|
16
|
+
*/
|
|
17
|
+
prepare(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the Express app for serverless exports.
|
|
20
|
+
* Automatically calls prepare() to ensure routes are registered.
|
|
21
|
+
*/
|
|
22
|
+
getHandler(): express.Application;
|
|
11
23
|
start(port: number): void;
|
|
12
24
|
}
|
|
@@ -10,6 +10,7 @@ const base_host_adapter_1 = require("./base.host.adapter");
|
|
|
10
10
|
class ExpressHostAdapter extends base_host_adapter_1.HostServerAdapter {
|
|
11
11
|
app = (0, express_1.default)();
|
|
12
12
|
router = express_1.default.Router();
|
|
13
|
+
prepared = false;
|
|
13
14
|
constructor() {
|
|
14
15
|
super();
|
|
15
16
|
this.app.use(express_1.default.json());
|
|
@@ -37,8 +38,27 @@ class ExpressHostAdapter extends base_host_adapter_1.HostServerAdapter {
|
|
|
37
38
|
return handler(request, response, next);
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Prepares the Express app with routes but does NOT start the HTTP server.
|
|
43
|
+
* Used for serverless deployments (Vercel, AWS Lambda, etc.)
|
|
44
|
+
* This method is idempotent - safe to call multiple times.
|
|
45
|
+
*/
|
|
46
|
+
prepare() {
|
|
47
|
+
if (this.prepared)
|
|
48
|
+
return;
|
|
49
|
+
this.prepared = true;
|
|
41
50
|
this.app.use('/', this.router);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns the Express app for serverless exports.
|
|
54
|
+
* Automatically calls prepare() to ensure routes are registered.
|
|
55
|
+
*/
|
|
56
|
+
getHandler() {
|
|
57
|
+
this.prepare();
|
|
58
|
+
return this.app;
|
|
59
|
+
}
|
|
60
|
+
start(port) {
|
|
61
|
+
this.prepare();
|
|
42
62
|
const server = http.createServer(this.app);
|
|
43
63
|
server.requestTimeout = 0;
|
|
44
64
|
server.headersTimeout = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.host.adapter.js","sourceRoot":"","sources":["../../../../src/server/adapters/express.host.adapter.ts"],"names":[],"mappings":";;;;AAAA,0CAA0C;AAC1C,wDAAkC;AAClC,8DAA8B;AAC9B,wDAAwB;AACxB,2DAAwD;AAGxD,MAAa,kBAAmB,SAAQ,qCAAiB;IAC/C,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;IAChB,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"express.host.adapter.js","sourceRoot":"","sources":["../../../../src/server/adapters/express.host.adapter.ts"],"names":[],"mappings":";;;;AAAA,0CAA0C;AAC1C,wDAAkC;AAClC,8DAA8B;AAC9B,wDAAwB;AACxB,2DAAwD;AAGxD,MAAa,kBAAmB,SAAQ,qCAAiB;IAC/C,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;IAChB,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;IAC1B,QAAQ,GAAG,KAAK,CAAC;IAEzB;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAA,cAAI,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACjD,oDAAoD;QACpD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC9B,GAAG,CAAC,SAAS,CAAC,+BAA+B,EAAE,kBAAkB,CAAC,CAAC;YACnE,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC;YACzD,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;YACjE,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;IACL,CAAC;IAED,aAAa,CAAC,MAAkB,EAAE,IAAY,EAAE,OAA6B;QAC3E,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,kBAAkB,CAAC,SAAiB,EAAE,OAA6B;QACjE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,OAAc,CAAC,CAAC;IAC7C,CAAC;IAED,eAAe,CAAC,OAA6B;QAC3C,OAAO,CAAC,GAAoB,EAAE,GAAqB,EAAE,IAA0B,EAAE,EAAE;YACjF,yDAAyD;YACzD,MAAM,OAAO,GAAG,GAAoB,CAAC;YACrC,MAAM,QAAQ,GAAG,GAAqB,CAAC;YACvC,OAAO,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,UAAU;QACR,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,IAAY;QAChB,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;CACF;AAhED,gDAgEC","sourcesContent":["// server/adapters/express.host.adapter.ts\nimport * as http from 'node:http';\nimport express from 'express';\nimport cors from 'cors';\nimport { HostServerAdapter } from './base.host.adapter';\nimport { HttpMethod, ServerRequest, ServerRequestHandler, ServerResponse } from '../../common';\n\nexport class ExpressHostAdapter extends HostServerAdapter {\n private app = express();\n private router = express.Router();\n private prepared = false;\n\n constructor() {\n super();\n this.app.use(express.json());\n this.app.use(express.urlencoded({ extended: true }));\n this.app.use(cors({ origin: '*', maxAge: 300 }));\n // When creating the HTTP(S) server that hosts /mcp:\n this.app.use((req, res, next) => {\n res.setHeader('Access-Control-Expose-Headers', 'WWW-Authenticate');\n res.setHeader('Cache-Control', 'no-cache, no-transform');\n res.setHeader('Content-Type', 'application/json; charset=utf-8');\n next();\n });\n }\n\n registerRoute(method: HttpMethod, path: string, handler: ServerRequestHandler) {\n this.router[method.toLowerCase()](path, this.enhancedHandler(handler));\n }\n\n registerMiddleware(entryPath: string, handler: ServerRequestHandler) {\n this.router.use(entryPath, handler as any);\n }\n\n enhancedHandler(handler: ServerRequestHandler) {\n return (req: express.Request, res: express.Response, next: express.NextFunction) => {\n // TODO: add request/response enhancements here if needed\n const request = req as ServerRequest;\n const response = res as ServerResponse;\n return handler(request, response, next);\n };\n }\n\n /**\n * Prepares the Express app with routes but does NOT start the HTTP server.\n * Used for serverless deployments (Vercel, AWS Lambda, etc.)\n * This method is idempotent - safe to call multiple times.\n */\n prepare(): void {\n if (this.prepared) return;\n this.prepared = true;\n this.app.use('/', this.router);\n }\n\n /**\n * Returns the Express app for serverless exports.\n * Automatically calls prepare() to ensure routes are registered.\n */\n getHandler(): express.Application {\n this.prepare();\n return this.app;\n }\n\n start(port: number) {\n this.prepare();\n const server = http.createServer(this.app);\n server.requestTimeout = 0;\n server.headersTimeout = 0;\n server.keepAliveTimeout = 75_000;\n server.listen(port, () => console.log(`MCP HTTP (Express) on ${port}`));\n }\n}\n"]}
|
|
@@ -3,10 +3,13 @@ import { HostServerAdapter } from './adapters/base.host.adapter';
|
|
|
3
3
|
export declare class FrontMcpServerInstance extends FrontMcpServer {
|
|
4
4
|
config: HttpConfig;
|
|
5
5
|
host: HostServerAdapter;
|
|
6
|
+
private healthRouteRegistered;
|
|
6
7
|
constructor(httpConfig: HttpConfig);
|
|
7
8
|
private setupDefaults;
|
|
8
9
|
registerMiddleware(entryPath: string, handler: ServerRequestHandler): void | Promise<void>;
|
|
9
10
|
registerRoute(method: HttpMethod, path: string, handler: ServerRequestHandler): void | Promise<void>;
|
|
10
11
|
enhancedHandler(handler: ServerRequestHandler): ServerRequestHandler;
|
|
12
|
+
prepare(): void;
|
|
13
|
+
getHandler(): unknown;
|
|
11
14
|
start(): void;
|
|
12
15
|
}
|
|
@@ -6,6 +6,7 @@ const express_host_adapter_1 = require("./adapters/express.host.adapter");
|
|
|
6
6
|
class FrontMcpServerInstance extends common_1.FrontMcpServer {
|
|
7
7
|
config;
|
|
8
8
|
host;
|
|
9
|
+
healthRouteRegistered = false;
|
|
9
10
|
constructor(httpConfig) {
|
|
10
11
|
super();
|
|
11
12
|
this.config = httpConfig;
|
|
@@ -26,20 +27,26 @@ class FrontMcpServerInstance extends common_1.FrontMcpServer {
|
|
|
26
27
|
registerMiddleware(entryPath, handler) {
|
|
27
28
|
return this.host.registerMiddleware(entryPath, handler);
|
|
28
29
|
}
|
|
29
|
-
;
|
|
30
30
|
registerRoute(method, path, handler) {
|
|
31
31
|
return this.host.registerRoute(method, path, handler);
|
|
32
32
|
}
|
|
33
|
-
;
|
|
34
33
|
enhancedHandler(handler) {
|
|
35
34
|
return this.host.enhancedHandler(handler);
|
|
36
35
|
}
|
|
37
|
-
|
|
38
|
-
this.
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
prepare() {
|
|
37
|
+
if (!this.healthRouteRegistered) {
|
|
38
|
+
this.healthRouteRegistered = true;
|
|
39
|
+
this.registerRoute('GET', '/health', async (req, res) => {
|
|
40
|
+
res.status(200).json({ status: 'ok' });
|
|
41
41
|
});
|
|
42
|
-
}
|
|
42
|
+
}
|
|
43
|
+
this.host.prepare();
|
|
44
|
+
}
|
|
45
|
+
getHandler() {
|
|
46
|
+
return this.host.getHandler();
|
|
47
|
+
}
|
|
48
|
+
start() {
|
|
49
|
+
this.prepare();
|
|
43
50
|
this.host.start(this.config.port);
|
|
44
51
|
}
|
|
45
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.instance.js","sourceRoot":"","sources":["../../../src/server/server.instance.ts"],"names":[],"mappings":";;;AAAA,sCAAyF;AACzF,0EAAqE;
|
|
1
|
+
{"version":3,"file":"server.instance.js","sourceRoot":"","sources":["../../../src/server/server.instance.ts"],"names":[],"mappings":";;;AAAA,sCAAyF;AACzF,0EAAqE;AAGrE,MAAa,sBAAuB,SAAQ,uBAAc;IACxD,MAAM,CAAa;IACnB,IAAI,CAAoB;IAChB,qBAAqB,GAAG,KAAK,CAAC;IAEtC,YAAY,UAAsB;QAChC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YAClD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;YAC/C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,GAAG,IAAI,yCAAkB,EAAE,CAAC;QACvC,CAAC;IACH,CAAC;IAED,kBAAkB,CAAC,SAAiB,EAAE,OAA6B;QACjE,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,aAAa,CAAC,MAAkB,EAAE,IAAY,EAAE,OAA6B;QAC3E,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAEQ,eAAe,CAAC,OAA6B;QACpD,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAChC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;YAClC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;gBACtD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;IAChC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;CACF;AApDD,wDAoDC","sourcesContent":["import { FrontMcpServer, HttpConfig, HttpMethod, ServerRequestHandler } from '../common';\nimport { ExpressHostAdapter } from './adapters/express.host.adapter';\nimport { HostServerAdapter } from './adapters/base.host.adapter';\n\nexport class FrontMcpServerInstance extends FrontMcpServer {\n config: HttpConfig;\n host: HostServerAdapter;\n private healthRouteRegistered = false;\n\n constructor(httpConfig: HttpConfig) {\n super();\n this.config = httpConfig;\n this.setupDefaults();\n }\n\n private setupDefaults() {\n if (typeof this.config.hostFactory === 'function') {\n const { hostFactory, ...config } = this.config;\n this.host = this.config.hostFactory(config);\n } else if (this.config.hostFactory !== undefined) {\n this.host = this.config.hostFactory;\n } else {\n this.host = new ExpressHostAdapter();\n }\n }\n\n registerMiddleware(entryPath: string, handler: ServerRequestHandler) {\n return this.host.registerMiddleware(entryPath, handler);\n }\n\n registerRoute(method: HttpMethod, path: string, handler: ServerRequestHandler) {\n return this.host.registerRoute(method, path, handler);\n }\n\n override enhancedHandler(handler: ServerRequestHandler): ServerRequestHandler {\n return this.host.enhancedHandler(handler);\n }\n\n prepare() {\n if (!this.healthRouteRegistered) {\n this.healthRouteRegistered = true;\n this.registerRoute('GET', '/health', async (req, res) => {\n res.status(200).json({ status: 'ok' });\n });\n }\n this.host.prepare();\n }\n\n getHandler(): unknown {\n return this.host.getHandler();\n }\n\n start() {\n this.prepare();\n this.host.start(this.config.port);\n }\n}\n"]}
|