@frontmcp/sdk 1.0.0-beta.7 → 1.0.0-beta.9

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 (107) hide show
  1. package/agent/agent.instance.d.ts +2 -2
  2. package/agent/agent.instance.d.ts.map +1 -1
  3. package/agent/agent.scope.d.ts +5 -4
  4. package/agent/agent.scope.d.ts.map +1 -1
  5. package/agent/flows/call-agent.flow.d.ts.map +1 -1
  6. package/app/instances/app.esm.instance.d.ts +7 -4
  7. package/app/instances/app.esm.instance.d.ts.map +1 -1
  8. package/app/instances/app.local.instance.d.ts +3 -3
  9. package/app/instances/app.local.instance.d.ts.map +1 -1
  10. package/app/instances/app.remote.instance.d.ts +7 -4
  11. package/app/instances/app.remote.instance.d.ts.map +1 -1
  12. package/auth/auth.registry.d.ts +2 -2
  13. package/auth/auth.registry.d.ts.map +1 -1
  14. package/auth/instances/instance.remote-primary-auth.d.ts.map +1 -1
  15. package/common/entries/app.entry.d.ts +8 -5
  16. package/common/entries/app.entry.d.ts.map +1 -1
  17. package/common/entries/plugin.entry.d.ts +1 -2
  18. package/common/entries/plugin.entry.d.ts.map +1 -1
  19. package/common/entries/provider.entry.d.ts +1 -2
  20. package/common/entries/provider.entry.d.ts.map +1 -1
  21. package/common/entries/scope.entry.d.ts +25 -8
  22. package/common/entries/scope.entry.d.ts.map +1 -1
  23. package/common/interfaces/app.interface.d.ts +1 -4
  24. package/common/interfaces/app.interface.d.ts.map +1 -1
  25. package/common/interfaces/internal/registry.interface.d.ts +15 -83
  26. package/common/interfaces/internal/registry.interface.d.ts.map +1 -1
  27. package/common/interfaces/plugin.interface.d.ts +1 -3
  28. package/common/interfaces/plugin.interface.d.ts.map +1 -1
  29. package/common/interfaces/provider.interface.d.ts +1 -3
  30. package/common/interfaces/provider.interface.d.ts.map +1 -1
  31. package/common/interfaces/scope.interface.d.ts +2 -4
  32. package/common/interfaces/scope.interface.d.ts.map +1 -1
  33. package/elicitation/flows/elicitation-request.flow.d.ts.map +1 -1
  34. package/elicitation/flows/elicitation-result.flow.d.ts.map +1 -1
  35. package/elicitation/helpers/fallback.helper.d.ts.map +1 -1
  36. package/elicitation/send-elicitation-result.tool.d.ts.map +1 -1
  37. package/errors/index.d.ts +1 -1
  38. package/errors/index.d.ts.map +1 -1
  39. package/errors/transport.errors.d.ts +6 -0
  40. package/errors/transport.errors.d.ts.map +1 -1
  41. package/esm/index.mjs +391 -156
  42. package/flows/flow.instance.d.ts +2 -3
  43. package/flows/flow.instance.d.ts.map +1 -1
  44. package/front-mcp/front-mcp.d.ts +2 -2
  45. package/front-mcp/front-mcp.d.ts.map +1 -1
  46. package/hooks/hook.registry.d.ts +2 -2
  47. package/hooks/hook.registry.d.ts.map +1 -1
  48. package/index.js +392 -156
  49. package/job/job.instance.d.ts +2 -2
  50. package/job/job.instance.d.ts.map +1 -1
  51. package/notification/notification.service.d.ts +5 -1
  52. package/notification/notification.service.d.ts.map +1 -1
  53. package/package.json +8 -8
  54. package/plugin/plugin.registry.d.ts +3 -4
  55. package/plugin/plugin.registry.d.ts.map +1 -1
  56. package/prompt/prompt.instance.d.ts +2 -2
  57. package/prompt/prompt.instance.d.ts.map +1 -1
  58. package/prompt/prompt.registry.d.ts +2 -2
  59. package/prompt/prompt.registry.d.ts.map +1 -1
  60. package/provider/provider.registry.d.ts +6 -8
  61. package/provider/provider.registry.d.ts.map +1 -1
  62. package/resource/flows/read-resource.flow.d.ts.map +1 -1
  63. package/resource/resource.instance.d.ts +2 -2
  64. package/resource/resource.instance.d.ts.map +1 -1
  65. package/resource/resource.registry.d.ts +2 -2
  66. package/resource/resource.registry.d.ts.map +1 -1
  67. package/scope/flows/http.request.flow.d.ts.map +1 -1
  68. package/scope/scope.instance.d.ts +4 -3
  69. package/scope/scope.instance.d.ts.map +1 -1
  70. package/skill/flows/http/skills-api.flow.d.ts.map +1 -1
  71. package/skill/flows/load-skill.flow.d.ts.map +1 -1
  72. package/skill/skill-http.utils.d.ts +4 -3
  73. package/skill/skill-http.utils.d.ts.map +1 -1
  74. package/skill/skill-md-parser.d.ts.map +1 -1
  75. package/skill/skill-storage.factory.d.ts +3 -3
  76. package/skill/skill-storage.factory.d.ts.map +1 -1
  77. package/skill/skill-validator.d.ts +2 -2
  78. package/skill/skill-validator.d.ts.map +1 -1
  79. package/skill/skill.instance.d.ts +2 -2
  80. package/skill/skill.instance.d.ts.map +1 -1
  81. package/skill/skill.registry.d.ts +2 -3
  82. package/skill/skill.registry.d.ts.map +1 -1
  83. package/tool/flows/call-tool.flow.d.ts.map +1 -1
  84. package/tool/flows/tools-list.flow.d.ts.map +1 -1
  85. package/tool/tool.instance.d.ts +2 -2
  86. package/tool/tool.instance.d.ts.map +1 -1
  87. package/tool/tool.registry.d.ts +2 -2
  88. package/tool/tool.registry.d.ts.map +1 -1
  89. package/transport/adapters/streamable-http-transport.d.ts +11 -0
  90. package/transport/adapters/streamable-http-transport.d.ts.map +1 -1
  91. package/transport/adapters/transport.local.adapter.d.ts +16 -1
  92. package/transport/adapters/transport.local.adapter.d.ts.map +1 -1
  93. package/transport/adapters/transport.sse.adapter.d.ts.map +1 -1
  94. package/transport/adapters/transport.streamable-http.adapter.d.ts +7 -0
  95. package/transport/adapters/transport.streamable-http.adapter.d.ts.map +1 -1
  96. package/transport/flows/handle.sse.flow.d.ts.map +1 -1
  97. package/transport/flows/handle.stateless-http.flow.d.ts.map +1 -1
  98. package/transport/flows/handle.streamable-http.flow.d.ts +50 -1
  99. package/transport/flows/handle.streamable-http.flow.d.ts.map +1 -1
  100. package/transport/transport.local.d.ts +2 -0
  101. package/transport/transport.local.d.ts.map +1 -1
  102. package/transport/transport.remote.d.ts +2 -0
  103. package/transport/transport.remote.d.ts.map +1 -1
  104. package/transport/transport.types.d.ts +10 -0
  105. package/transport/transport.types.d.ts.map +1 -1
  106. package/workflow/workflow.instance.d.ts +2 -2
  107. package/workflow/workflow.instance.d.ts.map +1 -1
package/esm/index.mjs CHANGED
@@ -4098,7 +4098,7 @@ var init_provider_errors = __esm({
4098
4098
  });
4099
4099
 
4100
4100
  // libs/sdk/src/errors/transport.errors.ts
4101
- var MethodNotImplementedError, UnsupportedTransportTypeError, TransportBusRequiredError, InvalidTransportSessionError, TransportNotConnectedError, TransportAlreadyStartedError, UnsupportedContentTypeError;
4101
+ var MethodNotImplementedError, UnsupportedTransportTypeError, TransportBusRequiredError, InvalidTransportSessionError, TransportNotConnectedError, TransportAlreadyStartedError, UnsupportedContentTypeError, TransportServiceNotAvailableError;
4102
4102
  var init_transport_errors = __esm({
4103
4103
  "libs/sdk/src/errors/transport.errors.ts"() {
4104
4104
  "use strict";
@@ -4141,6 +4141,11 @@ var init_transport_errors = __esm({
4141
4141
  this.contentType = contentType2;
4142
4142
  }
4143
4143
  };
4144
+ TransportServiceNotAvailableError = class extends InternalMcpError {
4145
+ constructor() {
4146
+ super("Transport service not available", "TRANSPORT_SERVICE_NOT_AVAILABLE");
4147
+ }
4148
+ };
4144
4149
  }
4145
4150
  });
4146
4151
 
