@mastra/editor 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,153 @@
1
1
  # @mastra/editor
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added Processor Providers — a new system for configuring and hydrating processors on stored agents. Define custom processor types with config schemas, available phases, and a factory method, then compose them into serializable processor graphs that support sequential, parallel, and conditional execution. ([#13219](https://github.com/mastra-ai/mastra/pull/13219))
8
+
9
+ **Example — custom processor provider:**
10
+
11
+ ```ts
12
+ import { MastraEditor } from '@mastra/editor';
13
+
14
+ // Built-in processors (token-limiter, unicode-normalizer, etc.) are registered automatically.
15
+ // Only register custom providers for your own processors:
16
+ const editor = new MastraEditor({
17
+ processorProviders: {
18
+ 'my-custom-filter': myCustomFilterProvider,
19
+ },
20
+ });
21
+ ```
22
+
23
+ **Example — stored agent with a processor graph:**
24
+
25
+ ```ts
26
+ const agentConfig = {
27
+ inputProcessors: {
28
+ steps: [
29
+ {
30
+ type: 'step',
31
+ step: { id: 'norm', providerId: 'unicode-normalizer', config: {}, enabledPhases: ['processInput'] },
32
+ },
33
+ {
34
+ type: 'step',
35
+ step: {
36
+ id: 'limit',
37
+ providerId: 'token-limiter',
38
+ config: { limit: 4000 },
39
+ enabledPhases: ['processInput', 'processOutputStream'],
40
+ },
41
+ },
42
+ ],
43
+ },
44
+ };
45
+ ```
46
+
47
+ - Added MCP server storage and editor support. MCP server configurations can now be persisted in storage and managed through the editor CMS. The editor's `mcpServer` namespace provides full CRUD operations and automatically hydrates stored configs into running `MCPServer` instances by resolving tool, agent, and workflow references from the Mastra registry. ([#13285](https://github.com/mastra-ai/mastra/pull/13285))
48
+
49
+ ```ts
50
+ const editor = new MastraEditor();
51
+ const mastra = new Mastra({
52
+ tools: { getWeather: weatherTool, calculate: calculatorTool },
53
+ storage: new LibSQLStore({ url: ':memory:' }),
54
+ editor,
55
+ });
56
+
57
+ // Store an MCP server config referencing tools by ID
58
+ const server = await editor.mcpServer.create({
59
+ id: 'my-server',
60
+ name: 'My MCP Server',
61
+ version: '1.0.0',
62
+ tools: { getWeather: {}, calculate: { description: 'Custom description' } },
63
+ });
64
+
65
+ // Retrieve — automatically hydrates into a real MCPServer with resolved tools
66
+ const mcp = await editor.mcpServer.getById('my-server');
67
+ const tools = mcp.tools(); // { getWeather: ..., calculate: ... }
68
+ ```
69
+
70
+ ### Patch Changes
71
+
72
+ - Updated dependencies [[`0d9efb4`](https://github.com/mastra-ai/mastra/commit/0d9efb47992c34aa90581c18b9f51f774f6252a5), [`7184d87`](https://github.com/mastra-ai/mastra/commit/7184d87c9237d26862f500ccfd0c9f9eadd38ddf), [`5caa13d`](https://github.com/mastra-ai/mastra/commit/5caa13d1b2a496e2565ab124a11de9a51ad3e3b9), [`270dd16`](https://github.com/mastra-ai/mastra/commit/270dd168a86698a699d8a9de8dbce1a40f72d862), [`940163f`](https://github.com/mastra-ai/mastra/commit/940163fc492401d7562301e6f106ccef4fefe06f), [`b260123`](https://github.com/mastra-ai/mastra/commit/b2601234bd093d358c92081a58f9b0befdae52b3), [`47892c8`](https://github.com/mastra-ai/mastra/commit/47892c85708eac348209f99f10f9a5f5267e11c0), [`45bb78b`](https://github.com/mastra-ai/mastra/commit/45bb78b70bd9db29678fe49476cd9f4ed01bfd0b), [`70eef84`](https://github.com/mastra-ai/mastra/commit/70eef84b8f44493598fdafa2980a0e7283415eda), [`d84e52d`](https://github.com/mastra-ai/mastra/commit/d84e52d0f6511283ddd21ed5fe7f945449d0f799), [`24b80af`](https://github.com/mastra-ai/mastra/commit/24b80af87da93bb84d389340181e17b7477fa9ca), [`608e156`](https://github.com/mastra-ai/mastra/commit/608e156def954c9604c5e3f6d9dfce3bcc7aeab0), [`78d1c80`](https://github.com/mastra-ai/mastra/commit/78d1c808ad90201897a300af551bcc1d34458a20), [`2b2e157`](https://github.com/mastra-ai/mastra/commit/2b2e157a092cd597d9d3f0000d62b8bb4a7348ed), [`78d1c80`](https://github.com/mastra-ai/mastra/commit/78d1c808ad90201897a300af551bcc1d34458a20), [`59d30b5`](https://github.com/mastra-ai/mastra/commit/59d30b5d0cb44ea7a1c440e7460dfb57eac9a9b5), [`453693b`](https://github.com/mastra-ai/mastra/commit/453693bf9e265ddccecef901d50da6caaea0fbc6), [`78d1c80`](https://github.com/mastra-ai/mastra/commit/78d1c808ad90201897a300af551bcc1d34458a20), [`c204b63`](https://github.com/mastra-ai/mastra/commit/c204b632d19e66acb6d6e19b11c4540dd6ad5380), [`742a417`](https://github.com/mastra-ai/mastra/commit/742a417896088220a3b5560c354c45c5ca6d88b9)]:
73
+ - @mastra/core@1.6.0
74
+ - @mastra/schema-compat@1.1.2
75
+ - @mastra/memory@1.5.0
76
+
77
+ ## 0.6.0-alpha.0
78
+
79
+ ### Minor Changes
80
+
81
+ - Added Processor Providers — a new system for configuring and hydrating processors on stored agents. Define custom processor types with config schemas, available phases, and a factory method, then compose them into serializable processor graphs that support sequential, parallel, and conditional execution. ([#13219](https://github.com/mastra-ai/mastra/pull/13219))
82
+
83
+ **Example — custom processor provider:**
84
+
85
+ ```ts
86
+ import { MastraEditor } from '@mastra/editor';
87
+
88
+ // Built-in processors (token-limiter, unicode-normalizer, etc.) are registered automatically.
89
+ // Only register custom providers for your own processors:
90
+ const editor = new MastraEditor({
91
+ processorProviders: {
92
+ 'my-custom-filter': myCustomFilterProvider,
93
+ },
94
+ });
95
+ ```
96
+
97
+ **Example — stored agent with a processor graph:**
98
+
99
+ ```ts
100
+ const agentConfig = {
101
+ inputProcessors: {
102
+ steps: [
103
+ {
104
+ type: 'step',
105
+ step: { id: 'norm', providerId: 'unicode-normalizer', config: {}, enabledPhases: ['processInput'] },
106
+ },
107
+ {
108
+ type: 'step',
109
+ step: {
110
+ id: 'limit',
111
+ providerId: 'token-limiter',
112
+ config: { limit: 4000 },
113
+ enabledPhases: ['processInput', 'processOutputStream'],
114
+ },
115
+ },
116
+ ],
117
+ },
118
+ };
119
+ ```
120
+
121
+ - Added MCP server storage and editor support. MCP server configurations can now be persisted in storage and managed through the editor CMS. The editor's `mcpServer` namespace provides full CRUD operations and automatically hydrates stored configs into running `MCPServer` instances by resolving tool, agent, and workflow references from the Mastra registry. ([#13285](https://github.com/mastra-ai/mastra/pull/13285))
122
+
123
+ ```ts
124
+ const editor = new MastraEditor();
125
+ const mastra = new Mastra({
126
+ tools: { getWeather: weatherTool, calculate: calculatorTool },
127
+ storage: new LibSQLStore({ url: ':memory:' }),
128
+ editor,
129
+ });
130
+
131
+ // Store an MCP server config referencing tools by ID
132
+ const server = await editor.mcpServer.create({
133
+ id: 'my-server',
134
+ name: 'My MCP Server',
135
+ version: '1.0.0',
136
+ tools: { getWeather: {}, calculate: { description: 'Custom description' } },
137
+ });
138
+
139
+ // Retrieve — automatically hydrates into a real MCPServer with resolved tools
140
+ const mcp = await editor.mcpServer.getById('my-server');
141
+ const tools = mcp.tools(); // { getWeather: ..., calculate: ... }
142
+ ```
143
+
144
+ ### Patch Changes
145
+
146
+ - Updated dependencies [[`0d9efb4`](https://github.com/mastra-ai/mastra/commit/0d9efb47992c34aa90581c18b9f51f774f6252a5), [`7184d87`](https://github.com/mastra-ai/mastra/commit/7184d87c9237d26862f500ccfd0c9f9eadd38ddf), [`5caa13d`](https://github.com/mastra-ai/mastra/commit/5caa13d1b2a496e2565ab124a11de9a51ad3e3b9), [`270dd16`](https://github.com/mastra-ai/mastra/commit/270dd168a86698a699d8a9de8dbce1a40f72d862), [`940163f`](https://github.com/mastra-ai/mastra/commit/940163fc492401d7562301e6f106ccef4fefe06f), [`b260123`](https://github.com/mastra-ai/mastra/commit/b2601234bd093d358c92081a58f9b0befdae52b3), [`47892c8`](https://github.com/mastra-ai/mastra/commit/47892c85708eac348209f99f10f9a5f5267e11c0), [`45bb78b`](https://github.com/mastra-ai/mastra/commit/45bb78b70bd9db29678fe49476cd9f4ed01bfd0b), [`70eef84`](https://github.com/mastra-ai/mastra/commit/70eef84b8f44493598fdafa2980a0e7283415eda), [`d84e52d`](https://github.com/mastra-ai/mastra/commit/d84e52d0f6511283ddd21ed5fe7f945449d0f799), [`24b80af`](https://github.com/mastra-ai/mastra/commit/24b80af87da93bb84d389340181e17b7477fa9ca), [`608e156`](https://github.com/mastra-ai/mastra/commit/608e156def954c9604c5e3f6d9dfce3bcc7aeab0), [`78d1c80`](https://github.com/mastra-ai/mastra/commit/78d1c808ad90201897a300af551bcc1d34458a20), [`2b2e157`](https://github.com/mastra-ai/mastra/commit/2b2e157a092cd597d9d3f0000d62b8bb4a7348ed), [`78d1c80`](https://github.com/mastra-ai/mastra/commit/78d1c808ad90201897a300af551bcc1d34458a20), [`59d30b5`](https://github.com/mastra-ai/mastra/commit/59d30b5d0cb44ea7a1c440e7460dfb57eac9a9b5), [`453693b`](https://github.com/mastra-ai/mastra/commit/453693bf9e265ddccecef901d50da6caaea0fbc6), [`78d1c80`](https://github.com/mastra-ai/mastra/commit/78d1c808ad90201897a300af551bcc1d34458a20), [`c204b63`](https://github.com/mastra-ai/mastra/commit/c204b632d19e66acb6d6e19b11c4540dd6ad5380), [`742a417`](https://github.com/mastra-ai/mastra/commit/742a417896088220a3b5560c354c45c5ca6d88b9)]:
147
+ - @mastra/core@1.6.0-alpha.0
148
+ - @mastra/schema-compat@1.1.2-alpha.0
149
+ - @mastra/memory@1.5.0-alpha.0
150
+
3
151
  ## 0.5.0
4
152
 
5
153
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  CrudEditorNamespace: () => CrudEditorNamespace,
34
34
  EditorAgentNamespace: () => EditorAgentNamespace,
35
35
  EditorMCPNamespace: () => EditorMCPNamespace,
36
+ EditorMCPServerNamespace: () => EditorMCPServerNamespace,
36
37
  EditorNamespace: () => EditorNamespace,
37
38
  EditorPromptNamespace: () => EditorPromptNamespace,
38
39
  EditorScorerNamespace: () => EditorScorerNamespace,
@@ -46,6 +47,7 @@ __export(index_exports, {
46
47
  resolveInstructionBlocks: () => resolveInstructionBlocks
47
48
  });
48
49
  module.exports = __toCommonJS(index_exports);
50
+ var import_processor_provider2 = require("@mastra/core/processor-provider");
49
51
 
50
52
  // src/namespaces/base.ts
51
53
  var EditorNamespace = class {
@@ -336,6 +338,177 @@ async function resolveInstructionBlocks(blocks, context, deps) {
336
338
  return segments.join("\n\n");
337
339
  }
338
340
 
341
+ // src/processor-graph-hydrator.ts
342
+ var import_processors = require("@mastra/core/processors");
343
+ var import_processor_provider = require("@mastra/core/processor-provider");
344
+ var import_workflows = require("@mastra/core/workflows");
345
+ var PASSTHROUGH_STEP_PREFIX = "passthrough-";
346
+ function resolveStep(step, ctx) {
347
+ const provider = ctx.providers[step.providerId];
348
+ if (!provider) {
349
+ ctx.logger?.warn(`ProcessorProvider "${step.providerId}" not found for graph step "${step.id}"`);
350
+ return void 0;
351
+ }
352
+ const processor = provider.createProcessor(step.config);
353
+ const allProviderPhases = provider.availablePhases;
354
+ const enabledSet = new Set(step.enabledPhases);
355
+ const needsFiltering = allProviderPhases.some((p) => !enabledSet.has(p));
356
+ if (needsFiltering) {
357
+ const filtered = new import_processor_provider.PhaseFilteredProcessor(processor, step.enabledPhases);
358
+ if (ctx.mastra) {
359
+ filtered.__registerMastra(ctx.mastra);
360
+ }
361
+ return filtered;
362
+ }
363
+ if (ctx.mastra && processor.__registerMastra) {
364
+ processor.__registerMastra(ctx.mastra);
365
+ }
366
+ return processor;
367
+ }
368
+ function isSequentialOnly(entries) {
369
+ return entries.every((e) => e.type === "step");
370
+ }
371
+ function hydrateSequential(entries, ctx) {
372
+ const processors = [];
373
+ for (const entry of entries) {
374
+ if (entry.type !== "step") continue;
375
+ const processor = resolveStep(entry.step, ctx);
376
+ if (processor) {
377
+ processors.push(processor);
378
+ }
379
+ }
380
+ return processors;
381
+ }
382
+ async function mergeBranchOutputs({ inputData }) {
383
+ const keys = Object.keys(inputData).sort((a, b) => {
384
+ const aPass = a.startsWith(PASSTHROUGH_STEP_PREFIX) ? 1 : 0;
385
+ const bPass = b.startsWith(PASSTHROUGH_STEP_PREFIX) ? 1 : 0;
386
+ return aPass - bPass;
387
+ });
388
+ for (const key of keys) {
389
+ const val = inputData[key];
390
+ if (val && typeof val === "object" && "phase" in val) {
391
+ return {
392
+ phase: val.phase,
393
+ messages: val.messages,
394
+ messageList: val.messageList,
395
+ ...val.systemMessages ? { systemMessages: val.systemMessages } : {},
396
+ ...val.part !== void 0 ? { part: val.part } : {},
397
+ ...val.streamParts ? { streamParts: val.streamParts } : {},
398
+ ...val.state ? { state: val.state } : {},
399
+ ...val.text !== void 0 ? { text: val.text } : {},
400
+ ...val.retryCount !== void 0 ? { retryCount: val.retryCount } : {}
401
+ };
402
+ }
403
+ }
404
+ return inputData;
405
+ }
406
+ function buildWorkflow(entries, workflowId, ctx) {
407
+ let workflow = (0, import_workflows.createWorkflow)({
408
+ id: workflowId,
409
+ inputSchema: import_processors.ProcessorStepSchema,
410
+ outputSchema: import_processors.ProcessorStepSchema,
411
+ type: "processor",
412
+ options: {
413
+ validateInputs: false
414
+ }
415
+ });
416
+ let hasSteps = false;
417
+ for (const entry of entries) {
418
+ if (entry.type === "step") {
419
+ const processor = resolveStep(entry.step, ctx);
420
+ if (!processor) continue;
421
+ const step = (0, import_workflows.createStep)(processor);
422
+ workflow = workflow.then(step);
423
+ hasSteps = true;
424
+ } else if (entry.type === "parallel") {
425
+ const branchSteps = entry.branches.map((branchEntries, branchIdx) => {
426
+ if (branchEntries.length === 1 && branchEntries[0].type === "step") {
427
+ const proc = resolveStep(branchEntries[0].step, ctx);
428
+ if (!proc) return void 0;
429
+ return (0, import_workflows.createStep)(proc);
430
+ }
431
+ const subWorkflow = buildWorkflow(branchEntries, `${workflowId}-parallel-branch-${branchIdx}`, ctx);
432
+ return subWorkflow;
433
+ }).filter(Boolean);
434
+ if (branchSteps.length > 0) {
435
+ workflow = workflow.parallel(branchSteps);
436
+ workflow = workflow.map(mergeBranchOutputs);
437
+ hasSteps = true;
438
+ }
439
+ } else if (entry.type === "conditional") {
440
+ const branchTuples = [];
441
+ for (const [i, condition] of entry.conditions.entries()) {
442
+ let branchStep;
443
+ if (condition.steps.length === 1 && condition.steps[0].type === "step") {
444
+ const proc = resolveStep(condition.steps[0].step, ctx);
445
+ if (!proc) continue;
446
+ branchStep = (0, import_workflows.createStep)(proc);
447
+ } else {
448
+ branchStep = buildWorkflow(condition.steps, `${workflowId}-cond-branch-${i}`, ctx);
449
+ if (!branchStep) continue;
450
+ }
451
+ if (condition.rules) {
452
+ const rules = condition.rules;
453
+ const conditionFn = async ({ inputData }) => {
454
+ return evaluateRuleGroup(rules, inputData);
455
+ };
456
+ branchTuples.push([conditionFn, branchStep]);
457
+ } else {
458
+ branchTuples.push([async () => true, branchStep]);
459
+ }
460
+ }
461
+ if (branchTuples.length > 0) {
462
+ const passthroughStep = (0, import_workflows.createStep)({
463
+ id: `${PASSTHROUGH_STEP_PREFIX}${workflowId}`,
464
+ inputSchema: import_processors.ProcessorStepSchema,
465
+ outputSchema: import_processors.ProcessorStepSchema,
466
+ execute: async ({ inputData }) => inputData
467
+ });
468
+ branchTuples.push([async () => true, passthroughStep]);
469
+ workflow = workflow.branch(branchTuples);
470
+ workflow = workflow.map(mergeBranchOutputs);
471
+ hasSteps = true;
472
+ }
473
+ }
474
+ }
475
+ if (!hasSteps) return void 0;
476
+ return workflow.commit();
477
+ }
478
+ function hydrateProcessorGraph(graph, mode, ctx) {
479
+ if (!graph) return void 0;
480
+ if (Array.isArray(graph)) {
481
+ ctx.logger?.warn(
482
+ "Processor graph is in legacy string[] format and cannot be hydrated. Re-save the agent to migrate."
483
+ );
484
+ return void 0;
485
+ }
486
+ if (!Array.isArray(graph.steps) || graph.steps.length === 0) return void 0;
487
+ if (isSequentialOnly(graph.steps)) {
488
+ const processors = hydrateSequential(graph.steps, ctx);
489
+ if (processors.length === 0) return void 0;
490
+ if (mode === "input") {
491
+ const filtered = processors.filter((p) => p.processInput || p.processInputStep);
492
+ return filtered.length > 0 ? filtered : void 0;
493
+ } else {
494
+ const filtered = processors.filter((p) => p.processOutputStream || p.processOutputResult || p.processOutputStep);
495
+ return filtered.length > 0 ? filtered : void 0;
496
+ }
497
+ }
498
+ const workflowId = `stored-${mode}-processor-graph`;
499
+ const workflow = buildWorkflow(graph.steps, workflowId, ctx);
500
+ if (!workflow) return void 0;
501
+ return [workflow];
502
+ }
503
+ function selectFirstMatchingGraph(variants, context) {
504
+ for (const variant of variants) {
505
+ if (!variant.rules || evaluateRuleGroup(variant.rules, context)) {
506
+ return variant.value;
507
+ }
508
+ }
509
+ return void 0;
510
+ }
511
+
339
512
  // src/namespaces/mcp.ts
340
513
  var EditorMCPNamespace = class _EditorMCPNamespace extends CrudEditorNamespace {
341
514
  onCacheEvict(_id) {
@@ -580,22 +753,24 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
580
753
  );
581
754
  return this.resolveStoredScorers(resolved);
582
755
  } : await this.resolveStoredScorers(storedAgent.scorers);
756
+ const processorProviders = this.editor.getProcessorProviders();
757
+ const hydrationCtx = { providers: processorProviders, mastra: this.mastra, logger: this.logger };
583
758
  const inputProcessors = hasConditionalInputProcessors ? ({ requestContext }) => {
584
759
  const ctx = requestContext.toJSON();
585
- const resolved = this.accumulateArrayVariants(
760
+ const graph = selectFirstMatchingGraph(
586
761
  storedAgent.inputProcessors,
587
762
  ctx
588
763
  );
589
- return this.resolveStoredInputProcessors(resolved);
590
- } : this.resolveStoredInputProcessors(storedAgent.inputProcessors);
764
+ return hydrateProcessorGraph(graph, "input", hydrationCtx);
765
+ } : hydrateProcessorGraph(storedAgent.inputProcessors, "input", hydrationCtx);
591
766
  const outputProcessors = hasConditionalOutputProcessors ? ({ requestContext }) => {
592
767
  const ctx = requestContext.toJSON();
593
- const resolved = this.accumulateArrayVariants(
768
+ const graph = selectFirstMatchingGraph(
594
769
  storedAgent.outputProcessors,
595
770
  ctx
596
771
  );
597
- return this.resolveStoredOutputProcessors(resolved);
598
- } : this.resolveStoredOutputProcessors(storedAgent.outputProcessors);
772
+ return hydrateProcessorGraph(graph, "output", hydrationCtx);
773
+ } : hydrateProcessorGraph(storedAgent.outputProcessors, "output", hydrationCtx);
599
774
  let model;
600
775
  let staticModelConfig;
601
776
  const modelSettingsFrom = (cfg) => ({
@@ -985,41 +1160,6 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
985
1160
  }
986
1161
  return Object.keys(resolvedScorers).length > 0 ? resolvedScorers : void 0;
987
1162
  }
988
- findProcessor(processorKey) {
989
- if (!this.mastra) return void 0;
990
- try {
991
- return this.mastra.getProcessor(processorKey);
992
- } catch {
993
- try {
994
- return this.mastra.getProcessorById(processorKey);
995
- } catch {
996
- this.logger?.warn(`Processor "${processorKey}" referenced in stored agent but not registered in Mastra`);
997
- return void 0;
998
- }
999
- }
1000
- }
1001
- resolveStoredInputProcessors(storedProcessors) {
1002
- if (!storedProcessors || storedProcessors.length === 0) return void 0;
1003
- const resolved = [];
1004
- for (const key of storedProcessors) {
1005
- const processor = this.findProcessor(key);
1006
- if (processor && (processor.processInput || processor.processInputStep)) {
1007
- resolved.push(processor);
1008
- }
1009
- }
1010
- return resolved.length > 0 ? resolved : void 0;
1011
- }
1012
- resolveStoredOutputProcessors(storedProcessors) {
1013
- if (!storedProcessors || storedProcessors.length === 0) return void 0;
1014
- const resolved = [];
1015
- for (const key of storedProcessors) {
1016
- const processor = this.findProcessor(key);
1017
- if (processor && (processor.processOutputStream || processor.processOutputResult || processor.processOutputStep)) {
1018
- resolved.push(processor);
1019
- }
1020
- }
1021
- return resolved.length > 0 ? resolved : void 0;
1022
- }
1023
1163
  // ============================================================================
1024
1164
  // Clone
1025
1165
  // ============================================================================
@@ -1067,9 +1207,6 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1067
1207
  const agentKeys = Object.keys(agentsResolved || {});
1068
1208
  const memory = await agent.getMemory({ requestContext });
1069
1209
  const memoryConfig = memory?.getConfig();
1070
- const { inputProcessorIds, outputProcessorIds } = await agent.getConfiguredProcessorIds(requestContext);
1071
- const inputProcessorKeys = inputProcessorIds.length > 0 ? inputProcessorIds : void 0;
1072
- const outputProcessorKeys = outputProcessorIds.length > 0 ? outputProcessorIds : void 0;
1073
1210
  let storedScorers;
1074
1211
  const resolvedScorers = await agent.listScorers({ requestContext });
1075
1212
  if (resolvedScorers && Object.keys(resolvedScorers).length > 0) {
@@ -1104,8 +1241,6 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1104
1241
  workflows: workflowKeys.length > 0 ? Object.fromEntries(workflowKeys.map((key) => [key, {}])) : void 0,
1105
1242
  agents: agentKeys.length > 0 ? Object.fromEntries(agentKeys.map((key) => [key, {}])) : void 0,
1106
1243
  memory: memoryConfig,
1107
- inputProcessors: inputProcessorKeys,
1108
- outputProcessors: outputProcessorKeys,
1109
1244
  scorers: storedScorers,
1110
1245
  defaultOptions: storageDefaultOptions,
1111
1246
  metadata: options.metadata,
@@ -1220,6 +1355,112 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1220
1355
  }
1221
1356
  };
1222
1357
 
1358
+ // src/namespaces/mcp-server.ts
1359
+ var EditorMCPServerNamespace = class extends CrudEditorNamespace {
1360
+ onCacheEvict(_id) {
1361
+ }
1362
+ async hydrate(resolved) {
1363
+ if (!this.mastra) {
1364
+ throw new Error("MastraEditor is not registered with a Mastra instance");
1365
+ }
1366
+ const tools = this.resolveStoredTools(resolved.tools);
1367
+ const agents = this.resolveStoredAgents(resolved.agents);
1368
+ const workflows = this.resolveStoredWorkflows(resolved.workflows);
1369
+ if (!this.mcpServerCtor) {
1370
+ try {
1371
+ const mod = await import("@mastra/mcp");
1372
+ this.mcpServerCtor = mod.MCPServer;
1373
+ } catch {
1374
+ throw new Error(
1375
+ "@mastra/mcp is required to hydrate MCP server configurations. Install it with: npm install @mastra/mcp"
1376
+ );
1377
+ }
1378
+ }
1379
+ const server = new this.mcpServerCtor({
1380
+ id: resolved.id,
1381
+ name: resolved.name,
1382
+ version: resolved.version,
1383
+ description: resolved.description,
1384
+ instructions: resolved.instructions,
1385
+ repository: resolved.repository,
1386
+ releaseDate: resolved.releaseDate,
1387
+ isLatest: resolved.isLatest,
1388
+ packageCanonical: resolved.packageCanonical,
1389
+ tools,
1390
+ agents,
1391
+ workflows
1392
+ });
1393
+ this.mastra.addMCPServer(server, resolved.id);
1394
+ return server;
1395
+ }
1396
+ resolveStoredTools(storedTools) {
1397
+ if (!storedTools || Object.keys(storedTools).length === 0) return {};
1398
+ if (!this.mastra) return {};
1399
+ const resolved = {};
1400
+ for (const [toolKey, toolConfig] of Object.entries(storedTools)) {
1401
+ try {
1402
+ const tool = this.mastra.getToolById(toolKey);
1403
+ if (toolConfig.description) {
1404
+ resolved[toolKey] = { ...tool, description: toolConfig.description };
1405
+ } else {
1406
+ resolved[toolKey] = tool;
1407
+ }
1408
+ } catch {
1409
+ this.logger?.warn(`Tool "${toolKey}" referenced in stored MCP server but not registered in Mastra`);
1410
+ }
1411
+ }
1412
+ return resolved;
1413
+ }
1414
+ resolveStoredAgents(storedAgents) {
1415
+ if (!storedAgents || Object.keys(storedAgents).length === 0) return {};
1416
+ if (!this.mastra) return {};
1417
+ const resolved = {};
1418
+ for (const agentKey of Object.keys(storedAgents)) {
1419
+ try {
1420
+ resolved[agentKey] = this.mastra.getAgent(agentKey);
1421
+ } catch {
1422
+ try {
1423
+ resolved[agentKey] = this.mastra.getAgentById(agentKey);
1424
+ } catch {
1425
+ this.logger?.warn(`Agent "${agentKey}" referenced in stored MCP server but not registered in Mastra`);
1426
+ }
1427
+ }
1428
+ }
1429
+ return resolved;
1430
+ }
1431
+ resolveStoredWorkflows(storedWorkflows) {
1432
+ if (!storedWorkflows || Object.keys(storedWorkflows).length === 0) return {};
1433
+ if (!this.mastra) return {};
1434
+ const resolved = {};
1435
+ for (const workflowKey of Object.keys(storedWorkflows)) {
1436
+ try {
1437
+ resolved[workflowKey] = this.mastra.getWorkflow(workflowKey);
1438
+ } catch {
1439
+ try {
1440
+ resolved[workflowKey] = this.mastra.getWorkflowById(workflowKey);
1441
+ } catch {
1442
+ this.logger?.warn(`Workflow "${workflowKey}" referenced in stored MCP server but not registered in Mastra`);
1443
+ }
1444
+ }
1445
+ }
1446
+ return resolved;
1447
+ }
1448
+ async getStorageAdapter() {
1449
+ const storage = this.mastra?.getStorage();
1450
+ if (!storage) throw new Error("Storage is not configured");
1451
+ const store = await storage.getStore("mcpServers");
1452
+ if (!store) throw new Error("MCP servers storage domain is not available");
1453
+ return {
1454
+ create: (input) => store.create({ mcpServer: input }),
1455
+ getByIdResolved: (id) => store.getByIdResolved(id),
1456
+ update: (input) => store.update(input),
1457
+ delete: (id) => store.delete(id),
1458
+ list: (args) => store.list(args),
1459
+ listResolved: (args) => store.listResolved(args)
1460
+ };
1461
+ }
1462
+ };
1463
+
1223
1464
  // src/namespaces/prompt.ts
1224
1465
  var EditorPromptNamespace = class extends CrudEditorNamespace {
1225
1466
  onCacheEvict(id) {
@@ -1578,6 +1819,7 @@ var MastraEditor = class {
1578
1819
  constructor(config) {
1579
1820
  this.__logger = config?.logger;
1580
1821
  this.__toolProviders = config?.toolProviders ?? {};
1822
+ this.__processorProviders = { ...import_processor_provider2.BUILT_IN_PROCESSOR_PROVIDERS, ...config?.processorProviders };
1581
1823
  this.__filesystems = /* @__PURE__ */ new Map();
1582
1824
  this.__filesystems.set(localFilesystemProvider.id, localFilesystemProvider);
1583
1825
  for (const [id, provider] of Object.entries(config?.filesystems ?? {})) {
@@ -1594,6 +1836,7 @@ var MastraEditor = class {
1594
1836
  }
1595
1837
  this.agent = new EditorAgentNamespace(this);
1596
1838
  this.mcp = new EditorMCPNamespace(this);
1839
+ this.mcpServer = new EditorMCPServerNamespace(this);
1597
1840
  this.prompt = new EditorPromptNamespace(this);
1598
1841
  this.scorer = new EditorScorerNamespace(this);
1599
1842
  this.workspace = new EditorWorkspaceNamespace(this);
@@ -1617,6 +1860,14 @@ var MastraEditor = class {
1617
1860
  getToolProviders() {
1618
1861
  return this.__toolProviders;
1619
1862
  }
1863
+ /** Get a processor provider by ID */
1864
+ getProcessorProvider(id) {
1865
+ return this.__processorProviders[id];
1866
+ }
1867
+ /** List all registered processor providers */
1868
+ getProcessorProviders() {
1869
+ return this.__processorProviders;
1870
+ }
1620
1871
  /** List all registered filesystem providers */
1621
1872
  getFilesystemProviders() {
1622
1873
  return Array.from(this.__filesystems.values());
@@ -1663,6 +1914,7 @@ var MastraEditor = class {
1663
1914
  CrudEditorNamespace,
1664
1915
  EditorAgentNamespace,
1665
1916
  EditorMCPNamespace,
1917
+ EditorMCPServerNamespace,
1666
1918
  EditorNamespace,
1667
1919
  EditorPromptNamespace,
1668
1920
  EditorScorerNamespace,
package/dist/index.d.cts CHANGED
@@ -2,10 +2,12 @@ import { Mastra } from '@mastra/core';
2
2
  import { GetByIdOptions, FilesystemProvider, SandboxProvider, IMastraEditor, BlobStoreProvider, MastraEditorConfig } from '@mastra/core/editor';
3
3
  export { MastraEditorConfig } from '@mastra/core/editor';
4
4
  import { IMastraLogger } from '@mastra/core/logger';
5
- import { StorageCreateAgentInput, StorageUpdateAgentInput, StorageListAgentsInput, StorageListAgentsOutput, StorageListAgentsResolvedOutput, StorageResolvedAgentType, StorageCreateMCPClientInput, StorageUpdateMCPClientInput, StorageListMCPClientsInput, StorageListMCPClientsOutput, StorageListMCPClientsResolvedOutput, StorageResolvedMCPClientType, StorageMCPServerConfig, StorageCreatePromptBlockInput, StorageUpdatePromptBlockInput, StorageListPromptBlocksInput, StorageListPromptBlocksOutput, StorageListPromptBlocksResolvedOutput, StorageResolvedPromptBlockType, AgentInstructionBlock, StorageCreateScorerDefinitionInput, StorageUpdateScorerDefinitionInput, StorageListScorerDefinitionsInput, StorageListScorerDefinitionsOutput, StorageListScorerDefinitionsResolvedOutput, StorageResolvedScorerDefinitionType, StorageCreateWorkspaceInput, StorageUpdateWorkspaceInput, StorageListWorkspacesInput, StorageListWorkspacesOutput, StorageListWorkspacesResolvedOutput, StorageResolvedWorkspaceType, StorageWorkspaceSnapshotType, StorageCreateSkillInput, StorageUpdateSkillInput, StorageListSkillsInput, StorageListSkillsOutput, StorageListSkillsResolvedOutput, StorageResolvedSkillType, RuleGroup, PromptBlocksStorage, BlobStore } from '@mastra/core/storage';
5
+ import { ProcessorProvider } from '@mastra/core/processor-provider';
6
+ import { StorageCreateAgentInput, StorageUpdateAgentInput, StorageListAgentsInput, StorageListAgentsOutput, StorageListAgentsResolvedOutput, StorageResolvedAgentType, StorageCreateMCPClientInput, StorageUpdateMCPClientInput, StorageListMCPClientsInput, StorageListMCPClientsOutput, StorageListMCPClientsResolvedOutput, StorageResolvedMCPClientType, StorageMCPServerConfig, StorageCreateMCPServerInput, StorageUpdateMCPServerInput, StorageListMCPServersInput, StorageListMCPServersOutput, StorageListMCPServersResolvedOutput, StorageResolvedMCPServerType, StorageCreatePromptBlockInput, StorageUpdatePromptBlockInput, StorageListPromptBlocksInput, StorageListPromptBlocksOutput, StorageListPromptBlocksResolvedOutput, StorageResolvedPromptBlockType, AgentInstructionBlock, StorageCreateScorerDefinitionInput, StorageUpdateScorerDefinitionInput, StorageListScorerDefinitionsInput, StorageListScorerDefinitionsOutput, StorageListScorerDefinitionsResolvedOutput, StorageResolvedScorerDefinitionType, StorageCreateWorkspaceInput, StorageUpdateWorkspaceInput, StorageListWorkspacesInput, StorageListWorkspacesOutput, StorageListWorkspacesResolvedOutput, StorageResolvedWorkspaceType, StorageWorkspaceSnapshotType, StorageCreateSkillInput, StorageUpdateSkillInput, StorageListSkillsInput, StorageListSkillsOutput, StorageListSkillsResolvedOutput, StorageResolvedSkillType, RuleGroup, PromptBlocksStorage, BlobStore } from '@mastra/core/storage';
6
7
  import { ToolProvider } from '@mastra/core/tool-provider';
7
8
  import { Agent } from '@mastra/core/agent';
8
9
  import { RequestContext } from '@mastra/core/request-context';
10
+ import { MCPServerBase } from '@mastra/core/mcp';
9
11
  import { MastraScorer } from '@mastra/core/evals';
10
12
  import { SkillSource, Workspace, WorkspaceFilesystem, WorkspaceSandbox } from '@mastra/core/workspace';
11
13
 
@@ -152,9 +154,6 @@ declare class EditorAgentNamespace extends CrudEditorNamespace<StorageCreateAgen
152
154
  private resolveStoredAgents;
153
155
  private resolveStoredMemory;
154
156
  private resolveStoredScorers;
155
- private findProcessor;
156
- private resolveStoredInputProcessors;
157
- private resolveStoredOutputProcessors;
158
157
  /**
159
158
  * Clone a runtime Agent instance into storage, creating a new stored agent
160
159
  * with the resolved configuration of the source agent.
@@ -208,6 +207,16 @@ declare class EditorMCPNamespace extends CrudEditorNamespace<StorageCreateMCPCli
208
207
  };
209
208
  }
210
209
 
210
+ declare class EditorMCPServerNamespace extends CrudEditorNamespace<StorageCreateMCPServerInput, StorageUpdateMCPServerInput, StorageListMCPServersInput, StorageListMCPServersOutput, StorageListMCPServersResolvedOutput, StorageResolvedMCPServerType, MCPServerBase> {
211
+ private mcpServerCtor;
212
+ protected onCacheEvict(_id: string): void;
213
+ protected hydrate(resolved: StorageResolvedMCPServerType): Promise<MCPServerBase>;
214
+ private resolveStoredTools;
215
+ private resolveStoredAgents;
216
+ private resolveStoredWorkflows;
217
+ protected getStorageAdapter(): Promise<StorageAdapter<StorageCreateMCPServerInput, StorageUpdateMCPServerInput, StorageListMCPServersInput, StorageListMCPServersOutput, StorageListMCPServersResolvedOutput, StorageResolvedMCPServerType>>;
218
+ }
219
+
211
220
  declare class EditorPromptNamespace extends CrudEditorNamespace<StorageCreatePromptBlockInput, StorageUpdatePromptBlockInput, StorageListPromptBlocksInput, StorageListPromptBlocksOutput, StorageListPromptBlocksResolvedOutput, StorageResolvedPromptBlockType> {
212
221
  protected onCacheEvict(id: string): void;
213
222
  protected getStorageAdapter(): Promise<StorageAdapter<StorageCreatePromptBlockInput, StorageUpdatePromptBlockInput, StorageListPromptBlocksInput, StorageListPromptBlocksOutput, StorageListPromptBlocksResolvedOutput, StorageResolvedPromptBlockType>>;
@@ -357,6 +366,7 @@ declare class MastraEditor implements IMastraEditor {
357
366
  /** @internal — exposed for namespace classes, not part of public API */
358
367
  __logger?: IMastraLogger;
359
368
  private __toolProviders;
369
+ private __processorProviders;
360
370
  /**
361
371
  * @internal — exposed for namespace classes to hydrate stored workspace configs.
362
372
  * Maps provider ID (e.g., 'local', 's3') to the provider descriptor.
@@ -378,6 +388,7 @@ declare class MastraEditor implements IMastraEditor {
378
388
  readonly __blobStores: Map<string, BlobStoreProvider>;
379
389
  readonly agent: EditorAgentNamespace;
380
390
  readonly mcp: EditorMCPNamespace;
391
+ readonly mcpServer: EditorMCPServerNamespace;
381
392
  readonly prompt: EditorPromptNamespace;
382
393
  readonly scorer: EditorScorerNamespace;
383
394
  readonly workspace: EditorWorkspaceNamespace;
@@ -392,6 +403,10 @@ declare class MastraEditor implements IMastraEditor {
392
403
  getToolProvider(id: string): ToolProvider | undefined;
393
404
  /** List all registered tool providers */
394
405
  getToolProviders(): Record<string, ToolProvider>;
406
+ /** Get a processor provider by ID */
407
+ getProcessorProvider(id: string): ProcessorProvider | undefined;
408
+ /** List all registered processor providers */
409
+ getProcessorProviders(): Record<string, ProcessorProvider>;
395
410
  /** List all registered filesystem providers */
396
411
  getFilesystemProviders(): FilesystemProvider[];
397
412
  /** List all registered sandbox providers */
@@ -411,4 +426,4 @@ declare class MastraEditor implements IMastraEditor {
411
426
  resolveBlobStore(providerId?: string, providerConfig?: Record<string, unknown>): Promise<BlobStore>;
412
427
  }
413
428
 
414
- export { CrudEditorNamespace, EditorAgentNamespace, EditorMCPNamespace, EditorNamespace, EditorPromptNamespace, EditorScorerNamespace, EditorSkillNamespace, EditorWorkspaceNamespace, MastraEditor, type StorageAdapter, evaluateRuleGroup, localFilesystemProvider, localSandboxProvider, renderTemplate, resolveInstructionBlocks };
429
+ export { CrudEditorNamespace, EditorAgentNamespace, EditorMCPNamespace, EditorMCPServerNamespace, EditorNamespace, EditorPromptNamespace, EditorScorerNamespace, EditorSkillNamespace, EditorWorkspaceNamespace, MastraEditor, type StorageAdapter, evaluateRuleGroup, localFilesystemProvider, localSandboxProvider, renderTemplate, resolveInstructionBlocks };
package/dist/index.d.ts CHANGED
@@ -2,10 +2,12 @@ import { Mastra } from '@mastra/core';
2
2
  import { GetByIdOptions, FilesystemProvider, SandboxProvider, IMastraEditor, BlobStoreProvider, MastraEditorConfig } from '@mastra/core/editor';
3
3
  export { MastraEditorConfig } from '@mastra/core/editor';
4
4
  import { IMastraLogger } from '@mastra/core/logger';
5
- import { StorageCreateAgentInput, StorageUpdateAgentInput, StorageListAgentsInput, StorageListAgentsOutput, StorageListAgentsResolvedOutput, StorageResolvedAgentType, StorageCreateMCPClientInput, StorageUpdateMCPClientInput, StorageListMCPClientsInput, StorageListMCPClientsOutput, StorageListMCPClientsResolvedOutput, StorageResolvedMCPClientType, StorageMCPServerConfig, StorageCreatePromptBlockInput, StorageUpdatePromptBlockInput, StorageListPromptBlocksInput, StorageListPromptBlocksOutput, StorageListPromptBlocksResolvedOutput, StorageResolvedPromptBlockType, AgentInstructionBlock, StorageCreateScorerDefinitionInput, StorageUpdateScorerDefinitionInput, StorageListScorerDefinitionsInput, StorageListScorerDefinitionsOutput, StorageListScorerDefinitionsResolvedOutput, StorageResolvedScorerDefinitionType, StorageCreateWorkspaceInput, StorageUpdateWorkspaceInput, StorageListWorkspacesInput, StorageListWorkspacesOutput, StorageListWorkspacesResolvedOutput, StorageResolvedWorkspaceType, StorageWorkspaceSnapshotType, StorageCreateSkillInput, StorageUpdateSkillInput, StorageListSkillsInput, StorageListSkillsOutput, StorageListSkillsResolvedOutput, StorageResolvedSkillType, RuleGroup, PromptBlocksStorage, BlobStore } from '@mastra/core/storage';
5
+ import { ProcessorProvider } from '@mastra/core/processor-provider';
6
+ import { StorageCreateAgentInput, StorageUpdateAgentInput, StorageListAgentsInput, StorageListAgentsOutput, StorageListAgentsResolvedOutput, StorageResolvedAgentType, StorageCreateMCPClientInput, StorageUpdateMCPClientInput, StorageListMCPClientsInput, StorageListMCPClientsOutput, StorageListMCPClientsResolvedOutput, StorageResolvedMCPClientType, StorageMCPServerConfig, StorageCreateMCPServerInput, StorageUpdateMCPServerInput, StorageListMCPServersInput, StorageListMCPServersOutput, StorageListMCPServersResolvedOutput, StorageResolvedMCPServerType, StorageCreatePromptBlockInput, StorageUpdatePromptBlockInput, StorageListPromptBlocksInput, StorageListPromptBlocksOutput, StorageListPromptBlocksResolvedOutput, StorageResolvedPromptBlockType, AgentInstructionBlock, StorageCreateScorerDefinitionInput, StorageUpdateScorerDefinitionInput, StorageListScorerDefinitionsInput, StorageListScorerDefinitionsOutput, StorageListScorerDefinitionsResolvedOutput, StorageResolvedScorerDefinitionType, StorageCreateWorkspaceInput, StorageUpdateWorkspaceInput, StorageListWorkspacesInput, StorageListWorkspacesOutput, StorageListWorkspacesResolvedOutput, StorageResolvedWorkspaceType, StorageWorkspaceSnapshotType, StorageCreateSkillInput, StorageUpdateSkillInput, StorageListSkillsInput, StorageListSkillsOutput, StorageListSkillsResolvedOutput, StorageResolvedSkillType, RuleGroup, PromptBlocksStorage, BlobStore } from '@mastra/core/storage';
6
7
  import { ToolProvider } from '@mastra/core/tool-provider';
7
8
  import { Agent } from '@mastra/core/agent';
8
9
  import { RequestContext } from '@mastra/core/request-context';
10
+ import { MCPServerBase } from '@mastra/core/mcp';
9
11
  import { MastraScorer } from '@mastra/core/evals';
10
12
  import { SkillSource, Workspace, WorkspaceFilesystem, WorkspaceSandbox } from '@mastra/core/workspace';
11
13
 
@@ -152,9 +154,6 @@ declare class EditorAgentNamespace extends CrudEditorNamespace<StorageCreateAgen
152
154
  private resolveStoredAgents;
153
155
  private resolveStoredMemory;
154
156
  private resolveStoredScorers;
155
- private findProcessor;
156
- private resolveStoredInputProcessors;
157
- private resolveStoredOutputProcessors;
158
157
  /**
159
158
  * Clone a runtime Agent instance into storage, creating a new stored agent
160
159
  * with the resolved configuration of the source agent.
@@ -208,6 +207,16 @@ declare class EditorMCPNamespace extends CrudEditorNamespace<StorageCreateMCPCli
208
207
  };
209
208
  }
210
209
 
210
+ declare class EditorMCPServerNamespace extends CrudEditorNamespace<StorageCreateMCPServerInput, StorageUpdateMCPServerInput, StorageListMCPServersInput, StorageListMCPServersOutput, StorageListMCPServersResolvedOutput, StorageResolvedMCPServerType, MCPServerBase> {
211
+ private mcpServerCtor;
212
+ protected onCacheEvict(_id: string): void;
213
+ protected hydrate(resolved: StorageResolvedMCPServerType): Promise<MCPServerBase>;
214
+ private resolveStoredTools;
215
+ private resolveStoredAgents;
216
+ private resolveStoredWorkflows;
217
+ protected getStorageAdapter(): Promise<StorageAdapter<StorageCreateMCPServerInput, StorageUpdateMCPServerInput, StorageListMCPServersInput, StorageListMCPServersOutput, StorageListMCPServersResolvedOutput, StorageResolvedMCPServerType>>;
218
+ }
219
+
211
220
  declare class EditorPromptNamespace extends CrudEditorNamespace<StorageCreatePromptBlockInput, StorageUpdatePromptBlockInput, StorageListPromptBlocksInput, StorageListPromptBlocksOutput, StorageListPromptBlocksResolvedOutput, StorageResolvedPromptBlockType> {
212
221
  protected onCacheEvict(id: string): void;
213
222
  protected getStorageAdapter(): Promise<StorageAdapter<StorageCreatePromptBlockInput, StorageUpdatePromptBlockInput, StorageListPromptBlocksInput, StorageListPromptBlocksOutput, StorageListPromptBlocksResolvedOutput, StorageResolvedPromptBlockType>>;
@@ -357,6 +366,7 @@ declare class MastraEditor implements IMastraEditor {
357
366
  /** @internal — exposed for namespace classes, not part of public API */
358
367
  __logger?: IMastraLogger;
359
368
  private __toolProviders;
369
+ private __processorProviders;
360
370
  /**
361
371
  * @internal — exposed for namespace classes to hydrate stored workspace configs.
362
372
  * Maps provider ID (e.g., 'local', 's3') to the provider descriptor.
@@ -378,6 +388,7 @@ declare class MastraEditor implements IMastraEditor {
378
388
  readonly __blobStores: Map<string, BlobStoreProvider>;
379
389
  readonly agent: EditorAgentNamespace;
380
390
  readonly mcp: EditorMCPNamespace;
391
+ readonly mcpServer: EditorMCPServerNamespace;
381
392
  readonly prompt: EditorPromptNamespace;
382
393
  readonly scorer: EditorScorerNamespace;
383
394
  readonly workspace: EditorWorkspaceNamespace;
@@ -392,6 +403,10 @@ declare class MastraEditor implements IMastraEditor {
392
403
  getToolProvider(id: string): ToolProvider | undefined;
393
404
  /** List all registered tool providers */
394
405
  getToolProviders(): Record<string, ToolProvider>;
406
+ /** Get a processor provider by ID */
407
+ getProcessorProvider(id: string): ProcessorProvider | undefined;
408
+ /** List all registered processor providers */
409
+ getProcessorProviders(): Record<string, ProcessorProvider>;
395
410
  /** List all registered filesystem providers */
396
411
  getFilesystemProviders(): FilesystemProvider[];
397
412
  /** List all registered sandbox providers */
@@ -411,4 +426,4 @@ declare class MastraEditor implements IMastraEditor {
411
426
  resolveBlobStore(providerId?: string, providerConfig?: Record<string, unknown>): Promise<BlobStore>;
412
427
  }
413
428
 
414
- export { CrudEditorNamespace, EditorAgentNamespace, EditorMCPNamespace, EditorNamespace, EditorPromptNamespace, EditorScorerNamespace, EditorSkillNamespace, EditorWorkspaceNamespace, MastraEditor, type StorageAdapter, evaluateRuleGroup, localFilesystemProvider, localSandboxProvider, renderTemplate, resolveInstructionBlocks };
429
+ export { CrudEditorNamespace, EditorAgentNamespace, EditorMCPNamespace, EditorMCPServerNamespace, EditorNamespace, EditorPromptNamespace, EditorScorerNamespace, EditorSkillNamespace, EditorWorkspaceNamespace, MastraEditor, type StorageAdapter, evaluateRuleGroup, localFilesystemProvider, localSandboxProvider, renderTemplate, resolveInstructionBlocks };
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ // src/index.ts
2
+ import { BUILT_IN_PROCESSOR_PROVIDERS } from "@mastra/core/processor-provider";
3
+
1
4
  // src/namespaces/base.ts
2
5
  var EditorNamespace = class {
3
6
  constructor(editor) {
@@ -287,6 +290,177 @@ async function resolveInstructionBlocks(blocks, context, deps) {
287
290
  return segments.join("\n\n");
288
291
  }
289
292
 
293
+ // src/processor-graph-hydrator.ts
294
+ import { ProcessorStepSchema } from "@mastra/core/processors";
295
+ import { PhaseFilteredProcessor } from "@mastra/core/processor-provider";
296
+ import { createWorkflow, createStep } from "@mastra/core/workflows";
297
+ var PASSTHROUGH_STEP_PREFIX = "passthrough-";
298
+ function resolveStep(step, ctx) {
299
+ const provider = ctx.providers[step.providerId];
300
+ if (!provider) {
301
+ ctx.logger?.warn(`ProcessorProvider "${step.providerId}" not found for graph step "${step.id}"`);
302
+ return void 0;
303
+ }
304
+ const processor = provider.createProcessor(step.config);
305
+ const allProviderPhases = provider.availablePhases;
306
+ const enabledSet = new Set(step.enabledPhases);
307
+ const needsFiltering = allProviderPhases.some((p) => !enabledSet.has(p));
308
+ if (needsFiltering) {
309
+ const filtered = new PhaseFilteredProcessor(processor, step.enabledPhases);
310
+ if (ctx.mastra) {
311
+ filtered.__registerMastra(ctx.mastra);
312
+ }
313
+ return filtered;
314
+ }
315
+ if (ctx.mastra && processor.__registerMastra) {
316
+ processor.__registerMastra(ctx.mastra);
317
+ }
318
+ return processor;
319
+ }
320
+ function isSequentialOnly(entries) {
321
+ return entries.every((e) => e.type === "step");
322
+ }
323
+ function hydrateSequential(entries, ctx) {
324
+ const processors = [];
325
+ for (const entry of entries) {
326
+ if (entry.type !== "step") continue;
327
+ const processor = resolveStep(entry.step, ctx);
328
+ if (processor) {
329
+ processors.push(processor);
330
+ }
331
+ }
332
+ return processors;
333
+ }
334
+ async function mergeBranchOutputs({ inputData }) {
335
+ const keys = Object.keys(inputData).sort((a, b) => {
336
+ const aPass = a.startsWith(PASSTHROUGH_STEP_PREFIX) ? 1 : 0;
337
+ const bPass = b.startsWith(PASSTHROUGH_STEP_PREFIX) ? 1 : 0;
338
+ return aPass - bPass;
339
+ });
340
+ for (const key of keys) {
341
+ const val = inputData[key];
342
+ if (val && typeof val === "object" && "phase" in val) {
343
+ return {
344
+ phase: val.phase,
345
+ messages: val.messages,
346
+ messageList: val.messageList,
347
+ ...val.systemMessages ? { systemMessages: val.systemMessages } : {},
348
+ ...val.part !== void 0 ? { part: val.part } : {},
349
+ ...val.streamParts ? { streamParts: val.streamParts } : {},
350
+ ...val.state ? { state: val.state } : {},
351
+ ...val.text !== void 0 ? { text: val.text } : {},
352
+ ...val.retryCount !== void 0 ? { retryCount: val.retryCount } : {}
353
+ };
354
+ }
355
+ }
356
+ return inputData;
357
+ }
358
+ function buildWorkflow(entries, workflowId, ctx) {
359
+ let workflow = createWorkflow({
360
+ id: workflowId,
361
+ inputSchema: ProcessorStepSchema,
362
+ outputSchema: ProcessorStepSchema,
363
+ type: "processor",
364
+ options: {
365
+ validateInputs: false
366
+ }
367
+ });
368
+ let hasSteps = false;
369
+ for (const entry of entries) {
370
+ if (entry.type === "step") {
371
+ const processor = resolveStep(entry.step, ctx);
372
+ if (!processor) continue;
373
+ const step = createStep(processor);
374
+ workflow = workflow.then(step);
375
+ hasSteps = true;
376
+ } else if (entry.type === "parallel") {
377
+ const branchSteps = entry.branches.map((branchEntries, branchIdx) => {
378
+ if (branchEntries.length === 1 && branchEntries[0].type === "step") {
379
+ const proc = resolveStep(branchEntries[0].step, ctx);
380
+ if (!proc) return void 0;
381
+ return createStep(proc);
382
+ }
383
+ const subWorkflow = buildWorkflow(branchEntries, `${workflowId}-parallel-branch-${branchIdx}`, ctx);
384
+ return subWorkflow;
385
+ }).filter(Boolean);
386
+ if (branchSteps.length > 0) {
387
+ workflow = workflow.parallel(branchSteps);
388
+ workflow = workflow.map(mergeBranchOutputs);
389
+ hasSteps = true;
390
+ }
391
+ } else if (entry.type === "conditional") {
392
+ const branchTuples = [];
393
+ for (const [i, condition] of entry.conditions.entries()) {
394
+ let branchStep;
395
+ if (condition.steps.length === 1 && condition.steps[0].type === "step") {
396
+ const proc = resolveStep(condition.steps[0].step, ctx);
397
+ if (!proc) continue;
398
+ branchStep = createStep(proc);
399
+ } else {
400
+ branchStep = buildWorkflow(condition.steps, `${workflowId}-cond-branch-${i}`, ctx);
401
+ if (!branchStep) continue;
402
+ }
403
+ if (condition.rules) {
404
+ const rules = condition.rules;
405
+ const conditionFn = async ({ inputData }) => {
406
+ return evaluateRuleGroup(rules, inputData);
407
+ };
408
+ branchTuples.push([conditionFn, branchStep]);
409
+ } else {
410
+ branchTuples.push([async () => true, branchStep]);
411
+ }
412
+ }
413
+ if (branchTuples.length > 0) {
414
+ const passthroughStep = createStep({
415
+ id: `${PASSTHROUGH_STEP_PREFIX}${workflowId}`,
416
+ inputSchema: ProcessorStepSchema,
417
+ outputSchema: ProcessorStepSchema,
418
+ execute: async ({ inputData }) => inputData
419
+ });
420
+ branchTuples.push([async () => true, passthroughStep]);
421
+ workflow = workflow.branch(branchTuples);
422
+ workflow = workflow.map(mergeBranchOutputs);
423
+ hasSteps = true;
424
+ }
425
+ }
426
+ }
427
+ if (!hasSteps) return void 0;
428
+ return workflow.commit();
429
+ }
430
+ function hydrateProcessorGraph(graph, mode, ctx) {
431
+ if (!graph) return void 0;
432
+ if (Array.isArray(graph)) {
433
+ ctx.logger?.warn(
434
+ "Processor graph is in legacy string[] format and cannot be hydrated. Re-save the agent to migrate."
435
+ );
436
+ return void 0;
437
+ }
438
+ if (!Array.isArray(graph.steps) || graph.steps.length === 0) return void 0;
439
+ if (isSequentialOnly(graph.steps)) {
440
+ const processors = hydrateSequential(graph.steps, ctx);
441
+ if (processors.length === 0) return void 0;
442
+ if (mode === "input") {
443
+ const filtered = processors.filter((p) => p.processInput || p.processInputStep);
444
+ return filtered.length > 0 ? filtered : void 0;
445
+ } else {
446
+ const filtered = processors.filter((p) => p.processOutputStream || p.processOutputResult || p.processOutputStep);
447
+ return filtered.length > 0 ? filtered : void 0;
448
+ }
449
+ }
450
+ const workflowId = `stored-${mode}-processor-graph`;
451
+ const workflow = buildWorkflow(graph.steps, workflowId, ctx);
452
+ if (!workflow) return void 0;
453
+ return [workflow];
454
+ }
455
+ function selectFirstMatchingGraph(variants, context) {
456
+ for (const variant of variants) {
457
+ if (!variant.rules || evaluateRuleGroup(variant.rules, context)) {
458
+ return variant.value;
459
+ }
460
+ }
461
+ return void 0;
462
+ }
463
+
290
464
  // src/namespaces/mcp.ts
291
465
  var EditorMCPNamespace = class _EditorMCPNamespace extends CrudEditorNamespace {
292
466
  onCacheEvict(_id) {
@@ -531,22 +705,24 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
531
705
  );
532
706
  return this.resolveStoredScorers(resolved);
533
707
  } : await this.resolveStoredScorers(storedAgent.scorers);
708
+ const processorProviders = this.editor.getProcessorProviders();
709
+ const hydrationCtx = { providers: processorProviders, mastra: this.mastra, logger: this.logger };
534
710
  const inputProcessors = hasConditionalInputProcessors ? ({ requestContext }) => {
535
711
  const ctx = requestContext.toJSON();
536
- const resolved = this.accumulateArrayVariants(
712
+ const graph = selectFirstMatchingGraph(
537
713
  storedAgent.inputProcessors,
538
714
  ctx
539
715
  );
540
- return this.resolveStoredInputProcessors(resolved);
541
- } : this.resolveStoredInputProcessors(storedAgent.inputProcessors);
716
+ return hydrateProcessorGraph(graph, "input", hydrationCtx);
717
+ } : hydrateProcessorGraph(storedAgent.inputProcessors, "input", hydrationCtx);
542
718
  const outputProcessors = hasConditionalOutputProcessors ? ({ requestContext }) => {
543
719
  const ctx = requestContext.toJSON();
544
- const resolved = this.accumulateArrayVariants(
720
+ const graph = selectFirstMatchingGraph(
545
721
  storedAgent.outputProcessors,
546
722
  ctx
547
723
  );
548
- return this.resolveStoredOutputProcessors(resolved);
549
- } : this.resolveStoredOutputProcessors(storedAgent.outputProcessors);
724
+ return hydrateProcessorGraph(graph, "output", hydrationCtx);
725
+ } : hydrateProcessorGraph(storedAgent.outputProcessors, "output", hydrationCtx);
550
726
  let model;
551
727
  let staticModelConfig;
552
728
  const modelSettingsFrom = (cfg) => ({
@@ -936,41 +1112,6 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
936
1112
  }
937
1113
  return Object.keys(resolvedScorers).length > 0 ? resolvedScorers : void 0;
938
1114
  }
939
- findProcessor(processorKey) {
940
- if (!this.mastra) return void 0;
941
- try {
942
- return this.mastra.getProcessor(processorKey);
943
- } catch {
944
- try {
945
- return this.mastra.getProcessorById(processorKey);
946
- } catch {
947
- this.logger?.warn(`Processor "${processorKey}" referenced in stored agent but not registered in Mastra`);
948
- return void 0;
949
- }
950
- }
951
- }
952
- resolveStoredInputProcessors(storedProcessors) {
953
- if (!storedProcessors || storedProcessors.length === 0) return void 0;
954
- const resolved = [];
955
- for (const key of storedProcessors) {
956
- const processor = this.findProcessor(key);
957
- if (processor && (processor.processInput || processor.processInputStep)) {
958
- resolved.push(processor);
959
- }
960
- }
961
- return resolved.length > 0 ? resolved : void 0;
962
- }
963
- resolveStoredOutputProcessors(storedProcessors) {
964
- if (!storedProcessors || storedProcessors.length === 0) return void 0;
965
- const resolved = [];
966
- for (const key of storedProcessors) {
967
- const processor = this.findProcessor(key);
968
- if (processor && (processor.processOutputStream || processor.processOutputResult || processor.processOutputStep)) {
969
- resolved.push(processor);
970
- }
971
- }
972
- return resolved.length > 0 ? resolved : void 0;
973
- }
974
1115
  // ============================================================================
975
1116
  // Clone
976
1117
  // ============================================================================
@@ -1018,9 +1159,6 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1018
1159
  const agentKeys = Object.keys(agentsResolved || {});
1019
1160
  const memory = await agent.getMemory({ requestContext });
1020
1161
  const memoryConfig = memory?.getConfig();
1021
- const { inputProcessorIds, outputProcessorIds } = await agent.getConfiguredProcessorIds(requestContext);
1022
- const inputProcessorKeys = inputProcessorIds.length > 0 ? inputProcessorIds : void 0;
1023
- const outputProcessorKeys = outputProcessorIds.length > 0 ? outputProcessorIds : void 0;
1024
1162
  let storedScorers;
1025
1163
  const resolvedScorers = await agent.listScorers({ requestContext });
1026
1164
  if (resolvedScorers && Object.keys(resolvedScorers).length > 0) {
@@ -1055,8 +1193,6 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1055
1193
  workflows: workflowKeys.length > 0 ? Object.fromEntries(workflowKeys.map((key) => [key, {}])) : void 0,
1056
1194
  agents: agentKeys.length > 0 ? Object.fromEntries(agentKeys.map((key) => [key, {}])) : void 0,
1057
1195
  memory: memoryConfig,
1058
- inputProcessors: inputProcessorKeys,
1059
- outputProcessors: outputProcessorKeys,
1060
1196
  scorers: storedScorers,
1061
1197
  defaultOptions: storageDefaultOptions,
1062
1198
  metadata: options.metadata,
@@ -1171,6 +1307,112 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1171
1307
  }
1172
1308
  };
1173
1309
 
1310
+ // src/namespaces/mcp-server.ts
1311
+ var EditorMCPServerNamespace = class extends CrudEditorNamespace {
1312
+ onCacheEvict(_id) {
1313
+ }
1314
+ async hydrate(resolved) {
1315
+ if (!this.mastra) {
1316
+ throw new Error("MastraEditor is not registered with a Mastra instance");
1317
+ }
1318
+ const tools = this.resolveStoredTools(resolved.tools);
1319
+ const agents = this.resolveStoredAgents(resolved.agents);
1320
+ const workflows = this.resolveStoredWorkflows(resolved.workflows);
1321
+ if (!this.mcpServerCtor) {
1322
+ try {
1323
+ const mod = await import("@mastra/mcp");
1324
+ this.mcpServerCtor = mod.MCPServer;
1325
+ } catch {
1326
+ throw new Error(
1327
+ "@mastra/mcp is required to hydrate MCP server configurations. Install it with: npm install @mastra/mcp"
1328
+ );
1329
+ }
1330
+ }
1331
+ const server = new this.mcpServerCtor({
1332
+ id: resolved.id,
1333
+ name: resolved.name,
1334
+ version: resolved.version,
1335
+ description: resolved.description,
1336
+ instructions: resolved.instructions,
1337
+ repository: resolved.repository,
1338
+ releaseDate: resolved.releaseDate,
1339
+ isLatest: resolved.isLatest,
1340
+ packageCanonical: resolved.packageCanonical,
1341
+ tools,
1342
+ agents,
1343
+ workflows
1344
+ });
1345
+ this.mastra.addMCPServer(server, resolved.id);
1346
+ return server;
1347
+ }
1348
+ resolveStoredTools(storedTools) {
1349
+ if (!storedTools || Object.keys(storedTools).length === 0) return {};
1350
+ if (!this.mastra) return {};
1351
+ const resolved = {};
1352
+ for (const [toolKey, toolConfig] of Object.entries(storedTools)) {
1353
+ try {
1354
+ const tool = this.mastra.getToolById(toolKey);
1355
+ if (toolConfig.description) {
1356
+ resolved[toolKey] = { ...tool, description: toolConfig.description };
1357
+ } else {
1358
+ resolved[toolKey] = tool;
1359
+ }
1360
+ } catch {
1361
+ this.logger?.warn(`Tool "${toolKey}" referenced in stored MCP server but not registered in Mastra`);
1362
+ }
1363
+ }
1364
+ return resolved;
1365
+ }
1366
+ resolveStoredAgents(storedAgents) {
1367
+ if (!storedAgents || Object.keys(storedAgents).length === 0) return {};
1368
+ if (!this.mastra) return {};
1369
+ const resolved = {};
1370
+ for (const agentKey of Object.keys(storedAgents)) {
1371
+ try {
1372
+ resolved[agentKey] = this.mastra.getAgent(agentKey);
1373
+ } catch {
1374
+ try {
1375
+ resolved[agentKey] = this.mastra.getAgentById(agentKey);
1376
+ } catch {
1377
+ this.logger?.warn(`Agent "${agentKey}" referenced in stored MCP server but not registered in Mastra`);
1378
+ }
1379
+ }
1380
+ }
1381
+ return resolved;
1382
+ }
1383
+ resolveStoredWorkflows(storedWorkflows) {
1384
+ if (!storedWorkflows || Object.keys(storedWorkflows).length === 0) return {};
1385
+ if (!this.mastra) return {};
1386
+ const resolved = {};
1387
+ for (const workflowKey of Object.keys(storedWorkflows)) {
1388
+ try {
1389
+ resolved[workflowKey] = this.mastra.getWorkflow(workflowKey);
1390
+ } catch {
1391
+ try {
1392
+ resolved[workflowKey] = this.mastra.getWorkflowById(workflowKey);
1393
+ } catch {
1394
+ this.logger?.warn(`Workflow "${workflowKey}" referenced in stored MCP server but not registered in Mastra`);
1395
+ }
1396
+ }
1397
+ }
1398
+ return resolved;
1399
+ }
1400
+ async getStorageAdapter() {
1401
+ const storage = this.mastra?.getStorage();
1402
+ if (!storage) throw new Error("Storage is not configured");
1403
+ const store = await storage.getStore("mcpServers");
1404
+ if (!store) throw new Error("MCP servers storage domain is not available");
1405
+ return {
1406
+ create: (input) => store.create({ mcpServer: input }),
1407
+ getByIdResolved: (id) => store.getByIdResolved(id),
1408
+ update: (input) => store.update(input),
1409
+ delete: (id) => store.delete(id),
1410
+ list: (args) => store.list(args),
1411
+ listResolved: (args) => store.listResolved(args)
1412
+ };
1413
+ }
1414
+ };
1415
+
1174
1416
  // src/namespaces/prompt.ts
1175
1417
  var EditorPromptNamespace = class extends CrudEditorNamespace {
1176
1418
  onCacheEvict(id) {
@@ -1529,6 +1771,7 @@ var MastraEditor = class {
1529
1771
  constructor(config) {
1530
1772
  this.__logger = config?.logger;
1531
1773
  this.__toolProviders = config?.toolProviders ?? {};
1774
+ this.__processorProviders = { ...BUILT_IN_PROCESSOR_PROVIDERS, ...config?.processorProviders };
1532
1775
  this.__filesystems = /* @__PURE__ */ new Map();
1533
1776
  this.__filesystems.set(localFilesystemProvider.id, localFilesystemProvider);
1534
1777
  for (const [id, provider] of Object.entries(config?.filesystems ?? {})) {
@@ -1545,6 +1788,7 @@ var MastraEditor = class {
1545
1788
  }
1546
1789
  this.agent = new EditorAgentNamespace(this);
1547
1790
  this.mcp = new EditorMCPNamespace(this);
1791
+ this.mcpServer = new EditorMCPServerNamespace(this);
1548
1792
  this.prompt = new EditorPromptNamespace(this);
1549
1793
  this.scorer = new EditorScorerNamespace(this);
1550
1794
  this.workspace = new EditorWorkspaceNamespace(this);
@@ -1568,6 +1812,14 @@ var MastraEditor = class {
1568
1812
  getToolProviders() {
1569
1813
  return this.__toolProviders;
1570
1814
  }
1815
+ /** Get a processor provider by ID */
1816
+ getProcessorProvider(id) {
1817
+ return this.__processorProviders[id];
1818
+ }
1819
+ /** List all registered processor providers */
1820
+ getProcessorProviders() {
1821
+ return this.__processorProviders;
1822
+ }
1571
1823
  /** List all registered filesystem providers */
1572
1824
  getFilesystemProviders() {
1573
1825
  return Array.from(this.__filesystems.values());
@@ -1613,6 +1865,7 @@ export {
1613
1865
  CrudEditorNamespace,
1614
1866
  EditorAgentNamespace,
1615
1867
  EditorMCPNamespace,
1868
+ EditorMCPServerNamespace,
1616
1869
  EditorNamespace,
1617
1870
  EditorPromptNamespace,
1618
1871
  EditorScorerNamespace,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/editor",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Mastra Editor for agent management and instantiation",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -55,19 +55,23 @@
55
55
  "@arcadeai/arcadejs": "^2.2.0",
56
56
  "@composio/core": "^0.6.3",
57
57
  "@composio/mastra": "^0.6.3",
58
- "@mastra/memory": "1.4.0",
59
- "@mastra/schema-compat": "1.1.1"
58
+ "@mastra/memory": "1.5.0",
59
+ "@mastra/schema-compat": "1.1.2"
60
60
  },
61
61
  "devDependencies": {
62
+ "@hono/node-server": "^1.14.1",
63
+ "hono": "^4.7.10",
62
64
  "tsup": "^8.0.2",
63
65
  "typescript": "^5.9.3",
64
- "vitest": "4.0.16",
66
+ "vitest": "4.0.18",
65
67
  "zod": "^3.25.76",
66
- "@internal/ai-sdk-v4": "0.0.7",
67
- "@internal/ai-v6": "0.0.7",
68
- "@internal/ai-sdk-v5": "0.0.7",
69
- "@mastra/core": "1.5.0",
70
- "@mastra/libsql": "1.5.0"
68
+ "@internal/ai-sdk-v5": "0.0.8",
69
+ "@internal/ai-sdk-v4": "0.0.8",
70
+ "@mastra/core": "1.6.0",
71
+ "@internal/ai-v6": "0.0.8",
72
+ "@mastra/hono": "1.1.5",
73
+ "@mastra/libsql": "1.6.0",
74
+ "@mastra/mcp": "1.0.1"
71
75
  },
72
76
  "peerDependencies": {
73
77
  "@mastra/core": ">=1.0.0-0 <2.0.0-0",