@mastra/factory 0.24.0 → 0.25.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/README.md +36 -9
  2. package/dist/auth.d.ts.map +1 -1
  3. package/dist/auth.js +18 -4
  4. package/dist/auth.js.map +1 -1
  5. package/dist/boards/review.d.ts.map +1 -1
  6. package/dist/boards/review.js +3 -2
  7. package/dist/boards/review.js.map +1 -1
  8. package/dist/factory.d.ts +3 -0
  9. package/dist/factory.d.ts.map +1 -1
  10. package/dist/factory.js +61 -69
  11. package/dist/factory.js.map +1 -1
  12. package/dist/integrations/base.d.ts +14 -1
  13. package/dist/integrations/base.d.ts.map +1 -1
  14. package/dist/{session → integrations/slack}/channel-reply-processor.d.ts +4 -3
  15. package/dist/integrations/slack/channel-reply-processor.d.ts.map +1 -0
  16. package/dist/integrations/slack/channel-reply-processor.js +61 -0
  17. package/dist/integrations/slack/channel-reply-processor.js.map +1 -0
  18. package/dist/integrations/slack/channel-session-link-processor.d.ts.map +1 -0
  19. package/dist/{session → integrations/slack}/channel-session-link-processor.js +13 -4
  20. package/dist/integrations/slack/channel-session-link-processor.js.map +1 -0
  21. package/dist/integrations/slack/integration.d.ts +25 -1
  22. package/dist/integrations/slack/integration.d.ts.map +1 -1
  23. package/dist/integrations/slack/integration.js +55 -5
  24. package/dist/integrations/slack/integration.js.map +1 -1
  25. package/dist/integrations/slack/reply-reminder-processor.d.ts +23 -0
  26. package/dist/integrations/slack/reply-reminder-processor.d.ts.map +1 -0
  27. package/dist/integrations/slack/reply-reminder-processor.js +58 -0
  28. package/dist/integrations/slack/reply-reminder-processor.js.map +1 -0
  29. package/dist/integrations/slack/reply-tool.d.ts +31 -0
  30. package/dist/integrations/slack/reply-tool.d.ts.map +1 -0
  31. package/dist/integrations/slack/reply-tool.js +203 -0
  32. package/dist/integrations/slack/reply-tool.js.map +1 -0
  33. package/dist/integrations/slack/share-file-tool.d.ts +45 -0
  34. package/dist/integrations/slack/share-file-tool.d.ts.map +1 -0
  35. package/dist/integrations/slack/share-file-tool.js +106 -0
  36. package/dist/integrations/slack/share-file-tool.js.map +1 -0
  37. package/dist/integrations/slack/slack.d.ts.map +1 -1
  38. package/dist/integrations/slack/slack.js +54 -6
  39. package/dist/integrations/slack/slack.js.map +1 -1
  40. package/dist/mcp/events.d.ts +73 -0
  41. package/dist/mcp/events.d.ts.map +1 -0
  42. package/dist/mcp/events.js +158 -0
  43. package/dist/mcp/events.js.map +1 -0
  44. package/dist/mcp/routes.d.ts +0 -1
  45. package/dist/mcp/routes.d.ts.map +1 -1
  46. package/dist/mcp/routes.js +30 -3
  47. package/dist/mcp/routes.js.map +1 -1
  48. package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
  49. package/dist/platform-auth-host.d.ts.map +1 -1
  50. package/dist/platform-auth-host.js +1 -1
  51. package/dist/platform-auth-host.js.map +1 -1
  52. package/dist/routes/config.d.ts +2 -0
  53. package/dist/routes/config.d.ts.map +1 -1
  54. package/dist/routes/config.js +50 -9
  55. package/dist/routes/config.js.map +1 -1
  56. package/dist/routes/contracts.d.ts +2 -0
  57. package/dist/routes/contracts.d.ts.map +1 -1
  58. package/dist/routes/contracts.js +1 -1
  59. package/dist/routes/contracts.js.map +1 -1
  60. package/dist/routes/session-access.d.ts +7 -2
  61. package/dist/routes/session-access.d.ts.map +1 -1
  62. package/dist/routes/session-access.js +41 -4
  63. package/dist/routes/session-access.js.map +1 -1
  64. package/dist/routes/skills.d.ts.map +1 -1
  65. package/dist/routes/skills.js +4 -3
  66. package/dist/routes/skills.js.map +1 -1
  67. package/dist/routes/source-control-sessions.d.ts +2 -0
  68. package/dist/routes/source-control-sessions.d.ts.map +1 -1
  69. package/dist/routes/source-control-sessions.js +161 -24
  70. package/dist/routes/source-control-sessions.js.map +1 -1
  71. package/dist/routes/surface.d.ts +2 -0
  72. package/dist/routes/surface.d.ts.map +1 -1
  73. package/dist/routes/surface.js +10 -4
  74. package/dist/routes/surface.js.map +1 -1
  75. package/dist/rules/dispatcher.d.ts.map +1 -1
  76. package/dist/rules/dispatcher.js +11 -3
  77. package/dist/rules/dispatcher.js.map +1 -1
  78. package/dist/rules/processor.d.ts +2 -2
  79. package/dist/rules/processor.d.ts.map +1 -1
  80. package/dist/rules/processor.js +3 -3
  81. package/dist/rules/processor.js.map +1 -1
  82. package/dist/sandbox/session-retirement.d.ts +11 -0
  83. package/dist/sandbox/session-retirement.d.ts.map +1 -1
  84. package/dist/sandbox/session-retirement.js +38 -1
  85. package/dist/sandbox/session-retirement.js.map +1 -1
  86. package/dist/sandbox/session-sandbox.d.ts +2 -0
  87. package/dist/sandbox/session-sandbox.d.ts.map +1 -1
  88. package/dist/sandbox/session-sandbox.js +5 -1
  89. package/dist/sandbox/session-sandbox.js.map +1 -1
  90. package/dist/session/credential-policy.d.ts +4 -2
  91. package/dist/session/credential-policy.d.ts.map +1 -1
  92. package/dist/session/credential-policy.js +11 -1
  93. package/dist/session/credential-policy.js.map +1 -1
  94. package/dist/session/factory-session.d.ts.map +1 -1
  95. package/dist/session/factory-session.js +14 -1
  96. package/dist/session/factory-session.js.map +1 -1
  97. package/dist/session/run-audit.d.ts +1 -0
  98. package/dist/session/run-audit.d.ts.map +1 -1
  99. package/dist/session/run-audit.js +7 -2
  100. package/dist/session/run-audit.js.map +1 -1
  101. package/dist/session/session-threads.d.ts +5 -0
  102. package/dist/session/session-threads.d.ts.map +1 -1
  103. package/dist/session/session-threads.js +8 -1
  104. package/dist/session/session-threads.js.map +1 -1
  105. package/dist/session/thinking-default.d.ts +6 -13
  106. package/dist/session/thinking-default.d.ts.map +1 -1
  107. package/dist/session/thinking-default.js +18 -22
  108. package/dist/session/thinking-default.js.map +1 -1
  109. package/dist/session-owner-signal.d.ts +2 -0
  110. package/dist/session-owner-signal.d.ts.map +1 -0
  111. package/dist/session-owner-signal.js +6 -0
  112. package/dist/session-owner-signal.js.map +1 -0
  113. package/dist/skills/service.d.ts +6 -7
  114. package/dist/skills/service.d.ts.map +1 -1
  115. package/dist/skills/service.js +9 -19
  116. package/dist/skills/service.js.map +1 -1
  117. package/dist/storage/domains/audit/actions.d.ts +1 -0
  118. package/dist/storage/domains/audit/actions.d.ts.map +1 -1
  119. package/dist/storage/domains/audit/actions.js +2 -1
  120. package/dist/storage/domains/audit/actions.js.map +1 -1
  121. package/dist/storage/domains/audit/base.d.ts +18 -2
  122. package/dist/storage/domains/audit/base.d.ts.map +1 -1
  123. package/dist/storage/domains/audit/base.js +22 -4
  124. package/dist/storage/domains/audit/base.js.map +1 -1
  125. package/dist/storage/domains/model-defaults/base.d.ts +8 -0
  126. package/dist/storage/domains/model-defaults/base.d.ts.map +1 -1
  127. package/dist/storage/domains/model-defaults/base.js +18 -0
  128. package/dist/storage/domains/model-defaults/base.js.map +1 -1
  129. package/dist/storage/domains/source-control/base.d.ts +26 -1
  130. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  131. package/dist/storage/domains/source-control/base.js +69 -5
  132. package/dist/storage/domains/source-control/base.js.map +1 -1
  133. package/dist/storage/domains/source-control/inmemory.d.ts +19 -1
  134. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  135. package/dist/storage/domains/source-control/inmemory.js +30 -2
  136. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  137. package/dist/tools/permissions.d.ts.map +1 -1
  138. package/dist/tools/permissions.js +2 -1
  139. package/dist/tools/permissions.js.map +1 -1
  140. package/dist/tools/sandbox-tools.d.ts +12 -0
  141. package/dist/tools/sandbox-tools.d.ts.map +1 -0
  142. package/dist/tools/sandbox-tools.js +40 -0
  143. package/dist/tools/sandbox-tools.js.map +1 -0
  144. package/dist/tools/scope.d.ts.map +1 -1
  145. package/dist/tools/scope.js +2 -5
  146. package/dist/tools/scope.js.map +1 -1
  147. package/dist/tools/session-tools.d.ts.map +1 -1
  148. package/dist/tools/session-tools.js +6 -2
  149. package/dist/tools/session-tools.js.map +1 -1
  150. package/dist/work-item-branch.d.ts +11 -3
  151. package/dist/work-item-branch.d.ts.map +1 -1
  152. package/dist/work-item-branch.js +34 -9
  153. package/dist/work-item-branch.js.map +1 -1
  154. package/dist/workspace.d.ts +2 -1
  155. package/dist/workspace.d.ts.map +1 -1
  156. package/dist/workspace.js +4 -2
  157. package/dist/workspace.js.map +1 -1
  158. package/factory-skills/configure-factory-rules/SKILL.md +2 -2
  159. package/package.json +14 -13
  160. package/dist/session/channel-reply-processor.d.ts.map +0 -1
  161. package/dist/session/channel-reply-processor.js +0 -46
  162. package/dist/session/channel-reply-processor.js.map +0 -1
  163. package/dist/session/channel-session-link-processor.d.ts.map +0 -1
  164. package/dist/session/channel-session-link-processor.js.map +0 -1
  165. /package/dist/{session → integrations/slack}/channel-session-link-processor.d.ts +0 -0