@@ -4563,6 +4568,7 @@ __export(errors_exports, {
4563
4568
  TransportAlreadyStartedError: () => TransportAlreadyStartedError,
4564
4569
  TransportBusRequiredError: () => TransportBusRequiredError,
4565
4570
  TransportNotConnectedError: () => TransportNotConnectedError,
4571
+ TransportServiceNotAvailableError: () => TransportServiceNotAvailableError,
4566
4572
  UnauthorizedError: () => UnauthorizedError,
4567
4573
  UnsupportedClientVersionError: () => UnsupportedClientVersionError,
4568
4574
  UnsupportedContentTypeError: () => UnsupportedContentTypeError,
@@ -7722,8 +7728,9 @@ var init_notification_service = __esm({
7722
7728
  emergency: 7
7723
7729
  };
7724
7730
  NotificationService = class _NotificationService {
7725
- constructor(scope) {
7731
+ constructor(scope, options = {}) {
7726
7732
  this.scope = scope;
7733
+ this.options = options;
7727
7734
  this.logger = scope.logger.child("NotificationService");
7728
7735
  }
7729
7736
  logger;
@@ -7740,6 +7747,9 @@ var init_notification_service = __esm({
7740
7747
  terminatedSessions = /* @__PURE__ */ new Set();
7741
7748
  /** Maximum number of terminated sessions to track before eviction */
7742
7749
  static MAX_TERMINATED_SESSIONS = 1e4;
7750
+ get maxTerminatedSessions() {
7751
+ return this.options.maxTerminatedSessions ?? _NotificationService.MAX_TERMINATED_SESSIONS;
7752
+ }
7743
7753
  /**
7744
7754
  * Initialize the notification service and subscribe to registry changes.
7745
7755
  * Called after all registries are ready.
@@ -7821,7 +7831,7 @@ var init_notification_service = __esm({
7821
7831
  const wasRegistered = this.unregisterServer(sessionId);
7822
7832
  this.scope.providers.cleanupSession(sessionId);
7823
7833
  this.logger.verbose(`Cleaned up provider cache for terminated session: ${sessionId.slice(0, 20)}...`);
7824
- if (this.terminatedSessions.size >= _NotificationService.MAX_TERMINATED_SESSIONS) {
7834
+ if (this.terminatedSessions.size >= this.maxTerminatedSessions) {
7825
7835
  const oldest = this.terminatedSessions.values().next().value;
7826
7836
  if (oldest) {
7827
7837
  this.terminatedSessions.delete(oldest);
@@ -8503,7 +8513,14 @@ async function handleWaitingFallback(deps, error) {
8503
8513
  );
8504
8514
  }
8505
8515
  }, ttl);
8506
- scope.elicitationStore.subscribeFallbackResult(
8516
+ const store = scope.elicitationStore;
8517
+ if (!store) {
8518
+ resolved = true;
8519
+ clearTimeout(timeoutHandle);
8520
+ reject(new ElicitationStoreNotInitializedError());
8521
+ return;
8522
+ }
8523
+ store.subscribeFallbackResult(
8507
8524
  error.elicitId,
8508
8525
  (result) => {
8509
8526
  if (!resolved) {
@@ -8584,7 +8601,7 @@ var init_tool_instance = __esm({
8584
8601
  this.name = record.metadata.id || record.metadata.name;
8585
8602
  this.fullName = this.owner.id + ":" + this.name;
8586
8603
  this.scope = this._providers.getActiveScope();
8587
- this.hooks = this.scope.providers.getHooksRegistry();
8604
+ this.hooks = this.scope.hooks;
8588
8605
  this.inputSchema = record.metadata.inputSchema ?? {};
8589
8606
  const meta = record.metadata;
8590
8607
  this.rawInputSchema = meta["rawInputSchema"];
@@ -9195,8 +9212,7 @@ var init_tools_list_flow = __esm({
9195
9212
  );
9196
9213
  }
9197
9214
  const sessionId = authInfo.sessionId;
9198
- const scope = this.scope;
9199
- const platformType = authInfo.sessionIdPayload?.platformType ?? (sessionId ? scope.notifications?.getPlatformType(sessionId) : void 0) ?? "unknown";
9215
+ const platformType = authInfo.sessionIdPayload?.platformType ?? (sessionId ? this.scope.notifications?.getPlatformType(sessionId) : void 0) ?? "unknown";
9200
9216
  this.logger.verbose(`parseInput: detected platform=${platformType}`);
9201
9217
  const cursor = params?.cursor;
9202
9218
  if (cursor) this.logger.verbose(`parseInput: cursor=${cursor}`);
@@ -9303,8 +9319,7 @@ var init_tools_list_flow = __esm({
9303
9319
  try {
9304
9320
  const allResolved = this.state.required.resolvedTools;
9305
9321
  const platformType = this.state.platformType ?? "unknown";
9306
- const scope = this.scope;
9307
- const paginationConfig = scope.pagination?.tools;
9322
+ const paginationConfig = this.scope.metadata.pagination?.tools;
9308
9323
  const usePagination = this.shouldPaginate(allResolved.length, paginationConfig);
9309
9324
  const sortedResolved = [...allResolved].sort((a, b) => a.finalName.localeCompare(b.finalName));
9310
9325
  let resolved = sortedResolved;
@@ -9364,12 +9379,12 @@ var init_tools_list_flow = __esm({
9364
9379
  this.logger.warn(`parseTools: toolUI not available in scope for ${finalName}`);
9365
9380
  return item;
9366
9381
  }
9367
- const scope2 = this.scope;
9382
+ const scope = this.scope;
9368
9383
  let manifest;
9369
9384
  let detectedType;
9370
9385
  try {
9371
- manifest = scope2.toolUI.getManifest(finalName);
9372
- detectedType = scope2.toolUI.detectUIType(uiConfig.template);
9386
+ manifest = scope.toolUI.getManifest(finalName);
9387
+ detectedType = scope.toolUI.detectUIType(uiConfig.template);
9373
9388
  } catch (error) {
9374
9389
  this.logger.warn(`parseTools: failed to access toolUI for ${finalName}`, error);
9375
9390
  return item;
@@ -9891,8 +9906,11 @@ var init_call_tool_flow = __esm({
9891
9906
  const authInfo = this.state.authInfo;
9892
9907
  const authInfoWithTransport = authInfo;
9893
9908
  const sessionId = authInfo?.sessionId ?? "anonymous";
9894
- const scope = this.scope;
9895
- await scope.elicitationStore.setPendingFallback({
9909
+ const store = this.scope.elicitationStore;
9910
+ if (!store) {
9911
+ throw new InternalMcpError("Elicitation store not initialized");
9912
+ }
9913
+ await store.setPendingFallback({
9896
9914
  elicitId: error.elicitId,
9897
9915
  sessionId,
9898
9916
  toolName: error.toolName,
@@ -9903,11 +9921,11 @@ var init_call_tool_flow = __esm({
9903
9921
  expiresAt: Date.now() + error.ttl
9904
9922
  });
9905
9923
  const transportType = authInfoWithTransport?.transport?.type;
9906
- if (transportType === "streamable-http" && canDeliverNotifications(scope, sessionId)) {
9924
+ if (transportType === "streamable-http" && canDeliverNotifications(this.scope, sessionId)) {
9907
9925
  this.logger.info("execute: using waiting fallback for streamable-http", {
9908
9926
  elicitId: error.elicitId
9909
9927
  });
9910
- const deps = { scope, sessionId, logger: this.logger };
9928
+ const deps = { scope: this.scope, sessionId, logger: this.logger };
9911
9929
  const result = await handleWaitingFallback(deps, error);
9912
9930
  toolContext.output = result;
9913
9931
  this.logger.verbose("execute:done (elicitation waiting fallback)");
@@ -10017,6 +10035,10 @@ ${JSON.stringify(error.schema, null, 2)}
10017
10035
  const useStructuredContent = resolvedMode.useStructuredContent;
10018
10036
  let htmlContent;
10019
10037
  let uiMeta = {};
10038
+ if (!scope.toolUI) {
10039
+ this.logger.verbose("applyUI: toolUI not available, skipping UI rendering");
10040
+ return;
10041
+ }
10020
10042
  if (servingMode === "static") {
10021
10043
  this.logger.verbose("applyUI: UI using static mode (structured data only)", {
10022
10044
  tool: tool.metadata.name,
@@ -10234,8 +10256,8 @@ var init_send_elicitation_result_tool = __esm({
10234
10256
  async execute(input) {
10235
10257
  const { elicitId, action, content } = input;
10236
10258
  this.logger.info("sendElicitationResult: processing", { elicitId, action });
10237
- const scope = this.scope;
10238
- if (!scope?.elicitationStore) {
10259
+ const store = this.scope.elicitationStore;
10260
+ if (!store) {
10239
10261
  this.logger.error("sendElicitationResult: scope or elicitationStore not available");
10240
10262
  return {
10241
10263
  content: [
@@ -10247,7 +10269,7 @@ var init_send_elicitation_result_tool = __esm({
10247
10269
  isError: true
10248
10270
  };
10249
10271
  }
10250
- const pending = await scope.elicitationStore.getPendingFallback(elicitId);
10272
+ const pending = await store.getPendingFallback(elicitId);
10251
10273
  if (!pending) {
10252
10274
  this.logger.warn("sendElicitationResult: no pending elicitation found", { elicitId });
10253
10275
  return {
@@ -10261,7 +10283,7 @@ var init_send_elicitation_result_tool = __esm({
10261
10283
  };
10262
10284
  }
10263
10285
  if (Date.now() > pending.expiresAt) {
10264
- await scope.elicitationStore.deletePendingFallback(elicitId);
10286
+ await store.deletePendingFallback(elicitId);
10265
10287
  this.logger.warn("sendElicitationResult: elicitation expired", { elicitId });
10266
10288
  return {
10267
10289
  content: [
@@ -10277,8 +10299,8 @@ var init_send_elicitation_result_tool = __esm({
10277
10299
  status: action,
10278
10300
  ...action === "accept" && content !== void 0 && { content }
10279
10301
  };
10280
- await scope.elicitationStore.setResolvedResult(elicitId, elicitResult, pending.sessionId);
10281
- await scope.elicitationStore.deletePendingFallback(elicitId);
10302
+ await store.setResolvedResult(elicitId, elicitResult, pending.sessionId);
10303
+ await store.deletePendingFallback(elicitId);
10282
10304
  this.logger.info("sendElicitationResult: re-invoking original tool", {
10283
10305
  elicitId,
10284
10306
  toolName: pending.toolName
@@ -10288,7 +10310,7 @@ var init_send_elicitation_result_tool = __esm({
10288
10310
  ctx.setPreResolvedElicitResult(elicitResult);
10289
10311
  }
10290
10312
  try {
10291
- const toolResult = await scope.runFlowForOutput("tools:call-tool", {
10313
+ const toolResult = await this.scope.runFlowForOutput("tools:call-tool", {
10292
10314
  request: {
10293
10315
  method: "tools/call",
10294
10316
  params: {
@@ -10303,19 +10325,19 @@ var init_send_elicitation_result_tool = __esm({
10303
10325
  elicitId,
10304
10326
  toolName: pending.toolName
10305
10327
  });
10306
- await scope.elicitationStore.publishFallbackResult(elicitId, pending.sessionId, {
10328
+ await store.publishFallbackResult(elicitId, pending.sessionId, {
10307
10329
  success: true,
10308
10330
  result: toolResult
10309
10331
  });
10310
- await scope.elicitationStore.deleteResolvedResult(elicitId);
10332
+ await store.deleteResolvedResult(elicitId);
10311
10333
  return toolResult;
10312
10334
  } catch (error) {
10313
10335
  const errorMessage = error instanceof Error ? error.message : String(error);
10314
- await scope.elicitationStore.publishFallbackResult(elicitId, pending.sessionId, {
10336
+ await store.publishFallbackResult(elicitId, pending.sessionId, {
10315
10337
  success: false,
10316
10338
  error: errorMessage
10317
10339
  });
10318
- await scope.elicitationStore.deleteResolvedResult(elicitId);
10340
+ await store.deleteResolvedResult(elicitId);
10319
10341
  this.logger.error("sendElicitationResult: original tool failed", {
10320
10342
  elicitId,
10321
10343
  toolName: pending.toolName,
@@ -11016,7 +11038,7 @@ var init_resource_instance = __esm({
11016
11038
  this.name = record.metadata.name;
11017
11039
  this.fullName = this.owner.id + ":" + this.name;
11018
11040
  this.scope = this.providers.getActiveScope();
11019
- this.hooks = this.scope.providers.getHooksRegistry();
11041
+ this.hooks = this.scope.hooks;
11020
11042
  this.isTemplate = "uriTemplate" in record.metadata;
11021
11043
  if (this.isTemplate) {
11022
11044
  const templateMetadata = record.metadata;
@@ -11271,11 +11293,14 @@ var init_read_resource_flow = __esm({
11271
11293
  this.logger.info(`findResource: looking for resource with URI "${uri}"`);
11272
11294
  if (isUIResourceUri(uri)) {
11273
11295
  this.logger.info(`findResource: detected UI resource URI "${uri}"`);
11274
- const scope = this.scope;
11275
11296
  const { sessionId, authInfo } = this.state;
11276
- const platformType = authInfo?.sessionIdPayload?.platformType ?? (sessionId ? scope.notifications.getPlatformType(sessionId) : void 0);
11297
+ const platformType = authInfo?.sessionIdPayload?.platformType ?? (sessionId ? this.scope.notifications.getPlatformType(sessionId) : void 0);
11277
11298
  this.logger.verbose(`findResource: platform type for session: ${platformType ?? "unknown"}`);
11278
- const uiResult = handleUIResourceRead(uri, scope.toolUI, platformType);
11299
+ if (!this.scope.toolUI) {
11300
+ this.logger.verbose("findResource: toolUI not available, skipping UI resource handling");
11301
+ throw new ResourceNotFoundError(uri);
11302
+ }
11303
+ const uiResult = handleUIResourceRead(uri, this.scope.toolUI, platformType);
11279
11304
  if (uiResult.handled) {
11280
11305
  if (uiResult.error) {
11281
11306
  this.logger.warn(`findResource: UI resource error - ${uiResult.error}`);
@@ -12753,7 +12778,7 @@ var init_prompt_instance = __esm({
12753
12778
  this.name = record.metadata.name;
12754
12779
  this.fullName = this.owner.id + ":" + this.name;
12755
12780
  this.scope = this._providers.getActiveScope();
12756
- this.hooks = this.scope.providers.getHooksRegistry();
12781
+ this.hooks = this.scope.hooks;
12757
12782
  this.ready = this.initialize();
12758
12783
  }
12759
12784
  async initialize() {
@@ -18335,7 +18360,7 @@ var init_flow_instance = __esm({
18335
18360
  this.FlowClass = this.record.provide;
18336
18361
  this.ready = this.initialize();
18337
18362
  this.plan = this.record.metadata.plan;
18338
- this.hooks = scope.providers.getHooksRegistry();
18363
+ this.hooks = scope.hooks;
18339
18364
  this.logger = scope.logger.child("FlowInstance");
18340
18365
  }
18341
18366
  async initialize() {
@@ -18703,8 +18728,8 @@ var init_flow_registry = __esm({
18703
18728
  const rec = this.defs.get(token);
18704
18729
  const deps = rec.metadata.dependsOn ?? [];
18705
18730
  for (const d of deps) {
18706
- if (d == ScopeEntry2) {
18707
- this.graph.get(token).add(ScopeEntry2);
18731
+ if (d == ScopeEntry3) {
18732
+ this.graph.get(token).add(ScopeEntry3);
18708
18733
  } else {
18709
18734
  if (!this.providers.get(d)) {
18710
18735
  throw new RegistryDependencyNotRegisteredError("Flow", tokenName11(token), tokenName11(d));
@@ -19025,7 +19050,7 @@ var init_agent_scope = __esm({
19025
19050
  {
19026
19051
  scope: ProviderScope4.GLOBAL,
19027
19052
  name: "ScopeEntry",
19028
- provide: ScopeEntry2,
19053
+ provide: ScopeEntry3,
19029
19054
  useValue: agentScopeEntry
19030
19055
  },
19031
19056
  // Also register as Scope so getActiveScope() returns the agent's scope
@@ -19136,6 +19161,12 @@ var init_agent_scope = __esm({
19136
19161
  get toolUI() {
19137
19162
  return this.parentScope.toolUI;
19138
19163
  }
19164
+ get skills() {
19165
+ return this.parentScope.skills;
19166
+ }
19167
+ get scopeMetadata() {
19168
+ return this.parentScope.metadata;
19169
+ }
19139
19170
  // ============================================================================
19140
19171
  // Flow Execution
19141
19172
  // ============================================================================
@@ -19194,18 +19225,42 @@ var init_agent_scope = __esm({
19194
19225
  get agents() {
19195
19226
  return this.agentScope.agents;
19196
19227
  }
19228
+ get skills() {
19229
+ return this.agentScope.skills;
19230
+ }
19197
19231
  get notifications() {
19198
19232
  return this.agentScope.notifications;
19199
19233
  }
19200
19234
  get toolUI() {
19201
19235
  return this.agentScope.toolUI;
19202
19236
  }
19237
+ get transportService() {
19238
+ return void 0;
19239
+ }
19240
+ get rateLimitManager() {
19241
+ return void 0;
19242
+ }
19243
+ get elicitationStore() {
19244
+ return void 0;
19245
+ }
19246
+ get metadata() {
19247
+ return this.agentScope.scopeMetadata;
19248
+ }
19249
+ get record() {
19250
+ return void 0;
19251
+ }
19252
+ get ready() {
19253
+ return this.agentScope.ready;
19254
+ }
19203
19255
  registryFlows(...flows) {
19204
19256
  return this.agentScope.registryFlows(...flows);
19205
19257
  }
19206
19258
  runFlow(name33, input, deps) {
19207
19259
  return this.agentScope.runFlow(name33, input, deps);
19208
19260
  }
19261
+ runFlowForOutput(name33, input, deps) {
19262
+ return this.agentScope.runFlowForOutput(name33, input, deps);
19263
+ }
19209
19264
  };
19210
19265
  }
19211
19266
  });
@@ -19253,7 +19308,7 @@ var init_agent_instance = __esm({
19253
19308
  this.id = record.metadata.id ?? record.metadata.name;
19254
19309
  this.fullName = this.owner.id + ":" + this.name;
19255
19310
  this.scope = this.providers.getActiveScope();
19256
- this.hooks = this.scope.providers.getHooksRegistry();
19311
+ this.hooks = this.scope.hooks;
19257
19312
  this.inputSchema = record.metadata.inputSchema ?? {};
19258
19313
  this.outputSchema = record.metadata.outputSchema;
19259
19314
  this.systemInstructions = record.metadata.systemInstructions;
@@ -27905,6 +27960,18 @@ var init_http_request_flow = __esm({
27905
27960
  this.respond(httpRespond.notFound("Session not found"));
27906
27961
  return;
27907
27962
  }
27963
+ const authorization = request[ServerRequestTokens.auth];
27964
+ if (authorization?.token) {
27965
+ const transportService = this.scope.transportService;
27966
+ if (transportService) {
27967
+ for (const protocol of ["streamable-http", "sse"]) {
27968
+ try {
27969
+ await transportService.destroyTransporter(protocol, authorization.token, sessionId);
27970
+ } catch {
27971
+ }
27972
+ }
27973
+ }
27974
+ }
27908
27975
  this.logger.info(`[${this.requestId}] Session terminated: ${sessionId}`);
27909
27976
  this.respond(httpRespond.noContent());
27910
27977
  } catch (error) {
@@ -28082,8 +28149,13 @@ var init_transport_remote = __esm({
28082
28149
  async destroy(_reason) {
28083
28150
  throw new MethodNotImplementedError("RemoteTransporter", "destroy");
28084
28151
  }
28152
+ get isInitialized() {
28153
+ return false;
28154
+ }
28085
28155
  markAsInitialized() {
28086
28156
  }
28157
+ resetForReinitialization() {
28158
+ }
28087
28159
  };
28088
28160
  }
28089
28161
  });
@@ -29429,12 +29501,25 @@ var init_transport_local_adapter = __esm({
29429
29501
  #requestId = 1;
29430
29502
  ready;
29431
29503
  server;
29504
+ /**
29505
+ * Whether this transport has already been initialized via the MCP initialize handshake.
29506
+ * Override in subclasses that track initialization state.
29507
+ */
29508
+ get isInitialized() {
29509
+ return false;
29510
+ }
29432
29511
  /**
29433
29512
  * Marks this transport as pre-initialized for session recreation.
29434
29513
  * Override in subclasses that need to set the MCP SDK's _initialized flag.
29435
29514
  */
29436
29515
  markAsInitialized() {
29437
29516
  }
29517
+ /**
29518
+ * Resets initialization state to allow re-initialization.
29519
+ * Override in subclasses that support session re-initialization.
29520
+ */
29521
+ resetForReinitialization() {
29522
+ }
29438
29523
  connectServer() {
29439
29524
  const { info, apps } = this.scope.metadata;
29440
29525
  const hasRemoteApps = apps?.some((app) => this.isRemoteApp(app)) ?? false;
@@ -29523,8 +29608,13 @@ var init_transport_local_adapter = __esm({
29523
29608
  }
29524
29609
  ensureAuthInfo(req, transport) {
29525
29610
  const { token, user, session } = req[ServerRequestTokens.auth];
29526
- const sessionId = session?.id ?? `fallback:${Date.now()}`;
29527
- const sessionPayload = session?.payload ?? { protocol: "streamable-http" };
29611
+ if (!session?.id) {
29612
+ throw new Error(
29613
+ "Session ID is required in ensureAuthInfo. This indicates a bug in session propagation \u2014 the session should have been set by the flow."
29614
+ );
29615
+ }
29616
+ const sessionId = session.id;
29617
+ const sessionPayload = session.payload ?? { protocol: "streamable-http" };
29528
29618
  if (this.initSessionPayload) {
29529
29619
  const init = this.initSessionPayload;
29530
29620
  if (init.supportsElicitation !== void 0 && sessionPayload.supportsElicitation === void 0) {
@@ -29559,6 +29649,17 @@ var init_transport_local_adapter = __esm({
29559
29649
  get elicitStore() {
29560
29650
  return this.scope.elicitationStore;
29561
29651
  }
29652
+ /**
29653
+ * Get the elicitation store, throwing if not initialized.
29654
+ * Use in contexts where elicitation is required (sendElicitRequest, cancelPendingElicit).
29655
+ */
29656
+ requireElicitStore() {
29657
+ const store = this.elicitStore;
29658
+ if (!store) {
29659
+ throw new Error("Elicitation store not initialized");
29660
+ }
29661
+ return store;
29662
+ }
29562
29663
  /**
29563
29664
  * Cancel any pending elicitation request.
29564
29665
  * Called before sending a new elicit to enforce single-elicit-per-session.
@@ -29576,9 +29677,12 @@ var init_transport_local_adapter = __esm({
29576
29677
  clearTimeout(this.pendingElicit.timeoutHandle);
29577
29678
  this.pendingElicit.resolve({ status: "cancel" });
29578
29679
  const sessionId = this.key.sessionId;
29579
- const pending = await this.elicitStore.getPending(sessionId);
29580
- if (pending) {
29581
- await this.elicitStore.publishResult(pending.elicitId, sessionId, { status: "cancel" });
29680
+ const store = this.elicitStore;
29681
+ if (store) {
29682
+ const pending = await store.getPending(sessionId);
29683
+ if (pending) {
29684
+ await store.publishResult(pending.elicitId, sessionId, { status: "cancel" });
29685
+ }
29582
29686
  }
29583
29687
  this.pendingElicit = void 0;
29584
29688
  this.logger.info("Cancelled previous pending elicit");
@@ -30935,7 +31039,8 @@ var init_transport_sse_adapter = __esm({
30935
31039
  const elicitId = elicitationId ?? `elicit-${this.newRequestId}`;
30936
31040
  const sessionId = this.key.sessionId;
30937
31041
  const expiresAt = Date.now() + ttl;
30938
- await this.elicitStore.setPending({
31042
+ const store = this.requireElicitStore();
31043
+ await store.setPending({
30939
31044
  elicitId,
30940
31045
  sessionId,
30941
31046
  createdAt: Date.now(),
@@ -30978,10 +31083,10 @@ var init_transport_sse_adapter = __esm({
30978
31083
  settled = true;
30979
31084
  this.pendingElicit = void 0;
30980
31085
  await unsubscribe?.();
30981
- await this.elicitStore.deletePending(sessionId);
31086
+ await store.deletePending(sessionId);
30982
31087
  reject(new ElicitationTimeoutError(elicitId, ttl));
30983
31088
  }, ttl);
30984
- this.elicitStore.subscribeResult(
31089
+ store.subscribeResult(
30985
31090
  elicitId,
30986
31091
  (result) => {
30987
31092
  safeResolve(result);
@@ -30995,7 +31100,7 @@ var init_transport_sse_adapter = __esm({
30995
31100
  clearTimeout(timeoutHandle);
30996
31101
  this.pendingElicit = void 0;
30997
31102
  await unsubscribe?.();
30998
- await this.elicitStore.deletePending(sessionId);
31103
+ await store.deletePending(sessionId);
30999
31104
  reject(err);
31000
31105
  });
31001
31106
  this.pendingElicit = {
@@ -31078,6 +31183,31 @@ var init_streamable_http_transport = __esm({
31078
31183
  }
31079
31184
  this._applyInitState(webTransport, sessionId);
31080
31185
  }
31186
+ /**
31187
+ * Resets the transport's initialization state to allow re-initialization.
31188
+ *
31189
+ * This is needed when a client reconnects after terminating its session:
31190
+ * the cached transport is still marked as initialized, but the client
31191
+ * needs to re-initialize. Resetting _initialized and sessionId allows
31192
+ * the MCP SDK to process a fresh initialize request.
31193
+ *
31194
+ * This is the inverse of setInitializationState().
31195
+ */
31196
+ resetForReinitialization() {
31197
+ const webTransport = this._webStandardTransport;
31198
+ if (!webTransport) {
31199
+ this._pendingInitState = void 0;
31200
+ return;
31201
+ }
31202
+ if (!("_initialized" in webTransport)) {
31203
+ throw new InvalidTransportSessionError(
31204
+ "[RecreateableStreamableHTTPServerTransport] Expected _initialized field not found on internal transport. This may indicate an incompatible MCP SDK version."
31205
+ );
31206
+ }
31207
+ webTransport._initialized = false;
31208
+ webTransport.sessionId = void 0;
31209
+ this._pendingInitState = void 0;
31210
+ }
31081
31211
  /**
31082
31212
  * Applies initialization state to the internal transport.
31083
31213
  * @param webTransport - The internal _webStandardTransport object
@@ -31237,6 +31367,7 @@ var init_transport_streamable_http_adapter = __esm({
31237
31367
  */
31238
31368
  async sendElicitRequest(relatedRequestId, message, requestedSchema, options) {
31239
31369
  await this.cancelPendingElicit();
31370
+ const store = this.requireElicitStore();
31240
31371
  const sessionId = this.key.sessionId;
31241
31372
  const flowOutput = await this.scope.runFlowForOutput("elicitation:request", {
31242
31373
  relatedRequestId,
@@ -31261,7 +31392,7 @@ var init_transport_streamable_http_adapter = __esm({
31261
31392
  } catch (error) {
31262
31393
  this.logger.error("[StreamableHttpAdapter] sendElicitRequest: transport.send() failed", error);
31263
31394
  try {
31264
- await this.elicitStore.deletePending(sessionId);
31395
+ await store.deletePending(sessionId);
31265
31396
  this.logger.verbose("[StreamableHttpAdapter] sendElicitRequest: cleaned up pending record after send failure");
31266
31397
  } catch (cleanupError) {
31267
31398
  this.logger.warn("[StreamableHttpAdapter] sendElicitRequest: failed to clean up pending record", cleanupError);
@@ -31293,10 +31424,10 @@ var init_transport_streamable_http_adapter = __esm({
31293
31424
  settled = true;
31294
31425
  this.pendingElicit = void 0;
31295
31426
  await unsubscribe?.();
31296
- await this.elicitStore.deletePending(sessionId);
31427
+ await store.deletePending(sessionId);
31297
31428
  reject(new ElicitationTimeoutError(elicitId, ttl));
31298
31429
  }, ttl);
31299
- this.elicitStore.subscribeResult(
31430
+ store.subscribeResult(
31300
31431
  elicitId,
31301
31432
  (result) => {
31302
31433
  safeResolve(result);
@@ -31310,7 +31441,7 @@ var init_transport_streamable_http_adapter = __esm({
31310
31441
  clearTimeout(timeoutHandle);
31311
31442
  this.pendingElicit = void 0;
31312
31443
  await unsubscribe?.();
31313
- await this.elicitStore.deletePending(sessionId);
31444
+ await store.deletePending(sessionId);
31314
31445
  reject(err);
31315
31446
  });
31316
31447
  this.pendingElicit = {
@@ -31321,6 +31452,20 @@ var init_transport_streamable_http_adapter = __esm({
31321
31452
  };
31322
31453
  });
31323
31454
  }
31455
+ get isInitialized() {
31456
+ return this.transport.isInitialized || this.transport.hasPendingInitState;
31457
+ }
31458
+ /**
31459
+ * Resets the transport's initialization state to allow re-initialization.
31460
+ * Used when a client retries initialize on an already-initialized session
31461
+ * (e.g., after reconnect following session termination).
31462
+ */
31463
+ resetForReinitialization() {
31464
+ this.transport.resetForReinitialization();
31465
+ this.logger.info("[StreamableHttpAdapter] Reset transport for re-initialization", {
31466
+ sessionId: this.key.sessionId?.slice(0, 20)
31467
+ });
31468
+ }
31324
31469
  /**
31325
31470
  * Marks this transport as pre-initialized for session recreation.
31326
31471
  * This is needed when recreating a transport from Redis because the
@@ -31395,6 +31540,9 @@ var init_transport_local = __esm({
31395
31540
  res.status(500).json(rpcError("Internal error"));
31396
31541
  }
31397
31542
  }
31543
+ get isInitialized() {
31544
+ return this.adapter.isInitialized;
31545
+ }
31398
31546
  /**
31399
31547
  * Marks this transport as pre-initialized for session recreation.
31400
31548
  * This is needed when recreating a transport from Redis because the
@@ -31403,6 +31551,9 @@ var init_transport_local = __esm({
31403
31551
  markAsInitialized() {
31404
31552
  this.adapter.markAsInitialized();
31405
31553
  }
31554
+ resetForReinitialization() {
31555
+ this.adapter.resetForReinitialization();
31556
+ }
31406
31557
  async destroy(reason) {
31407
31558
  try {
31408
31559
  await this.adapter.destroy(reason);
@@ -31789,6 +31940,79 @@ var init_ext_apps2 = __esm({
31789
31940
  // libs/sdk/src/transport/flows/handle.streamable-http.flow.ts
31790
31941
  import { z as z62 } from "zod";
31791
31942
  import { ElicitResultSchema as ElicitResultSchema2, RequestSchema, CallToolResultSchema as CallToolResultSchema3 } from "@frontmcp/protocol";
31943
+ function resolveStreamableHttpSession(params) {
31944
+ const { rawHeader, authorizationSession, createSession } = params;
31945
+ const rawMcpSessionHeader = typeof rawHeader === "string" ? rawHeader : void 0;
31946
+ const mcpSessionHeader = validateMcpSessionHeader(rawMcpSessionHeader);
31947
+ if (rawHeader !== void 0 && !mcpSessionHeader) {
31948
+ return { responded404: true, createdNew: false };
31949
+ }
31950
+ if (mcpSessionHeader) {
31951
+ if (authorizationSession?.id === mcpSessionHeader) {
31952
+ return { session: authorizationSession, createdNew: false, responded404: false };
31953
+ }
31954
+ return { session: { id: mcpSessionHeader }, createdNew: false, responded404: false };
31955
+ }
31956
+ if (authorizationSession) {
31957
+ return { session: authorizationSession, createdNew: false, responded404: false };
31958
+ }
31959
+ return { session: createSession(), createdNew: true, responded404: false };
31960
+ }
31961
+ function classifyStreamableHttpRequest(params) {
31962
+ const { method, body } = params;
31963
+ if (method.toUpperCase() === "GET") {
31964
+ return { requestType: "sseListener" };
31965
+ }
31966
+ const jsonRpcMethod = body?.method;
31967
+ if (jsonRpcMethod === "initialize") {
31968
+ return { requestType: "initialize" };
31969
+ }
31970
+ if (typeof jsonRpcMethod === "string" && jsonRpcMethod.startsWith("ui/")) {
31971
+ return { requestType: "extApps" };
31972
+ }
31973
+ if (ElicitResultSchema2.safeParse(body?.result).success) {
31974
+ return { requestType: "elicitResult" };
31975
+ }
31976
+ if (jsonRpcMethod && RequestSchema.safeParse(body).success) {
31977
+ return { requestType: "message" };
31978
+ }
31979
+ return { error: "Invalid Request" };
31980
+ }
31981
+ function syncStreamableHttpAuthorizationSession(authorization, session) {
31982
+ if (!authorization.session) {
31983
+ authorization.session = session;
31984
+ }
31985
+ }
31986
+ async function lookupStreamableHttpTransport(params) {
31987
+ const { transportService, token, sessionId, response } = params;
31988
+ const inMemoryTransport = await transportService.getTransporter("streamable-http", token, sessionId);
31989
+ if (inMemoryTransport) {
31990
+ return { kind: "transport", source: "memory", transport: inMemoryTransport };
31991
+ }
31992
+ let recreationError;
31993
+ try {
31994
+ const storedSession = await transportService.getStoredSession("streamable-http", token, sessionId);
31995
+ if (storedSession) {
31996
+ const recreatedTransport = await transportService.recreateTransporter(
31997
+ "streamable-http",
31998
+ token,
31999
+ sessionId,
32000
+ storedSession,
32001
+ response
32002
+ );
32003
+ if (recreatedTransport) {
32004
+ return { kind: "transport", source: "redis", transport: recreatedTransport };
32005
+ }
32006
+ }
32007
+ } catch (error) {
32008
+ recreationError = error;
32009
+ }
32010
+ const wasCreated = await transportService.wasSessionCreatedAsync("streamable-http", token, sessionId);
32011
+ if (wasCreated) {
32012
+ return { kind: "session-expired", recreationError };
32013
+ }
32014
+ return { kind: "session-not-initialized", recreationError };
32015
+ }
31792
32016
  var plan19, stateSessionSchema, stateSchema18, name20, Stage20, HandleStreamableHttpFlow;
31793
32017
  var init_handle_streamable_http_flow = __esm({
31794
32018
  "libs/sdk/src/transport/flows/handle.streamable-http.flow.ts"() {
@@ -31830,64 +32054,60 @@ var init_handle_streamable_http_flow = __esm({
31830
32054
  const authorization = request[ServerRequestTokens.auth];
31831
32055
  const { token } = authorization;
31832
32056
  const logger = this.scopeLogger.child("handle:streamable-http:parseInput");
31833
- const raw = request.headers?.["mcp-session-id"];
31834
- const rawMcpSessionHeader = typeof raw === "string" ? raw : void 0;
31835
- const mcpSessionHeader = validateMcpSessionHeader(rawMcpSessionHeader);
31836
- if (raw !== void 0 && !mcpSessionHeader) {
32057
+ const sessionResolution = resolveStreamableHttpSession({
32058
+ rawHeader: request.headers?.["mcp-session-id"],
32059
+ authorizationSession: authorization.session,
32060
+ createSession: () => {
32061
+ const query = request.query;
32062
+ const skillsOnlyMode = detectSkillsOnlyMode(query);
32063
+ return createSessionId("streamable-http", token, {
32064
+ userAgent: request.headers?.["user-agent"],
32065
+ platformDetectionConfig: this.scope.metadata.transport?.platformDetection,
32066
+ skillsOnlyMode
32067
+ });
32068
+ }
32069
+ });
32070
+ if (sessionResolution.responded404 || !sessionResolution.session) {
31837
32071
  logger.warn("parseInput: invalid mcp-session-id header");
31838
32072
  this.respond(httpRespond.sessionNotFound("invalid session id"));
31839
32073
  return;
31840
32074
  }
31841
- let session;
31842
- if (mcpSessionHeader) {
31843
- if (authorization.session?.id === mcpSessionHeader) {
31844
- session = authorization.session;
31845
- } else {
31846
- session = { id: mcpSessionHeader };
31847
- }
31848
- } else if (authorization.session) {
31849
- session = authorization.session;
31850
- } else {
31851
- const query = request.query;
31852
- const skillsOnlyMode = detectSkillsOnlyMode(query);
31853
- session = createSessionId("streamable-http", token, {
31854
- userAgent: request.headers?.["user-agent"],
31855
- platformDetectionConfig: this.scope.metadata.transport?.platformDetection,
31856
- skillsOnlyMode
31857
- });
31858
- }
32075
+ const session = sessionResolution.session;
31859
32076
  this.state.set(stateSchema18.parse({ token, session }));
31860
32077
  logger.info("parseInput: session resolved", { sessionId: session.id?.slice(0, 20) });
31861
32078
  }
31862
32079
  async router() {
31863
32080
  const { request } = this.rawInput;
31864
32081
  const logger = this.scopeLogger.child("handle:streamable-http:router");
31865
- if (request.method.toUpperCase() === "GET") {
31866
- this.state.set("requestType", "sseListener");
31867
- logger.info("router: requestType=sseListener, method=GET");
32082
+ const classification = classifyStreamableHttpRequest({
32083
+ method: request.method,
32084
+ body: request.body
32085
+ });
32086
+ if ("error" in classification) {
32087
+ logger.warn("router: invalid request, no valid method");
32088
+ this.respond(httpRespond.rpcError("Invalid Request"));
31868
32089
  return;
31869
32090
  }
31870
- const body = request.body;
31871
- const method = body?.method;
31872
- if (method === "initialize") {
31873
- this.state.set("requestType", "initialize");
32091
+ this.state.set("requestType", classification.requestType);
32092
+ if (classification.requestType === "sseListener") {
32093
+ logger.info("router: requestType=sseListener, method=GET");
32094
+ } else if (classification.requestType === "initialize") {
31874
32095
  logger.info("router: requestType=initialize, method=POST");
31875
- } else if (typeof method === "string" && method.startsWith("ui/")) {
31876
- this.state.set("requestType", "extApps");
32096
+ } else if (classification.requestType === "extApps") {
32097
+ const method = request.body?.method;
31877
32098
  logger.info(`router: requestType=extApps, method=${method}`);
31878
- } else if (ElicitResultSchema2.safeParse(request.body?.result).success) {
31879
- this.state.set("requestType", "elicitResult");
32099
+ } else if (classification.requestType === "elicitResult") {
31880
32100
  logger.info("router: requestType=elicitResult, method=POST");
31881
- } else if (method && RequestSchema.safeParse(request.body).success) {
31882
- this.state.set("requestType", "message");
31883
- logger.info(`router: requestType=message, method=${method}`);
31884
32101
  } else {
31885
- logger.warn("router: invalid request, no valid method");
31886
- this.respond(httpRespond.rpcError("Invalid Request"));
32102
+ const method = request.body?.method;
32103
+ logger.info(`router: requestType=message, method=${method}`);
31887
32104
  }
31888
32105
  }
31889
32106
  async onInitialize() {
31890
32107
  const transportService = this.scope.transportService;
32108
+ if (!transportService) {
32109
+ throw new TransportServiceNotAvailableError();
32110
+ }
31891
32111
  const logger = this.scope.logger.child("handle:streamable-http:onInitialize");
31892
32112
  const { request, response } = this.rawInput;
31893
32113
  const { token, session } = this.state.required;
@@ -31897,7 +32117,15 @@ var init_handle_streamable_http_flow = __esm({
31897
32117
  tokenPrefix: token?.slice(0, 10)
31898
32118
  });
31899
32119
  try {
32120
+ const authorization = request[ServerRequestTokens.auth];
32121
+ syncStreamableHttpAuthorizationSession(authorization, session);
31900
32122
  const transport = await transportService.createTransporter("streamable-http", token, session.id, response);
32123
+ if (transport.isInitialized) {
32124
+ logger.info("onInitialize: transport already initialized, resetting for re-initialization", {
32125
+ sessionId: session.id?.slice(0, 20)
32126
+ });
32127
+ transport.resetForReinitialization();
32128
+ }
31901
32129
  logger.info("onInitialize: transport created, calling initialize");
31902
32130
  await transport.initialize(request, response);
31903
32131
  logger.info("onInitialize: completed successfully");
@@ -31915,6 +32143,9 @@ var init_handle_streamable_http_flow = __esm({
31915
32143
  }
31916
32144
  async onElicitResult() {
31917
32145
  const transportService = this.scope.transportService;
32146
+ if (!transportService) {
32147
+ throw new TransportServiceNotAvailableError();
32148
+ }
31918
32149
  const logger = this.scopeLogger.child("handle:streamable-http:onElicitResult");
31919
32150
  const { request, response } = this.rawInput;
31920
32151
  const { token, session } = this.state.required;
@@ -31965,6 +32196,9 @@ var init_handle_streamable_http_flow = __esm({
31965
32196
  }
31966
32197
  async onMessage() {
31967
32198
  const transportService = this.scope.transportService;
32199
+ if (!transportService) {
32200
+ throw new TransportServiceNotAvailableError();
32201
+ }
31968
32202
  const logger = this.scopeLogger.child("handle:streamable-http:onMessage");
31969
32203
  const { request, response } = this.rawInput;
31970
32204
  const { token, session } = this.state.required;
@@ -31972,44 +32206,21 @@ var init_handle_streamable_http_flow = __esm({
31972
32206
  sessionId: session.id?.slice(0, 20),
31973
32207
  hasToken: !!token
31974
32208
  });
31975
- let transport = await transportService.getTransporter("streamable-http", token, session.id);
31976
- logger.verbose("onMessage: getTransporter result", { found: !!transport });
31977
- if (!transport) {
31978
- try {
31979
- logger.verbose("onMessage: transport not in memory, checking Redis", {
31980
- sessionId: session.id?.slice(0, 20)
31981
- });
31982
- const storedSession = await transportService.getStoredSession("streamable-http", token, session.id);
31983
- logger.verbose("onMessage: getStoredSession result", {
31984
- found: !!storedSession,
31985
- initialized: storedSession?.initialized
31986
- });
31987
- if (storedSession) {
31988
- logger.verbose("onMessage: recreating transport from stored session", {
31989
- sessionId: session.id?.slice(0, 20),
31990
- createdAt: storedSession.createdAt,
31991
- initialized: storedSession.initialized
31992
- });
31993
- transport = await transportService.recreateTransporter(
31994
- "streamable-http",
31995
- token,
31996
- session.id,
31997
- storedSession,
31998
- response
31999
- );
32000
- logger.verbose("onMessage: transport recreated successfully");
32001
- }
32002
- } catch (error) {
32209
+ const transportLookup = await lookupStreamableHttpTransport({
32210
+ transportService,
32211
+ token,
32212
+ sessionId: session.id,
32213
+ response
32214
+ });
32215
+ if (transportLookup.kind !== "transport") {
32216
+ const body = request.body;
32217
+ if (transportLookup.recreationError) {
32003
32218
  logger.warn("Failed to recreate transport from stored session", {
32004
32219
  sessionId: session.id?.slice(0, 20),
32005
- error: error instanceof Error ? error.message : String(error)
32220
+ error: transportLookup.recreationError instanceof Error ? transportLookup.recreationError.message : String(transportLookup.recreationError)
32006
32221
  });
32007
32222
  }
32008
- }
32009
- if (!transport) {
32010
- const wasCreated = await transportService.wasSessionCreatedAsync("streamable-http", token, session.id);
32011
- const body = request.body;
32012
- if (wasCreated) {
32223
+ if (transportLookup.kind === "session-expired") {
32013
32224
  logger.info("Session expired - client should re-initialize", {
32014
32225
  sessionId: session.id?.slice(0, 20),
32015
32226
  tokenHash: token.slice(0, 8),
@@ -32031,6 +32242,8 @@ var init_handle_streamable_http_flow = __esm({
32031
32242
  }
32032
32243
  return;
32033
32244
  }
32245
+ const transport = transportLookup.transport;
32246
+ logger.verbose("onMessage: transport resolved", { source: transportLookup.source });
32034
32247
  try {
32035
32248
  await transport.handleRequest(request, response);
32036
32249
  this.handled();
@@ -32049,6 +32262,9 @@ var init_handle_streamable_http_flow = __esm({
32049
32262
  }
32050
32263
  async onSseListener() {
32051
32264
  const transportService = this.scope.transportService;
32265
+ if (!transportService) {
32266
+ throw new TransportServiceNotAvailableError();
32267
+ }
32052
32268
  const logger = this.scopeLogger.child("handle:streamable-http:onSseListener");
32053
32269
  const { request, response } = this.rawInput;
32054
32270
  const { token, session } = this.state.required;
@@ -32086,6 +32302,9 @@ var init_handle_streamable_http_flow = __esm({
32086
32302
  }
32087
32303
  async onExtApps() {
32088
32304
  const transportService = this.scope.transportService;
32305
+ if (!transportService) {
32306
+ throw new TransportServiceNotAvailableError();
32307
+ }
32089
32308
  const logger = this.scopeLogger.child("handle:streamable-http:onExtApps");
32090
32309
  const { request, response } = this.rawInput;
32091
32310
  const { token, session } = this.state.required;
@@ -32136,8 +32355,7 @@ var init_handle_streamable_http_flow = __esm({
32136
32355
  }
32137
32356
  return;
32138
32357
  }
32139
- const scope = this.scope;
32140
- const configuredCapabilities = scope.metadata.extApps?.hostCapabilities;
32358
+ const configuredCapabilities = this.scope.metadata.extApps?.hostCapabilities;
32141
32359
  const hostCapabilities = {
32142
32360
  serverToolProxy: configuredCapabilities?.serverToolProxy ?? true,
32143
32361
  logging: configuredCapabilities?.logging ?? true,
@@ -32146,9 +32364,9 @@ var init_handle_streamable_http_flow = __esm({
32146
32364
  const handler = createExtAppsMessageHandler({
32147
32365
  context: {
32148
32366
  sessionId: session.id,
32149
- logger: scope.logger,
32367
+ logger: this.scope.logger,
32150
32368
  callTool: async (name33, args) => {
32151
- const result = await scope.runFlow("tools:call-tool", {
32369
+ const result = await this.scope.runFlow("tools:call-tool", {
32152
32370
  request: { method: "tools/call", params: { name: name33, arguments: args } },
32153
32371
  ctx: {
32154
32372
  authInfo: {
@@ -32234,6 +32452,7 @@ var init_handle_sse_flow = __esm({
32234
32452
  "libs/sdk/src/transport/flows/handle.sse.flow.ts"() {
32235
32453
  "use strict";
32236
32454
  init_common();
32455
+ init_errors();
32237
32456
  init_session_id_utils();
32238
32457
  init_skill_mode_utils();
32239
32458
  plan20 = {
@@ -32303,10 +32522,9 @@ var init_handle_sse_flow = __esm({
32303
32522
  }
32304
32523
  async router() {
32305
32524
  const { request } = this.rawInput;
32306
- const scope = this.scope;
32307
32525
  const requestPath = normalizeEntryPrefix(request.path);
32308
- const prefix = normalizeEntryPrefix(scope.entryPath);
32309
- const scopePath = normalizeScopeBase(scope.routeBase);
32526
+ const prefix = normalizeEntryPrefix(this.scope.entryPath);
32527
+ const scopePath = normalizeScopeBase(this.scope.routeBase);
32310
32528
  const basePath = `${prefix}${scopePath}`;
32311
32529
  if (requestPath === `${basePath}/sse`) {
32312
32530
  this.state.set("requestType", "initialize");
@@ -32316,6 +32534,9 @@ var init_handle_sse_flow = __esm({
32316
32534
  }
32317
32535
  async onInitialize() {
32318
32536
  const transportService = this.scope.transportService;
32537
+ if (!transportService) {
32538
+ throw new TransportServiceNotAvailableError();
32539
+ }
32319
32540
  const { request, response } = this.rawInput;
32320
32541
  const { token, session } = this.state.required;
32321
32542
  const transport = await transportService.createTransporter("sse", token, session.id, response);
@@ -32327,6 +32548,9 @@ var init_handle_sse_flow = __esm({
32327
32548
  }
32328
32549
  async onMessage() {
32329
32550
  const transportService = this.scope.transportService;
32551
+ if (!transportService) {
32552
+ throw new TransportServiceNotAvailableError();
32553
+ }
32330
32554
  const logger = this.scopeLogger.child("handle:legacy-sse:onMessage");
32331
32555
  const { request, response } = this.rawInput;
32332
32556
  const { token, session } = this.state.required;
@@ -32399,6 +32623,7 @@ var init_handle_stateless_http_flow = __esm({
32399
32623
  "libs/sdk/src/transport/flows/handle.stateless-http.flow.ts"() {
32400
32624
  "use strict";
32401
32625
  init_common();
32626
+ init_errors();
32402
32627
  plan21 = {
32403
32628
  pre: ["parseInput", "router"],
32404
32629
  execute: ["handleRequest"],
@@ -32446,6 +32671,9 @@ var init_handle_stateless_http_flow = __esm({
32446
32671
  }
32447
32672
  async handleRequest() {
32448
32673
  const transportService = this.scope.transportService;
32674
+ if (!transportService) {
32675
+ throw new TransportServiceNotAvailableError();
32676
+ }
32449
32677
  const logger = this.scope.logger.child("HandleStatelessHttpFlow");
32450
32678
  const { request, response } = this.rawInput;
32451
32679
  const { token, isAuthenticated, requestType } = this.state;
@@ -36135,11 +36363,10 @@ var init_call_agent_flow = __esm({
36135
36363
  throw new InvalidMethodError(method, "tools/call");
36136
36364
  }
36137
36365
  const { name: toolName } = params;
36138
- const scope = this.scope;
36139
36366
  const agentId = toolName;
36140
36367
  let agent;
36141
- if (scope.agents) {
36142
- agent = scope.agents.findById(agentId) ?? scope.agents.findByName(agentId);
36368
+ if (this.scope.agents) {
36369
+ agent = this.scope.agents.findById(agentId) ?? this.scope.agents.findByName(agentId);
36143
36370
  }
36144
36371
  const agentOwnerId = agent?.owner?.id;
36145
36372
  const progressToken = params._meta?.progressToken;
@@ -36155,8 +36382,7 @@ var init_call_agent_flow = __esm({
36155
36382
  }
36156
36383
  async findAgent() {
36157
36384
  this.logger.verbose("findAgent:start");
36158
- const scope = this.scope;
36159
- const agents = scope.agents;
36385
+ const agents = this.scope.agents;
36160
36386
  if (!agents) {
36161
36387
  this.logger.warn("findAgent: no agent registry available");
36162
36388
  throw new AgentNotFoundError(this.state.required.input.name);
@@ -36577,7 +36803,10 @@ var init_elicitation_request_flow = __esm({
36577
36803
  async storePendingRecord() {
36578
36804
  this.logger.verbose("storePendingRecord:start");
36579
36805
  const { elicitId, sessionId, message, mode, expiresAt, requestedSchema } = this.state.required;
36580
- const scope = this.scope;
36806
+ const store = this.scope.elicitationStore;
36807
+ if (!store) {
36808
+ throw new ElicitationStoreNotInitializedError();
36809
+ }
36581
36810
  const pendingRecord = {
36582
36811
  elicitId,
36583
36812
  sessionId,
@@ -36587,7 +36816,7 @@ var init_elicitation_request_flow = __esm({
36587
36816
  mode,
36588
36817
  requestedSchema
36589
36818
  };
36590
- await scope.elicitationStore.setPending(pendingRecord);
36819
+ await store.setPending(pendingRecord);
36591
36820
  this.state.set("pendingRecord", pendingRecord);
36592
36821
  this.logger.verbose("storePendingRecord:done", { elicitId, sessionId });
36593
36822
  }
@@ -36714,8 +36943,11 @@ var init_elicitation_result_flow = __esm({
36714
36943
  async lookupPending() {
36715
36944
  this.logger.verbose("lookupPending:start");
36716
36945
  const { sessionId } = this.state.required;
36717
- const scope = this.scope;
36718
- const pendingRecord = await scope.elicitationStore.getPending(sessionId);
36946
+ const store = this.scope.elicitationStore;
36947
+ if (!store) {
36948
+ throw new ElicitationStoreNotInitializedError();
36949
+ }
36950
+ const pendingRecord = await store.getPending(sessionId);
36719
36951
  this.state.set("pendingRecord", pendingRecord ?? void 0);
36720
36952
  if (!pendingRecord) {
36721
36953
  this.logger.verbose("lookupPending:notFound", { sessionId });
@@ -36767,14 +36999,14 @@ var init_elicitation_result_flow = __esm({
36767
36999
  this.logger.verbose("publishResult:start");
36768
37000
  const { pendingRecord, elicitResult } = this.state;
36769
37001
  const { sessionId } = this.state.required;
36770
- const scope = this.scope;
36771
- if (!pendingRecord || !elicitResult) {
37002
+ const store = this.scope.elicitationStore;
37003
+ if (!pendingRecord || !elicitResult || !store) {
36772
37004
  this.state.set("handled", false);
36773
37005
  this.logger.verbose("publishResult:skip (no pending or no result)");
36774
37006
  return;
36775
37007
  }
36776
37008
  try {
36777
- await scope.elicitationStore.publishResult(pendingRecord.elicitId, sessionId, elicitResult);
37009
+ await store.publishResult(pendingRecord.elicitId, sessionId, elicitResult);
36778
37010
  this.state.set("handled", true);
36779
37011
  this.logger.verbose("publishResult:done", {
36780
37012
  elicitId: pendingRecord.elicitId,
@@ -38167,7 +38399,7 @@ var init_job_instance = __esm({
38167
38399
  this.name = record.metadata.id || record.metadata.name;
38168
38400
  this.fullName = this.owner.id + ":" + this.name;
38169
38401
  this.scope = this._providers.getActiveScope();
38170
- this.hooks = this.scope.providers.getHooksRegistry();
38402
+ this.hooks = this.scope.hooks;
38171
38403
  this.inputSchema = record.metadata.inputSchema ?? {};
38172
38404
  this.outputSchema = record.metadata.outputSchema ?? {};
38173
38405
  this.ready = this.initialize();
@@ -38553,7 +38785,7 @@ var init_workflow_instance = __esm({
38553
38785
  this.name = record.metadata.id || record.metadata.name;
38554
38786
  this.fullName = this.owner.id + ":" + this.name;
38555
38787
  this.scope = this._providers.getActiveScope();
38556
- this.hooks = this.scope.providers.getHooksRegistry();
38788
+ this.hooks = this.scope.hooks;
38557
38789
  this.ready = this.initialize();
38558
38790
  }
38559
38791
  async initialize() {
@@ -40211,13 +40443,12 @@ var init_scope_instance = __esm({
40211
40443
  init_plugin_registry();
40212
40444
  init_elicitation2();
40213
40445
  init_flows2();
40214
- init_elicitation_error();
40215
40446
  init_send_elicitation_result_tool();
40216
40447
  init_tool_utils();
40217
40448
  init_tool_instance();
40218
40449
  init_event_stores();
40219
40450
  init_job_scope_helper();
40220
- Scope = class _Scope extends ScopeEntry2 {
40451
+ Scope = class _Scope extends ScopeEntry3 {
40221
40452
  id;
40222
40453
  globalProviders;
40223
40454
  logger;
@@ -40626,7 +40857,7 @@ var init_scope_instance = __esm({
40626
40857
  {
40627
40858
  scope: ProviderScope2.GLOBAL,
40628
40859
  name: "ScopeEntry",
40629
- provide: ScopeEntry2,
40860
+ provide: ScopeEntry3,
40630
40861
  useValue: this
40631
40862
  },
40632
40863
  {
@@ -40723,9 +40954,6 @@ var init_scope_instance = __esm({
40723
40954
  * @see createElicitationStore for factory implementation details
40724
40955
  */
40725
40956
  get elicitationStore() {
40726
- if (!this._elicitationStore) {
40727
- throw new ElicitationStoreNotInitializedError();
40728
- }
40729
40957
  return this._elicitationStore;
40730
40958
  }
40731
40959
  /**
@@ -42583,7 +42811,13 @@ var init_front_mcp = __esm({
42583
42811
  return this.scopes.getScopes();
42584
42812
  }
42585
42813
  static async bootstrap(options) {
42586
- const frontMcp = new _FrontMcpInstance2(options);
42814
+ const parsedConfig = frontMcpMetadataSchema.parse(options);
42815
+ const daemonSocket = process.env["FRONTMCP_DAEMON_SOCKET"];
42816
+ if (daemonSocket) {
42817
+ await _FrontMcpInstance2.runUnixSocket({ ...parsedConfig, socketPath: daemonSocket });
42818
+ return;
42819
+ }
42820
+ const frontMcp = new _FrontMcpInstance2(parsedConfig);
42587
42821
  await frontMcp.ready;
42588
42822
  await frontMcp.start();
42589
42823
  frontMcp.log?.info("FrontMCP bootstrap complete");
@@ -43651,7 +43885,7 @@ var init_front_mcp_interface = __esm({
43651
43885
 
43652
43886
  // libs/sdk/src/common/interfaces/server.interface.ts
43653
43887
  import { IncomingMessage, HttpServerResponse } from "@frontmcp/protocol";
43654
- var ServerRequest11, ServerResponse3, FrontMcpServer;
43888
+ var ServerRequest11, ServerResponse4, FrontMcpServer;
43655
43889
  var init_server_interface = __esm({
43656
43890
  "libs/sdk/src/common/interfaces/server.interface.ts"() {
43657
43891
  "use strict";
@@ -43661,7 +43895,7 @@ var init_server_interface = __esm({
43661
43895
  body;
43662
43896
  authSession;
43663
43897
  };
43664
- ServerResponse3 = class extends HttpServerResponse {
43898
+ ServerResponse4 = class extends HttpServerResponse {
43665
43899
  };
43666
43900
  FrontMcpServer = class {
43667
43901
  };
@@ -45606,13 +45840,13 @@ var init_dynamic = __esm({
45606
45840
  });
45607
45841
 
45608
45842
  // libs/sdk/src/common/entries/scope.entry.ts
45609
- var ScopeEntry2;
45843
+ var ScopeEntry3;
45610
45844
  var init_scope_entry = __esm({
45611
45845
  "libs/sdk/src/common/entries/scope.entry.ts"() {
45612
45846
  "use strict";
45613
45847
  init_base_entry();
45614
45848
  init_utils2();
45615
- ScopeEntry2 = class extends BaseEntry {
45849
+ ScopeEntry3 = class extends BaseEntry {
45616
45850
  get fullPath() {
45617
45851
  const prefix = normalizeEntryPrefix(this.entryPath ?? "");
45618
45852
  const scope = normalizeScopeBase(this.routeBase ?? "");
@@ -46859,12 +47093,12 @@ export {
46859
47093
  ResourceTemplateKind,
46860
47094
  ScopeConfigurationError,
46861
47095
  ScopeDeniedError,
46862
- ScopeEntry2 as ScopeEntry,
47096
+ ScopeEntry3 as ScopeEntry,
46863
47097
  ScopeKind,
46864
47098
  ServerNotFoundError,
46865
47099
  ServerRequest11 as ServerRequest,
46866
47100
  ServerRequestTokens,
46867
- ServerResponse3 as ServerResponse,
47101
+ ServerResponse4 as ServerResponse,
46868
47102
  ServerlessHandlerNotInitializedError,
46869
47103
  SessionHookStage,
46870
47104
  SessionIdEmptyError,
@@ -46897,6 +47131,7 @@ export {
46897
47131
  TransportAlreadyStartedError,
46898
47132
  TransportBusRequiredError,
46899
47133
  TransportNotConnectedError,
47134
+ TransportServiceNotAvailableError,
46900
47135
  UnauthorizedError,
46901
47136
  UnsupportedClientVersionError,
46902
47137
  UnsupportedContentTypeError,