@ema.co/mcp-toolkit 2026.2.13 → 2026.2.23-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @ema.co/mcp-toolkit might be problematic. Click here for more details.

Files changed (67) hide show
  1. package/.context/public/guides/ema-user-guide.md +12 -16
  2. package/.context/public/guides/mcp-tools-guide.md +203 -334
  3. package/dist/cli/index.js +2 -2
  4. package/dist/mcp/domain/loop-detection.js +89 -0
  5. package/dist/mcp/domain/sanitizer.js +1 -1
  6. package/dist/mcp/domain/structural-rules.js +4 -5
  7. package/dist/mcp/domain/validation-rules.js +5 -5
  8. package/dist/mcp/domain/workflow-graph.js +3 -5
  9. package/dist/mcp/domain/workflow-path-enumerator.js +7 -4
  10. package/dist/mcp/guidance.js +62 -29
  11. package/dist/mcp/handlers/debug/adapter.js +15 -0
  12. package/dist/mcp/handlers/debug/formatters.js +282 -0
  13. package/dist/mcp/handlers/debug/index.js +133 -0
  14. package/dist/mcp/handlers/demo/adapter.js +180 -0
  15. package/dist/mcp/handlers/env/config.js +2 -2
  16. package/dist/mcp/handlers/feedback/index.js +1 -1
  17. package/dist/mcp/handlers/index.js +0 -1
  18. package/dist/mcp/handlers/persona/adapter.js +135 -0
  19. package/dist/mcp/handlers/persona/index.js +237 -8
  20. package/dist/mcp/handlers/persona/schema.js +27 -0
  21. package/dist/mcp/handlers/reference/index.js +6 -4
  22. package/dist/mcp/handlers/sync/adapter.js +200 -0
  23. package/dist/mcp/handlers/workflow/adapter.js +174 -0
  24. package/dist/mcp/handlers/workflow/fix.js +11 -12
  25. package/dist/mcp/handlers/workflow/index.js +12 -40
  26. package/dist/mcp/handlers/workflow/validation.js +1 -1
  27. package/dist/mcp/knowledge-guidance-topics.js +615 -0
  28. package/dist/mcp/knowledge-types.js +7 -0
  29. package/dist/mcp/knowledge.js +75 -1403
  30. package/dist/mcp/resources-dynamic.js +2395 -0
  31. package/dist/mcp/resources-validation.js +408 -0
  32. package/dist/mcp/resources.js +72 -2508
  33. package/dist/mcp/server.js +69 -2825
  34. package/dist/mcp/tools.js +106 -5
  35. package/dist/sdk/client-adapter.js +265 -24
  36. package/dist/sdk/ema-client.js +100 -9
  37. package/dist/sdk/generated/agent-catalog.js +615 -0
  38. package/dist/sdk/generated/api-client/client/client.gen.js +3 -3
  39. package/dist/sdk/generated/api-client/client/index.js +5 -5
  40. package/dist/sdk/generated/api-client/client/utils.gen.js +4 -4
  41. package/dist/sdk/generated/api-client/client.gen.js +1 -1
  42. package/dist/sdk/generated/api-client/core/utils.gen.js +1 -1
  43. package/dist/sdk/generated/api-client/index.js +1 -1
  44. package/dist/sdk/generated/api-client/sdk.gen.js +2 -2
  45. package/dist/sdk/generated/well-known-types.js +99 -0
  46. package/dist/sdk/generated/widget-catalog.js +60 -0
  47. package/dist/sdk/grpc-client.js +115 -1
  48. package/dist/sync/sdk.js +2 -2
  49. package/dist/sync.js +4 -3
  50. package/docs/README.md +17 -9
  51. package/package.json +4 -3
  52. package/.context/public/guides/dashboard-operations.md +0 -349
  53. package/.context/public/guides/email-patterns.md +0 -125
  54. package/.context/public/guides/workflow-builder-patterns.md +0 -708
  55. package/dist/mcp/domain/intent-architect.js +0 -914
  56. package/dist/mcp/domain/quality-gates.js +0 -110
  57. package/dist/mcp/domain/workflow-execution-analyzer.js +0 -412
  58. package/dist/mcp/domain/workflow-intent.js +0 -1806
  59. package/dist/mcp/domain/workflow-merge.js +0 -449
  60. package/dist/mcp/domain/workflow-tracer.js +0 -648
  61. package/dist/mcp/domain/workflow-transformer.js +0 -742
  62. package/dist/mcp/handlers/knowledge/index.js +0 -54
  63. package/dist/mcp/handlers/persona/intent.js +0 -141
  64. package/dist/mcp/handlers/workflow/analyze.js +0 -119
  65. package/dist/mcp/handlers/workflow/compare.js +0 -70
  66. package/dist/mcp/handlers/workflow/generate.js +0 -384
  67. package/dist/mcp/handlers-consolidated.js +0 -333
