@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/index.js CHANGED
@@ -4085,7 +4085,7 @@ var init_provider_errors = __esm({
4085
4085
  });
4086
4086
 
4087
4087
  // libs/sdk/src/errors/transport.errors.ts
4088
- var MethodNotImplementedError, UnsupportedTransportTypeError, TransportBusRequiredError, InvalidTransportSessionError, TransportNotConnectedError, TransportAlreadyStartedError, UnsupportedContentTypeError;
4088
+ var MethodNotImplementedError, UnsupportedTransportTypeError, TransportBusRequiredError, InvalidTransportSessionError, TransportNotConnectedError, TransportAlreadyStartedError, UnsupportedContentTypeError, TransportServiceNotAvailableError;
4089
4089
  var init_transport_errors = __esm({
4090
4090
  "libs/sdk/src/errors/transport.errors.ts"() {
4091
4091
  "use strict";
@@ -4128,6 +4128,11 @@ var init_transport_errors = __esm({
4128
4128
  this.contentType = contentType2;
4129
4129
  }
4130
4130
  };
4131
+ TransportServiceNotAvailableError = class extends InternalMcpError {
4132
+ constructor() {
4133
+ super("Transport service not available", "TRANSPORT_SERVICE_NOT_AVAILABLE");
4134
+ }
4135
+ };
4131
4136
  }
4132
4137
  });
4133
4138
 
