@1mcp/agent 0.29.0 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/build/auth/sessionTypes.d.ts +16 -0
  2. package/build/auth/sessionTypes.d.ts.map +1 -1
  3. package/build/commands/serve/index.d.ts +5 -0
  4. package/build/commands/serve/index.d.ts.map +1 -1
  5. package/build/commands/serve/index.js +5 -0
  6. package/build/commands/serve/index.js.map +1 -1
  7. package/build/commands/serve/serve.d.ts +1 -0
  8. package/build/commands/serve/serve.d.ts.map +1 -1
  9. package/build/commands/serve/serve.js +1 -0
  10. package/build/commands/serve/serve.js.map +1 -1
  11. package/build/constants/mcp.d.ts +1 -1
  12. package/build/constants/mcp.js +1 -1
  13. package/build/core/server/agentConfig.d.ts +2 -0
  14. package/build/core/server/agentConfig.d.ts.map +1 -1
  15. package/build/core/server/agentConfig.js +4 -0
  16. package/build/core/server/agentConfig.js.map +1 -1
  17. package/build/transport/http/loggingSseTransport.d.ts +13 -0
  18. package/build/transport/http/loggingSseTransport.d.ts.map +1 -0
  19. package/build/transport/http/loggingSseTransport.js +43 -0
  20. package/build/transport/http/loggingSseTransport.js.map +1 -0
  21. package/build/transport/http/middlewares/tagsExtractor.d.ts.map +1 -1
  22. package/build/transport/http/middlewares/tagsExtractor.js +21 -62
  23. package/build/transport/http/middlewares/tagsExtractor.js.map +1 -1
  24. package/build/transport/http/restorableStreamableTransport.d.ts +16 -59
  25. package/build/transport/http/restorableStreamableTransport.d.ts.map +1 -1
  26. package/build/transport/http/restorableStreamableTransport.js +18 -114
  27. package/build/transport/http/restorableStreamableTransport.js.map +1 -1
  28. package/build/transport/http/routes/sseRoutes.d.ts.map +1 -1
  29. package/build/transport/http/routes/sseRoutes.js +2 -1
  30. package/build/transport/http/routes/sseRoutes.js.map +1 -1
  31. package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -1
  32. package/build/transport/http/routes/streamableHttpRoutes.js +169 -60
  33. package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -1
  34. package/build/transport/http/storage/streamableSessionRepository.d.ts +28 -0
  35. package/build/transport/http/storage/streamableSessionRepository.d.ts.map +1 -1
  36. package/build/transport/http/storage/streamableSessionRepository.js +103 -0
  37. package/build/transport/http/storage/streamableSessionRepository.js.map +1 -1
  38. package/build/transport/http/utils/httpErrorHandler.d.ts +36 -0
  39. package/build/transport/http/utils/httpErrorHandler.d.ts.map +1 -0
  40. package/build/transport/http/utils/httpErrorHandler.js +83 -0
  41. package/build/transport/http/utils/httpErrorHandler.js.map +1 -0
  42. package/build/transport/http/utils/sessionService.d.ts +30 -0
  43. package/build/transport/http/utils/sessionService.d.ts.map +1 -1
  44. package/build/transport/http/utils/sessionService.js +130 -20
  45. package/build/transport/http/utils/sessionService.js.map +1 -1
  46. package/build/transport/http/utils/unifiedLogger.d.ts +52 -0
  47. package/build/transport/http/utils/unifiedLogger.d.ts.map +1 -0
  48. package/build/transport/http/utils/unifiedLogger.js +80 -0
  49. package/build/transport/http/utils/unifiedLogger.js.map +1 -0
  50. package/package.json +1 -1
  51. package/build/transport/http/utils/sdkInternals.d.ts +0 -32
  52. package/build/transport/http/utils/sdkInternals.d.ts.map +0 -1
  53. package/build/transport/http/utils/sdkInternals.js +0 -6
  54. package/build/transport/http/utils/sdkInternals.js.map +0 -1
@@ -7,84 +7,41 @@ export interface RestorationInfo {
7
7
  isRestored: boolean;
8
8
  sessionId?: string;
9
9
  }