package/dist/factory.js CHANGED
@@ -66,15 +66,13 @@ import { createFactoryTransitionTools } from "./rules/tools.js";
66
66
  import { CallbackFactorySandbox } from "./sandbox/callback-factory-sandbox.js";
67
67
  import { SessionRetirementCoordinator } from "./sandbox/session-retirement.js";
68
68
  import { handleServerError } from "./server-error.js";
69
- import { FactoryChannelReplyProcessor } from "./session/channel-reply-processor.js";
70
- import { FactoryChannelSessionLinkProcessor } from "./session/channel-session-link-processor.js";
71
69
  import { hydrateSessionDefaultModel } from "./session/default-model-hydration.js";
72
70
  import { observeSessionFirstMessage } from "./session/first-message-capture.js";
73
71
  import { LiveSessions } from "./session/live-sessions.js";
74
72
  import { FactoryReplyCredentialProcessor } from "./session/reply-credential-processor.js";
75
73
  import { migrateSessionResources, privatizeOwnerResourceSessions } from "./session/resource-migration.js";
76
74
  import { createSourceControlTools } from "./session/source-control-tools.js";
77
- import { readFactoryThinkingLevel, resolveFactoryThinkingLevel } from "./session/thinking-default.js";
75
+ import { resolveFactoryThinkingLevel } from "./session/thinking-default.js";
78
76
  import { observeSessionThreadStamp } from "./session/thread-session-stamp.js";
