@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../../src/context/request-context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RequestContext - Production-ready request context for FrontMCP\n *\n * Provides request-scoped state that flows through the entire async execution\n * chain via AsyncLocalStorage. Access via DI only using the REQUEST_CONTEXT token.\n */\n\nimport { randomUUID, createHash } from 'node:crypto';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport { FrontMcpLogger } from '../common/interfaces/logger.interface';\nimport { TraceContext, generateTraceContext } from './trace-context';\nimport type { SessionIdPayload } from '../common/types';\n\n/**\n * Request metadata extracted from HTTP headers.\n */\nexport interface RequestMetadata {\n /** User-Agent header */\n userAgent?: string;\n /** Content-Type header */\n contentType?: string;\n /** Accept header */\n accept?: string;\n /** Client IP address (from x-forwarded-for or socket) */\n clientIp?: string;\n /** Custom headers matching x-frontmcp-* pattern */\n customHeaders: Record<string, string>;\n}\n\n/**\n * Arguments for creating a RequestContext.\n */\nexport interface RequestContextArgs {\n /** Optional request ID (generated if not provided) */\n requestId?: string;\n /** Optional trace context (generated if not provided) */\n traceContext?: TraceContext;\n /** Session identifier (required) */\n sessionId: string;\n /** Authentication information (can be partial, progressively populated) */\n authInfo: Partial<AuthInfo>;\n /** Scope identifier (required) */\n scopeId: string;\n /** Optional timestamp (defaults to Date.now()) */\n timestamp?: number;\n /** Optional request metadata */\n metadata?: RequestMetadata;\n}\n\n/**\n * RequestContext provides per-request state that flows through\n * the entire async execution chain via AsyncLocalStorage.\n *\n * Access via DI only using the REQUEST_CONTEXT token:\n * ```typescript\n * const ctx = this.get(REQUEST_CONTEXT);\n * console.log(ctx.requestId, ctx.traceContext.traceId);\n * ```\n */\nexport class RequestContext {\n /** Unique request identifier (UUID v4) */\n readonly requestId: string;\n\n /** W3C Trace Context or generated trace ID */\n readonly traceContext: TraceContext;\n\n /** Session identifier (from mcp-session-id header or authorization) */\n readonly sessionId: string;\n\n /**\n * Authentication information.\n * Note: This is mutable to allow updating after authorization is verified.\n * It's Partial<AuthInfo> because auth info is progressively populated\n * throughout the request lifecycle (some fields like transport are only\n * available after the transport is established).\n */\n private _authInfo: Partial<AuthInfo>;\n\n /** Scope identifier */\n readonly scopeId: string;\n\n /** Request start timestamp */\n readonly timestamp: number;\n\n /** Request metadata (headers, user-agent, etc.) */\n readonly metadata: RequestMetadata;\n\n /** Timing marks for performance tracking */\n private readonly marks: Map<string, number> = new Map();\n\n /** Request-scoped data store */\n private readonly store: Map<string | symbol, unknown> = new Map();\n\n constructor(args: RequestContextArgs) {\n this.requestId = args.requestId ?? randomUUID();\n this.traceContext = args.traceContext ?? generateTraceContext();\n this.sessionId = args.sessionId;\n this._authInfo = args.authInfo;\n this.scopeId = args.scopeId;\n this.timestamp = args.timestamp ?? Date.now();\n // Defensive normalization: ensure customHeaders is always an object\n // even if args.metadata is partially defined at runtime (TS can't enforce this)\n const metadata = args.metadata;\n this.metadata = {\n ...metadata,\n customHeaders: metadata?.customHeaders ?? {},\n };\n\n // Initial mark\n this.marks.set('init', this.timestamp);\n }\n\n /**\n * Get authentication information.\n * Returns Partial<AuthInfo> because auth info is progressively populated.\n */\n get authInfo(): Partial<AuthInfo> {\n return this._authInfo;\n }\n\n /**\n * Update auth info after authorization is verified.\n * Called by checkAuthorization stage after session verification.\n * Can be called multiple times to progressively add fields.\n *\n * @param authInfo - The auth info fields to set/update\n * @internal\n */\n updateAuthInfo(authInfo: Partial<AuthInfo>): void {\n // Merge with existing auth info to support progressive updates\n this._authInfo = { ...this._authInfo, ...authInfo };\n }\n\n /**\n * Session metadata including protocol, platform type, and node info.\n * Only available after session verification in authenticated flows.\n */\n private _sessionMetadata?: SessionIdPayload;\n\n /**\n * Get session metadata.\n *\n * Contains protocol type, platform type, nodeId, and authSignature.\n * Only available after session verification completes.\n *\n * @returns Session metadata or undefined if not yet verified\n */\n get sessionMetadata(): SessionIdPayload | undefined {\n return this._sessionMetadata;\n }\n\n /**\n * Update session metadata after session verification.\n * Called by checkAuthorization stage after session verification.\n *\n * @param metadata - Session metadata from verified session\n * @internal\n */\n updateSessionMetadata(metadata: SessionIdPayload): void {\n this._sessionMetadata = metadata;\n }\n\n /**\n * Get a child logger with request context attached.\n *\n * Creates a child logger with a prefix containing the request ID and trace ID\n * for easy request tracing in logs.\n *\n * @param parentLogger - The parent logger to create a child from\n * @returns A logger with requestId and traceId in the prefix\n */\n getLogger(parentLogger: FrontMcpLogger): FrontMcpLogger {\n // FrontMcpLogger.child() takes a string prefix\n const prefix = `[${this.requestId.slice(0, 8)}:${this.traceContext.traceId.slice(0, 8)}]`;\n return parentLogger.child(prefix);\n }\n\n /**\n * Mark a timing point for performance tracking.\n *\n * @param name - Name of the timing mark\n */\n mark(name: string): void {\n this.marks.set(name, Date.now());\n }\n\n /**\n * Get elapsed time in milliseconds between two marks.\n *\n * @param from - Start mark name (defaults to 'init')\n * @param to - End mark name (defaults to current time)\n * @returns Elapsed time in milliseconds\n */\n elapsed(from?: string, to?: string): number {\n const fromTime = this.marks.get(from ?? 'init') ?? this.timestamp;\n const toTime = to ? this.marks.get(to) ?? Date.now() : Date.now();\n return toTime - fromTime;\n }\n\n /**\n * Get all timing marks.\n *\n * @returns Read-only map of mark names to timestamps\n */\n getMarks(): ReadonlyMap<string, number> {\n return this.marks;\n }\n\n /**\n * Store request-scoped data.\n *\n * @param key - Storage key\n * @param value - Value to store\n */\n set<T>(key: string | symbol, value: T): void {\n this.store.set(key, value);\n }\n\n /**\n * Retrieve request-scoped data.\n *\n * @param key - Storage key\n * @returns Stored value or undefined\n */\n get<T>(key: string | symbol): T | undefined {\n return this.store.get(key) as T | undefined;\n }\n\n /**\n * Check if a key exists in the request-scoped store.\n *\n * @param key - Storage key\n * @returns True if key exists\n */\n has(key: string | symbol): boolean {\n return this.store.has(key);\n }\n\n /**\n * Delete a key from the request-scoped store.\n *\n * @param key - Storage key\n * @returns True if key was deleted\n */\n delete(key: string | symbol): boolean {\n return this.store.delete(key);\n }\n\n /**\n * Get a summary of the context for logging.\n *\n * Note: sessionId is hashed to prevent accidental exposure of user-identifying\n * session identifiers in logs while still allowing correlation.\n *\n * @returns Object with key context fields\n */\n toLogContext(): Record<string, unknown> {\n return {\n requestId: this.requestId,\n traceId: this.traceContext.traceId,\n parentId: this.traceContext.parentId,\n // Hash sessionId to prevent logging user-identifying information\n // while preserving ability to correlate logs for the same session\n sessionIdHash: createHash('sha256').update(this.sessionId).digest('hex').slice(0, 12),\n scopeId: this.scopeId,\n elapsed: this.elapsed(),\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REQUEST_CONTEXT Provider
|
|
3
|
+
*
|
|
4
|
+
* Defines the DI token and factory provider for accessing RequestContext.
|
|
5
|
+
* The context is retrieved from AsyncLocalStorage via RequestContextStorage.
|
|
6
|
+
*/
|
|
7
|
+
import { ProviderFactoryType } from '../common/interfaces/provider.interface';
|
|
8
|
+
import { RequestContext } from './request-context';
|
|
9
|
+
import { RequestContextStorage } from './request-context-storage';
|
|
10
|
+
/**
|
|
11
|
+
* DI token for accessing the current RequestContext.
|
|
12
|
+
*
|
|
13
|
+
* Use this token to inject the current request context in any provider or context:
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // In a tool/resource/prompt
|
|
18
|
+
* const ctx = this.get(REQUEST_CONTEXT);
|
|
19
|
+
* console.log(ctx.requestId, ctx.traceContext.traceId);
|
|
20
|
+
*
|
|
21
|
+
* // In a provider with constructor injection
|
|
22
|
+
* constructor(
|
|
23
|
+
* @Inject(REQUEST_CONTEXT) private ctx: RequestContext
|
|
24
|
+
* ) {}
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare const REQUEST_CONTEXT: unique symbol;
|
|
28
|
+
/**
|
|
29
|
+
* Factory provider for RequestContext.
|
|
30
|
+
*
|
|
31
|
+
* This provider is marked as REQUEST scope and retrieves the current
|
|
32
|
+
* RequestContext from AsyncLocalStorage via RequestContextStorage.
|
|
33
|
+
*
|
|
34
|
+
* Note: This provider will throw if called outside of a request scope
|
|
35
|
+
* (i.e., without first calling RequestContextStorage.run or runFromHeaders).
|
|
36
|
+
*/
|
|
37
|
+
export declare const RequestContextProvider: ProviderFactoryType<RequestContext, readonly [typeof RequestContextStorage]>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* REQUEST_CONTEXT Provider
|
|
4
|
+
*
|
|
5
|
+
* Defines the DI token and factory provider for accessing RequestContext.
|
|
6
|
+
* The context is retrieved from AsyncLocalStorage via RequestContextStorage.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RequestContextProvider = exports.REQUEST_CONTEXT = void 0;
|
|
10
|
+
const metadata_1 = require("../common/metadata");
|
|
11
|
+
const request_context_storage_1 = require("./request-context-storage");
|
|
12
|
+
/**
|
|
13
|
+
* DI token for accessing the current RequestContext.
|
|
14
|
+
*
|
|
15
|
+
* Use this token to inject the current request context in any provider or context:
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // In a tool/resource/prompt
|
|
20
|
+
* const ctx = this.get(REQUEST_CONTEXT);
|
|
21
|
+
* console.log(ctx.requestId, ctx.traceContext.traceId);
|
|
22
|
+
*
|
|
23
|
+
* // In a provider with constructor injection
|
|
24
|
+
* constructor(
|
|
25
|
+
* @Inject(REQUEST_CONTEXT) private ctx: RequestContext
|
|
26
|
+
* ) {}
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
exports.REQUEST_CONTEXT = Symbol.for('frontmcp:REQUEST_CONTEXT');
|
|
30
|
+
/**
|
|
31
|
+
* Factory provider for RequestContext.
|
|
32
|
+
*
|
|
33
|
+
* This provider is marked as REQUEST scope and retrieves the current
|
|
34
|
+
* RequestContext from AsyncLocalStorage via RequestContextStorage.
|
|
35
|
+
*
|
|
36
|
+
* Note: This provider will throw if called outside of a request scope
|
|
37
|
+
* (i.e., without first calling RequestContextStorage.run or runFromHeaders).
|
|
38
|
+
*/
|
|
39
|
+
exports.RequestContextProvider = {
|
|
40
|
+
provide: exports.REQUEST_CONTEXT,
|
|
41
|
+
inject: () => [request_context_storage_1.RequestContextStorage],
|
|
42
|
+
useFactory: (storage) => {
|
|
43
|
+
return storage.getStoreOrThrow();
|
|
44
|
+
},
|
|
45
|
+
metadata: {
|
|
46
|
+
name: 'RequestContext',
|
|
47
|
+
description: 'Current request context from AsyncLocalStorage',
|
|
48
|
+
scope: metadata_1.ProviderScope.REQUEST,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=request-context.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.provider.js","sourceRoot":"","sources":["../../../src/context/request-context.provider.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,iDAAmD;AAGnD,uEAAkE;AAElE;;;;;;;;;;;;;;;;GAgBG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;AAEtE;;;;;;;;GAQG;AACU,QAAA,sBAAsB,GAAiF;IAClH,OAAO,EAAE,uBAAe;IACxB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,+CAAqB,CAAU;IAC9C,UAAU,EAAE,CAAC,OAA8B,EAAkB,EAAE;QAC7D,OAAO,OAAO,CAAC,eAAe,EAAE,CAAC;IACnC,CAAC;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,gDAAgD;QAC7D,KAAK,EAAE,wBAAa,CAAC,OAAO;KAC7B;CACK,CAAC","sourcesContent":["/**\n * REQUEST_CONTEXT Provider\n *\n * Defines the DI token and factory provider for accessing RequestContext.\n * The context is retrieved from AsyncLocalStorage via RequestContextStorage.\n */\n\nimport { ProviderScope } from '../common/metadata';\nimport { ProviderFactoryType } from '../common/interfaces/provider.interface';\nimport { RequestContext } from './request-context';\nimport { RequestContextStorage } from './request-context-storage';\n\n/**\n * DI token for accessing the current RequestContext.\n *\n * Use this token to inject the current request context in any provider or context:\n *\n * @example\n * ```typescript\n * // In a tool/resource/prompt\n * const ctx = this.get(REQUEST_CONTEXT);\n * console.log(ctx.requestId, ctx.traceContext.traceId);\n *\n * // In a provider with constructor injection\n * constructor(\n * @Inject(REQUEST_CONTEXT) private ctx: RequestContext\n * ) {}\n * ```\n */\nexport const REQUEST_CONTEXT = Symbol.for('frontmcp:REQUEST_CONTEXT');\n\n/**\n * Factory provider for RequestContext.\n *\n * This provider is marked as REQUEST scope and retrieves the current\n * RequestContext from AsyncLocalStorage via RequestContextStorage.\n *\n * Note: This provider will throw if called outside of a request scope\n * (i.e., without first calling RequestContextStorage.run or runFromHeaders).\n */\nexport const RequestContextProvider: ProviderFactoryType<RequestContext, readonly [typeof RequestContextStorage]> = {\n provide: REQUEST_CONTEXT,\n inject: () => [RequestContextStorage] as const,\n useFactory: (storage: RequestContextStorage): RequestContext => {\n return storage.getStoreOrThrow();\n },\n metadata: {\n name: 'RequestContext',\n description: 'Current request context from AsyncLocalStorage',\n scope: ProviderScope.REQUEST,\n },\n} as any;\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session key wrapper for DI injection in SESSION-scoped providers.
|
|
3
|
+
*
|
|
4
|
+
* FrontMCP's DI system uses class tokens (reads `design:paramtypes` from constructors).
|
|
5
|
+
* This class wraps the session ID so it can be injected via constructor parameters.
|
|
6
|
+
*
|
|
7
|
+
* The SessionKey is validated at construction to prevent:
|
|
8
|
+
* - Memory bombs (very long session IDs)
|
|
9
|
+
* - Log injection attacks (special characters)
|
|
10
|
+
* - Cache exhaustion (unique massive IDs)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { Provider, ProviderScope, SessionKey } from '@frontmcp/sdk';
|
|
15
|
+
*
|
|
16
|
+
* @Provider({ scope: ProviderScope.SESSION })
|
|
17
|
+
* class SessionScopedCache {
|
|
18
|
+
* constructor(private readonly sessionKey: SessionKey) {
|
|
19
|
+
* // sessionKey.value available at construction time
|
|
20
|
+
* const sessionId = sessionKey.value;
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class SessionKey {
|
|
26
|
+
readonly value: string;
|
|
27
|
+
/** Maximum allowed length for session keys */
|
|
28
|
+
static readonly MAX_LENGTH = 2048;
|
|
29
|
+
/**
|
|
30
|
+
* Valid characters for session keys:
|
|
31
|
+
* - Alphanumeric (a-z, A-Z, 0-9)
|
|
32
|
+
* - Hyphen, underscore, period
|
|
33
|
+
* - Colon (for namespaced IDs like "anon:uuid")
|
|
34
|
+
*/
|
|
35
|
+
static readonly VALID_PATTERN: RegExp;
|
|
36
|
+
/**
|
|
37
|
+
* Validate a session key string without constructing.
|
|
38
|
+
* Use this for early validation before cache operations.
|
|
39
|
+
*
|
|
40
|
+
* @param value - The session key string to validate
|
|
41
|
+
* @throws InvalidInputError if validation fails (empty, too long, invalid characters)
|
|
42
|
+
*/
|
|
43
|
+
static validate(value: string): void;
|
|
44
|
+
constructor(value: string);
|
|
45
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionKey = void 0;
|
|
4
|
+
const mcp_error_1 = require("../errors/mcp.error");
|
|
5
|
+
/**
|
|
6
|
+
* Session key wrapper for DI injection in SESSION-scoped providers.
|
|
7
|
+
*
|
|
8
|
+
* FrontMCP's DI system uses class tokens (reads `design:paramtypes` from constructors).
|
|
9
|
+
* This class wraps the session ID so it can be injected via constructor parameters.
|
|
10
|
+
*
|
|
11
|
+
* The SessionKey is validated at construction to prevent:
|
|
12
|
+
* - Memory bombs (very long session IDs)
|
|
13
|
+
* - Log injection attacks (special characters)
|
|
14
|
+
* - Cache exhaustion (unique massive IDs)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { Provider, ProviderScope, SessionKey } from '@frontmcp/sdk';
|
|
19
|
+
*
|
|
20
|
+
* @Provider({ scope: ProviderScope.SESSION })
|
|
21
|
+
* class SessionScopedCache {
|
|
22
|
+
* constructor(private readonly sessionKey: SessionKey) {
|
|
23
|
+
* // sessionKey.value available at construction time
|
|
24
|
+
* const sessionId = sessionKey.value;
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
class SessionKey {
|
|
30
|
+
value;
|
|
31
|
+
/** Maximum allowed length for session keys */
|
|
32
|
+
static MAX_LENGTH = 2048;
|
|
33
|
+
/**
|
|
34
|
+
* Valid characters for session keys:
|
|
35
|
+
* - Alphanumeric (a-z, A-Z, 0-9)
|
|
36
|
+
* - Hyphen, underscore, period
|
|
37
|
+
* - Colon (for namespaced IDs like "anon:uuid")
|
|
38
|
+
*/
|
|
39
|
+
static VALID_PATTERN = /^[a-zA-Z0-9\-_.:]+$/;
|
|
40
|
+
/**
|
|
41
|
+
* Validate a session key string without constructing.
|
|
42
|
+
* Use this for early validation before cache operations.
|
|
43
|
+
*
|
|
44
|
+
* @param value - The session key string to validate
|
|
45
|
+
* @throws InvalidInputError if validation fails (empty, too long, invalid characters)
|
|
46
|
+
*/
|
|
47
|
+
static validate(value) {
|
|
48
|
+
if (!value || value.length === 0) {
|
|
49
|
+
throw new mcp_error_1.InvalidInputError('SessionKey cannot be empty');
|
|
50
|
+
}
|
|
51
|
+
if (value.length > SessionKey.MAX_LENGTH) {
|
|
52
|
+
throw new mcp_error_1.InvalidInputError(`SessionKey exceeds maximum length of ${SessionKey.MAX_LENGTH} characters`);
|
|
53
|
+
}
|
|
54
|
+
if (!SessionKey.VALID_PATTERN.test(value)) {
|
|
55
|
+
throw new mcp_error_1.InvalidInputError('SessionKey contains invalid characters. Allowed: alphanumeric, hyphen, underscore, period, colon');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
constructor(value) {
|
|
59
|
+
this.value = value;
|
|
60
|
+
// Delegate to static method to avoid code duplication
|
|
61
|
+
SessionKey.validate(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.SessionKey = SessionKey;
|
|
65
|
+
//# sourceMappingURL=session-key.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-key.provider.js","sourceRoot":"","sources":["../../../src/context/session-key.provider.ts"],"names":[],"mappings":";;;AAAA,mDAAwD;AAExD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAa,UAAU;IAiCO;IAhC5B,8CAA8C;IAC9C,MAAM,CAAU,UAAU,GAAG,IAAI,CAAC;IAElC;;;;;OAKG;IACH,MAAM,CAAU,aAAa,GAAG,qBAAqB,CAAC;IAEtD;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAa;QAC3B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,6BAAiB,CAAC,4BAA4B,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,UAAU,EAAE,CAAC;YACzC,MAAM,IAAI,6BAAiB,CAAC,wCAAwC,UAAU,CAAC,UAAU,aAAa,CAAC,CAAC;QAC1G,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,6BAAiB,CACzB,kGAAkG,CACnG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,YAA4B,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;QACvC,sDAAsD;QACtD,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;;AApCH,gCAqCC","sourcesContent":["import { InvalidInputError } from '../errors/mcp.error';\n\n/**\n * Session key wrapper for DI injection in SESSION-scoped providers.\n *\n * FrontMCP's DI system uses class tokens (reads `design:paramtypes` from constructors).\n * This class wraps the session ID so it can be injected via constructor parameters.\n *\n * The SessionKey is validated at construction to prevent:\n * - Memory bombs (very long session IDs)\n * - Log injection attacks (special characters)\n * - Cache exhaustion (unique massive IDs)\n *\n * @example\n * ```typescript\n * import { Provider, ProviderScope, SessionKey } from '@frontmcp/sdk';\n *\n * @Provider({ scope: ProviderScope.SESSION })\n * class SessionScopedCache {\n * constructor(private readonly sessionKey: SessionKey) {\n * // sessionKey.value available at construction time\n * const sessionId = sessionKey.value;\n * }\n * }\n * ```\n */\nexport class SessionKey {\n /** Maximum allowed length for session keys */\n static readonly MAX_LENGTH = 2048;\n\n /**\n * Valid characters for session keys:\n * - Alphanumeric (a-z, A-Z, 0-9)\n * - Hyphen, underscore, period\n * - Colon (for namespaced IDs like \"anon:uuid\")\n */\n static readonly VALID_PATTERN = /^[a-zA-Z0-9\\-_.:]+$/;\n\n /**\n * Validate a session key string without constructing.\n * Use this for early validation before cache operations.\n *\n * @param value - The session key string to validate\n * @throws InvalidInputError if validation fails (empty, too long, invalid characters)\n */\n static validate(value: string): void {\n if (!value || value.length === 0) {\n throw new InvalidInputError('SessionKey cannot be empty');\n }\n if (value.length > SessionKey.MAX_LENGTH) {\n throw new InvalidInputError(`SessionKey exceeds maximum length of ${SessionKey.MAX_LENGTH} characters`);\n }\n if (!SessionKey.VALID_PATTERN.test(value)) {\n throw new InvalidInputError(\n 'SessionKey contains invalid characters. Allowed: alphanumeric, hyphen, underscore, period, colon',\n );\n }\n }\n\n constructor(public readonly value: string) {\n // Delegate to static method to avoid code duplication\n SessionKey.validate(value);\n }\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* W3C Trace Context Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses distributed tracing headers according to W3C Trace Context specification.
|
|
5
|
+
* Supports traceparent header with fallback to x-frontmcp-trace-id custom header.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.w3.org/TR/trace-context/
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* W3C Trace Context parsed from traceparent header.
|
|
11
|
+
* Format: 00-<trace-id>-<parent-id>-<trace-flags>
|
|
12
|
+
*/
|
|
13
|
+
export interface TraceContext {
|
|
14
|
+
/** 128-bit trace identifier (32 hex chars) */
|
|
15
|
+
traceId: string;
|
|
16
|
+
/** 64-bit parent span identifier (16 hex chars) */
|
|
17
|
+
parentId: string;
|
|
18
|
+
/** 8-bit trace flags (sampled = 0x01) */
|
|
19
|
+
traceFlags: number;
|
|
20
|
+
/** Raw traceparent header value */
|
|
21
|
+
raw: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Parse trace context from HTTP headers.
|
|
25
|
+
*
|
|
26
|
+
* Priority:
|
|
27
|
+
* 1. W3C traceparent header
|
|
28
|
+
* 2. x-frontmcp-trace-id custom header
|
|
29
|
+
* 3. Generate new trace context
|
|
30
|
+
*
|
|
31
|
+
* @param headers - HTTP headers object
|
|
32
|
+
* @returns Parsed or generated TraceContext
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseTraceContext(headers: Record<string, unknown>): TraceContext;
|
|
35
|
+
/**
|
|
36
|
+
* Generate a new trace context with random IDs.
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateTraceContext(): TraceContext;
|
|
39
|
+
/**
|
|
40
|
+
* Create a child span context from a parent context.
|
|
41
|
+
* Generates a new parentId while preserving the traceId.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createChildSpanContext(parent: TraceContext): TraceContext;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* W3C Trace Context Parser
|
|
4
|
+
*
|
|
5
|
+
* Parses distributed tracing headers according to W3C Trace Context specification.
|
|
6
|
+
* Supports traceparent header with fallback to x-frontmcp-trace-id custom header.
|
|
7
|
+
*
|
|
8
|
+
* @see https://www.w3.org/TR/trace-context/
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.parseTraceContext = parseTraceContext;
|
|
12
|
+
exports.generateTraceContext = generateTraceContext;
|
|
13
|
+
exports.createChildSpanContext = createChildSpanContext;
|
|
14
|
+
const node_crypto_1 = require("node:crypto");
|
|
15
|
+
/**
|
|
16
|
+
* Parse trace context from HTTP headers.
|
|
17
|
+
*
|
|
18
|
+
* Priority:
|
|
19
|
+
* 1. W3C traceparent header
|
|
20
|
+
* 2. x-frontmcp-trace-id custom header
|
|
21
|
+
* 3. Generate new trace context
|
|
22
|
+
*
|
|
23
|
+
* @param headers - HTTP headers object
|
|
24
|
+
* @returns Parsed or generated TraceContext
|
|
25
|
+
*/
|
|
26
|
+
function parseTraceContext(headers) {
|
|
27
|
+
// Priority 1: W3C traceparent header
|
|
28
|
+
const traceparent = getHeader(headers, 'traceparent');
|
|
29
|
+
if (traceparent) {
|
|
30
|
+
const parsed = parseTraceparent(traceparent);
|
|
31
|
+
if (parsed)
|
|
32
|
+
return parsed;
|
|
33
|
+
}
|
|
34
|
+
// Priority 2: x-frontmcp-trace-id custom header
|
|
35
|
+
const customTraceId = getHeader(headers, 'x-frontmcp-trace-id');
|
|
36
|
+
if (customTraceId && isValidTraceId(customTraceId)) {
|
|
37
|
+
const parentId = generateParentId();
|
|
38
|
+
return {
|
|
39
|
+
traceId: customTraceId.toLowerCase(),
|
|
40
|
+
parentId,
|
|
41
|
+
traceFlags: 0x01,
|
|
42
|
+
raw: `00-${customTraceId.toLowerCase()}-${parentId}-01`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// Priority 3: Generate new trace context
|
|
46
|
+
return generateTraceContext();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse W3C traceparent header.
|
|
50
|
+
*
|
|
51
|
+
* Format: version-traceId-parentId-traceFlags
|
|
52
|
+
* Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
|
|
53
|
+
*
|
|
54
|
+
* @param value - traceparent header value
|
|
55
|
+
* @returns Parsed TraceContext or null if invalid
|
|
56
|
+
*/
|
|
57
|
+
function parseTraceparent(value) {
|
|
58
|
+
const parts = value.split('-');
|
|
59
|
+
if (parts.length !== 4)
|
|
60
|
+
return null;
|
|
61
|
+
const [version, traceId, parentId, flags] = parts;
|
|
62
|
+
// Validate version (must be 00 for current spec)
|
|
63
|
+
if (version !== '00')
|
|
64
|
+
return null;
|
|
65
|
+
// Validate trace-id (32 hex chars, not all zeros)
|
|
66
|
+
if (!isValidTraceId(traceId))
|
|
67
|
+
return null;
|
|
68
|
+
// Validate parent-id (16 hex chars, not all zeros)
|
|
69
|
+
if (!isValidParentId(parentId))
|
|
70
|
+
return null;
|
|
71
|
+
// Parse trace-flags
|
|
72
|
+
const traceFlags = parseInt(flags, 16);
|
|
73
|
+
if (isNaN(traceFlags))
|
|
74
|
+
return null;
|
|
75
|
+
return {
|
|
76
|
+
traceId: traceId.toLowerCase(),
|
|
77
|
+
parentId: parentId.toLowerCase(),
|
|
78
|
+
traceFlags,
|
|
79
|
+
raw: value,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Validate a trace ID according to W3C spec.
|
|
84
|
+
* Must be 32 lowercase hex characters, not all zeros.
|
|
85
|
+
*/
|
|
86
|
+
function isValidTraceId(id) {
|
|
87
|
+
return /^[a-f0-9]{32}$/i.test(id) && id !== '00000000000000000000000000000000';
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Validate a parent ID according to W3C spec.
|
|
91
|
+
* Must be 16 lowercase hex characters, not all zeros.
|
|
92
|
+
*/
|
|
93
|
+
function isValidParentId(id) {
|
|
94
|
+
return /^[a-f0-9]{16}$/i.test(id) && id !== '0000000000000000';
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Generate a new parent ID (16 hex chars).
|
|
98
|
+
*/
|
|
99
|
+
function generateParentId() {
|
|
100
|
+
return (0, node_crypto_1.randomUUID)().replace(/-/g, '').slice(0, 16);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Generate a new trace context with random IDs.
|
|
104
|
+
*/
|
|
105
|
+
function generateTraceContext() {
|
|
106
|
+
const traceId = (0, node_crypto_1.randomUUID)().replace(/-/g, '');
|
|
107
|
+
const parentId = generateParentId();
|
|
108
|
+
return {
|
|
109
|
+
traceId,
|
|
110
|
+
parentId,
|
|
111
|
+
traceFlags: 0x01, // sampled
|
|
112
|
+
raw: `00-${traceId}-${parentId}-01`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get a header value from headers object (case-insensitive).
|
|
117
|
+
*/
|
|
118
|
+
function getHeader(headers, name) {
|
|
119
|
+
// Try exact match first
|
|
120
|
+
const value = headers[name];
|
|
121
|
+
if (typeof value === 'string')
|
|
122
|
+
return value;
|
|
123
|
+
// Try lowercase
|
|
124
|
+
const lowerValue = headers[name.toLowerCase()];
|
|
125
|
+
if (typeof lowerValue === 'string')
|
|
126
|
+
return lowerValue;
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Create a child span context from a parent context.
|
|
131
|
+
* Generates a new parentId while preserving the traceId.
|
|
132
|
+
*/
|
|
133
|
+
function createChildSpanContext(parent) {
|
|
134
|
+
const newParentId = generateParentId();
|
|
135
|
+
return {
|
|
136
|
+
traceId: parent.traceId,
|
|
137
|
+
parentId: newParentId,
|
|
138
|
+
traceFlags: parent.traceFlags,
|
|
139
|
+
raw: `00-${parent.traceId}-${newParentId}-${parent.traceFlags.toString(16).padStart(2, '0')}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=trace-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-context.js","sourceRoot":"","sources":["../../../src/context/trace-context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * W3C Trace Context Parser\n *\n * Parses distributed tracing headers according to W3C Trace Context specification.\n * Supports traceparent header with fallback to x-frontmcp-trace-id custom header.\n *\n * @see https://www.w3.org/TR/trace-context/\n */\n\nimport { randomUUID } from 'node:crypto';\n\n/**\n * W3C Trace Context parsed from traceparent header.\n * Format: 00-<trace-id>-<parent-id>-<trace-flags>\n */\nexport interface TraceContext {\n /** 128-bit trace identifier (32 hex chars) */\n traceId: string;\n /** 64-bit parent span identifier (16 hex chars) */\n parentId: string;\n /** 8-bit trace flags (sampled = 0x01) */\n traceFlags: number;\n /** Raw traceparent header value */\n raw: string;\n}\n\n/**\n * Parse trace context from HTTP headers.\n *\n * Priority:\n * 1. W3C traceparent header\n * 2. x-frontmcp-trace-id custom header\n * 3. Generate new trace context\n *\n * @param headers - HTTP headers object\n * @returns Parsed or generated TraceContext\n */\nexport function parseTraceContext(headers: Record<string, unknown>): TraceContext {\n // Priority 1: W3C traceparent header\n const traceparent = getHeader(headers, 'traceparent');\n if (traceparent) {\n const parsed = parseTraceparent(traceparent);\n if (parsed) return parsed;\n }\n\n // Priority 2: x-frontmcp-trace-id custom header\n const customTraceId = getHeader(headers, 'x-frontmcp-trace-id');\n if (customTraceId && isValidTraceId(customTraceId)) {\n const parentId = generateParentId();\n return {\n traceId: customTraceId.toLowerCase(),\n parentId,\n traceFlags: 0x01,\n raw: `00-${customTraceId.toLowerCase()}-${parentId}-01`,\n };\n }\n\n // Priority 3: Generate new trace context\n return generateTraceContext();\n}\n\n/**\n * Parse W3C traceparent header.\n *\n * Format: version-traceId-parentId-traceFlags\n * Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\n *\n * @param value - traceparent header value\n * @returns Parsed TraceContext or null if invalid\n */\nfunction parseTraceparent(value: string): TraceContext | null {\n const parts = value.split('-');\n if (parts.length !== 4) return null;\n\n const [version, traceId, parentId, flags] = parts;\n\n // Validate version (must be 00 for current spec)\n if (version !== '00') return null;\n\n // Validate trace-id (32 hex chars, not all zeros)\n if (!isValidTraceId(traceId)) return null;\n\n // Validate parent-id (16 hex chars, not all zeros)\n if (!isValidParentId(parentId)) return null;\n\n // Parse trace-flags\n const traceFlags = parseInt(flags, 16);\n if (isNaN(traceFlags)) return null;\n\n return {\n traceId: traceId.toLowerCase(),\n parentId: parentId.toLowerCase(),\n traceFlags,\n raw: value,\n };\n}\n\n/**\n * Validate a trace ID according to W3C spec.\n * Must be 32 lowercase hex characters, not all zeros.\n */\nfunction isValidTraceId(id: string): boolean {\n return /^[a-f0-9]{32}$/i.test(id) && id !== '00000000000000000000000000000000';\n}\n\n/**\n * Validate a parent ID according to W3C spec.\n * Must be 16 lowercase hex characters, not all zeros.\n */\nfunction isValidParentId(id: string): boolean {\n return /^[a-f0-9]{16}$/i.test(id) && id !== '0000000000000000';\n}\n\n/**\n * Generate a new parent ID (16 hex chars).\n */\nfunction generateParentId(): string {\n return randomUUID().replace(/-/g, '').slice(0, 16);\n}\n\n/**\n * Generate a new trace context with random IDs.\n */\nexport function generateTraceContext(): TraceContext {\n const traceId = randomUUID().replace(/-/g, '');\n const parentId = generateParentId();\n return {\n traceId,\n parentId,\n traceFlags: 0x01, // sampled\n raw: `00-${traceId}-${parentId}-01`,\n };\n}\n\n/**\n * Get a header value from headers object (case-insensitive).\n */\nfunction getHeader(headers: Record<string, unknown>, name: string): string | undefined {\n // Try exact match first\n const value = headers[name];\n if (typeof value === 'string') return value;\n\n // Try lowercase\n const lowerValue = headers[name.toLowerCase()];\n if (typeof lowerValue === 'string') return lowerValue;\n\n return undefined;\n}\n\n/**\n * Create a child span context from a parent context.\n * Generates a new parentId while preserving the traceId.\n */\nexport function createChildSpanContext(parent: TraceContext): TraceContext {\n const newParentId = generateParentId();\n return {\n traceId: parent.traceId,\n parentId: newParentId,\n traceFlags: parent.traceFlags,\n raw: `00-${parent.traceId}-${newParentId}-${parent.traceFlags.toString(16).padStart(2, '0')}`,\n };\n}\n"]}
|
package/src/errors/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { McpError, PublicMcpError, InternalMcpError, ToolNotFoundError, ResourceNotFoundError, ResourceReadError, InvalidResourceUriError, InvalidInputError, InvalidOutputError, InvalidMethodError, ToolExecutionError, RateLimitError, QuotaExceededError, UnauthorizedError, GenericServerError, DependencyNotFoundError, InvalidHookFlowError, AuthConfigurationError, PromptNotFoundError, PromptExecutionError, isPublicError, toMcpError, formatMcpErrorResponse, } from './mcp.error';
|
|
1
|
+
export { McpError, PublicMcpError, InternalMcpError, ToolNotFoundError, ResourceNotFoundError, ResourceReadError, InvalidResourceUriError, InvalidInputError, InvalidOutputError, InvalidMethodError, ToolExecutionError, RateLimitError, QuotaExceededError, UnauthorizedError, GenericServerError, DependencyNotFoundError, InvalidHookFlowError, AuthConfigurationError, PromptNotFoundError, PromptExecutionError, isPublicError, toMcpError, formatMcpErrorResponse, MCP_ERROR_CODES, type McpErrorCode, } from './mcp.error';
|
|
2
2
|
export { authorizationRequiredDataSchema, authorizationRequiredParamsSchema, authorizationRequiredMetaSchema, AuthorizationRequiredData, AuthorizationRequiredParams, AuthorizationRequiredMeta, AuthorizationRequiredError, } from './authorization-required.error';
|
|
3
3
|
export { ErrorHandler, ErrorHandlerOptions, createErrorHandler, shouldStopExecution } from './error-handler';
|
package/src/errors/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.shouldStopExecution = exports.createErrorHandler = exports.ErrorHandler = exports.AuthorizationRequiredError = exports.authorizationRequiredMetaSchema = exports.authorizationRequiredParamsSchema = exports.authorizationRequiredDataSchema = exports.formatMcpErrorResponse = exports.toMcpError = exports.isPublicError = exports.PromptExecutionError = exports.PromptNotFoundError = exports.AuthConfigurationError = exports.InvalidHookFlowError = exports.DependencyNotFoundError = exports.GenericServerError = exports.UnauthorizedError = exports.QuotaExceededError = exports.RateLimitError = exports.ToolExecutionError = exports.InvalidMethodError = exports.InvalidOutputError = exports.InvalidInputError = exports.InvalidResourceUriError = exports.ResourceReadError = exports.ResourceNotFoundError = exports.ToolNotFoundError = exports.InternalMcpError = exports.PublicMcpError = exports.McpError = void 0;
|
|
3
|
+
exports.shouldStopExecution = exports.createErrorHandler = exports.ErrorHandler = exports.AuthorizationRequiredError = exports.authorizationRequiredMetaSchema = exports.authorizationRequiredParamsSchema = exports.authorizationRequiredDataSchema = exports.MCP_ERROR_CODES = exports.formatMcpErrorResponse = exports.toMcpError = exports.isPublicError = exports.PromptExecutionError = exports.PromptNotFoundError = exports.AuthConfigurationError = exports.InvalidHookFlowError = exports.DependencyNotFoundError = exports.GenericServerError = exports.UnauthorizedError = exports.QuotaExceededError = exports.RateLimitError = exports.ToolExecutionError = exports.InvalidMethodError = exports.InvalidOutputError = exports.InvalidInputError = exports.InvalidResourceUriError = exports.ResourceReadError = exports.ResourceNotFoundError = exports.ToolNotFoundError = exports.InternalMcpError = exports.PublicMcpError = exports.McpError = void 0;
|
|
4
4
|
// Export all error classes
|
|
5
5
|
var mcp_error_1 = require("./mcp.error");
|
|
6
6
|
Object.defineProperty(exports, "McpError", { enumerable: true, get: function () { return mcp_error_1.McpError; } });
|
|
@@ -26,6 +26,8 @@ Object.defineProperty(exports, "PromptExecutionError", { enumerable: true, get:
|
|
|
26
26
|
Object.defineProperty(exports, "isPublicError", { enumerable: true, get: function () { return mcp_error_1.isPublicError; } });
|
|
27
27
|
Object.defineProperty(exports, "toMcpError", { enumerable: true, get: function () { return mcp_error_1.toMcpError; } });
|
|
28
28
|
Object.defineProperty(exports, "formatMcpErrorResponse", { enumerable: true, get: function () { return mcp_error_1.formatMcpErrorResponse; } });
|
|
29
|
+
// Error codes
|
|
30
|
+
Object.defineProperty(exports, "MCP_ERROR_CODES", { enumerable: true, get: function () { return mcp_error_1.MCP_ERROR_CODES; } });
|
|
29
31
|
// Export authorization required error for progressive auth
|
|
30
32
|
var authorization_required_error_1 = require("./authorization-required.error");
|
|
31
33
|
// Schemas
|
package/src/errors/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/errors/index.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AAC3B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/errors/index.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AAC3B,yCA2BqB;AA1BnB,qGAAA,QAAQ,OAAA;AACR,2GAAA,cAAc,OAAA;AACd,6GAAA,gBAAgB,OAAA;AAChB,8GAAA,iBAAiB,OAAA;AACjB,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,oHAAA,uBAAuB,OAAA;AACvB,8GAAA,iBAAiB,OAAA;AACjB,+GAAA,kBAAkB,OAAA;AAClB,+GAAA,kBAAkB,OAAA;AAClB,+GAAA,kBAAkB,OAAA;AAClB,2GAAA,cAAc,OAAA;AACd,+GAAA,kBAAkB,OAAA;AAClB,8GAAA,iBAAiB,OAAA;AACjB,+GAAA,kBAAkB,OAAA;AAClB,oHAAA,uBAAuB,OAAA;AACvB,iHAAA,oBAAoB,OAAA;AACpB,mHAAA,sBAAsB,OAAA;AACtB,gHAAA,mBAAmB,OAAA;AACnB,iHAAA,oBAAoB,OAAA;AACpB,0GAAA,aAAa,OAAA;AACb,uGAAA,UAAU,OAAA;AACV,mHAAA,sBAAsB,OAAA;AACtB,cAAc;AACd,4GAAA,eAAe,OAAA;AAIjB,2DAA2D;AAC3D,+EAWwC;AAVtC,UAAU;AACV,+IAAA,+BAA+B,OAAA;AAC/B,iJAAA,iCAAiC,OAAA;AACjC,+IAAA,+BAA+B,OAAA;AAK/B,cAAc;AACd,0IAAA,0BAA0B,OAAA;AAG5B,iCAAiC;AACjC,iDAA6G;AAApG,6GAAA,YAAY,OAAA;AAAuB,mHAAA,kBAAkB,OAAA;AAAE,oHAAA,mBAAmB,OAAA","sourcesContent":["// Export all error classes\nexport {\n McpError,\n PublicMcpError,\n InternalMcpError,\n ToolNotFoundError,\n ResourceNotFoundError,\n ResourceReadError,\n InvalidResourceUriError,\n InvalidInputError,\n InvalidOutputError,\n InvalidMethodError,\n ToolExecutionError,\n RateLimitError,\n QuotaExceededError,\n UnauthorizedError,\n GenericServerError,\n DependencyNotFoundError,\n InvalidHookFlowError,\n AuthConfigurationError,\n PromptNotFoundError,\n PromptExecutionError,\n isPublicError,\n toMcpError,\n formatMcpErrorResponse,\n // Error codes\n MCP_ERROR_CODES,\n type McpErrorCode,\n} from './mcp.error';\n\n// Export authorization required error for progressive auth\nexport {\n // Schemas\n authorizationRequiredDataSchema,\n authorizationRequiredParamsSchema,\n authorizationRequiredMetaSchema,\n // Types (inferred from schemas)\n AuthorizationRequiredData,\n AuthorizationRequiredParams,\n AuthorizationRequiredMeta,\n // Error class\n AuthorizationRequiredError,\n} from './authorization-required.error';\n\n// Export error handler utilities\nexport { ErrorHandler, ErrorHandlerOptions, createErrorHandler, shouldStopExecution } from './error-handler';\n"]}
|
|
@@ -202,6 +202,13 @@ export declare class DependencyNotFoundError extends InternalMcpError {
|
|
|
202
202
|
export declare class InvalidHookFlowError extends InternalMcpError {
|
|
203
203
|
constructor(message: string);
|
|
204
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Request context not available error - thrown when code attempts to access
|
|
207
|
+
* RequestContext outside of a request scope (i.e., without AsyncLocalStorage context).
|
|
208
|
+
*/
|
|
209
|
+
export declare class RequestContextNotAvailableError extends InternalMcpError {
|
|
210
|
+
constructor(message?: string);
|
|
211
|
+
}
|
|
205
212
|
/**
|
|
206
213
|
* Auth configuration error - thrown when auth configuration is invalid
|
|
207
214
|
* (e.g., transparent mode on parent with multiple child providers).
|
package/src/errors/mcp.error.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PromptExecutionError = exports.PromptNotFoundError = exports.AuthConfigurationError = exports.InvalidHookFlowError = exports.DependencyNotFoundError = exports.GenericServerError = exports.UnauthorizedError = exports.QuotaExceededError = exports.RateLimitError = exports.ToolExecutionError = exports.InvalidMethodError = exports.InvalidOutputError = exports.InvalidInputError = exports.InvalidResourceUriError = exports.ResourceReadError = exports.ResourceNotFoundError = exports.ToolNotFoundError = exports.InternalMcpError = exports.PublicMcpError = exports.McpError = exports.MCP_ERROR_CODES = void 0;
|
|
3
|
+
exports.PromptExecutionError = exports.PromptNotFoundError = exports.AuthConfigurationError = exports.RequestContextNotAvailableError = exports.InvalidHookFlowError = exports.DependencyNotFoundError = exports.GenericServerError = exports.UnauthorizedError = exports.QuotaExceededError = exports.RateLimitError = exports.ToolExecutionError = exports.InvalidMethodError = exports.InvalidOutputError = exports.InvalidInputError = exports.InvalidResourceUriError = exports.ResourceReadError = exports.ResourceNotFoundError = exports.ToolNotFoundError = exports.InternalMcpError = exports.PublicMcpError = exports.McpError = exports.MCP_ERROR_CODES = void 0;
|
|
4
4
|
exports.isPublicError = isPublicError;
|
|
5
5
|
exports.toMcpError = toMcpError;
|
|
6
6
|
exports.formatMcpErrorResponse = formatMcpErrorResponse;
|
|
@@ -305,6 +305,16 @@ class InvalidHookFlowError extends InternalMcpError {
|
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
307
|
exports.InvalidHookFlowError = InvalidHookFlowError;
|
|
308
|
+
/**
|
|
309
|
+
* Request context not available error - thrown when code attempts to access
|
|
310
|
+
* RequestContext outside of a request scope (i.e., without AsyncLocalStorage context).
|
|
311
|
+
*/
|
|
312
|
+
class RequestContextNotAvailableError extends InternalMcpError {
|
|
313
|
+
constructor(message = 'RequestContext not available. Ensure execution runs within a request scope created by RequestContextStorage.run().') {
|
|
314
|
+
super(message, 'REQUEST_CONTEXT_NOT_AVAILABLE');
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
exports.RequestContextNotAvailableError = RequestContextNotAvailableError;
|
|
308
318
|
/**
|
|
309
319
|
* Auth configuration error - thrown when auth configuration is invalid
|
|
310
320
|
* (e.g., transparent mode on parent with multiple child providers).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.error.js","sourceRoot":"","sources":["../../../src/errors/mcp.error.ts"],"names":[],"mappings":"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","sourcesContent":["// errors/mcp.error.ts\nimport { randomBytes } from 'crypto';\n\n/**\n * MCP-specific error codes per JSON-RPC specification.\n * These codes are used in the JSON-RPC error response format.\n */\nexport const MCP_ERROR_CODES = {\n /** Resource not found (-32002) */\n RESOURCE_NOT_FOUND: -32002,\n /** Invalid request (-32600) */\n INVALID_REQUEST: -32600,\n /** Method not found (-32601) */\n METHOD_NOT_FOUND: -32601,\n /** Invalid params (-32602) */\n INVALID_PARAMS: -32602,\n /** Internal error (-32603) */\n INTERNAL_ERROR: -32603,\n /** Parse error (-32700) */\n PARSE_ERROR: -32700,\n} as const;\n\nexport type McpErrorCode = (typeof MCP_ERROR_CODES)[keyof typeof MCP_ERROR_CODES];\n\n/**\n * Base class for all MCP-related errors\n */\nexport abstract class McpError extends Error {\n /**\n * Unique error ID for tracking in logs\n */\n errorId: string;\n\n /**\n * Whether this error should expose details to the client\n */\n abstract readonly isPublic: boolean;\n\n /**\n * HTTP status code equivalent (for reference)\n */\n abstract readonly statusCode: number;\n\n /**\n * Error code for categorization\n */\n abstract readonly code: string;\n\n protected constructor(message: string, errorId?: string) {\n super(message);\n this.name = this.constructor.name;\n this.errorId = errorId || this.generateErrorId();\n Error.captureStackTrace(this, this.constructor);\n }\n\n private generateErrorId(): string {\n return `err_${randomBytes(8).toString('hex')}`;\n }\n\n /**\n * Get the public-facing error message\n */\n abstract getPublicMessage(): string;\n\n /**\n * Get the internal error message (for logging)\n */\n getInternalMessage(): string {\n return this.message;\n }\n\n /**\n * Convert to MCP error response format\n */\n toMcpError(isDevelopment = false): {\n content: Array<{ type: 'text'; text: string }>;\n isError: true;\n _meta?: {\n errorId: string;\n code: string;\n timestamp: string;\n stack?: string;\n };\n } {\n const message = isDevelopment ? this.getInternalMessage() : this.getPublicMessage();\n\n return {\n content: [\n {\n type: 'text',\n text: message,\n },\n ],\n isError: true,\n _meta: {\n errorId: this.errorId,\n code: this.code,\n timestamp: new Date().toISOString(),\n ...(isDevelopment && { stack: this.stack }),\n },\n };\n }\n}\n\n/**\n * Public errors - safe to expose to clients\n * These include validation errors, not found errors, etc.\n */\nexport class PublicMcpError extends McpError {\n readonly isPublic = true;\n readonly statusCode: number;\n readonly code: string;\n\n constructor(message: string, code = 'PUBLIC_ERROR', statusCode = 400) {\n super(message);\n this.code = code;\n this.statusCode = statusCode;\n }\n\n getPublicMessage(): string {\n return this.message;\n }\n}\n\n/**\n * Internal errors - should not expose details to clients\n * These are server errors, unexpected failures, etc.\n */\nexport class InternalMcpError extends McpError {\n readonly isPublic = false;\n readonly statusCode = 500;\n readonly code: string;\n\n constructor(message: string, code = 'INTERNAL_ERROR') {\n super(message);\n this.code = code;\n }\n\n getPublicMessage(): string {\n return `Internal FrontMCP error. Please contact support with error ID: ${this.errorId}`;\n }\n}\n\n// ============================================================================\n// Specific Error Classes\n// ============================================================================\n\n/**\n * Tool not found error\n */\nexport class ToolNotFoundError extends PublicMcpError {\n constructor(toolName: string) {\n super(`Tool \"${toolName}\" not found`, 'TOOL_NOT_FOUND', 404);\n }\n}\n\n/**\n * Resource not found error\n */\nexport class ResourceNotFoundError extends PublicMcpError {\n readonly uri: string;\n readonly mcpErrorCode = MCP_ERROR_CODES.RESOURCE_NOT_FOUND;\n\n constructor(uri: string) {\n super(`Resource not found: ${uri}`, 'RESOURCE_NOT_FOUND', 404);\n this.uri = uri;\n }\n\n /**\n * Convert to JSON-RPC error format per MCP specification.\n *\n * @example\n * {\n * \"code\": -32002,\n * \"message\": \"Resource not found: file:///missing.txt\",\n * \"data\": { \"uri\": \"file:///missing.txt\" }\n * }\n */\n toJsonRpcError(): {\n code: number;\n message: string;\n data?: { uri: string };\n } {\n return {\n code: this.mcpErrorCode,\n message: this.getPublicMessage(),\n data: { uri: this.uri },\n };\n }\n}\n\n/**\n * Resource read error (internal)\n */\nexport class ResourceReadError extends InternalMcpError {\n readonly originalError?: Error;\n\n constructor(uri: string, originalError?: Error) {\n super(`Resource \"${uri}\" read failed: ${originalError?.message || 'Unknown error'}`, 'RESOURCE_READ_ERROR');\n this.originalError = originalError;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n/**\n * Invalid resource URI error\n */\nexport class InvalidResourceUriError extends PublicMcpError {\n constructor(uri: string, reason?: string) {\n super(`Invalid resource URI: ${uri}${reason ? ` (${reason})` : ''}`, 'INVALID_RESOURCE_URI', 400);\n }\n}\n\n/**\n * Invalid input validation error\n */\nexport class InvalidInputError extends PublicMcpError {\n readonly validationErrors?: any;\n\n constructor(message = 'Invalid input: validation failed', validationErrors?: any) {\n super(message, 'INVALID_INPUT', 400);\n this.validationErrors = validationErrors;\n }\n\n override getInternalMessage(): string {\n return this.message + (this.validationErrors ? `\\nDetails: ${JSON.stringify(this.validationErrors, null, 2)}` : '');\n }\n override getPublicMessage(): string {\n if (this.validationErrors) {\n return `${this.message}\\nDetails: ${JSON.stringify(this.validationErrors, null, 2)}`;\n }\n return this.message;\n }\n}\n\n/**\n * Invalid output validation error (internal - don't expose schema details)\n */\nexport class InvalidOutputError extends InternalMcpError {\n private readonly hasCustomErrorId: boolean;\n\n constructor(errorId?: string) {\n super('Tool output validation failed', 'INVALID_OUTPUT');\n this.hasCustomErrorId = !!errorId;\n if (errorId) {\n this.errorId = errorId;\n }\n }\n\n override getPublicMessage(): string {\n // If a custom errorId was provided (e.g., request ID), include it for correlation\n // Otherwise, use a simpler message since the auto-generated ID isn't meaningful to users\n if (this.hasCustomErrorId) {\n return `Output validation failed. Please contact support with error ID: ${this.errorId}`;\n }\n return 'Output validation failed. Please contact support.';\n }\n}\n\n/**\n * Invalid method error\n */\nexport class InvalidMethodError extends PublicMcpError {\n constructor(method: string, expected: string) {\n super(`Invalid method \"${method}\". Expected \"${expected}\"`, 'INVALID_METHOD', 400);\n }\n}\n\n/**\n * Tool execution error (internal)\n */\nexport class ToolExecutionError extends InternalMcpError {\n readonly originalError?: Error;\n\n constructor(toolName: string, originalError?: Error) {\n super(`Tool \"${toolName}\" execution failed: ${originalError?.message || 'Unknown error'}`, 'TOOL_EXECUTION_ERROR');\n this.originalError = originalError;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n/**\n * Rate limit error\n */\nexport class RateLimitError extends PublicMcpError {\n constructor(retryAfter?: number) {\n const message = retryAfter ? `Rate limit exceeded. Retry after ${retryAfter} seconds` : 'Rate limit exceeded';\n super(message, 'RATE_LIMIT_EXCEEDED', 429);\n }\n}\n\n/**\n * Quota exceeded error\n */\nexport class QuotaExceededError extends PublicMcpError {\n constructor(quotaType = 'usage') {\n super(`${quotaType} quota exceeded`, 'QUOTA_EXCEEDED', 429);\n }\n}\n\n/**\n * Unauthorized error\n */\nexport class UnauthorizedError extends PublicMcpError {\n constructor(message = 'Unauthorized') {\n super(message, 'UNAUTHORIZED', 401);\n }\n}\n\n/**\n * Generic server error wrapper\n */\nexport class GenericServerError extends InternalMcpError {\n readonly originalError?: Error;\n\n constructor(message: string, originalError?: Error) {\n super(message, 'SERVER_ERROR');\n this.originalError = originalError;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n/**\n * Dependency not found error (internal) - thrown when a required dependency\n * is not found in a registry during initialization.\n */\nexport class DependencyNotFoundError extends InternalMcpError {\n constructor(registryName: string, dependencyName: string) {\n super(`Dependency \"${dependencyName}\" not found in ${registryName}`, 'DEPENDENCY_NOT_FOUND');\n }\n}\n\n/**\n * Invalid hook flow error - thrown when a hook is registered with a flow\n * that is not supported by the entry type (e.g., tool hook on resource class).\n */\nexport class InvalidHookFlowError extends InternalMcpError {\n constructor(message: string) {\n super(message, 'INVALID_HOOK_FLOW');\n }\n}\n\n/**\n * Auth configuration error - thrown when auth configuration is invalid\n * (e.g., transparent mode on parent with multiple child providers).\n */\nexport class AuthConfigurationError extends PublicMcpError {\n readonly errors: string[];\n readonly suggestion?: string;\n\n constructor(message: string, options?: { errors?: string[]; suggestion?: string }) {\n super(message, 'AUTH_CONFIGURATION_ERROR', 500);\n this.errors = options?.errors ?? [message];\n this.suggestion = options?.suggestion;\n }\n\n override getPublicMessage(): string {\n let msg = this.message;\n if (this.suggestion) {\n msg += `\\n\\nTo fix this issue:\\n${this.suggestion}`;\n }\n return msg;\n }\n}\n\n// ============================================================================\n// Prompt Errors\n// ============================================================================\n\n/**\n * Prompt not found error.\n */\nexport class PromptNotFoundError extends PublicMcpError {\n constructor(promptName: string) {\n super(`Prompt not found: ${promptName}`, 'PROMPT_NOT_FOUND', 404);\n }\n}\n\n/**\n * Prompt execution error - wraps errors during prompt execution.\n */\nexport class PromptExecutionError extends InternalMcpError {\n readonly promptName: string;\n readonly originalError?: Error;\n\n constructor(promptName: string, cause?: Error) {\n super(\n cause ? `Prompt execution failed: ${cause.message}` : `Prompt execution failed: ${promptName}`,\n 'PROMPT_EXECUTION_FAILED',\n );\n this.promptName = promptName;\n this.originalError = cause;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n// ============================================================================\n// Error Utilities\n// ============================================================================\n\n/**\n * Check if the error is a public error that can be safely shown to users\n */\nexport function isPublicError(error: any): error is PublicMcpError {\n return error instanceof McpError && error.isPublic;\n}\n\n/**\n * Convert any error to an MCP error\n */\nexport function toMcpError(error: any): McpError {\n if (error instanceof McpError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new GenericServerError(error.message, error);\n }\n\n return new GenericServerError(String(error));\n}\n\n/**\n * Format error for MCP response\n */\nexport function formatMcpErrorResponse(error: any, isDevelopment: boolean = process.env['NODE_ENV'] !== 'production') {\n const mcpError = toMcpError(error);\n return mcpError.toMcpError(isDevelopment);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp.error.js","sourceRoot":"","sources":["../../../src/errors/mcp.error.ts"],"names":[],"mappings":"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","sourcesContent":["// errors/mcp.error.ts\nimport { randomBytes } from 'crypto';\n\n/**\n * MCP-specific error codes per JSON-RPC specification.\n * These codes are used in the JSON-RPC error response format.\n */\nexport const MCP_ERROR_CODES = {\n /** Resource not found (-32002) */\n RESOURCE_NOT_FOUND: -32002,\n /** Invalid request (-32600) */\n INVALID_REQUEST: -32600,\n /** Method not found (-32601) */\n METHOD_NOT_FOUND: -32601,\n /** Invalid params (-32602) */\n INVALID_PARAMS: -32602,\n /** Internal error (-32603) */\n INTERNAL_ERROR: -32603,\n /** Parse error (-32700) */\n PARSE_ERROR: -32700,\n} as const;\n\nexport type McpErrorCode = (typeof MCP_ERROR_CODES)[keyof typeof MCP_ERROR_CODES];\n\n/**\n * Base class for all MCP-related errors\n */\nexport abstract class McpError extends Error {\n /**\n * Unique error ID for tracking in logs\n */\n errorId: string;\n\n /**\n * Whether this error should expose details to the client\n */\n abstract readonly isPublic: boolean;\n\n /**\n * HTTP status code equivalent (for reference)\n */\n abstract readonly statusCode: number;\n\n /**\n * Error code for categorization\n */\n abstract readonly code: string;\n\n protected constructor(message: string, errorId?: string) {\n super(message);\n this.name = this.constructor.name;\n this.errorId = errorId || this.generateErrorId();\n Error.captureStackTrace(this, this.constructor);\n }\n\n private generateErrorId(): string {\n return `err_${randomBytes(8).toString('hex')}`;\n }\n\n /**\n * Get the public-facing error message\n */\n abstract getPublicMessage(): string;\n\n /**\n * Get the internal error message (for logging)\n */\n getInternalMessage(): string {\n return this.message;\n }\n\n /**\n * Convert to MCP error response format\n */\n toMcpError(isDevelopment = false): {\n content: Array<{ type: 'text'; text: string }>;\n isError: true;\n _meta?: {\n errorId: string;\n code: string;\n timestamp: string;\n stack?: string;\n };\n } {\n const message = isDevelopment ? this.getInternalMessage() : this.getPublicMessage();\n\n return {\n content: [\n {\n type: 'text',\n text: message,\n },\n ],\n isError: true,\n _meta: {\n errorId: this.errorId,\n code: this.code,\n timestamp: new Date().toISOString(),\n ...(isDevelopment && { stack: this.stack }),\n },\n };\n }\n}\n\n/**\n * Public errors - safe to expose to clients\n * These include validation errors, not found errors, etc.\n */\nexport class PublicMcpError extends McpError {\n readonly isPublic = true;\n readonly statusCode: number;\n readonly code: string;\n\n constructor(message: string, code = 'PUBLIC_ERROR', statusCode = 400) {\n super(message);\n this.code = code;\n this.statusCode = statusCode;\n }\n\n getPublicMessage(): string {\n return this.message;\n }\n}\n\n/**\n * Internal errors - should not expose details to clients\n * These are server errors, unexpected failures, etc.\n */\nexport class InternalMcpError extends McpError {\n readonly isPublic = false;\n readonly statusCode = 500;\n readonly code: string;\n\n constructor(message: string, code = 'INTERNAL_ERROR') {\n super(message);\n this.code = code;\n }\n\n getPublicMessage(): string {\n return `Internal FrontMCP error. Please contact support with error ID: ${this.errorId}`;\n }\n}\n\n// ============================================================================\n// Specific Error Classes\n// ============================================================================\n\n/**\n * Tool not found error\n */\nexport class ToolNotFoundError extends PublicMcpError {\n constructor(toolName: string) {\n super(`Tool \"${toolName}\" not found`, 'TOOL_NOT_FOUND', 404);\n }\n}\n\n/**\n * Resource not found error\n */\nexport class ResourceNotFoundError extends PublicMcpError {\n readonly uri: string;\n readonly mcpErrorCode = MCP_ERROR_CODES.RESOURCE_NOT_FOUND;\n\n constructor(uri: string) {\n super(`Resource not found: ${uri}`, 'RESOURCE_NOT_FOUND', 404);\n this.uri = uri;\n }\n\n /**\n * Convert to JSON-RPC error format per MCP specification.\n *\n * @example\n * {\n * \"code\": -32002,\n * \"message\": \"Resource not found: file:///missing.txt\",\n * \"data\": { \"uri\": \"file:///missing.txt\" }\n * }\n */\n toJsonRpcError(): {\n code: number;\n message: string;\n data?: { uri: string };\n } {\n return {\n code: this.mcpErrorCode,\n message: this.getPublicMessage(),\n data: { uri: this.uri },\n };\n }\n}\n\n/**\n * Resource read error (internal)\n */\nexport class ResourceReadError extends InternalMcpError {\n readonly originalError?: Error;\n\n constructor(uri: string, originalError?: Error) {\n super(`Resource \"${uri}\" read failed: ${originalError?.message || 'Unknown error'}`, 'RESOURCE_READ_ERROR');\n this.originalError = originalError;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n/**\n * Invalid resource URI error\n */\nexport class InvalidResourceUriError extends PublicMcpError {\n constructor(uri: string, reason?: string) {\n super(`Invalid resource URI: ${uri}${reason ? ` (${reason})` : ''}`, 'INVALID_RESOURCE_URI', 400);\n }\n}\n\n/**\n * Invalid input validation error\n */\nexport class InvalidInputError extends PublicMcpError {\n readonly validationErrors?: any;\n\n constructor(message = 'Invalid input: validation failed', validationErrors?: any) {\n super(message, 'INVALID_INPUT', 400);\n this.validationErrors = validationErrors;\n }\n\n override getInternalMessage(): string {\n return this.message + (this.validationErrors ? `\\nDetails: ${JSON.stringify(this.validationErrors, null, 2)}` : '');\n }\n override getPublicMessage(): string {\n if (this.validationErrors) {\n return `${this.message}\\nDetails: ${JSON.stringify(this.validationErrors, null, 2)}`;\n }\n return this.message;\n }\n}\n\n/**\n * Invalid output validation error (internal - don't expose schema details)\n */\nexport class InvalidOutputError extends InternalMcpError {\n private readonly hasCustomErrorId: boolean;\n\n constructor(errorId?: string) {\n super('Tool output validation failed', 'INVALID_OUTPUT');\n this.hasCustomErrorId = !!errorId;\n if (errorId) {\n this.errorId = errorId;\n }\n }\n\n override getPublicMessage(): string {\n // If a custom errorId was provided (e.g., request ID), include it for correlation\n // Otherwise, use a simpler message since the auto-generated ID isn't meaningful to users\n if (this.hasCustomErrorId) {\n return `Output validation failed. Please contact support with error ID: ${this.errorId}`;\n }\n return 'Output validation failed. Please contact support.';\n }\n}\n\n/**\n * Invalid method error\n */\nexport class InvalidMethodError extends PublicMcpError {\n constructor(method: string, expected: string) {\n super(`Invalid method \"${method}\". Expected \"${expected}\"`, 'INVALID_METHOD', 400);\n }\n}\n\n/**\n * Tool execution error (internal)\n */\nexport class ToolExecutionError extends InternalMcpError {\n readonly originalError?: Error;\n\n constructor(toolName: string, originalError?: Error) {\n super(`Tool \"${toolName}\" execution failed: ${originalError?.message || 'Unknown error'}`, 'TOOL_EXECUTION_ERROR');\n this.originalError = originalError;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n/**\n * Rate limit error\n */\nexport class RateLimitError extends PublicMcpError {\n constructor(retryAfter?: number) {\n const message = retryAfter ? `Rate limit exceeded. Retry after ${retryAfter} seconds` : 'Rate limit exceeded';\n super(message, 'RATE_LIMIT_EXCEEDED', 429);\n }\n}\n\n/**\n * Quota exceeded error\n */\nexport class QuotaExceededError extends PublicMcpError {\n constructor(quotaType = 'usage') {\n super(`${quotaType} quota exceeded`, 'QUOTA_EXCEEDED', 429);\n }\n}\n\n/**\n * Unauthorized error\n */\nexport class UnauthorizedError extends PublicMcpError {\n constructor(message = 'Unauthorized') {\n super(message, 'UNAUTHORIZED', 401);\n }\n}\n\n/**\n * Generic server error wrapper\n */\nexport class GenericServerError extends InternalMcpError {\n readonly originalError?: Error;\n\n constructor(message: string, originalError?: Error) {\n super(message, 'SERVER_ERROR');\n this.originalError = originalError;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n/**\n * Dependency not found error (internal) - thrown when a required dependency\n * is not found in a registry during initialization.\n */\nexport class DependencyNotFoundError extends InternalMcpError {\n constructor(registryName: string, dependencyName: string) {\n super(`Dependency \"${dependencyName}\" not found in ${registryName}`, 'DEPENDENCY_NOT_FOUND');\n }\n}\n\n/**\n * Invalid hook flow error - thrown when a hook is registered with a flow\n * that is not supported by the entry type (e.g., tool hook on resource class).\n */\nexport class InvalidHookFlowError extends InternalMcpError {\n constructor(message: string) {\n super(message, 'INVALID_HOOK_FLOW');\n }\n}\n\n/**\n * Request context not available error - thrown when code attempts to access\n * RequestContext outside of a request scope (i.e., without AsyncLocalStorage context).\n */\nexport class RequestContextNotAvailableError extends InternalMcpError {\n constructor(\n message = 'RequestContext not available. Ensure execution runs within a request scope created by RequestContextStorage.run().',\n ) {\n super(message, 'REQUEST_CONTEXT_NOT_AVAILABLE');\n }\n}\n\n/**\n * Auth configuration error - thrown when auth configuration is invalid\n * (e.g., transparent mode on parent with multiple child providers).\n */\nexport class AuthConfigurationError extends PublicMcpError {\n readonly errors: string[];\n readonly suggestion?: string;\n\n constructor(message: string, options?: { errors?: string[]; suggestion?: string }) {\n super(message, 'AUTH_CONFIGURATION_ERROR', 500);\n this.errors = options?.errors ?? [message];\n this.suggestion = options?.suggestion;\n }\n\n override getPublicMessage(): string {\n let msg = this.message;\n if (this.suggestion) {\n msg += `\\n\\nTo fix this issue:\\n${this.suggestion}`;\n }\n return msg;\n }\n}\n\n// ============================================================================\n// Prompt Errors\n// ============================================================================\n\n/**\n * Prompt not found error.\n */\nexport class PromptNotFoundError extends PublicMcpError {\n constructor(promptName: string) {\n super(`Prompt not found: ${promptName}`, 'PROMPT_NOT_FOUND', 404);\n }\n}\n\n/**\n * Prompt execution error - wraps errors during prompt execution.\n */\nexport class PromptExecutionError extends InternalMcpError {\n readonly promptName: string;\n readonly originalError?: Error;\n\n constructor(promptName: string, cause?: Error) {\n super(\n cause ? `Prompt execution failed: ${cause.message}` : `Prompt execution failed: ${promptName}`,\n 'PROMPT_EXECUTION_FAILED',\n );\n this.promptName = promptName;\n this.originalError = cause;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n// ============================================================================\n// Error Utilities\n// ============================================================================\n\n/**\n * Check if the error is a public error that can be safely shown to users\n */\nexport function isPublicError(error: any): error is PublicMcpError {\n return error instanceof McpError && error.isPublic;\n}\n\n/**\n * Convert any error to an MCP error\n */\nexport function toMcpError(error: any): McpError {\n if (error instanceof McpError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new GenericServerError(error.message, error);\n }\n\n return new GenericServerError(String(error));\n}\n\n/**\n * Format error for MCP response\n */\nexport function formatMcpErrorResponse(error: any, isDevelopment: boolean = process.env['NODE_ENV'] !== 'production') {\n const mcpError = toMcpError(error);\n return mcpError.toMcpError(isDevelopment);\n}\n"]}
|