10
- /**
11
- * Result type for operations that may fail.
12
- * Uses discriminated union to make invalid states unrepresentable.
13
- */
14
- export type OperationResult = {
15
- success: true;
16
- error?: never;
17
- } | {
18
- success: false;
19
- error: string;
20
- };
21
10
  /**
22
11
  * RestorableStreamableHTTPServerTransport extends the MCP SDK's StreamableHTTPServerTransport
23
- * to provide proper session restoration capabilities with type-safe access to internal properties.
12
+ * to track whether a transport was restored from persistent storage.
24
13
  *
25
- * This wrapper class encapsulates the initialization logic needed for restored sessions,
26
- * providing a clean interface that's less likely to break with SDK updates.
14
+ * This is a minimal wrapper that only adds restoration tracking. Session ID management
15
+ * is handled entirely through the SDK's public `sessionIdGenerator` callback - when
16
+ * restoring a session, we pass a generator that returns the stored session ID.
27
17
  *
28
18
  * @remarks
29
- * The class works by:
30
- * 1. Storing a restored sessionId that overrides the SDK's getter
31
- * 2. Providing methods to safely access and modify internal SDK properties
32
- * 3. Returning success/failure status from operations for proper error handling
19
+ * The restoration flow works as follows:
20
+ * 1. Create transport with `sessionIdGenerator: () => storedSessionId`
21
+ * 2. Connect transport to ServerManager
22
+ * 3. Call virtualInitialize() which triggers SDK's handleRequest
23
+ * 4. SDK calls sessionIdGenerator() internally to get the session ID
24
+ * 5. Call markAsRestored() to indicate successful restoration
33
25
  *
34
26
  * @example
35
27
  * ```typescript
36
- * // SessionService handles the full restoration flow:
37
28
  * const transport = new RestorableStreamableHTTPServerTransport({
38
29
  * sessionIdGenerator: () => originalSessionId,
39
30
  * });
40
- * const initResult = transport.markAsInitialized();
41
- * transport.setSessionId(originalSessionId);
31
+ * // After successful virtual initialize...
32
+ * transport.markAsRestored();
42
33
  * // Now transport.isRestored() returns true
43
34
  * ```
44
35
  */