79
77
  import { observeSessionThreadTitle } from "./session/thread-title-mirror.js";
80
78
  import { createSpaStaticMiddleware, resolveUiDistDir } from "./spa-static.js";
@@ -87,6 +85,7 @@ import { CustomProvidersStorage } from "./storage/domains/custom-providers/base.
87
85
  import { FilesystemStorage } from "./storage/domains/filesystem/base.js";
88
86
  import { IntegrationStorage } from "./storage/domains/integrations/base.js";
89
87
  import { ModelDefaultsStorage } from "./storage/domains/model-defaults/base.js";
88
+ import { createFactorySandboxTools } from "./tools/sandbox-tools.js";
90
89
  import { FactorySessionsStateProcessor } from "./tools/sessions-state-processor.js";
91
90
  import { RequestContext } from "@mastra/core/request-context";
92
91
  import { hasAuthInit, isUserProvider } from "@mastra/core/server";
@@ -118,6 +117,12 @@ import { describeFactorySandbox, isFactorySandbox } from "@mastra/core/workspace
118
117
  * and the storage domains those capabilities require.
119
118
  */
120
119
  const CONTROLLER_ID = "code";
120
+ /**
121
+ * Providers whose sandbox a session's agent may recreate itself. Each needs
122
+ * its `destroy()` to leave the instance able to start a fresh VM, proven
123
+ * against the real provider.
124
+ */
125
+ const SELF_RECREATE_SANDBOX_PROVIDERS = /* @__PURE__ */ new Set(["platform"]);
121
126
  /** Why a wake couldn't be run as its Factory session's owner. */