@@ -4533,6 +4538,7 @@ __export(errors_exports, {
4533
4538
  TransportAlreadyStartedError: () => TransportAlreadyStartedError,
4534
4539
  TransportBusRequiredError: () => TransportBusRequiredError,
4535
4540
  TransportNotConnectedError: () => TransportNotConnectedError,
4541
+ TransportServiceNotAvailableError: () => TransportServiceNotAvailableError,
4536
4542
  UnauthorizedError: () => UnauthorizedError,
4537
4543
  UnsupportedClientVersionError: () => UnsupportedClientVersionError,
4538
4544
  UnsupportedContentTypeError: () => UnsupportedContentTypeError,
@@ -7688,8 +7694,9 @@ var init_notification_service = __esm({
7688
7694
  emergency: 7
7689
7695
  };
7690
7696
  NotificationService = class _NotificationService {
7691
- constructor(scope) {
7697
+ constructor(scope, options = {}) {
7692
7698
  this.scope = scope;
7699
+ this.options = options;
7693
7700
  this.logger = scope.logger.child("NotificationService");
7694
7701
  }
7695
7702
  logger;
@@ -7706,6 +7713,9 @@ var init_notification_service = __esm({
7706
7713
  terminatedSessions = /* @__PURE__ */ new Set();
7707
7714
  /** Maximum number of terminated sessions to track before eviction */
7708
7715
  static MAX_TERMINATED_SESSIONS = 1e4;
7716
+ get maxTerminatedSessions() {
7717
+ return this.options.maxTerminatedSessions ?? _NotificationService.MAX_TERMINATED_SESSIONS;
7718
+ }
7709
7719
  /**
7710
7720
  * Initialize the notification service and subscribe to registry changes.
7711
7721
  * Called after all registries are ready.
@@ -7787,7 +7797,7 @@ var init_notification_service = __esm({
7787
7797
  const wasRegistered = this.unregisterServer(sessionId);
7788
7798
  this.scope.providers.cleanupSession(sessionId);
7789
7799
  this.logger.verbose(`Cleaned up provider cache for terminated session: ${sessionId.slice(0, 20)}...`);
7790
- if (this.terminatedSessions.size >= _NotificationService.MAX_TERMINATED_SESSIONS) {
7800
+ if (this.terminatedSessions.size >= this.maxTerminatedSessions) {
7791
7801
  const oldest = this.terminatedSessions.values().next().value;
7792
7802
  if (oldest) {
7793
7803
  this.terminatedSessions.delete(oldest);
@@ -8471,7 +8481,14 @@ async function handleWaitingFallback(deps, error) {
8471
8481
  );
8472
8482
  }
8473
8483
  }, ttl);
8474
- scope.elicitationStore.subscribeFallbackResult(
8484
+ const store = scope.elicitationStore;
8485
+ if (!store) {
8486
+ resolved = true;
8487
+ clearTimeout(timeoutHandle);
8488
+ reject(new ElicitationStoreNotInitializedError());
8489
+ return;
8490
+ }
8491
+ store.subscribeFallbackResult(
8475
8492
  error.elicitId,
8476
8493
  (result) => {
8477
8494
  if (!resolved) {
@@ -8552,7 +8569,7 @@ var init_tool_instance = __esm({
8552
8569
  this.name = record.metadata.id || record.metadata.name;
8553
8570
  this.fullName = this.owner.id + ":" + this.name;
8554
8571
  this.scope = this._providers.getActiveScope();
8555
- this.hooks = this.scope.providers.getHooksRegistry();
8572
+ this.hooks = this.scope.hooks;
8556
8573
  this.inputSchema = record.metadata.inputSchema ?? {};
8557
8574
  const meta = record.metadata;
8558
8575
  this.rawInputSchema = meta["rawInputSchema"];
@@ -9167,8 +9184,7 @@ var init_tools_list_flow = __esm({
9167
9184
  );
9168
9185
  }
9169
9186
  const sessionId = authInfo.sessionId;
9170
- const scope = this.scope;
9171
- const platformType = authInfo.sessionIdPayload?.platformType ?? (sessionId ? scope.notifications?.getPlatformType(sessionId) : void 0) ?? "unknown";
9187
+ const platformType = authInfo.sessionIdPayload?.platformType ?? (sessionId ? this.scope.notifications?.getPlatformType(sessionId) : void 0) ?? "unknown";
9172
9188
  this.logger.verbose(`parseInput: detected platform=${platformType}`);
9173
9189
  const cursor = params?.cursor;
9174
9190
  if (cursor) this.logger.verbose(`parseInput: cursor=${cursor}`);
@@ -9275,8 +9291,7 @@ var init_tools_list_flow = __esm({
9275
9291
  try {
9276
9292
  const allResolved = this.state.required.resolvedTools;
9277
9293
  const platformType = this.state.platformType ?? "unknown";
9278
- const scope = this.scope;
9279
- const paginationConfig = scope.pagination?.tools;
9294
+ const paginationConfig = this.scope.metadata.pagination?.tools;
9280
9295
  const usePagination = this.shouldPaginate(allResolved.length, paginationConfig);
9281
9296
  const sortedResolved = [...allResolved].sort((a, b) => a.finalName.localeCompare(b.finalName));
9282
9297
  let resolved = sortedResolved;
@@ -9336,12 +9351,12 @@ var init_tools_list_flow = __esm({
9336
9351
  this.logger.warn(`parseTools: toolUI not available in scope for ${finalName}`);
9337
9352
  return item;
9338
9353
  }
9339
- const scope2 = this.scope;
9354
+ const scope = this.scope;
9340
9355
  let manifest;
9341
9356
  let detectedType;
9342
9357
  try {
9343
- manifest = scope2.toolUI.getManifest(finalName);
9344
- detectedType = scope2.toolUI.detectUIType(uiConfig.template);
9358
+ manifest = scope.toolUI.getManifest(finalName);
9359
+ detectedType = scope.toolUI.detectUIType(uiConfig.template);
9345
9360
  } catch (error) {
9346
9361
  this.logger.warn(`parseTools: failed to access toolUI for ${finalName}`, error);
9347
9362
  return item;
@@ -9858,8 +9873,11 @@ var init_call_tool_flow = __esm({
9858
9873
  const authInfo = this.state.authInfo;
9859
9874
  const authInfoWithTransport = authInfo;
9860
9875
  const sessionId = authInfo?.sessionId ?? "anonymous";
9861
- const scope = this.scope;
9862
- await scope.elicitationStore.setPendingFallback({
9876
+ const store = this.scope.elicitationStore;
9877
+ if (!store) {
9878
+ throw new InternalMcpError("Elicitation store not initialized");
9879
+ }
9880
+ await store.setPendingFallback({
9863
9881
  elicitId: error.elicitId,
9864
9882
  sessionId,
9865
9883
  toolName: error.toolName,
@@ -9870,11 +9888,11 @@ var init_call_tool_flow = __esm({
9870
9888
  expiresAt: Date.now() + error.ttl
9871
9889
  });
9872
9890
  const transportType = authInfoWithTransport?.transport?.type;
9873
- if (transportType === "streamable-http" && canDeliverNotifications(scope, sessionId)) {
9891
+ if (transportType === "streamable-http" && canDeliverNotifications(this.scope, sessionId)) {
9874
9892
  this.logger.info("execute: using waiting fallback for streamable-http", {
9875
9893
  elicitId: error.elicitId
9876
9894
  });
9877
- const deps = { scope, sessionId, logger: this.logger };
9895
+ const deps = { scope: this.scope, sessionId, logger: this.logger };
9878
9896
  const result = await handleWaitingFallback(deps, error);
9879
9897
  toolContext.output = result;
9880
9898
  this.logger.verbose("execute:done (elicitation waiting fallback)");
@@ -9984,6 +10002,10 @@ ${JSON.stringify(error.schema, null, 2)}
9984
10002
  const useStructuredContent = resolvedMode.useStructuredContent;
9985
10003
  let htmlContent;
9986
10004
  let uiMeta = {};
10005
+ if (!scope.toolUI) {
10006
+ this.logger.verbose("applyUI: toolUI not available, skipping UI rendering");
10007
+ return;
10008
+ }
9987
10009
  if (servingMode === "static") {
9988
10010
  this.logger.verbose("applyUI: UI using static mode (structured data only)", {
9989
10011
  tool: tool.metadata.name,
@@ -10201,8 +10223,8 @@ var init_send_elicitation_result_tool = __esm({
10201
10223
  async execute(input) {
10202
10224
  const { elicitId, action, content } = input;
10203
10225
  this.logger.info("sendElicitationResult: processing", { elicitId, action });
10204
- const scope = this.scope;
10205
- if (!scope?.elicitationStore) {
10226
+ const store = this.scope.elicitationStore;
10227
+ if (!store) {
10206
10228
  this.logger.error("sendElicitationResult: scope or elicitationStore not available");
10207
10229
  return {
10208
10230
  content: [
@@ -10214,7 +10236,7 @@ var init_send_elicitation_result_tool = __esm({
10214
10236
  isError: true
10215
10237
  };
10216
10238
  }
10217
- const pending = await scope.elicitationStore.getPendingFallback(elicitId);
10239
+ const pending = await store.getPendingFallback(elicitId);
10218
10240
  if (!pending) {
10219
10241
  this.logger.warn("sendElicitationResult: no pending elicitation found", { elicitId });
10220
10242
  return {
@@ -10228,7 +10250,7 @@ var init_send_elicitation_result_tool = __esm({
10228
10250
  };
10229
10251
  }
10230
10252
  if (Date.now() > pending.expiresAt) {
10231
- await scope.elicitationStore.deletePendingFallback(elicitId);
10253
+ await store.deletePendingFallback(elicitId);
10232
10254
  this.logger.warn("sendElicitationResult: elicitation expired", { elicitId });
10233
10255
  return {
10234
10256
  content: [
@@ -10244,8 +10266,8 @@ var init_send_elicitation_result_tool = __esm({
10244
10266
  status: action,
10245
10267
  ...action === "accept" && content !== void 0 && { content }
10246
10268
  };
10247
- await scope.elicitationStore.setResolvedResult(elicitId, elicitResult, pending.sessionId);
10248
- await scope.elicitationStore.deletePendingFallback(elicitId);
10269
+ await store.setResolvedResult(elicitId, elicitResult, pending.sessionId);
10270
+ await store.deletePendingFallback(elicitId);
10249
10271
  this.logger.info("sendElicitationResult: re-invoking original tool", {
10250
10272
  elicitId,
10251
10273
  toolName: pending.toolName
@@ -10255,7 +10277,7 @@ var init_send_elicitation_result_tool = __esm({
10255
10277
  ctx.setPreResolvedElicitResult(elicitResult);
10256
10278
  }
10257
10279
  try {
10258
- const toolResult = await scope.runFlowForOutput("tools:call-tool", {
10280
+ const toolResult = await this.scope.runFlowForOutput("tools:call-tool", {
10259
10281
  request: {
10260
10282
  method: "tools/call",
10261
10283
  params: {
@@ -10270,19 +10292,19 @@ var init_send_elicitation_result_tool = __esm({
10270
10292
  elicitId,
10271
10293
  toolName: pending.toolName
10272
10294
  });
10273
- await scope.elicitationStore.publishFallbackResult(elicitId, pending.sessionId, {
10295
+ await store.publishFallbackResult(elicitId, pending.sessionId, {
10274
10296
  success: true,
10275
10297
  result: toolResult
10276
10298
  });
10277
- await scope.elicitationStore.deleteResolvedResult(elicitId);
10299
+ await store.deleteResolvedResult(elicitId);
10278
10300
  return toolResult;
10279
10301
  } catch (error) {
10280
10302
  const errorMessage = error instanceof Error ? error.message : String(error);
10281
- await scope.elicitationStore.publishFallbackResult(elicitId, pending.sessionId, {
10303
+ await store.publishFallbackResult(elicitId, pending.sessionId, {
10282
10304
  success: false,
10283
10305
  error: errorMessage
10284
10306
  });
10285
- await scope.elicitationStore.deleteResolvedResult(elicitId);
10307
+ await store.deleteResolvedResult(elicitId);
10286
10308
  this.logger.error("sendElicitationResult: original tool failed", {
10287
10309
  elicitId,
10288
10310
  toolName: pending.toolName,
@@ -10984,7 +11006,7 @@ var init_resource_instance = __esm({
10984
11006
  this.name = record.metadata.name;
10985
11007
  this.fullName = this.owner.id + ":" + this.name;
10986
11008
  this.scope = this.providers.getActiveScope();
10987
- this.hooks = this.scope.providers.getHooksRegistry();
11009
+ this.hooks = this.scope.hooks;
10988
11010
  this.isTemplate = "uriTemplate" in record.metadata;
10989
11011
  if (this.isTemplate) {
10990
11012
  const templateMetadata = record.metadata;
@@ -11239,11 +11261,14 @@ var init_read_resource_flow = __esm({
11239
11261
  this.logger.info(`findResource: looking for resource with URI "${uri}"`);
11240
11262
  if (isUIResourceUri(uri)) {
11241
11263
  this.logger.info(`findResource: detected UI resource URI "${uri}"`);
11242
- const scope = this.scope;
11243
11264
  const { sessionId, authInfo } = this.state;
11244
- const platformType = authInfo?.sessionIdPayload?.platformType ?? (sessionId ? scope.notifications.getPlatformType(sessionId) : void 0);
11265
+ const platformType = authInfo?.sessionIdPayload?.platformType ?? (sessionId ? this.scope.notifications.getPlatformType(sessionId) : void 0);
11245
11266
  this.logger.verbose(`findResource: platform type for session: ${platformType ?? "unknown"}`);
11246
- const uiResult = handleUIResourceRead(uri, scope.toolUI, platformType);
11267
+ if (!this.scope.toolUI) {
11268
+ this.logger.verbose("findResource: toolUI not available, skipping UI resource handling");
11269
+ throw new ResourceNotFoundError(uri);
11270
+ }
11271
+ const uiResult = handleUIResourceRead(uri, this.scope.toolUI, platformType);
11247
11272
  if (uiResult.handled) {
11248
11273
  if (uiResult.error) {
11249
11274
  this.logger.warn(`findResource: UI resource error - ${uiResult.error}`);
@@ -12719,7 +12744,7 @@ var init_prompt_instance = __esm({
12719
12744
  this.name = record.metadata.name;
12720
12745
  this.fullName = this.owner.id + ":" + this.name;
12721
12746
  this.scope = this._providers.getActiveScope();
12722
- this.hooks = this.scope.providers.getHooksRegistry();
12747
+ this.hooks = this.scope.hooks;
12723
12748
  this.ready = this.initialize();
12724
12749
  }
12725
12750
  async initialize() {
@@ -18311,7 +18336,7 @@ var init_flow_instance = __esm({
18311
18336
  this.FlowClass = this.record.provide;
18312
18337
  this.ready = this.initialize();
18313
18338
  this.plan = this.record.metadata.plan;
18314
- this.hooks = scope.providers.getHooksRegistry();
18339
+ this.hooks = scope.hooks;
18315
18340
  this.logger = scope.logger.child("FlowInstance");
18316
18341
  }
18317
18342
  async initialize() {
@@ -18679,8 +18704,8 @@ var init_flow_registry = __esm({
18679
18704
  const rec = this.defs.get(token);
18680
18705
  const deps = rec.metadata.dependsOn ?? [];
18681
18706
  for (const d of deps) {
18682
- if (d == ScopeEntry2) {
18683
- this.graph.get(token).add(ScopeEntry2);
18707
+ if (d == ScopeEntry3) {
18708
+ this.graph.get(token).add(ScopeEntry3);
18684
18709
  } else {
18685
18710
  if (!this.providers.get(d)) {
18686
18711
  throw new RegistryDependencyNotRegisteredError("Flow", (0, import_di22.tokenName)(token), (0, import_di22.tokenName)(d));
@@ -19001,7 +19026,7 @@ var init_agent_scope = __esm({
19001
19026
  {
19002
19027
  scope: import_di23.ProviderScope.GLOBAL,
19003
19028
  name: "ScopeEntry",
19004
- provide: ScopeEntry2,
19029
+ provide: ScopeEntry3,
19005
19030
  useValue: agentScopeEntry
19006
19031
  },
19007
19032
  // Also register as Scope so getActiveScope() returns the agent's scope
@@ -19112,6 +19137,12 @@ var init_agent_scope = __esm({
19112
19137
  get toolUI() {
19113
19138
  return this.parentScope.toolUI;
19114
19139
  }
19140
+ get skills() {
19141
+ return this.parentScope.skills;
19142
+ }
19143
+ get scopeMetadata() {
19144
+ return this.parentScope.metadata;
19145
+ }
19115
19146
  // ============================================================================
19116
19147
  // Flow Execution
19117
19148
  // ============================================================================
@@ -19170,18 +19201,42 @@ var init_agent_scope = __esm({
19170
19201
  get agents() {
19171
19202
  return this.agentScope.agents;
19172
19203
  }
19204
+ get skills() {
19205
+ return this.agentScope.skills;
19206
+ }
19173
19207
  get notifications() {
19174
19208
  return this.agentScope.notifications;
19175
19209
  }
19176
19210
  get toolUI() {
19177
19211
  return this.agentScope.toolUI;
19178
19212
  }
19213
+ get transportService() {
19214
+ return void 0;
19215
+ }
19216
+ get rateLimitManager() {
19217
+ return void 0;
19218
+ }
19219
+ get elicitationStore() {
19220
+ return void 0;
19221
+ }
19222
+ get metadata() {
19223
+ return this.agentScope.scopeMetadata;
19224
+ }
19225
+ get record() {
19226
+ return void 0;
19227
+ }
19228
+ get ready() {
19229
+ return this.agentScope.ready;
19230
+ }
19179
19231
  registryFlows(...flows) {
19180
19232
  return this.agentScope.registryFlows(...flows);
19181
19233
  }
19182
19234
  runFlow(name33, input, deps) {
19183
19235
  return this.agentScope.runFlow(name33, input, deps);
19184
19236
  }
19237
+ runFlowForOutput(name33, input, deps) {
19238
+ return this.agentScope.runFlowForOutput(name33, input, deps);
19239
+ }
19185
19240
  };
19186
19241
  }
19187
19242
  });
@@ -19229,7 +19284,7 @@ var init_agent_instance = __esm({
19229
19284
  this.id = record.metadata.id ?? record.metadata.name;
19230
19285
  this.fullName = this.owner.id + ":" + this.name;
19231
19286
  this.scope = this.providers.getActiveScope();
19232
- this.hooks = this.scope.providers.getHooksRegistry();
19287
+ this.hooks = this.scope.hooks;
19233
19288
  this.inputSchema = record.metadata.inputSchema ?? {};
19234
19289
  this.outputSchema = record.metadata.outputSchema;
19235
19290
  this.systemInstructions = record.metadata.systemInstructions;
@@ -27845,6 +27900,18 @@ var init_http_request_flow = __esm({
27845
27900
  this.respond(httpRespond.notFound("Session not found"));
27846
27901
  return;
27847
27902
  }
27903
+ const authorization = request[ServerRequestTokens.auth];
27904
+ if (authorization?.token) {
27905
+ const transportService = this.scope.transportService;
27906
+ if (transportService) {
27907
+ for (const protocol of ["streamable-http", "sse"]) {
27908
+ try {
27909
+ await transportService.destroyTransporter(protocol, authorization.token, sessionId);
27910
+ } catch {
27911
+ }
27912
+ }
27913
+ }
27914
+ }
27848
27915
  this.logger.info(`[${this.requestId}] Session terminated: ${sessionId}`);
27849
27916
  this.respond(httpRespond.noContent());
27850
27917
  } catch (error) {
@@ -28022,8 +28089,13 @@ var init_transport_remote = __esm({
28022
28089
  async destroy(_reason) {
28023
28090
  throw new MethodNotImplementedError("RemoteTransporter", "destroy");
28024
28091
  }
28092
+ get isInitialized() {
28093
+ return false;
28094
+ }
28025
28095
  markAsInitialized() {
28026
28096
  }
28097
+ resetForReinitialization() {
28098
+ }
28027
28099
  };
28028
28100
  }
28029
28101
  });
@@ -29379,12 +29451,25 @@ var init_transport_local_adapter = __esm({
29379
29451
  #requestId = 1;
29380
29452
  ready;
29381
29453
  server;
29454
+ /**
29455
+ * Whether this transport has already been initialized via the MCP initialize handshake.
29456
+ * Override in subclasses that track initialization state.
29457
+ */
29458
+ get isInitialized() {
29459
+ return false;
29460
+ }
29382
29461
  /**
29383
29462
  * Marks this transport as pre-initialized for session recreation.
29384
29463
  * Override in subclasses that need to set the MCP SDK's _initialized flag.
29385
29464
  */
29386
29465
  markAsInitialized() {
29387
29466
  }
29467
+ /**
29468
+ * Resets initialization state to allow re-initialization.
29469
+ * Override in subclasses that support session re-initialization.
29470
+ */
29471
+ resetForReinitialization() {
29472
+ }
29388
29473
  connectServer() {
29389
29474
  const { info, apps } = this.scope.metadata;
29390
29475
  const hasRemoteApps = apps?.some((app) => this.isRemoteApp(app)) ?? false;
@@ -29473,8 +29558,13 @@ var init_transport_local_adapter = __esm({
29473
29558
  }
29474
29559
  ensureAuthInfo(req, transport) {
29475
29560
  const { token, user, session } = req[ServerRequestTokens.auth];
29476
- const sessionId = session?.id ?? `fallback:${Date.now()}`;
29477
- const sessionPayload = session?.payload ?? { protocol: "streamable-http" };
29561
+ if (!session?.id) {
29562
+ throw new Error(
29563
+ "Session ID is required in ensureAuthInfo. This indicates a bug in session propagation \u2014 the session should have been set by the flow."
29564
+ );
29565
+ }
29566
+ const sessionId = session.id;
29567
+ const sessionPayload = session.payload ?? { protocol: "streamable-http" };
29478
29568
  if (this.initSessionPayload) {
29479
29569
  const init = this.initSessionPayload;
29480
29570
  if (init.supportsElicitation !== void 0 && sessionPayload.supportsElicitation === void 0) {
@@ -29509,6 +29599,17 @@ var init_transport_local_adapter = __esm({
29509
29599
  get elicitStore() {
29510
29600
  return this.scope.elicitationStore;
29511
29601
  }
29602
+ /**
29603
+ * Get the elicitation store, throwing if not initialized.
29604
+ * Use in contexts where elicitation is required (sendElicitRequest, cancelPendingElicit).
29605
+ */
29606
+ requireElicitStore() {
29607
+ const store = this.elicitStore;
29608
+ if (!store) {
29609
+ throw new Error("Elicitation store not initialized");
29610
+ }
29611
+ return store;
29612
+ }
29512
29613
  /**
29513
29614
  * Cancel any pending elicitation request.
29514
29615
  * Called before sending a new elicit to enforce single-elicit-per-session.
@@ -29526,9 +29627,12 @@ var init_transport_local_adapter = __esm({
29526
29627
  clearTimeout(this.pendingElicit.timeoutHandle);
29527
29628
  this.pendingElicit.resolve({ status: "cancel" });
29528
29629
  const sessionId = this.key.sessionId;
29529
- const pending = await this.elicitStore.getPending(sessionId);
29530
- if (pending) {
29531
- await this.elicitStore.publishResult(pending.elicitId, sessionId, { status: "cancel" });
29630
+ const store = this.elicitStore;
29631
+ if (store) {
29632
+ const pending = await store.getPending(sessionId);
29633
+ if (pending) {
29634
+ await store.publishResult(pending.elicitId, sessionId, { status: "cancel" });
29635
+ }
29532
29636
  }
29533
29637
  this.pendingElicit = void 0;
29534
29638
  this.logger.info("Cancelled previous pending elicit");
@@ -30878,7 +30982,8 @@ var init_transport_sse_adapter = __esm({
30878
30982
  const elicitId = elicitationId ?? `elicit-${this.newRequestId}`;
30879
30983
  const sessionId = this.key.sessionId;
30880
30984
  const expiresAt = Date.now() + ttl;
30881
- await this.elicitStore.setPending({
30985
+ const store = this.requireElicitStore();
30986
+ await store.setPending({
30882
30987
  elicitId,
30883
30988
  sessionId,
30884
30989
  createdAt: Date.now(),
@@ -30921,10 +31026,10 @@ var init_transport_sse_adapter = __esm({
30921
31026
  settled = true;
30922
31027
  this.pendingElicit = void 0;
30923
31028
  await unsubscribe?.();
30924
- await this.elicitStore.deletePending(sessionId);
31029
+ await store.deletePending(sessionId);
30925
31030
  reject(new ElicitationTimeoutError(elicitId, ttl));
30926
31031
  }, ttl);
30927
- this.elicitStore.subscribeResult(
31032
+ store.subscribeResult(
30928
31033
  elicitId,
30929
31034
  (result) => {
30930
31035
  safeResolve(result);
@@ -30938,7 +31043,7 @@ var init_transport_sse_adapter = __esm({
30938
31043
  clearTimeout(timeoutHandle);
30939
31044
  this.pendingElicit = void 0;
30940
31045
  await unsubscribe?.();
30941
- await this.elicitStore.deletePending(sessionId);
31046
+ await store.deletePending(sessionId);
30942
31047
  reject(err);
30943
31048
  });
30944
31049
  this.pendingElicit = {
@@ -31021,6 +31126,31 @@ var init_streamable_http_transport = __esm({
31021
31126
  }
31022
31127
  this._applyInitState(webTransport, sessionId);
31023
31128
  }
31129
+ /**
31130
+ * Resets the transport's initialization state to allow re-initialization.
31131
+ *
31132
+ * This is needed when a client reconnects after terminating its session:
31133
+ * the cached transport is still marked as initialized, but the client
31134
+ * needs to re-initialize. Resetting _initialized and sessionId allows
31135
+ * the MCP SDK to process a fresh initialize request.
31136
+ *
31137
+ * This is the inverse of setInitializationState().
31138
+ */
31139
+ resetForReinitialization() {
31140
+ const webTransport = this._webStandardTransport;
31141
+ if (!webTransport) {
31142
+ this._pendingInitState = void 0;
31143
+ return;
31144
+ }
31145
+ if (!("_initialized" in webTransport)) {
31146
+ throw new InvalidTransportSessionError(
31147
+ "[RecreateableStreamableHTTPServerTransport] Expected _initialized field not found on internal transport. This may indicate an incompatible MCP SDK version."
31148
+ );
31149
+ }
31150
+ webTransport._initialized = false;
31151
+ webTransport.sessionId = void 0;
31152
+ this._pendingInitState = void 0;
31153
+ }
31024
31154
  /**
31025
31155
  * Applies initialization state to the internal transport.
31026
31156
  * @param webTransport - The internal _webStandardTransport object
@@ -31180,6 +31310,7 @@ var init_transport_streamable_http_adapter = __esm({
31180
31310
  */
31181
31311
  async sendElicitRequest(relatedRequestId, message, requestedSchema, options) {
31182
31312
  await this.cancelPendingElicit();
31313
+ const store = this.requireElicitStore();
31183
31314
  const sessionId = this.key.sessionId;
31184
31315
  const flowOutput = await this.scope.runFlowForOutput("elicitation:request", {
31185
31316
  relatedRequestId,
@@ -31204,7 +31335,7 @@ var init_transport_streamable_http_adapter = __esm({
31204
31335
  } catch (error) {
31205
31336
  this.logger.error("[StreamableHttpAdapter] sendElicitRequest: transport.send() failed", error);
31206
31337
  try {
31207
- await this.elicitStore.deletePending(sessionId);
31338
+ await store.deletePending(sessionId);
31208
31339
  this.logger.verbose("[StreamableHttpAdapter] sendElicitRequest: cleaned up pending record after send failure");
31209
31340
  } catch (cleanupError) {
31210
31341
  this.logger.warn("[StreamableHttpAdapter] sendElicitRequest: failed to clean up pending record", cleanupError);
@@ -31236,10 +31367,10 @@ var init_transport_streamable_http_adapter = __esm({
31236
31367
  settled = true;
31237
31368
  this.pendingElicit = void 0;
31238
31369
  await unsubscribe?.();
31239
- await this.elicitStore.deletePending(sessionId);
31370
+ await store.deletePending(sessionId);
31240
31371
  reject(new ElicitationTimeoutError(elicitId, ttl));
31241
31372
  }, ttl);
31242
- this.elicitStore.subscribeResult(
31373
+ store.subscribeResult(
31243
31374
  elicitId,
31244
31375
  (result) => {
31245
31376
  safeResolve(result);
@@ -31253,7 +31384,7 @@ var init_transport_streamable_http_adapter = __esm({
31253
31384
  clearTimeout(timeoutHandle);
31254
31385
  this.pendingElicit = void 0;
31255
31386
  await unsubscribe?.();
31256
- await this.elicitStore.deletePending(sessionId);
31387
+ await store.deletePending(sessionId);
31257
31388
  reject(err);
31258
31389
  });
31259
31390
  this.pendingElicit = {
@@ -31264,6 +31395,20 @@ var init_transport_streamable_http_adapter = __esm({
31264
31395
  };
31265
31396
  });
31266
31397
  }
31398
+ get isInitialized() {
31399
+ return this.transport.isInitialized || this.transport.hasPendingInitState;
31400
+ }
31401
+ /**
31402
+ * Resets the transport's initialization state to allow re-initialization.
31403
+ * Used when a client retries initialize on an already-initialized session
31404
+ * (e.g., after reconnect following session termination).
31405
+ */
31406
+ resetForReinitialization() {
31407
+ this.transport.resetForReinitialization();
31408
+ this.logger.info("[StreamableHttpAdapter] Reset transport for re-initialization", {
31409
+ sessionId: this.key.sessionId?.slice(0, 20)
31410
+ });
31411
+ }
31267
31412
  /**
31268
31413
  * Marks this transport as pre-initialized for session recreation.
31269
31414
  * This is needed when recreating a transport from Redis because the
@@ -31338,6 +31483,9 @@ var init_transport_local = __esm({
31338
31483
  res.status(500).json(rpcError("Internal error"));
31339
31484
  }
31340
31485
  }
31486
+ get isInitialized() {
31487
+ return this.adapter.isInitialized;
31488
+ }
31341
31489
  /**
31342
31490
  * Marks this transport as pre-initialized for session recreation.
31343
31491
  * This is needed when recreating a transport from Redis because the
@@ -31346,6 +31494,9 @@ var init_transport_local = __esm({
31346
31494
  markAsInitialized() {
31347
31495
  this.adapter.markAsInitialized();
31348
31496
  }
31497
+ resetForReinitialization() {
31498
+ this.adapter.resetForReinitialization();
31499
+ }
31349
31500
  async destroy(reason) {
31350
31501
  try {
31351
31502
  await this.adapter.destroy(reason);
@@ -31730,6 +31881,79 @@ var init_ext_apps2 = __esm({
31730
31881
  });
31731
31882
 
31732
31883
  // libs/sdk/src/transport/flows/handle.streamable-http.flow.ts
31884
+ function resolveStreamableHttpSession(params) {
31885
+ const { rawHeader, authorizationSession, createSession } = params;
31886
+ const rawMcpSessionHeader = typeof rawHeader === "string" ? rawHeader : void 0;
31887
+ const mcpSessionHeader = validateMcpSessionHeader(rawMcpSessionHeader);
31888
+ if (rawHeader !== void 0 && !mcpSessionHeader) {
31889
+ return { responded404: true, createdNew: false };
31890
+ }
31891
+ if (mcpSessionHeader) {
31892
+ if (authorizationSession?.id === mcpSessionHeader) {
31893
+ return { session: authorizationSession, createdNew: false, responded404: false };
31894
+ }
31895
+ return { session: { id: mcpSessionHeader }, createdNew: false, responded404: false };
31896
+ }
31897
+ if (authorizationSession) {
31898
+ return { session: authorizationSession, createdNew: false, responded404: false };
31899
+ }
31900
+ return { session: createSession(), createdNew: true, responded404: false };
31901
+ }
31902
+ function classifyStreamableHttpRequest(params) {
31903
+ const { method, body } = params;
31904
+ if (method.toUpperCase() === "GET") {
31905
+ return { requestType: "sseListener" };
31906
+ }
31907
+ const jsonRpcMethod = body?.method;
31908
+ if (jsonRpcMethod === "initialize") {
31909
+ return { requestType: "initialize" };
31910
+ }
31911
+ if (typeof jsonRpcMethod === "string" && jsonRpcMethod.startsWith("ui/")) {
31912
+ return { requestType: "extApps" };
31913
+ }
31914
+ if (import_protocol38.ElicitResultSchema.safeParse(body?.result).success) {
31915
+ return { requestType: "elicitResult" };
31916
+ }
31917
+ if (jsonRpcMethod && import_protocol38.RequestSchema.safeParse(body).success) {
31918
+ return { requestType: "message" };
31919
+ }
31920
+ return { error: "Invalid Request" };
31921
+ }
31922
+ function syncStreamableHttpAuthorizationSession(authorization, session) {
31923
+ if (!authorization.session) {
31924
+ authorization.session = session;
31925
+ }
31926
+ }
31927
+ async function lookupStreamableHttpTransport(params) {
31928
+ const { transportService, token, sessionId, response } = params;
31929
+ const inMemoryTransport = await transportService.getTransporter("streamable-http", token, sessionId);
31930
+ if (inMemoryTransport) {
31931
+ return { kind: "transport", source: "memory", transport: inMemoryTransport };
31932
+ }
31933
+ let recreationError;
31934
+ try {
31935
+ const storedSession = await transportService.getStoredSession("streamable-http", token, sessionId);
31936
+ if (storedSession) {
31937
+ const recreatedTransport = await transportService.recreateTransporter(
31938
+ "streamable-http",
31939
+ token,
31940
+ sessionId,
31941
+ storedSession,
31942
+ response
31943
+ );
31944
+ if (recreatedTransport) {
31945
+ return { kind: "transport", source: "redis", transport: recreatedTransport };
31946
+ }
31947
+ }
31948
+ } catch (error) {
31949
+ recreationError = error;
31950
+ }
31951
+ const wasCreated = await transportService.wasSessionCreatedAsync("streamable-http", token, sessionId);
31952
+ if (wasCreated) {
31953
+ return { kind: "session-expired", recreationError };
31954
+ }
31955
+ return { kind: "session-not-initialized", recreationError };
31956
+ }
31733
31957
  var import_zod62, import_protocol38, plan19, stateSessionSchema, stateSchema18, name20, Stage20, HandleStreamableHttpFlow;
31734
31958
  var init_handle_streamable_http_flow = __esm({
31735
31959
  "libs/sdk/src/transport/flows/handle.streamable-http.flow.ts"() {
@@ -31773,64 +31997,60 @@ var init_handle_streamable_http_flow = __esm({
31773
31997
  const authorization = request[ServerRequestTokens.auth];
31774
31998
  const { token } = authorization;
31775
31999
  const logger = this.scopeLogger.child("handle:streamable-http:parseInput");
31776
- const raw = request.headers?.["mcp-session-id"];
31777
- const rawMcpSessionHeader = typeof raw === "string" ? raw : void 0;
31778
- const mcpSessionHeader = validateMcpSessionHeader(rawMcpSessionHeader);
31779
- if (raw !== void 0 && !mcpSessionHeader) {
32000
+ const sessionResolution = resolveStreamableHttpSession({
32001
+ rawHeader: request.headers?.["mcp-session-id"],
32002
+ authorizationSession: authorization.session,
32003
+ createSession: () => {
32004
+ const query = request.query;
32005
+ const skillsOnlyMode = detectSkillsOnlyMode(query);
32006
+ return createSessionId("streamable-http", token, {
32007
+ userAgent: request.headers?.["user-agent"],
32008
+ platformDetectionConfig: this.scope.metadata.transport?.platformDetection,
32009
+ skillsOnlyMode
32010
+ });
32011
+ }
32012
+ });
32013
+ if (sessionResolution.responded404 || !sessionResolution.session) {
31780
32014
  logger.warn("parseInput: invalid mcp-session-id header");
31781
32015
  this.respond(httpRespond.sessionNotFound("invalid session id"));
31782
32016
  return;
31783
32017
  }
31784
- let session;
31785
- if (mcpSessionHeader) {
31786
- if (authorization.session?.id === mcpSessionHeader) {
31787
- session = authorization.session;
31788
- } else {
31789
- session = { id: mcpSessionHeader };
31790
- }
31791
- } else if (authorization.session) {
31792
- session = authorization.session;
31793
- } else {
31794
- const query = request.query;
31795
- const skillsOnlyMode = detectSkillsOnlyMode(query);
31796
- session = createSessionId("streamable-http", token, {
31797
- userAgent: request.headers?.["user-agent"],
31798
- platformDetectionConfig: this.scope.metadata.transport?.platformDetection,
31799
- skillsOnlyMode
31800
- });
31801
- }
32018
+ const session = sessionResolution.session;
31802
32019
  this.state.set(stateSchema18.parse({ token, session }));
31803
32020
  logger.info("parseInput: session resolved", { sessionId: session.id?.slice(0, 20) });
31804
32021
  }
31805
32022
  async router() {
31806
32023
  const { request } = this.rawInput;
31807
32024
  const logger = this.scopeLogger.child("handle:streamable-http:router");
31808
- if (request.method.toUpperCase() === "GET") {
31809
- this.state.set("requestType", "sseListener");
31810
- logger.info("router: requestType=sseListener, method=GET");
32025
+ const classification = classifyStreamableHttpRequest({
32026
+ method: request.method,
32027
+ body: request.body
32028
+ });
32029
+ if ("error" in classification) {
32030
+ logger.warn("router: invalid request, no valid method");
32031
+ this.respond(httpRespond.rpcError("Invalid Request"));
31811
32032
  return;
31812
32033
  }
31813
- const body = request.body;
31814
- const method = body?.method;
31815
- if (method === "initialize") {
31816
- this.state.set("requestType", "initialize");
32034
+ this.state.set("requestType", classification.requestType);
32035
+ if (classification.requestType === "sseListener") {
32036
+ logger.info("router: requestType=sseListener, method=GET");
32037
+ } else if (classification.requestType === "initialize") {
31817
32038
  logger.info("router: requestType=initialize, method=POST");
31818
- } else if (typeof method === "string" && method.startsWith("ui/")) {
31819
- this.state.set("requestType", "extApps");
32039
+ } else if (classification.requestType === "extApps") {
32040
+ const method = request.body?.method;
31820
32041
  logger.info(`router: requestType=extApps, method=${method}`);
31821
- } else if (import_protocol38.ElicitResultSchema.safeParse(request.body?.result).success) {
31822
- this.state.set("requestType", "elicitResult");
32042
+ } else if (classification.requestType === "elicitResult") {
31823
32043
  logger.info("router: requestType=elicitResult, method=POST");
31824
- } else if (method && import_protocol38.RequestSchema.safeParse(request.body).success) {
31825
- this.state.set("requestType", "message");
31826
- logger.info(`router: requestType=message, method=${method}`);
31827
32044
  } else {
31828
- logger.warn("router: invalid request, no valid method");
31829
- this.respond(httpRespond.rpcError("Invalid Request"));
32045
+ const method = request.body?.method;
32046
+ logger.info(`router: requestType=message, method=${method}`);
31830
32047
  }
31831
32048
  }
31832
32049
  async onInitialize() {
31833
32050
  const transportService = this.scope.transportService;
32051
+ if (!transportService) {
32052
+ throw new TransportServiceNotAvailableError();
32053
+ }
31834
32054
  const logger = this.scope.logger.child("handle:streamable-http:onInitialize");
31835
32055
  const { request, response } = this.rawInput;
31836
32056
  const { token, session } = this.state.required;
@@ -31840,7 +32060,15 @@ var init_handle_streamable_http_flow = __esm({
31840
32060
  tokenPrefix: token?.slice(0, 10)
31841
32061
  });
31842
32062
  try {
32063
+ const authorization = request[ServerRequestTokens.auth];
32064
+ syncStreamableHttpAuthorizationSession(authorization, session);
31843
32065
  const transport = await transportService.createTransporter("streamable-http", token, session.id, response);
32066
+ if (transport.isInitialized) {
32067
+ logger.info("onInitialize: transport already initialized, resetting for re-initialization", {
32068
+ sessionId: session.id?.slice(0, 20)
32069
+ });
32070
+ transport.resetForReinitialization();
32071
+ }
31844
32072
  logger.info("onInitialize: transport created, calling initialize");
31845
32073
  await transport.initialize(request, response);
31846
32074
  logger.info("onInitialize: completed successfully");
@@ -31858,6 +32086,9 @@ var init_handle_streamable_http_flow = __esm({
31858
32086
  }
31859
32087
  async onElicitResult() {
31860
32088
  const transportService = this.scope.transportService;
32089
+ if (!transportService) {
32090
+ throw new TransportServiceNotAvailableError();
32091
+ }
31861
32092
  const logger = this.scopeLogger.child("handle:streamable-http:onElicitResult");
31862
32093
  const { request, response } = this.rawInput;
31863
32094
  const { token, session } = this.state.required;
@@ -31908,6 +32139,9 @@ var init_handle_streamable_http_flow = __esm({
31908
32139
  }
31909
32140
  async onMessage() {
31910
32141
  const transportService = this.scope.transportService;
32142
+ if (!transportService) {
32143
+ throw new TransportServiceNotAvailableError();
32144
+ }
31911
32145
  const logger = this.scopeLogger.child("handle:streamable-http:onMessage");
31912
32146
  const { request, response } = this.rawInput;
31913
32147
  const { token, session } = this.state.required;
@@ -31915,44 +32149,21 @@ var init_handle_streamable_http_flow = __esm({
31915
32149
  sessionId: session.id?.slice(0, 20),
31916
32150
  hasToken: !!token
31917
32151
  });
31918
- let transport = await transportService.getTransporter("streamable-http", token, session.id);
31919
- logger.verbose("onMessage: getTransporter result", { found: !!transport });
31920
- if (!transport) {
31921
- try {
31922
- logger.verbose("onMessage: transport not in memory, checking Redis", {
31923
- sessionId: session.id?.slice(0, 20)
31924
- });
31925
- const storedSession = await transportService.getStoredSession("streamable-http", token, session.id);
31926
- logger.verbose("onMessage: getStoredSession result", {
31927
- found: !!storedSession,
31928
- initialized: storedSession?.initialized
31929
- });
31930
- if (storedSession) {
31931
- logger.verbose("onMessage: recreating transport from stored session", {
31932
- sessionId: session.id?.slice(0, 20),
31933
- createdAt: storedSession.createdAt,
31934
- initialized: storedSession.initialized
31935
- });
31936
- transport = await transportService.recreateTransporter(
31937
- "streamable-http",
31938
- token,
31939
- session.id,
31940
- storedSession,
31941
- response
31942
- );
31943
- logger.verbose("onMessage: transport recreated successfully");
31944
- }
31945
- } catch (error) {
32152
+ const transportLookup = await lookupStreamableHttpTransport({
32153
+ transportService,
32154
+ token,
32155
+ sessionId: session.id,
32156
+ response
32157
+ });
32158
+ if (transportLookup.kind !== "transport") {
32159
+ const body = request.body;
32160
+ if (transportLookup.recreationError) {
31946
32161
  logger.warn("Failed to recreate transport from stored session", {
31947
32162
  sessionId: session.id?.slice(0, 20),
31948
- error: error instanceof Error ? error.message : String(error)
32163
+ error: transportLookup.recreationError instanceof Error ? transportLookup.recreationError.message : String(transportLookup.recreationError)
31949
32164
  });
31950
32165
  }
31951
- }
31952
- if (!transport) {
31953
- const wasCreated = await transportService.wasSessionCreatedAsync("streamable-http", token, session.id);
31954
- const body = request.body;
31955
- if (wasCreated) {
32166
+ if (transportLookup.kind === "session-expired") {
31956
32167
  logger.info("Session expired - client should re-initialize", {
31957
32168
  sessionId: session.id?.slice(0, 20),
31958
32169
  tokenHash: token.slice(0, 8),
@@ -31974,6 +32185,8 @@ var init_handle_streamable_http_flow = __esm({
31974
32185
  }
31975
32186
  return;
31976
32187
  }
32188
+ const transport = transportLookup.transport;
32189
+ logger.verbose("onMessage: transport resolved", { source: transportLookup.source });
31977
32190
  try {
31978
32191
  await transport.handleRequest(request, response);
31979
32192
  this.handled();
@@ -31992,6 +32205,9 @@ var init_handle_streamable_http_flow = __esm({
31992
32205
  }
31993
32206
  async onSseListener() {
31994
32207
  const transportService = this.scope.transportService;
32208
+ if (!transportService) {
32209
+ throw new TransportServiceNotAvailableError();
32210
+ }
31995
32211
  const logger = this.scopeLogger.child("handle:streamable-http:onSseListener");
31996
32212
  const { request, response } = this.rawInput;
31997
32213
  const { token, session } = this.state.required;
@@ -32029,6 +32245,9 @@ var init_handle_streamable_http_flow = __esm({
32029
32245
  }
32030
32246
  async onExtApps() {
32031
32247
  const transportService = this.scope.transportService;
32248
+ if (!transportService) {
32249
+ throw new TransportServiceNotAvailableError();
32250
+ }
32032
32251
  const logger = this.scopeLogger.child("handle:streamable-http:onExtApps");
32033
32252
  const { request, response } = this.rawInput;
32034
32253
  const { token, session } = this.state.required;
@@ -32079,8 +32298,7 @@ var init_handle_streamable_http_flow = __esm({
32079
32298
  }
32080
32299
  return;
32081
32300
  }
32082
- const scope = this.scope;
32083
- const configuredCapabilities = scope.metadata.extApps?.hostCapabilities;
32301
+ const configuredCapabilities = this.scope.metadata.extApps?.hostCapabilities;
32084
32302
  const hostCapabilities = {
32085
32303
  serverToolProxy: configuredCapabilities?.serverToolProxy ?? true,
32086
32304
  logging: configuredCapabilities?.logging ?? true,
@@ -32089,9 +32307,9 @@ var init_handle_streamable_http_flow = __esm({
32089
32307
  const handler = createExtAppsMessageHandler({
32090
32308
  context: {
32091
32309
  sessionId: session.id,
32092
- logger: scope.logger,
32310
+ logger: this.scope.logger,
32093
32311
  callTool: async (name33, args) => {
32094
- const result = await scope.runFlow("tools:call-tool", {
32312
+ const result = await this.scope.runFlow("tools:call-tool", {
32095
32313
  request: { method: "tools/call", params: { name: name33, arguments: args } },
32096
32314
  ctx: {
32097
32315
  authInfo: {
@@ -32177,6 +32395,7 @@ var init_handle_sse_flow = __esm({
32177
32395
  "use strict";
32178
32396
  init_common();
32179
32397
  import_zod63 = require("zod");
32398
+ init_errors();
32180
32399
  init_session_id_utils();
32181
32400
  init_skill_mode_utils();
32182
32401
  plan20 = {
@@ -32246,10 +32465,9 @@ var init_handle_sse_flow = __esm({
32246
32465
  }
32247
32466
  async router() {
32248
32467
  const { request } = this.rawInput;
32249
- const scope = this.scope;
32250
32468
  const requestPath = normalizeEntryPrefix(request.path);
32251
- const prefix = normalizeEntryPrefix(scope.entryPath);
32252
- const scopePath = normalizeScopeBase(scope.routeBase);
32469
+ const prefix = normalizeEntryPrefix(this.scope.entryPath);
32470
+ const scopePath = normalizeScopeBase(this.scope.routeBase);
32253
32471
  const basePath = `${prefix}${scopePath}`;
32254
32472
  if (requestPath === `${basePath}/sse`) {
32255
32473
  this.state.set("requestType", "initialize");
@@ -32259,6 +32477,9 @@ var init_handle_sse_flow = __esm({
32259
32477
  }
32260
32478
  async onInitialize() {
32261
32479
  const transportService = this.scope.transportService;
32480
+ if (!transportService) {
32481
+ throw new TransportServiceNotAvailableError();
32482
+ }
32262
32483
  const { request, response } = this.rawInput;
32263
32484
  const { token, session } = this.state.required;
32264
32485
  const transport = await transportService.createTransporter("sse", token, session.id, response);
@@ -32270,6 +32491,9 @@ var init_handle_sse_flow = __esm({
32270
32491
  }
32271
32492
  async onMessage() {
32272
32493
  const transportService = this.scope.transportService;
32494
+ if (!transportService) {
32495
+ throw new TransportServiceNotAvailableError();
32496
+ }
32273
32497
  const logger = this.scopeLogger.child("handle:legacy-sse:onMessage");
32274
32498
  const { request, response } = this.rawInput;
32275
32499
  const { token, session } = this.state.required;
@@ -32342,6 +32566,7 @@ var init_handle_stateless_http_flow = __esm({
32342
32566
  init_common();
32343
32567
  import_zod64 = require("zod");
32344
32568
  import_protocol39 = require("@frontmcp/protocol");
32569
+ init_errors();
32345
32570
  plan21 = {
32346
32571
  pre: ["parseInput", "router"],
32347
32572
  execute: ["handleRequest"],
@@ -32389,6 +32614,9 @@ var init_handle_stateless_http_flow = __esm({
32389
32614
  }
32390
32615
  async handleRequest() {
32391
32616
  const transportService = this.scope.transportService;
32617
+ if (!transportService) {
32618
+ throw new TransportServiceNotAvailableError();
32619
+ }
32392
32620
  const logger = this.scope.logger.child("HandleStatelessHttpFlow");
32393
32621
  const { request, response } = this.rawInput;
32394
32622
  const { token, isAuthenticated, requestType } = this.state;
@@ -36079,11 +36307,10 @@ var init_call_agent_flow = __esm({
36079
36307
  throw new InvalidMethodError(method, "tools/call");
36080
36308
  }
36081
36309
  const { name: toolName } = params;
36082
- const scope = this.scope;
36083
36310
  const agentId = toolName;
36084
36311
  let agent;
36085
- if (scope.agents) {
36086
- agent = scope.agents.findById(agentId) ?? scope.agents.findByName(agentId);
36312
+ if (this.scope.agents) {
36313
+ agent = this.scope.agents.findById(agentId) ?? this.scope.agents.findByName(agentId);
36087
36314
  }
36088
36315
  const agentOwnerId = agent?.owner?.id;
36089
36316
  const progressToken = params._meta?.progressToken;
@@ -36099,8 +36326,7 @@ var init_call_agent_flow = __esm({
36099
36326
  }
36100
36327
  async findAgent() {
36101
36328
  this.logger.verbose("findAgent:start");
36102
- const scope = this.scope;
36103
- const agents = scope.agents;
36329
+ const agents = this.scope.agents;
36104
36330
  if (!agents) {
36105
36331
  this.logger.warn("findAgent: no agent registry available");
36106
36332
  throw new AgentNotFoundError(this.state.required.input.name);
@@ -36521,7 +36747,10 @@ var init_elicitation_request_flow = __esm({
36521
36747
  async storePendingRecord() {
36522
36748
  this.logger.verbose("storePendingRecord:start");
36523
36749
  const { elicitId, sessionId, message, mode, expiresAt, requestedSchema } = this.state.required;
36524
- const scope = this.scope;
36750
+ const store = this.scope.elicitationStore;
36751
+ if (!store) {
36752
+ throw new ElicitationStoreNotInitializedError();
36753
+ }
36525
36754
  const pendingRecord = {
36526
36755
  elicitId,
36527
36756
  sessionId,
@@ -36531,7 +36760,7 @@ var init_elicitation_request_flow = __esm({
36531
36760
  mode,
36532
36761
  requestedSchema
36533
36762
  };
36534
- await scope.elicitationStore.setPending(pendingRecord);
36763
+ await store.setPending(pendingRecord);
36535
36764
  this.state.set("pendingRecord", pendingRecord);
36536
36765
  this.logger.verbose("storePendingRecord:done", { elicitId, sessionId });
36537
36766
  }
@@ -36658,8 +36887,11 @@ var init_elicitation_result_flow = __esm({
36658
36887
  async lookupPending() {
36659
36888
  this.logger.verbose("lookupPending:start");
36660
36889
  const { sessionId } = this.state.required;
36661
- const scope = this.scope;
36662
- const pendingRecord = await scope.elicitationStore.getPending(sessionId);
36890
+ const store = this.scope.elicitationStore;
36891
+ if (!store) {
36892
+ throw new ElicitationStoreNotInitializedError();
36893
+ }
36894
+ const pendingRecord = await store.getPending(sessionId);
36663
36895
  this.state.set("pendingRecord", pendingRecord ?? void 0);
36664
36896
  if (!pendingRecord) {
36665
36897
  this.logger.verbose("lookupPending:notFound", { sessionId });
@@ -36711,14 +36943,14 @@ var init_elicitation_result_flow = __esm({
36711
36943
  this.logger.verbose("publishResult:start");
36712
36944
  const { pendingRecord, elicitResult } = this.state;
36713
36945
  const { sessionId } = this.state.required;
36714
- const scope = this.scope;
36715
- if (!pendingRecord || !elicitResult) {
36946
+ const store = this.scope.elicitationStore;
36947
+ if (!pendingRecord || !elicitResult || !store) {
36716
36948
  this.state.set("handled", false);
36717
36949
  this.logger.verbose("publishResult:skip (no pending or no result)");
36718
36950
  return;
36719
36951
  }
36720
36952
  try {
36721
- await scope.elicitationStore.publishResult(pendingRecord.elicitId, sessionId, elicitResult);
36953
+ await store.publishResult(pendingRecord.elicitId, sessionId, elicitResult);
36722
36954
  this.state.set("handled", true);
36723
36955
  this.logger.verbose("publishResult:done", {
36724
36956
  elicitId: pendingRecord.elicitId,
@@ -38112,7 +38344,7 @@ var init_job_instance = __esm({
38112
38344
  this.name = record.metadata.id || record.metadata.name;
38113
38345
  this.fullName = this.owner.id + ":" + this.name;
38114
38346
  this.scope = this._providers.getActiveScope();
38115
- this.hooks = this.scope.providers.getHooksRegistry();
38347
+ this.hooks = this.scope.hooks;
38116
38348
  this.inputSchema = record.metadata.inputSchema ?? {};
38117
38349
  this.outputSchema = record.metadata.outputSchema ?? {};
38118
38350
  this.ready = this.initialize();
@@ -38499,7 +38731,7 @@ var init_workflow_instance = __esm({
38499
38731
  this.name = record.metadata.id || record.metadata.name;
38500
38732
  this.fullName = this.owner.id + ":" + this.name;
38501
38733
  this.scope = this._providers.getActiveScope();
38502
- this.hooks = this.scope.providers.getHooksRegistry();
38734
+ this.hooks = this.scope.hooks;
38503
38735
  this.ready = this.initialize();
38504
38736
  }
38505
38737
  async initialize() {
@@ -40156,14 +40388,13 @@ var init_scope_instance = __esm({
40156
40388
  init_plugin_registry();
40157
40389
  init_elicitation2();
40158
40390
  init_flows2();
40159
- init_elicitation_error();
40160
40391
  init_send_elicitation_result_tool();
40161
40392
  init_tool_utils();
40162
40393
  init_tool_instance();
40163
40394
  init_event_stores();
40164
40395
  init_job_scope_helper();
40165
40396
  import_guard6 = require("@frontmcp/guard");
40166
- Scope = class _Scope extends ScopeEntry2 {
40397
+ Scope = class _Scope extends ScopeEntry3 {
40167
40398
  id;
40168
40399
  globalProviders;
40169
40400
  logger;
@@ -40572,7 +40803,7 @@ var init_scope_instance = __esm({
40572
40803
  {
40573
40804
  scope: import_di4.ProviderScope.GLOBAL,
40574
40805
  name: "ScopeEntry",
40575
- provide: ScopeEntry2,
40806
+ provide: ScopeEntry3,
40576
40807
  useValue: this
40577
40808
  },
40578
40809
  {
@@ -40669,9 +40900,6 @@ var init_scope_instance = __esm({
40669
40900
  * @see createElicitationStore for factory implementation details
40670
40901
  */
40671
40902
  get elicitationStore() {
40672
- if (!this._elicitationStore) {
40673
- throw new ElicitationStoreNotInitializedError();
40674
- }
40675
40903
  return this._elicitationStore;
40676
40904
  }
40677
40905
  /**
@@ -42532,7 +42760,13 @@ var init_front_mcp = __esm({
42532
42760
  return this.scopes.getScopes();
42533
42761
  }
42534
42762
  static async bootstrap(options) {
42535
- const frontMcp = new _FrontMcpInstance2(options);
42763
+ const parsedConfig = frontMcpMetadataSchema.parse(options);
42764
+ const daemonSocket = process.env["FRONTMCP_DAEMON_SOCKET"];
42765
+ if (daemonSocket) {
42766
+ await _FrontMcpInstance2.runUnixSocket({ ...parsedConfig, socketPath: daemonSocket });
42767
+ return;
42768
+ }
42769
+ const frontMcp = new _FrontMcpInstance2(parsedConfig);
42536
42770
  await frontMcp.ready;
42537
42771
  await frontMcp.start();
42538
42772
  frontMcp.log?.info("FrontMCP bootstrap complete");
@@ -43606,7 +43840,7 @@ var init_front_mcp_interface = __esm({
43606
43840
  });
43607
43841
 
43608
43842
  // libs/sdk/src/common/interfaces/server.interface.ts
43609
- var import_protocol44, ServerRequest11, ServerResponse3, FrontMcpServer;
43843
+ var import_protocol44, ServerRequest11, ServerResponse4, FrontMcpServer;
43610
43844
  var init_server_interface = __esm({
43611
43845
  "libs/sdk/src/common/interfaces/server.interface.ts"() {
43612
43846
  "use strict";
@@ -43617,7 +43851,7 @@ var init_server_interface = __esm({
43617
43851
  body;
43618
43852
  authSession;
43619
43853
  };
43620
- ServerResponse3 = class extends import_protocol44.HttpServerResponse {
43854
+ ServerResponse4 = class extends import_protocol44.HttpServerResponse {
43621
43855
  };
43622
43856
  FrontMcpServer = class {
43623
43857
  };
@@ -45563,13 +45797,13 @@ var init_dynamic = __esm({
45563
45797
  });
45564
45798
 
45565
45799
  // libs/sdk/src/common/entries/scope.entry.ts
45566
- var ScopeEntry2;
45800
+ var ScopeEntry3;
45567
45801
  var init_scope_entry = __esm({
45568
45802
  "libs/sdk/src/common/entries/scope.entry.ts"() {
45569
45803
  "use strict";
45570
45804
  init_base_entry();
45571
45805
  init_utils2();
45572
- ScopeEntry2 = class extends BaseEntry {
45806
+ ScopeEntry3 = class extends BaseEntry {
45573
45807
  get fullPath() {
45574
45808
  const prefix = normalizeEntryPrefix(this.entryPath ?? "");
45575
45809
  const scope = normalizeScopeBase(this.routeBase ?? "");
@@ -46609,12 +46843,12 @@ __export(index_exports, {
46609
46843
  ResourceTemplateKind: () => ResourceTemplateKind,
46610
46844
  ScopeConfigurationError: () => ScopeConfigurationError,
46611
46845
  ScopeDeniedError: () => import_auth11.ScopeDeniedError,
46612
- ScopeEntry: () => ScopeEntry2,
46846
+ ScopeEntry: () => ScopeEntry3,
46613
46847
  ScopeKind: () => ScopeKind,
46614
46848
  ServerNotFoundError: () => ServerNotFoundError,
46615
46849
  ServerRequest: () => ServerRequest11,
46616
46850
  ServerRequestTokens: () => ServerRequestTokens,
46617
- ServerResponse: () => ServerResponse3,
46851
+ ServerResponse: () => ServerResponse4,
46618
46852
  ServerlessHandlerNotInitializedError: () => ServerlessHandlerNotInitializedError,
46619
46853
  SessionHookStage: () => SessionHookStage,
46620
46854
  SessionIdEmptyError: () => import_auth11.SessionIdEmptyError,
@@ -46647,6 +46881,7 @@ __export(index_exports, {
46647
46881
  TransportAlreadyStartedError: () => TransportAlreadyStartedError,
46648
46882
  TransportBusRequiredError: () => TransportBusRequiredError,
46649
46883
  TransportNotConnectedError: () => TransportNotConnectedError,
46884
+ TransportServiceNotAvailableError: () => TransportServiceNotAvailableError,
46650
46885
  UnauthorizedError: () => UnauthorizedError,
46651
46886
  UnsupportedClientVersionError: () => UnsupportedClientVersionError,
46652
46887
  UnsupportedContentTypeError: () => UnsupportedContentTypeError,
@@ -47498,6 +47733,7 @@ var AgentCallHook = FlowHooksOf("agents:call-agent");
47498
47733
  TransportAlreadyStartedError,
47499
47734
  TransportBusRequiredError,
47500
47735
  TransportNotConnectedError,
47736
+ TransportServiceNotAvailableError,
47501
47737
  UnauthorizedError,
47502
47738
  UnsupportedClientVersionError,
47503
47739
  UnsupportedContentTypeError,