45
36
  export declare class RestorableStreamableHTTPServerTransport extends StreamableHTTPServerTransport {
46
37
  private _isRestored;
47
- private _restoredSessionId?;
48
- /**
49
- * Sets the sessionId for a restored session.
50
- *
51
- * When restoring a session, we need to ensure the sessionId is available immediately
52
- * without waiting for the sessionIdGenerator to be called by the SDK. This method
53
- * directly sets the sessionId on the underlying transport.
54
- *
55
- * @param sessionId - The sessionId to set for the restored session
56
- * @returns OperationResult indicating success or failure with error details
57
- */
58
- setSessionId(sessionId: string): OperationResult;
59
38
  /**
60
- * Override sessionId getter to return restored sessionId if available.
61
- *
62
- * This ensures that even if the underlying transport hasn't generated the sessionId yet,
63
- * we return the correct restored sessionId. If no restored session ID exists, delegates
64
- * to the parent class's getter by manually accessing the property descriptor.
65
- *
66
- * @remarks
67
- * We cannot use `super.sessionId` directly because this override shadows the parent's
68
- * getter. Instead, we use Object.getOwnPropertyDescriptor to access the parent's
69
- * property descriptor and call its getter with the correct context.
70
- *
71
- * Type assertion to `object` is safe here because we know the prototype chain exists:
72
- * this -> RestorableStreamableHTTPServerTransport -> StreamableHTTPServerTransport -> Object.prototype
73
- * Object.getOwnPropertyDescriptor requires an object type, and TypeScript cannot infer this
74
- * from the double getPrototypeOf call.
75
- */
76
- get sessionId(): string | undefined;
77
- /**
78
- * Marks the transport as initialized for restored sessions.
79
- *
80
- * When restoring a session, the client won't send an initialize request again
81
- * because from the client's perspective, the session is already initialized.
82
- * The MCP SDK checks the _initialized flag and rejects requests if it's false.
83
- * This method safely sets that flag to allow the restored session to work.
39
+ * Marks this transport as having been restored from persistent storage.
84
40
  *
85
- * @returns OperationResult indicating success or failure with error details
41
+ * This should be called after successful virtual initialization to indicate
42
+ * that the transport is ready to handle requests for a restored session.
86
43
  */
87
- markAsInitialized(): OperationResult;
44
+ markAsRestored(): void;
88
45
  /**
89
46
  * Returns whether this transport was created for a restored session.
90
47
  *
@@ -1 +1 @@
1
- {"version":3,"file":"restorableStreamableTransport.d.ts","sourceRoot":"","sources":["../../../src/transport/http/restorableStreamableTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAKnG;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,uCAAwC,SAAQ,6BAA6B;IACxF,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAS;IAEpC;;;;;;;;;OASG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe;IAwBhD;;;;;;;;;;;;;;;;OAgBG;IACH,IAAa,SAAS,IAAI,MAAM,GAAG,SAAS,CAiB3C;IAED;;;;;;;;;OASG;IACH,iBAAiB,IAAI,eAAe;IAyBpC;;;;OAIG;IACH,UAAU,IAAI,OAAO;IAIrB;;;;OAIG;IACH,kBAAkB,IAAI,eAAe;CAUtC"}
1
+ {"version":3,"file":"restorableStreamableTransport.d.ts","sourceRoot":"","sources":["../../../src/transport/http/restorableStreamableTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAEnG;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,uCAAwC,SAAQ,6BAA6B;IACxF,OAAO,CAAC,WAAW,CAAS;IAE5B;;;;;OAKG;IACH,cAAc,IAAI,IAAI;IAItB;;;;OAIG;IACH,UAAU,IAAI,OAAO;IAIrB;;;;OAIG;IACH,kBAAkB,IAAI,eAAe;CAMtC"}
@@ -1,133 +1,40 @@
1
1
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
2
- import logger from '../../logger/logger.js';
3
2
  /**
4
3
  * RestorableStreamableHTTPServerTransport extends the MCP SDK's StreamableHTTPServerTransport
5
- * to provide proper session restoration capabilities with type-safe access to internal properties.
4
+ * to track whether a transport was restored from persistent storage.
6
5
  *
7
- * This wrapper class encapsulates the initialization logic needed for restored sessions,
8
- * providing a clean interface that's less likely to break with SDK updates.
6
+ * This is a minimal wrapper that only adds restoration tracking. Session ID management
7
+ * is handled entirely through the SDK's public `sessionIdGenerator` callback - when
8
+ * restoring a session, we pass a generator that returns the stored session ID.
9
9
  *
10
10
  * @remarks
11
- * The class works by:
12
- * 1. Storing a restored sessionId that overrides the SDK's getter
13
- * 2. Providing methods to safely access and modify internal SDK properties
14
- * 3. Returning success/failure status from operations for proper error handling
11
+ * The restoration flow works as follows:
12
+ * 1. Create transport with `sessionIdGenerator: () => storedSessionId`
13
+ * 2. Connect transport to ServerManager
14
+ * 3. Call virtualInitialize() which triggers SDK's handleRequest
15
+ * 4. SDK calls sessionIdGenerator() internally to get the session ID
16
+ * 5. Call markAsRestored() to indicate successful restoration
15
17
  *
16
18
  * @example
17
19
  * ```typescript
18
- * // SessionService handles the full restoration flow:
19
20
  * const transport = new RestorableStreamableHTTPServerTransport({
20
21
  * sessionIdGenerator: () => originalSessionId,
21
22
  * });
22
- * const initResult = transport.markAsInitialized();
23
- * transport.setSessionId(originalSessionId);
23
+ * // After successful virtual initialize...
24
+ * transport.markAsRestored();
24
25
  * // Now transport.isRestored() returns true
25
26
  * ```
26
27
  */
27
28
  export class RestorableStreamableHTTPServerTransport extends StreamableHTTPServerTransport {
28
29
  _isRestored = false;
29
- _restoredSessionId;
30
30
  /**
31
- * Sets the sessionId for a restored session.
31
+ * Marks this transport as having been restored from persistent storage.
32
32
  *
33
- * When restoring a session, we need to ensure the sessionId is available immediately
34
- * without waiting for the sessionIdGenerator to be called by the SDK. This method
35
- * directly sets the sessionId on the underlying transport.
36
- *
37
- * @param sessionId - The sessionId to set for the restored session
38
- * @returns OperationResult indicating success or failure with error details
39
- */
40
- setSessionId(sessionId) {
41
- this._restoredSessionId = sessionId;
42
- try {
43
- // Access the underlying _webStandardTransport where sessionId is stored
44
- // StreamableHTTPServerTransport is a wrapper with getter-only sessionId
45
- // The actual sessionId is on _webStandardTransport which allows setting
46
- const internalTransport = this;
47
- const webStandardTransport = internalTransport._webStandardTransport;
48
- if (webStandardTransport) {
49
- webStandardTransport.sessionId = sessionId;
50
- return { success: true };
51
- }
52
- return {
53
- success: false,
54
- error: 'No webStandardTransport found - SDK internal structure may have changed or transport is not properly initialized',
55
- };
56
- }
57
- catch (error) {
58
- const errorMessage = error instanceof Error ? error.message : String(error);
59
- logger.warn(`Failed to set sessionId "${sessionId}" on underlying transport: ${errorMessage}`);
60
- return { success: false, error: errorMessage };
61
- }
62
- }
63
- /**
64
- * Override sessionId getter to return restored sessionId if available.
65
- *
66
- * This ensures that even if the underlying transport hasn't generated the sessionId yet,
67
- * we return the correct restored sessionId. If no restored session ID exists, delegates
68
- * to the parent class's getter by manually accessing the property descriptor.
69
- *
70
- * @remarks
71
- * We cannot use `super.sessionId` directly because this override shadows the parent's
72
- * getter. Instead, we use Object.getOwnPropertyDescriptor to access the parent's
73
- * property descriptor and call its getter with the correct context.
74
- *
75
- * Type assertion to `object` is safe here because we know the prototype chain exists:
76
- * this -> RestorableStreamableHTTPServerTransport -> StreamableHTTPServerTransport -> Object.prototype
77
- * Object.getOwnPropertyDescriptor requires an object type, and TypeScript cannot infer this
78
- * from the double getPrototypeOf call.
79
- */
80
- get sessionId() {
81
- // First check if we have a restored sessionId
82
- if (this._restoredSessionId) {
83
- return this._restoredSessionId;
84
- }
85
- // Otherwise delegate to parent class's getter directly
86
- // Use Object.getOwnPropertyDescriptor to get the parent's property descriptor
87
- // and call the getter with the parent's context
88
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
89
- const proto = Object.getPrototypeOf(Object.getPrototypeOf(this));
90
- if (!proto)
91
- return undefined;
92
- const descriptor = Object.getOwnPropertyDescriptor(proto, 'sessionId');
93
- if (descriptor?.get) {
94
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
95
- return descriptor.get.call(this);
96
- }
97
- return undefined;
98
- }
99
- /**
100
- * Marks the transport as initialized for restored sessions.
101
- *
102
- * When restoring a session, the client won't send an initialize request again
103
- * because from the client's perspective, the session is already initialized.
104
- * The MCP SDK checks the _initialized flag and rejects requests if it's false.
105
- * This method safely sets that flag to allow the restored session to work.
106
- *
107
- * @returns OperationResult indicating success or failure with error details
33
+ * This should be called after successful virtual initialization to indicate
34
+ * that the transport is ready to handle requests for a restored session.
108
35
  */
109
- markAsInitialized() {
110
- try {
111
- // Use type-safe interface to access internal SDK properties
112
- // MCP SDK private property _initialized is not exposed in public types
113
- const internalTransport = this;
114
- // Accessing private SDK property for session restoration functionality
115
- if (internalTransport._initialized !== undefined) {
116
- // Setting private SDK property to mark session as initialized for restoration
117
- internalTransport._initialized = true;
118
- }
119
- // Note: If _initialized is undefined, we still mark as restored since the SDK may have changed
120
- // This provides graceful degradation while allowing session restoration to proceed
121
- this._isRestored = true;
122
- logger.debug('Transport marked as initialized for restored session');
123
- return { success: true };
124
- }
125
- catch (error) {
126
- const errorMessage = error instanceof Error ? error.message : String(error);
127
- logger.warn(`Failed to mark transport as initialized: ${errorMessage}`);
128
- this._isRestored = false;
129
- return { success: false, error: errorMessage };
130
- }
36
+ markAsRestored() {
37
+ this._isRestored = true;
131
38
  }
132
39
  /**
133
40
  * Returns whether this transport was created for a restored session.
@@ -143,12 +50,9 @@ export class RestorableStreamableHTTPServerTransport extends StreamableHTTPServe
143
50
  * @returns Object containing restoration metadata
144
51
  */
145
52
  getRestorationInfo() {
146
- // Use type-safe interface to access potentially private sessionId
147
- const internalTransport = this;
148
53
  return {
149
54
  isRestored: this._isRestored,
150
- // Accessing potentially private sessionId property for debugging
151
- sessionId: internalTransport.sessionId,
55
+ sessionId: this.sessionId,
152
56
  };
153
57
  }
154
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"restorableStreamableTransport.js","sourceRoot":"","sources":["../../../src/transport/http/restorableStreamableTransport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"restorableStreamableTransport.js","sourceRoot":"","sources":["../../../src/transport/http/restorableStreamableTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAWnG;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,OAAO,uCAAwC,SAAQ,6BAA6B;IAChF,WAAW,GAAG,KAAK,CAAC;IAE5B;;;;;OAKG;IACH,cAAc;QACZ,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,kBAAkB;QAChB,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC;IACJ,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"sseRoutes.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/routes/sseRoutes.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oDAAoD,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAYlE,OAAO,EAAW,cAAc,EAAY,MAAM,EAAE,MAAM,SAAS,CAAC;AAEpE,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,aAAa,EAC5B,cAAc,EAAE,cAAc,EAC9B,sBAAsB,CAAC,EAAE,cAAc,EACvC,iBAAiB,CAAC,EAAE,wBAAwB,EAC5C,cAAc,CAAC,EAAE,MAAM,GACtB,IAAI,CA6GN"}
1
+ {"version":3,"file":"sseRoutes.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/routes/sseRoutes.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oDAAoD,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAalE,OAAO,EAAW,cAAc,EAAY,MAAM,EAAE,MAAM,SAAS,CAAC;AAEpE,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,aAAa,EAC5B,cAAc,EAAE,cAAc,EAC9B,sBAAsB,CAAC,EAAE,cAAc,EACvC,iBAAiB,CAAC,EAAE,wBAAwB,EAC5C,cAAc,CAAC,EAAE,MAAM,GACtB,IAAI,CA6GN"}
@@ -3,6 +3,7 @@ import { ErrorCode } from '@modelcontextprotocol/sdk/types.js';
3
3
  import { MESSAGES_ENDPOINT, SSE_ENDPOINT } from '../../../constants.js';
4
4
  import { ServerStatus } from '../../../core/types/index.js';
5
5
  import logger from '../../../logger/logger.js';
6
+ import { LoggingSSEServerTransport } from '../../../transport/http/loggingSseTransport.js';
6
7
  import { getPresetName, getTagExpression, getTagFilterMode, getTagQuery, getValidatedTags, } from '../../../transport/http/middlewares/scopeAuthMiddleware.js';
7
8
  import tagsExtractor from '../../../transport/http/middlewares/tagsExtractor.js';
8
9
  export function setupSseRoutes(router, serverManager, authMiddleware, availabilityMiddleware, asyncOrchestrator, customTemplate) {
@@ -13,7 +14,7 @@ export function setupSseRoutes(router, serverManager, authMiddleware, availabili
13
14
  }
14
15
  router.get(SSE_ENDPOINT, ...middlewares, async (req, res) => {
15
16
  try {
16
- const transport = new SSEServerTransport(MESSAGES_ENDPOINT, res);
17
+ const transport = new LoggingSSEServerTransport(MESSAGES_ENDPOINT, res);
17
18
  // Use validated tags and tag expression from scope auth middleware
18
19
  const tags = getValidatedTags(res);
19
20
  const tagExpression = getTagExpression(res);
@@ -1 +1 @@
1
- {"version":3,"file":"sseRoutes.js","sourceRoot":"","sources":["../../../../src/transport/http/routes/sseRoutes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sseRoutes.js","sourceRoot":"","sources":["../../../../src/transport/http/routes/sseRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,MAAM,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,gBAAgB,GACjB,MAAM,wDAAwD,CAAC;AAChE,OAAO,aAAa,MAAM,kDAAkD,CAAC;AAI7E,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,aAA4B,EAC5B,cAA8B,EAC9B,sBAAuC,EACvC,iBAA4C,EAC5C,cAAuB;IAEvB,MAAM,WAAW,GAAG,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAEpD,0CAA0C;IAC1C,IAAI,sBAAsB,EAAE,CAAC;QAC3B,WAAW,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC7E,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,yBAAyB,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;YAExE,mEAAmE;YACnE,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAC5C,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAC5C,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;YAEtC,iDAAiD;YACjD,MAAM,aAAa,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE;gBACnE,IAAI;gBACJ,aAAa;gBACb,aAAa;gBACb,QAAQ;gBACR,UAAU;gBACV,gBAAgB,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,MAAM;gBACjD,cAAc;aACf,CAAC,CAAC;YAEH,wDAAwD;YACxD,IAAI,iBAAiB,EAAE,CAAC;gBACtB,MAAM,iBAAiB,GAAG,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBACvE,IAAI,iBAAiB,EAAE,CAAC;oBACtB,iBAAiB,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;oBAC7D,MAAM,CAAC,KAAK,CAAC,2DAA2D,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;gBACjG,CAAC;YACH,CAAC;YAED,kDAAkD;YAClD,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;gBACzC,IAAI,CAAC;oBACH,4DAA4D;oBAC5D,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBAC/B,CAAC;gBAAC,OAAO,MAAM,EAAE,CAAC;oBAChB,kDAAkD;oBAClD,MAAM,CAAC,KAAK,CAAC,oCAAoC,SAAS,CAAC,SAAS,sBAAsB,CAAC,CAAC;oBAC5F,aAAa,CAAC,iBAAiB,CAAC,CAAC;oBACjC,aAAa,CAAC,mBAAmB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,kCAAkC;YAE7C,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;gBACvB,aAAa,CAAC,iBAAiB,CAAC,CAAC;gBACjC,aAAa,CAAC,mBAAmB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBACvD,qDAAqD;YACvD,CAAC,CAAC;YAEF,SAAS,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;gBAC5B,aAAa,CAAC,iBAAiB,CAAC,CAAC;gBACjC,MAAM,CAAC,KAAK,CAAC,mCAAmC,SAAS,CAAC,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC/E,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBAC5D,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC;oBACnC,MAAM,CAAC,SAAS,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC/E,CAAC;YACH,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;YAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACnF,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,SAAmB,CAAC;YAChD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE;wBACL,IAAI,EAAE,SAAS,CAAC,aAAa;wBAC7B,OAAO,EAAE,uCAAuC;qBACjD;iBACF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,MAAM,SAAS,GAAG,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAExD,IAAI,SAAS,YAAY,kBAAkB,EAAE,CAAC;gBAC5C,MAAM,SAAS,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;gBACtD,OAAO;YACT,CAAC;YAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE;oBACL,IAAI,EAAE,SAAS,CAAC,aAAa;oBAC7B,OAAO,EAAE,qBAAqB;iBAC/B;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAC/C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE;oBACL,IAAI,EAAE,SAAS,CAAC,aAAa;oBAC7B,OAAO,EAAE,uBAAuB;iBACjC;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"streamableHttpRoutes.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/routes/streamableHttpRoutes.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oDAAoD,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAWlE,OAAO,EAAE,2BAA2B,EAAE,MAAM,4DAA4D,CAAC;AAEzG,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAE7E,OAAO,EAAW,cAAc,EAAY,MAAM,EAAE,MAAM,SAAS,CAAC;AAsDpE,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,aAAa,EAC5B,iBAAiB,EAAE,2BAA2B,EAC9C,cAAc,EAAE,cAAc,EAC9B,sBAAsB,CAAC,EAAE,cAAc,EACvC,iBAAiB,CAAC,EAAE,wBAAwB,EAC5C,cAAc,CAAC,EAAE,MAAM,EACvB,sBAAsB,CAAC,EAAE,cAAc,GACtC,IAAI,CAqJN"}
1
+ {"version":3,"file":"streamableHttpRoutes.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/routes/streamableHttpRoutes.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oDAAoD,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAWlE,OAAO,EAAE,2BAA2B,EAAE,MAAM,4DAA4D,CAAC;AAGzG,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAG7E,OAAO,EAAW,cAAc,EAAY,MAAM,EAAE,MAAM,SAAS,CAAC;AA2JpE,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,aAAa,EAC5B,iBAAiB,EAAE,2BAA2B,EAC9C,cAAc,EAAE,cAAc,EAC9B,sBAAsB,CAAC,EAAE,cAAc,EACvC,iBAAiB,CAAC,EAAE,wBAAwB,EAC5C,cAAc,CAAC,EAAE,MAAM,EACvB,sBAAsB,CAAC,EAAE,cAAc,GACtC,IAAI,CAyKN"}
@@ -1,11 +1,100 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { ErrorCode } from '@modelcontextprotocol/sdk/types.js';
3
- import { AUTH_CONFIG, STREAMABLE_HTTP_ENDPOINT } from '../../../constants.js';
2
+ import { AUTH_CONFIG, MCP_SERVER_NAME, MCP_SERVER_VERSION, STREAMABLE_HTTP_ENDPOINT } from '../../../constants.js';
4
3
  import logger from '../../../logger/logger.js';
5
4
  import { getPresetName, getTagExpression, getTagFilterMode, getTagQuery, getValidatedTags, } from '../../../transport/http/middlewares/scopeAuthMiddleware.js';
6
5
  import tagsExtractor from '../../../transport/http/middlewares/tagsExtractor.js';
6
+ import { RestorableStreamableHTTPServerTransport } from '../../../transport/http/restorableStreamableTransport.js';
7
7
  import { extractContextFromMeta } from '../../../transport/http/utils/contextExtractor.js';
8
+ import { sendBadRequest, sendInternalError, sendNotFound } from '../../../transport/http/utils/httpErrorHandler.js';
8
9
  import { SessionService } from '../../../transport/http/utils/sessionService.js';
10
+ import { logError, logWarn } from '../../../transport/http/utils/unifiedLogger.js';
11
+ /**
12
+ * Type guard to check if a request body is an initialize request.
13
+ */
14
+ function isInitializeRequest(body) {
15
+ return (typeof body === 'object' &&
16
+ body !== null &&
17
+ 'method' in body &&
18
+ body.method === 'initialize' &&
19
+ 'jsonrpc' in body &&
20
+ body.jsonrpc === '2.0');
21
+ }
22
+ /**
23
+ * Extract protocol version from initialize request body.
24
+ * Similar to contextExtractor pattern - extract directly from req.body.params
25
+ */
26
+ function extractProtocolVersion(body) {
27
+ try {
28
+ const reqBody = body;
29
+ if (reqBody?.params?.protocolVersion && typeof reqBody.params.protocolVersion === 'string') {
30
+ return reqBody.params.protocolVersion;
31
+ }
32
+ return null;
33
+ }
34
+ catch (error) {
35
+ logWarn('Failed to extract protocol version from request body', {
36
+ reason: 'Request body structure incompatible',
37
+ context: { error },
38
+ });
39
+ return null;
40
+ }
41
+ }
42
+ /**
43
+ * Wraps an Express response to log when status >= 400 is set.
44
+ * This catches SDK responses that don't throw errors.
45
+ */
46
+ function wrapResponseForLogging(req, res, sessionId) {
47
+ const originalStatus = res.status.bind(res);
48
+ const originalJson = res.json.bind(res);
49
+ let logged = false;
50
+ const logIfNeeded = (responseBody) => {
51
+ if (logged || res.statusCode < 400)
52
+ return;
53
+ logged = true;
54
+ const level = res.statusCode >= 500 ? 'error' : 'warn';
55
+ const logFn = level === 'error' ? logError : logWarn;
56
+ logFn(`HTTP error ${res.statusCode}`, {
57
+ method: req.method,
58
+ path: req.path,
59
+ sessionId,
60
+ statusCode: res.statusCode,
61
+ reason: 'SDK request validation failed',
62
+ });
63
+ // Log request/response details at debug level for troubleshooting
64
+ logger.debug('SDK error details', {
65
+ sessionId,
66
+ requestBody: req.body,
67
+ responseBody,
68
+ });
69
+ };
70
+ // Intercept res.status() to detect when error codes are set
71
+ res.status = function (code) {
72
+ const result = originalStatus(code);
73
+ if (code >= 400) {
74
+ logIfNeeded();
75
+ }
76
+ return result;
77
+ };
78
+ // Intercept res.json() to capture response body for error logging
79
+ res.json = function (body) {
80
+ if (res.statusCode >= 400) {
81
+ logIfNeeded(body);
82
+ }
83
+ return originalJson(body);
84
+ };
85
+ // Intercept res.writeHead() - SDK uses this via Hono adapter
86
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument */
87
+ const origWriteHead = res.writeHead.bind(res);
88
+ res.writeHead = function (statusCode, ...rest) {
89
+ if (statusCode >= 400) {
90
+ res.statusCode = statusCode;
91
+ logIfNeeded();
92
+ }
93
+ return origWriteHead(statusCode, ...rest);
94
+ };
95
+ /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument */
96
+ return res;
97
+ }
9
98
  /**
10
99
  * Builds the inbound connection config from request data.
11
100
  *
@@ -63,10 +152,12 @@ export function setupStreamableHttpRoutes(router, serverManager, sessionReposito
63
152
  router.post(STREAMABLE_HTTP_ENDPOINT, ...middlewares, async (req, res) => {
64
153
  try {
65
154
  let transport;
155
+ let actualSessionId;
66
156
  const sessionId = req.headers['mcp-session-id'];
67
157
  if (!sessionId) {
68
158
  // Generate new session ID
69
159
  const id = AUTH_CONFIG.SERVER.STREAMABLE_SESSION.ID_PREFIX + randomUUID();
160
+ actualSessionId = id;
70
161
  const config = buildConfigFromRequest(res, req, customTemplate);
71
162
  // Extract context from _meta field (from STDIO proxy)
72
163
  const context = extractContextFromMeta(req);
@@ -78,31 +169,69 @@ export function setupStreamableHttpRoutes(router, serverManager, sessionReposito
78
169
  }
79
170
  }
80
171
  else {
172
+ actualSessionId = sessionId;
81
173
  transport = await sessionService.getSession(sessionId);
82
174
  if (!transport) {
83
- // Session restoration failed - create new session with provided ID (handles proxy use case)
84
- logger.error(`Session restoration failed for ${sessionId}, creating new session as fallback`);
85
- const config = buildConfigFromRequest(res, req, customTemplate);
86
- // Extract context from _meta field (from STDIO proxy)
87
- const context = extractContextFromMeta(req);
88
- const createResult = await sessionService.createSession(config, context || undefined, sessionId);
89
- transport = createResult.transport;
90
- // Log warning if session was not persisted
91
- if (!createResult.persisted) {
92
- logger.warn(`Fallback session ${sessionId} was created but not persisted: ${createResult.persistenceError}`);
175
+ // Session doesn't exist - only allow creation via initialize request
176
+ if (isInitializeRequest(req.body)) {
177
+ // Allow creating new session with specific ID via initialize
178
+ logger.info(`Creating new session ${sessionId} via initialize request`);
179
+ const config = buildConfigFromRequest(res, req, customTemplate);
180
+ // Extract context from _meta field (from STDIO proxy)
181
+ const context = extractContextFromMeta(req);
182
+ const createResult = await sessionService.createSession(config, context || undefined, sessionId);
183
+ transport = createResult.transport;
184
+ // Log warning if session was not persisted
185
+ if (!createResult.persisted) {
186
+ logger.warn(`New session ${sessionId} was created but not persisted: ${createResult.persistenceError}`);
187
+ }
93
188
  }
189
+ else {
190
+ // Non-initialize request for non-existent session → 404
191
+ sendNotFound(res, 'Session not found. Send an initialize request first to create a new session.', {
192
+ sessionId,
193
+ });
194
+ return;
195
+ }
196
+ }
197
+ }
198
+ // Wrap response to catch SDK errors
199
+ const wrappedRes = wrapResponseForLogging(req, res, actualSessionId);
200
+ // Check if this is an initialize request
201
+ const isInitialize = isInitializeRequest(req.body);
202
+ const protocolVersion = isInitialize ? extractProtocolVersion(req.body) : null;
203
+ // Log request details for debugging restored sessions
204
+ if (transport instanceof RestorableStreamableHTTPServerTransport && transport.isRestored()) {
205
+ logger.debug('Handling request for restored session', {
206
+ sessionId: actualSessionId,
207
+ isInitialize,
208
+ method: req.body?.method,
209
+ });
210
+ }
211
+ await transport.handleRequest(req, wrappedRes, req.body);
212
+ // After handleRequest completes for initialize, store the response data
213
+ if (isInitialize && protocolVersion) {
214
+ try {
215
+ // Store minimal initialize response data for session restoration
216
+ // The exact capabilities don't matter for restoration - we just need protocol version and server info
217
+ sessionService.storeInitializeResponse(actualSessionId, {
218
+ protocolVersion,
219
+ capabilities: {}, // Minimal capabilities - actual capabilities are aggregated dynamically
220
+ serverInfo: { name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION },
221
+ });
222
+ logger.debug(`Stored initialize response for session ${actualSessionId}`);
223
+ }
224
+ catch (err) {
225
+ logger.warn(`Failed to store initialize response for ${actualSessionId}:`, err);
94
226
  }
95
227
  }
96
- await transport.handleRequest(req, res, req.body);
97
228
  }
98
229
  catch (error) {
99
- const errorMessage = error instanceof Error ? error.message : String(error);
100
- logger.error('Streamable HTTP POST error:', { error: errorMessage, sessionId: req.headers['mcp-session-id'] });
101
- res.status(500).json({
102
- error: {
103
- code: ErrorCode.InternalError,
104
- message: 'An internal server error occurred while processing the request',
105
- },
230
+ sendInternalError(res, error, {
231
+ method: req.method,
232
+ path: req.path,
233
+ sessionId: req.headers['mcp-session-id'],
234
+ phase: 'handleRequest',
106
235
  });
107
236
  }
108
237
  });
@@ -110,36 +239,26 @@ export function setupStreamableHttpRoutes(router, serverManager, sessionReposito
110
239
  try {
111
240
  const sessionId = req.headers['mcp-session-id'];
112
241
  if (!sessionId) {
113
- res.status(400).json({
114
- error: {
115
- code: ErrorCode.InvalidParams,
116
- message: 'Invalid params: sessionId is required',
117
- },
118
- });
242
+ sendBadRequest(res, 'Invalid params: sessionId is required');
119
243
  return;
120
244
  }
121
245
  const transport = await sessionService.getSession(sessionId);
122
246
  if (!transport) {
123
- res.status(404).json({
124
- error: {
125
- code: ErrorCode.InvalidParams,
126
- message: 'No active streamable HTTP session found for the provided sessionId',
127
- },
128
- });
247
+ sendNotFound(res, 'No active streamable HTTP session found for the provided sessionId', { sessionId });
129
248
  return;
130
249
  }
131
250
  // Set up disconnect detection for SSE stream (GET endpoint maintains persistent connection)
132
251
  setupDisconnectDetection(req, res, sessionId, serverManager);
133
- await transport.handleRequest(req, res, req.body);
252
+ // Wrap response to catch SDK errors
253
+ const wrappedRes = wrapResponseForLogging(req, res, sessionId);
254
+ await transport.handleRequest(req, wrappedRes, req.body);
134
255
  }
135
256
  catch (error) {
136
- const errorMessage = error instanceof Error ? error.message : String(error);
137
- logger.error('Streamable HTTP GET error:', { error: errorMessage, sessionId: req.headers['mcp-session-id'] });
138
- res.status(500).json({
139
- error: {
140
- code: ErrorCode.InternalError,
141
- message: 'An internal server error occurred while processing the request',
142
- },
257
+ sendInternalError(res, error, {
258
+ method: req.method,
259
+ path: req.path,
260
+ sessionId: req.headers['mcp-session-id'],
261
+ phase: 'handleRequest',
143
262
  });
144
263
  }
145
264
  });
@@ -147,36 +266,26 @@ export function setupStreamableHttpRoutes(router, serverManager, sessionReposito
147
266
  try {
148
267
  const sessionId = req.headers['mcp-session-id'];
149
268
  if (!sessionId) {
150
- res.status(400).json({
151
- error: {
152
- code: ErrorCode.InvalidParams,
153
- message: 'Invalid params: sessionId is required',
154
- },
155
- });
269
+ sendBadRequest(res, 'Invalid params: sessionId is required');
156
270
  return;
157
271
  }
158
272
  const transport = await sessionService.getSession(sessionId);
159
273
  if (!transport) {
160
- res.status(404).json({
161
- error: {
162
- code: ErrorCode.InvalidParams,
163
- message: 'No active streamable HTTP session found for the provided sessionId',
164
- },
165
- });
274
+ sendNotFound(res, 'No active streamable HTTP session found for the provided sessionId', { sessionId });
166
275
  return;
167
276
  }
168
- await transport.handleRequest(req, res);
277
+ // Wrap response to catch SDK errors
278
+ const wrappedRes = wrapResponseForLogging(req, res, sessionId);
279
+ await transport.handleRequest(req, wrappedRes);
169
280
  // Delete session from storage after explicit delete request
170
281
  await sessionService.deleteSession(sessionId);
171
282
  }
172
283
  catch (error) {
173
- const errorMessage = error instanceof Error ? error.message : String(error);
174
- logger.error('Streamable HTTP DELETE error:', { error: errorMessage, sessionId: req.headers['mcp-session-id'] });
175
- res.status(500).json({
176
- error: {
177
- code: ErrorCode.InternalError,
178
- message: 'An internal server error occurred while processing the request',
179
- },
284
+ sendInternalError(res, error, {
285
+ method: req.method,
286
+ path: req.path,
287
+ sessionId: req.headers['mcp-session-id'],
288
+ phase: 'handleRequest',
180
289
  });
181
290
  }
182
291
  });