@@ -1,333 +0,0 @@
1
- /**
2
- * Consolidated Tool Handlers
3
- *
4
- * Each handler dispatches based on mode/flags following Unix CLI patterns.
5
- */
6
- // Import shared utilities from handlers module
7
- import { resolvePersona, } from "./handlers/index.js";
8
- // Import extracted persona mode handlers
9
- import { hasExtractedHandler, getPersonaModeHandler, handleVersion, } from "./handlers/persona/index.js";
10
- // Import extracted handlers (Phase 1 modularization)
11
- import { handleEnv as handleEnvExtracted } from "./handlers/env/index.js";
12
- import { handleTemplate as handleTemplateExtracted } from "./handlers/template/index.js";
13
- import { handleAction as handleActionExtracted } from "./handlers/action/index.js";
14
- import { handleReference as handleReferenceExtracted } from "./handlers/reference/index.js";
15
- import { handleKnowledge as handleKnowledgeExtracted } from "./handlers/knowledge/index.js";
16
- import { handleSync as handleSyncExtracted } from "./handlers/sync/index.js";
17
- // Import extracted workflow handler (Phase 2 modularization)
18
- // Note: Imported as "Extracted" to avoid conflict with local definition during transition
19
- // The local handleWorkflow will be removed once all tests pass
20
- import { handleWorkflow as handleWorkflowExtracted } from "./handlers/workflow/index.js";
21
- // Args type imported from handlers/types.ts
22
- // ─────────────────────────────────────────────────────────────────────────────
23
- // Generation Templates - MOVED to handlers/data/templates.ts
24
- // Import via: import { GENERATION_TEMPLATES } from "./handlers/data/templates.js"
25
- // ─────────────────────────────────────────────────────────────────────────────
26
- // ─────────────────────────────────────────────────────────────────────────────
27
- // Widget Validation Helpers
28
- // ─────────────────────────────────────────────────────────────────────────────
29
- // isValidWidget and sanitizeWidgets imported from ../sdk/proto-config.js
30
- // validateWidgetsForApi imported from handlers/utils.ts
31
- // Deprecation tracking - single source of truth
32
- import { checkDeprecatedParams, addDeprecationWarnings } from "./handlers/deprecation.js";
33
- // Template utilities imported from handlers/utils.ts:
34
- // - normalizeTriggerType
35
- // - getTemplates
36
- // - clearTemplateCache
37
- // - getPersonaTypeFromTemplate
38
- // ═══════════════════════════════════════════════════════════════════════════
39
- // Extracted Handler Exports
40
- // ═══════════════════════════════════════════════════════════════════════════
41
- // These handlers are fully extracted to handlers/*/ directories.
42
- // Re-exported here for backwards compatibility with server.ts imports.
43
- export const handleEnv = handleEnvExtracted;
44
- export const handleAction = handleActionExtracted;
45
- export const handleTemplate = handleTemplateExtracted;
46
- export const handleKnowledge = handleKnowledgeExtracted;
47
- export const handleReference = handleReferenceExtracted;
48
- export const handleSync = handleSyncExtracted;
49
- // ═══════════════════════════════════════════════════════════════════════════
50
- // PERSONA Handler
51
- // ═══════════════════════════════════════════════════════════════════════════
52
- export async function handlePersona(args, client, getTemplateId, createClientForEnv, versionContext) {
53
- // Check for deprecated params and log warnings
54
- const deprecationWarnings = checkDeprecatedParams(args);
55
- for (const warning of deprecationWarnings) {
56
- console.warn(`[persona] Deprecation: ${warning}`);
57
- }
58
- const id = args.id;
59
- const identifier = args.identifier; // deprecated alias for 'id'
60
- const idOrName = id ?? identifier;
61
- // Support both 'method' (new) and 'mode' (legacy) - method takes precedence
62
- const method = args.method;
63
- const mode = method ?? args.mode;
64
- // ═══════════════════════════════════════════════════════════════════════════
65
- // DATA SUB-RESOURCE: Handle data={method:...} early
66
- // ═══════════════════════════════════════════════════════════════════════════
67
- const dataArg = args.data;
68
- if (dataArg && typeof dataArg === "object") {
69
- // Data operations require persona id
70
- if (!idOrName) {
71
- return {
72
- error: "Data operations require persona id",
73
- hint: "Use persona(id=\"abc\", data={method:\"list\"})",
74
- };
75
- }
76
- const dataMethod = dataArg.method;
77
- if (!dataMethod) {
78
- return {
79
- error: "Data operations require explicit method",
80
- hint: "Use data={method:\"list|schema|upload|copy|delete|embed|search\", ...}",
81
- valid_methods: ["list", "schema", "upload", "copy", "delete", "embed", "search"],
82
- };
83
- }
84
- // Map new method names to existing handlers
85
- const methodToMode = {
86
- "list": "list",
87
- "schema": "schema",
88
- "upload": "upload",
89
- "copy": "dashboard_clone", // copy → dashboard_clone handler
90
- "delete": "delete",
91
- "embed": "embed",
92
- "search": "search",
93
- };
94
- const mappedMode = methodToMode[dataMethod];
95
- if (!mappedMode) {
96
- return {
97
- error: `Unknown data method: ${dataMethod}`,
98
- valid_methods: Object.keys(methodToMode),
99
- };
100
- }
101
- // Build args for data handler - map new param names to old param names
102
- const dataArgs = {
103
- persona_id: idOrName,
104
- mode: mappedMode,
105
- };
106
- // Add optional params if present
107
- if (dataArg.from)
108
- dataArgs.source_persona_id = dataArg.from;
109
- if (dataArg.sanitize !== undefined)
110
- dataArgs.sanitize = dataArg.sanitize;
111
- if (dataArg.path)
112
- dataArgs.file_path = dataArg.path;
113
- if (dataArg.content)
114
- dataArgs.content = dataArg.content;
115
- if (dataArg.file_id)
116
- dataArgs.file_id = dataArg.file_id;
117
- else if (dataArg.id)
118
- dataArgs.file_id = dataArg.id; // backwards compat
119
- if (dataArg.enabled !== undefined)
120
- dataArgs.embed = dataArg.enabled;
121
- if (dataArg.query)
122
- dataArgs.query = dataArg.query;
123
- // Data handler requires readFile function - use fs.readFile
124
- const readFile = async (path) => {
125
- const fs = await import("fs/promises");
126
- return fs.readFile(path);
127
- };
128
- // Use extracted handler
129
- const { handleData: handleDataExtracted } = await import("./handlers/data/index.js");
130
- return handleDataExtracted(dataArgs, client, readFile);
131
- }
132
- // ═══════════════════════════════════════════════════════════════════════════
133
- // ROUTING: Persona operations
134
- // ═══════════════════════════════════════════════════════════════════════════
135
- // ───────────────────────────────────────────────────────────────────────────
136
- // LLM-DRIVEN ARCHITECTURE:
137
- // - persona tool: config changes only (name, description, widgets)
138
- // - workflow tool: ALL workflow changes (get → modify → deploy)
139
- //
140
- // The LLM generates the full workflow_def, MCP just deploys it.
141
- // There is NO incremental workflow modification via persona tool.
142
- // ───────────────────────────────────────────────────────────────────────────
143
- // mode="update" → modular handleUpdate (config changes, workflow_spec for rewire/remove only)
144
- if (mode === "update" && idOrName) {
145
- return getPersonaModeHandler("update")(args, client);
146
- }
147
- // Legacy: optimize flag routes to workflow handler
148
- const optimize = args.optimize;
149
- const workflowDef = args.workflow_def ?? args.workflow;
150
- if (optimize || (idOrName && workflowDef && mode !== "update")) {
151
- const workflowArgs = {
152
- ...args,
153
- persona_id: idOrName,
154
- };
155
- delete workflowArgs.id;
156
- delete workflowArgs.identifier;
157
- return handleWorkflowExtracted(workflowArgs, client, getTemplateId);
158
- }
159
- // ═══════════════════════════════════════════════════════════════════════════
160
- // Standard persona operations (get, list, compare, version management)
161
- // ═══════════════════════════════════════════════════════════════════════════
162
- // Determine effective mode
163
- // Support both new `from` and deprecated `clone_from`/`template_id` parameters
164
- const fromParam = args.from;
165
- const cloneFromParam = args.clone_from;
166
- const templateIdParam = args.template_id;
167
- const hasBase = fromParam || cloneFromParam || templateIdParam;
168
- // Explicit method required - clarify if not provided
169
- let effectiveMode = mode;
170
- if (!effectiveMode) {
171
- // Provide contextual clarification based on what params were provided
172
- const availableMethods = ["list", "get", "create", "update", "delete", "analyze", "sanitize", "snapshot", "history", "restore", "compare"];
173
- if (idOrName && args.proto_config) {
174
- return {
175
- error: "Explicit method required",
176
- message: "You provided id and proto_config. Did you want to update this persona?",
177
- suggested_method: "update",
178
- hint: "Use method='update' to apply changes",
179
- example: `persona(method="update", id="${idOrName}", config={...})`,
180
- };
181
- }
182
- else if (idOrName) {
183
- return {
184
- error: "Explicit method required",
185
- message: "You provided a persona id/name. What operation would you like to perform?",
186
- valid_methods: ["get", "update", "delete", "sanitize", "snapshot", "history", "restore"],
187
- hint: "LLM does analysis/comparison. Use method='get' to fetch data, then reason about it.",
188
- example: `persona(method="get", id="${idOrName}")`,
189
- };
190
- }
191
- else if (hasBase || (args.name && args.type)) {
192
- return {
193
- error: "Explicit method required",
194
- message: "You provided creation parameters. Did you want to create a new persona?",
195
- suggested_method: "create",
196
- hint: "Use method='create'",
197
- example: `persona(method="create", name="...", type="voice")`,
198
- };
199
- }
200
- else {
201
- return {
202
- error: "Explicit method required",
203
- message: "All persona operations require explicit method parameter",
204
- valid_methods: availableMethods,
205
- examples: [
206
- 'persona(method="list") - list all personas',
207
- 'persona(method="get", id="...") - get specific persona',
208
- 'persona(method="create", name="...", type="voice") - create new',
209
- 'persona(method="update", id="...", config={...}) - update config',
210
- 'persona(method="delete", id="...", confirm=true) - delete',
211
- ],
212
- };
213
- }
214
- }
215
- // ─────────────────────────────────────────────────────────────────────────
216
- // Dispatch to extracted handlers (incremental migration)
217
- // All standard persona modes are now extracted to handlers/persona/*.ts
218
- // Version management modes (version_*) remain in the switch below
219
- // ─────────────────────────────────────────────────────────────────────────
220
- if (hasExtractedHandler(effectiveMode)) {
221
- const handler = getPersonaModeHandler(effectiveMode);
222
- if (handler) {
223
- // Some handlers need extra context:
224
- // - create/clone: needs getTemplateId callback
225
- // - compare: needs createClientForEnv callback
226
- let extraContext = undefined;
227
- if (effectiveMode === "create" || effectiveMode === "clone") {
228
- extraContext = getTemplateId;
229
- }
230
- else if (effectiveMode === "compare") {
231
- extraContext = createClientForEnv;
232
- }
233
- const result = await handler(args, client, extraContext);
234
- return addDeprecationWarnings(result, deprecationWarnings);
235
- }
236
- }
237
- switch (effectiveMode) {
238
- // NOTE: These modes are now handled by extracted handlers above
239
- // These cases are kept as fallback but should not be reached
240
- case "get":
241
- case "list":
242
- case "templates":
243
- case "sanitize":
244
- case "update":
245
- case "delete": {
246
- // Should be handled by extracted handlers above
247
- return { error: `Mode "${effectiveMode}" should be handled by extracted handler` };
248
- }
249
- // Schema - get persona input schema (dashboard columns, types)
250
- case "schema": {
251
- if (!idOrName) {
252
- return { error: "id required for schema mode" };
253
- }
254
- const persona = await resolvePersona(client, idOrName);
255
- if (!persona) {
256
- return { error: `Persona not found: ${idOrName}` };
257
- }
258
- try {
259
- // For dashboard personas, get schema from dashboard
260
- const schema = await client.getDashboardSchema(persona.id, persona.id);
261
- return {
262
- mode: "schema",
263
- persona_id: persona.id,
264
- persona_name: persona.name,
265
- schema: schema,
266
- column_count: schema.columns?.length ?? 0,
267
- };
268
- }
269
- catch (error) {
270
- return { error: `Failed to get schema: ${error instanceof Error ? error.message : String(error)}` };
271
- }
272
- }
273
- // Clone and create - handled by extracted handlers
274
- case "clone":
275
- case "create": {
276
- // These modes have been extracted to handlers/persona/*.ts
277
- // - create.ts: handleCreate (~410 lines)
278
- return { error: `Mode "${effectiveMode}" should be handled by extracted handler` };
279
- }
280
- // Analyze and compare - LLM does this, not MCP
281
- case "analyze":
282
- case "compare": {
283
- return {
284
- error: `Method "${effectiveMode}" removed - LLM does analysis/comparison`,
285
- hint: "Use method='get' to fetch persona data, then do your own analysis/comparison.",
286
- example: `persona(method="get", id="...", include_workflow=true)`,
287
- };
288
- }
289
- // ─────────────── Version Management Modes ───────────────
290
- // Extracted to handlers/persona/version.ts
291
- case "snapshot":
292
- case "history":
293
- case "restore":
294
- case "version_create":
295
- case "version_list":
296
- case "version_get":
297
- case "version_compare":
298
- case "version_restore":
299
- case "version_policy": {
300
- if (!idOrName) {
301
- return { error: `id required for ${effectiveMode} mode` };
302
- }
303
- if (!versionContext) {
304
- return { error: "Version tracking not configured. Provide workspaceRoot in context." };
305
- }
306
- const persona = await resolvePersona(client, idOrName);
307
- if (!persona) {
308
- return { error: `Persona not found: ${idOrName}` };
309
- }
310
- return handleVersion(effectiveMode, args, client, persona, versionContext);
311
- }
312
- default:
313
- return { error: `Unknown mode: ${effectiveMode}` };
314
- }
315
- }
316
- // ═══════════════════════════════════════════════════════════════════════════
317
- // WORKFLOW Handler - REMOVED
318
- // ═══════════════════════════════════════════════════════════════════════════
319
- // The handleWorkflow function has been fully extracted to handlers/workflow/
320
- // Import via: import { handleWorkflow } from "./handlers/workflow/index.js"
321
- //
322
- // Modular structure:
323
- // - handlers/workflow/analyze.ts
324
- // - handlers/workflow/compare.ts
325
- // - handlers/workflow/compile.ts
326
- // - handlers/workflow/deploy.ts
327
- // - handlers/workflow/generate.ts
328
- // - handlers/workflow/modify.ts
329
- // - handlers/workflow/optimize.ts
330
- // - handlers/workflow/index.ts (router)
331
- // ═══════════════════════════════════════════════════════════════════════════
332
- // Re-export the extracted handler for backwards compatibility
333
- export { handleWorkflow } from "./handlers/workflow/index.js";