122
127
  const WAKE_OWNER_UNRESOLVED = {
123
128
  "session-not-found": "no Factory session row names its owner",
@@ -129,53 +134,18 @@ function hasPlatformCredentials() {
129
134
  }
130
135
  /**
131
136
  * Default auth provider — `MastraAuthStudio`, which proxies identity to the
132
- * shared Mastra platform API. `MastraAuthStudio` resolves `MASTRA_SHARED_API_URL`,
133
- * `MASTRA_ORGANIZATION_ID`, and `MASTRA_COOKIE_DOMAIN` from env on its own —
134
- * this helper only derives a cookie-domain fallback from the factory's
135
- * `publicUrl`.
136
- *
137
- * Cookie-domain resolution (Studio picks the first that wins):
138
- * 1. explicit `MASTRA_COOKIE_DOMAIN` env, if set;
139
- * 2. `.mastra.ai` when `sharedApiUrl` is on `.mastra.ai`;
140
- * 3. this parent-domain fallback derived from `publicUrl` — so a deploy on
141
- * `https://foo.mastra.cloud` mints cookies with `Domain=.mastra.cloud`
142
- * without the caller wiring the env var by hand.
143
- * 4. otherwise host-only (no `Domain=`), which is correct for `localhost`.
144
- */
145
- function buildDefaultStudioAuth(publicUrl) {
146
- return new MastraAuthStudio({ cookieDomain: parentDomainFromPublicUrl(publicUrl) });
147
- }
148
- /**
149
- * Derive a parent cookie domain from `publicUrl` by stripping the leftmost
150
- * label — the same shape platform-API's env injection uses (see
151
- * `platform/servers/api/src/lib/studio-env-vars.ts`: `.${routingDomain.replace(/^[^.]+\./, '')}`).
137
+ * shared Mastra platform API and resolves its own env (`MASTRA_SHARED_API_URL`,
138
+ * `MASTRA_ORGANIZATION_ID`, ...).
152
139
  *
153
- * Rather than a generic `strip-left-label` heuristic — which either emits
154
- * cookies scoped to a public suffix (`sub.example.co.uk` → `.example.co.uk`
155
- * requires PSL data to be safe) or misclassifies numeric hostnames like
156
- * `3scale.example.com` as IPv4 — we only derive a parent domain when the
157
- * host sits under one of the platform's known registrable domains. Anything
158
- * else (custom domains, arbitrary tenant hostnames, IPs, `localhost`)
159
- * falls through to host-only cookies. Callers that need a different scope
160
- * pass `MASTRA_COOKIE_DOMAIN` explicitly (Studio honors that first).
140
+ * The session cookie is **host-only** (`__Host-wos-session` on secure
141
+ * deployments). No parent `Domain` (e.g. `.mastra.cloud`) is derived from
142
+ * `publicUrl`: a parent-scoped session cookie is sent by the browser to every
143
+ * host under that parent, including other tenants' deployments. Callers that
144
+ * really want a domain-scoped cookie pass their own `MastraAuthStudio` (with
145
+ * `cookieDomain`) via `auth:`.
161
146
  */
162
- const KNOWN_PLATFORM_COOKIE_PARENTS = ["mastra.cloud", "mastra.ai"];
163
- function isIpLiteral(hostname) {
164
- if (hostname.includes(":")) return true;
165
- return /^\d+(?:\.\d+){3}$/.test(hostname);
166
- }
167
- function parentDomainFromPublicUrl(publicUrl) {
168
- let hostname;
169
- try {
170
- hostname = new URL(publicUrl).hostname.toLowerCase();
171
- } catch {
172
- return;
173
- }
174
- if (hostname === "localhost" || isIpLiteral(hostname)) return void 0;
175
- for (const parent of KNOWN_PLATFORM_COOKIE_PARENTS) {
176
- if (hostname === parent) return void 0;
177
- if (hostname.endsWith(`.${parent}`)) return `.${parent}`;
178
- }
147
+ function buildDefaultStudioAuth() {
148
+ return new MastraAuthStudio();
179
149
  }
180
150
  /** A session parking or being answered is inbox news, so the registry bumps the project's feed. */
181
151
  function liveSessionsTouchingTheFeed(controller, eventBus) {
@@ -265,13 +235,14 @@ var MastraFactory = class {
265
235
  const pubsub = this.#config.pubsub;
266
236
  const eventBus = pubsub ?? new EventEmitterPubSub();
267
237
  const configuredAuth = this.#config.auth;
268
- const auth = configuredAuth === null ? void 0 : configuredAuth ?? buildDefaultStudioAuth(publicOrigin);
238
+ const auth = configuredAuth === null ? void 0 : configuredAuth ?? buildDefaultStudioAuth();
269
239
  if (auth && !this.#config.secretEncryption) console.warn("[factory] auth is enabled but 'secretEncryption' is not configured. Persisted model credentials, custom-provider API keys, and integration secrets will be stored as plaintext. Provide 'secretEncryption' (e.g. via FACTORY_CREDENTIAL_ENCRYPTION_KEY) to encrypt them at rest.");
270
240
  const secretEncryption = this.#config.secretEncryption ?? createPlaintextFactorySecretEncryption();
271
241
  const deploymentModelProviders = resolveDeploymentModelProviders(this.#config.deploymentModelProviders);
272
242
  const routeAuth = createFactoryRouteAuth(auth);
273
243
  const mcpConfig = this.#config.mcp;
274
244
  const mcpAuthorizationServers = mcpConfig === false || mcpConfig?.enabled === false ? [] : resolveMcpAuthorizationServers(auth?.name, mcpConfig);
245
+ const mcpEnabled = Boolean(auth) && mcpAuthorizationServers.length > 0;
275
246
  const integrations = [...this.#config.integrations ?? []];
276
247
  const explicitGithub = integrations.some((integration) => integration.id === "github");
277
248
  let installedPlatformGithub = false;
@@ -374,7 +345,8 @@ var MastraFactory = class {
374
345
  projects: factoryProjectsStorage,
375
346
  auth: routeAuth,
376
347
  intake: intakeStorage,
377
- ...integrationSourceControl ? { sourceControl: integrationSourceControl } : {}
348
+ ...integrationSourceControl ? { sourceControl: integrationSourceControl } : {},
349
+ channels: () => this.#prepared?.base.controller.getChannels()
378
350
  });
379
351
  if (integration.versionControl && integrationSourceControl) integration.versionControl.initialize({ storage: integrationSourceControl });
380
352
  }
@@ -688,12 +660,18 @@ var MastraFactory = class {
688
660
  }
689
661
  requestContext.set("mastra__factoryMemorySettings", layerPersonalMemorySettings(record, personal));
690
662
  };
663
+ const resolveDefaultThinkingLevel = (requestContext) => resolveFactoryThinkingLevel(requestContext, {
664
+ projects: factoryProjectsStorage,
665
+ sourceControl: sourceControlSessions,
666
+ workItems: workItemsStorage,
667
+ modelDefaults: modelDefaultsStorage
668
+ });
691
669
  const factoryProcessor = workItemsReady ? new FactoryPhaseStateProcessor({
692
670
  configVersion,
693
671
  storage: workItemsStorage,
694
672
  boards: this.#boards,
695
673
  loadMemorySettings,
696
- factoryThinkingLevel: (factoryProjectId) => readFactoryThinkingLevel(factoryProjectsStorage, factoryProjectId),
674
+ defaultThinkingLevel: resolveDefaultThinkingLevel,
697
675
  ...transitionService ? { transitionService } : {},
698
676
  ...githubIntegration ? { recordPullRequestProvenance: (input) => recordFactoryPullRequestProvenance(githubIntegration, sourceControlStorage.forIntegration("github"), integrationStorage.forIntegration("github"), workItemsStorage, input) } : {},
699
677
  messageReader: { listMessages: async (input) => {
@@ -711,6 +689,7 @@ var MastraFactory = class {
711
689
  if (proto.constructor?.name === "LibSQLFactoryStorage") return "libsql";
712
690
  }
713
691
  })();
692
+ const integrationInputProcessors = integrations.flatMap((integration) => integration.processors?.input ?? []);
714
693
  const toolIntegrations = integrationRegistrations.filter(({ integration }) => integration.agentTools || integration.sessionTools);
715
694
  const sourceControlToolProviders = integrations.flatMap((integration) => integration.versionControl ? [{
716
695
  id: integration.id,
@@ -719,14 +698,12 @@ var MastraFactory = class {
719
698
  }] : []);
720
699
  const prepared = await timedPhase("prepare.controllerMount", () => prepareAgentControllerMount({
721
700
  controllerId: CONTROLLER_ID,
701
+ browser: this.#config.browser,
722
702
  coAuthor: { name: "mastra-platform[bot]" },
723
703
  ...this.#config.disableBuiltinTools?.length ? { disableBuiltinTools: this.#config.disableBuiltinTools } : {},
724
704
  modes: false,
725
705
  subagents: [],
726
- resolveDefaultThinkingLevel: ({ requestContext }) => resolveFactoryThinkingLevel(requestContext, {
727
- projects: factoryProjectsStorage,
728
- sourceControl: sourceControlSessions
729
- }),
706
+ resolveDefaultThinkingLevel: ({ requestContext }) => resolveDefaultThinkingLevel(requestContext),
730
707
  workspace: createWorkspaceFactory({
731
708
  ...sandboxConfig ? { sandbox: sandboxConfig } : {},
732
709
  ...this.#config.sandboxStart ? { sandboxStart: this.#config.sandboxStart } : {},
@@ -839,7 +816,6 @@ var MastraFactory = class {
839
816
  ...mastraStorageBackend ? { storageBackend: mastraStorageBackend } : {},
840
817
  ...this.#config.knowledge ? { knowledge: this.#config.knowledge } : {},
841
818
  inputProcessors: async ({ requestContext }) => {
842
- const channelReplyProcessor = new FactoryChannelReplyProcessor();
843
819
  const environmentProcessor = new FactoryEnvironmentStateProcessor();
844
820
  const sessionsProcessor = workItemsStorage && storage.isDomainReady("source-control") ? [new FactorySessionsStateProcessor({
845
821
  authEnabled: routeAuth.enabled(),
@@ -859,7 +835,7 @@ var MastraFactory = class {
859
835
  if (factoryProcessor) {
860
836
  await factoryProcessor.prepareMemorySettings(requestContext);
861
837
  return [
862
- channelReplyProcessor,
838
+ ...integrationInputProcessors,
863
839
  environmentProcessor,
864
840
  ...sessionsProcessor,
865
841
  factoryProcessor
@@ -874,14 +850,14 @@ var MastraFactory = class {
874
850
  reportMemorySettingsUnavailable(requestContext, error instanceof Error ? error.message : String(error));
875
851
  }
876
852
  return [
877
- channelReplyProcessor,
853
+ ...integrationInputProcessors,
878
854
  environmentProcessor,
879
855
  ...sessionsProcessor
880
856
  ];
881
857
  },
882
- outputProcessors: [new FactoryChannelSessionLinkProcessor(), new FactoryReplyCredentialProcessor()],
858
+ outputProcessors: [...integrations.flatMap((integration) => integration.processors?.output ?? []), new FactoryReplyCredentialProcessor()],
883
859
  ...vector ? { vector } : {},
884
- ...toolIntegrations.length > 0 || sourceControlToolProviders.length > 0 || workItemsStorage && transitionService ? { extraTools: async ({ requestContext }) => {
860
+ extraTools: async ({ requestContext }) => {
885
861
  const tools = {};
886
862
  const toolOwners = /* @__PURE__ */ new Map();
887
863
  const mergeTools = (ownerId, contributed) => {
@@ -968,10 +944,16 @@ var MastraFactory = class {
968
944
  projects: factoryProjectsStorage,
969
945
  workItems: workItemsStorage
970
946
  });
971
- if (scope) mergeTools("factory-tools", createFactoryTools({
972
- scope,
973
- deps: factoryToolDeps
974
- }));
947
+ if (scope) {
948
+ mergeTools("factory-tools", createFactoryTools({
949
+ scope,
950
+ deps: factoryToolDeps
951
+ }));
952
+ if (sessionRetirement && sandboxConfig && SELF_RECREATE_SANDBOX_PROVIDERS.has(sandboxConfig.provider)) mergeTools("factory-sandbox-tools", createFactorySandboxTools(scope, {
953
+ sessions: sourceControlSessions,
954
+ resetSandbox: (input) => sessionRetirement.resetSessionSandbox(input)
955
+ }));
956
+ }
975
957
  }
976
958
  }
977
959
  for (const { integration, ready, ensureReady } of toolIntegrations) {
@@ -984,7 +966,7 @@ var MastraFactory = class {
984
966
  if (integration.sessionTools) mergeTools(integration.id, integration.sessionTools({ requestContext }));
985
967
  }
986
968
  return tools;
987
- } } : {},
969
+ },
988
970
  postToolObserver: async (toolContext) => {
989
971
  const requestContext = toolContext.context?.requestContext;
990
972
  if (requestContext) await observeAgentGitAction({
@@ -1023,7 +1005,7 @@ var MastraFactory = class {
1023
1005
  } : {},
1024
1006
  buildApiRoutes: ({ controller, authStorage }) => [
1025
1007
  ...auth ? buildAuthRoutes(auth, { publicUrl: publicOrigin }) : buildAuthDisabledRoutes(),
1026
- ...auth && mcpAuthorizationServers.length > 0 ? buildFactoryMcpRoutes({
1008
+ ...mcpEnabled ? buildFactoryMcpRoutes({
1027
1009
  auth: routeAuth,
1028
1010
  publicOrigin,
1029
1011
  authorizationServers: mcpAuthorizationServers,
@@ -1067,6 +1049,7 @@ var MastraFactory = class {
1067
1049
  intakeReady,
1068
1050
  factoryReady,
1069
1051
  knowledgeEnabled,
1052
+ mcpEnabled,
1070
1053
  deploymentModelProviders,
1071
1054
  knowledgeKey: this.#config.knowledge?.key,
1072
1055
  configVersion,
@@ -1137,10 +1120,19 @@ var MastraFactory = class {
1137
1120
  }) : []
1138
1121
  ],
1139
1122
  buildServerConfig: () => {
1140
- const cors = allowedOrigins.length ? { cors: {
1123
+ const mcpCors = {
1124
+ allowHeaders: [
1125
+ "Mcp-Protocol-Version",
1126
+ "Mcp-Method",
1127
+ "Mcp-Name"
1128
+ ],
1129
+ exposeHeaders: ["WWW-Authenticate"]
1130
+ };
1131
+ const cors = { cors: allowedOrigins.length ? {
1141
1132
  origin: allowedOrigins,
1142
- credentials: true
1143
- } } : {};
1133
+ credentials: true,
1134
+ ...mcpCors
1135
+ } : mcpCors };
1144
1136
  const onError = { onError: handleServerError };
1145
1137
  const uiDist = resolveUiDistDir();
1146
1138
  const spa = uiDist ? [createSpaStaticMiddleware(uiDist)] : [];