@ema.co/mcp-toolkit 2026.1.26 → 2026.1.27-10
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.
- package/dist/mcp/handlers/action/index.js +17 -20
- package/dist/mcp/handlers/data/index.js +75 -6
- package/dist/mcp/handlers/deprecation.js +50 -0
- package/dist/mcp/handlers/env/index.js +3 -3
- package/dist/mcp/handlers/knowledge/index.js +44 -237
- package/dist/mcp/handlers/persona/create.js +63 -18
- package/dist/mcp/handlers/persona/index.js +9 -10
- package/dist/mcp/handlers/persona/update.js +6 -3
- package/dist/mcp/handlers/reference/index.js +15 -2
- package/dist/mcp/handlers/sync/index.js +3 -18
- package/dist/mcp/handlers/workflow/analyze.js +53 -105
- package/dist/mcp/handlers/workflow/deploy.js +160 -1
- package/dist/mcp/handlers/workflow/generate.js +8 -28
- package/dist/mcp/handlers/workflow/index.js +258 -85
- package/dist/mcp/handlers/workflow/modify.js +69 -26
- package/dist/mcp/handlers/workflow/optimize.js +22 -108
- package/dist/mcp/handlers/workflow/utils.js +0 -102
- package/dist/mcp/handlers-consolidated.js +15 -38
- package/dist/mcp/prompts.js +82 -44
- package/dist/mcp/resources.js +335 -3
- package/dist/mcp/server.js +242 -457
- package/dist/mcp/tools.js +44 -61
- package/dist/sdk/action-schema-parser.js +11 -5
- package/dist/sdk/client.js +81 -25
- package/dist/sdk/ema-client.js +11 -0
- package/dist/sdk/generated/deprecated-actions.js +171 -0
- package/dist/sdk/guidance.js +58 -35
- package/dist/sdk/index.js +8 -7
- package/dist/sdk/knowledge.js +216 -1932
- package/dist/sdk/quality-gates.js +60 -336
- package/dist/sdk/validation-rules.js +33 -0
- package/dist/sdk/workflow-fixer.js +29 -360
- package/dist/sdk/workflow-generator.js +2 -1
- package/dist/sdk/workflow-intent.js +43 -3
- package/dist/sdk/workflow-transformer.js +0 -342
- package/docs/dashboard-operations.md +35 -0
- package/docs/ema-user-guide.md +66 -0
- package/docs/mcp-tools-guide.md +74 -45
- package/package.json +2 -2
- package/dist/mcp/handlers/persona/analyze.js +0 -275
- package/dist/mcp/handlers/persona/compare.js +0 -32
- package/dist/mcp/handlers/workflow/compile.js +0 -39
- package/docs/DEBUG-ANALYSIS-unused-category-type-mismatch.md +0 -481
- package/docs/TODO-fix-analyzer-and-modify.md +0 -182
- package/resources/action-schema.json +0 -5678
package/dist/sdk/guidance.js
CHANGED
|
@@ -71,30 +71,55 @@ await persona({ id: "abc", update: { workflow_spec: spec } }); // Then deploy`,
|
|
|
71
71
|
{ name: "Fallback", description: "Anything else" } // Required!
|
|
72
72
|
]`,
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
id: "data-sources-before-search",
|
|
76
|
+
level: "critical",
|
|
77
|
+
category: "workflow",
|
|
78
|
+
title: "Upload Data Sources Before Search",
|
|
79
|
+
applies: "When creating workflows with search/RAG nodes",
|
|
80
|
+
description: "Workflows with search/v2 nodes require data sources (documents) to be uploaded to the persona. " +
|
|
81
|
+
"Without documents, search returns empty results and RAG is useless.",
|
|
82
|
+
do: "1. Upload documents: persona(id='...', data={method:'upload', path:'/path/to/doc.pdf'})\n" +
|
|
83
|
+
"2. Check status: persona(id='...', data={method:'stats'}) → verify 'success' count > 0\n" +
|
|
84
|
+
"3. Then deploy workflow with search node",
|
|
85
|
+
dont: "Deploy search-based workflows before uploading any documents to the knowledge base.",
|
|
86
|
+
example: `// Upload documents first
|
|
87
|
+
await persona({ id: "abc", data: { method: "upload", path: "/docs/product-faq.pdf" } });
|
|
88
|
+
await persona({ id: "abc", data: { method: "upload", path: "/docs/pricing.pdf" } });
|
|
89
|
+
|
|
90
|
+
// Check they're indexed
|
|
91
|
+
const stats = await persona({ id: "abc", data: { method: "stats" } });
|
|
92
|
+
// stats.success should be > 0
|
|
93
|
+
|
|
94
|
+
// Then deploy workflow with search
|
|
95
|
+
await workflow({ mode: "deploy", persona_id: "abc", workflow_def: workflowWithSearch });`,
|
|
96
|
+
antiExample: `// BAD: Deploy search workflow with no documents
|
|
97
|
+
await workflow({ mode: "deploy", persona_id: "abc", workflow_def: workflowWithSearch });
|
|
98
|
+
// Search will return empty results!`,
|
|
99
|
+
related: ["analyze-before-modify"],
|
|
100
|
+
},
|
|
74
101
|
{
|
|
75
102
|
id: "workflow-modification-scope",
|
|
76
103
|
level: "critical",
|
|
77
104
|
category: "workflow",
|
|
78
105
|
title: "Structure vs Content Changes",
|
|
79
106
|
applies: "When modifying workflows",
|
|
80
|
-
description: "
|
|
107
|
+
description: "persona(method='update', input='...') only supports STRUCTURAL changes (add/remove nodes, rewire connections). " +
|
|
81
108
|
"CONTENT changes (fixed_response data, call_llm prompts) require manual workflow_def editing.",
|
|
82
|
-
do: "For content changes: 1) Get workflow with persona(
|
|
109
|
+
do: "For content changes: 1) Get workflow with persona(method='get', id='...'), " +
|
|
83
110
|
"2) Edit the node's stringValue in the JSON, 3) Deploy with workflow(mode='deploy', workflow_def={...})",
|
|
84
|
-
dont: "Use
|
|
85
|
-
example: `// STRUCTURAL change (supported via
|
|
86
|
-
persona({
|
|
87
|
-
{ type: "insert", insert: { action_type: "hitl", insert_before: "send_email" }}
|
|
88
|
-
]})
|
|
111
|
+
dont: "Use update with input for content changes - it will silently return 0 changes.",
|
|
112
|
+
example: `// STRUCTURAL change (supported via update + input)
|
|
113
|
+
persona({ method: "update", id: "abc", input: "add HITL before send_email" })
|
|
89
114
|
|
|
90
115
|
// CONTENT change (requires manual edit)
|
|
91
|
-
const p = await persona({
|
|
116
|
+
const p = await persona({ method: "get", id: "abc" });
|
|
92
117
|
const wf = p.workflow_def;
|
|
93
118
|
// Find and edit the fixed_response node's inputs.data.stringValue
|
|
94
119
|
wf.actions[2].inputs.data.stringValue = JSON.stringify(newData);
|
|
95
120
|
await workflow({ mode: "deploy", persona_id: "abc", workflow_def: wf });`,
|
|
96
|
-
antiExample: `// This will silently fail - content change via
|
|
97
|
-
persona({
|
|
121
|
+
antiExample: `// This will silently fail - content change via update
|
|
122
|
+
persona({ method: "update", id: "abc", input: "change the welcome message" }) // for content changes`,
|
|
98
123
|
related: ["workflow-spec-not-def", "llm-driven-modifications"],
|
|
99
124
|
},
|
|
100
125
|
{
|
|
@@ -103,15 +128,16 @@ persona({ mode: "modify", id: "abc", operations: [...] }) // for content change
|
|
|
103
128
|
category: "workflow",
|
|
104
129
|
title: "LLM-Driven Workflow Modifications",
|
|
105
130
|
applies: "When modifying workflows structurally",
|
|
106
|
-
description: "
|
|
107
|
-
"
|
|
108
|
-
do: "1)
|
|
109
|
-
"2)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
131
|
+
description: "Use persona(method='update', input='...') for incremental changes. The MCP routes this to the workflow modify handler. " +
|
|
132
|
+
"For structured operations, use persona(method='update', operations=[...]).",
|
|
133
|
+
do: "1) Analyze workflow: persona(method='analyze', id='...') returns workflow_spec and issues. " +
|
|
134
|
+
"2) Make changes: persona(method='update', id='...', input='add HITL before email') " +
|
|
135
|
+
"3) Or use structured operations: persona(method='update', id='...', operations=[...])",
|
|
136
|
+
dont: "Expect operations to work without understanding the current workflow structure first.",
|
|
137
|
+
example: `// Option 1: Natural language input (routed to modify handler)
|
|
138
|
+
await persona({ method: "update", id: "abc", input: "add HITL approval before send_email" });
|
|
139
|
+
|
|
140
|
+
// Option 2: Structured operations
|
|
115
141
|
const operations = [
|
|
116
142
|
{
|
|
117
143
|
type: "insert",
|
|
@@ -123,12 +149,10 @@ const operations = [
|
|
|
123
149
|
}
|
|
124
150
|
}
|
|
125
151
|
];
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
await persona({
|
|
129
|
-
|
|
130
|
-
await persona({ mode: "modify", id: "abc", input: "add approval before email" })
|
|
131
|
-
// The MCP will NOT parse this - it returns context instead`,
|
|
152
|
+
await persona({ method: "update", id: "abc", operations });`,
|
|
153
|
+
antiExample: `// DON'T: Try to modify without analyzing first
|
|
154
|
+
await persona({ method: "update", id: "abc", operations: [...] })
|
|
155
|
+
// Always analyze the workflow first to understand structure`,
|
|
132
156
|
related: ["workflow-modification-scope", "analyze-before-modify"],
|
|
133
157
|
},
|
|
134
158
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -240,14 +264,14 @@ export const TOOL_GUIDANCE = {
|
|
|
240
264
|
example: 'persona(id="abc", analyze=true)',
|
|
241
265
|
},
|
|
242
266
|
{
|
|
243
|
-
name: "
|
|
244
|
-
description: "
|
|
245
|
-
example: 'persona(
|
|
267
|
+
name: "Update with input",
|
|
268
|
+
description: "Incremental workflow changes via natural language",
|
|
269
|
+
example: 'persona(method="update", id="abc", input="add HITL before email")',
|
|
246
270
|
},
|
|
247
271
|
{
|
|
248
|
-
name: "
|
|
272
|
+
name: "Update with operations",
|
|
249
273
|
description: "Apply structured operations (insert/remove/rewire)",
|
|
250
|
-
example: 'persona(
|
|
274
|
+
example: 'persona(method="update", id="abc", operations=[...])',
|
|
251
275
|
},
|
|
252
276
|
{
|
|
253
277
|
name: "Create",
|
|
@@ -406,12 +430,11 @@ ${critical.map((r) => `- **${r.title}**: ${r.do}`).join("\n")}
|
|
|
406
430
|
${important.map((r) => `- **${r.title}**: ${r.do}`).join("\n")}
|
|
407
431
|
|
|
408
432
|
## LLM-Driven Architecture (CRITICAL)
|
|
409
|
-
|
|
410
|
-
**YOU (the Agent) must build structured operations:**
|
|
433
|
+
Use \`persona(method="update", input="...")\` for workflow modifications:
|
|
411
434
|
|
|
412
|
-
1.
|
|
413
|
-
2.
|
|
414
|
-
3.
|
|
435
|
+
1. Analyze: \`persona(method="analyze", id="...")\` → returns workflow_spec, issues
|
|
436
|
+
2. Update with natural language: \`persona(method="update", id="...", input="add HITL before email")\`
|
|
437
|
+
3. Or use structured operations: \`persona(method="update", id="...", operations=[...])\`
|
|
415
438
|
|
|
416
439
|
Example operations: insert, remove, rewire, update_config
|
|
417
440
|
|
package/dist/sdk/index.js
CHANGED
|
@@ -27,8 +27,8 @@ AGENT_CATALOG, WIDGET_CATALOG, WORKFLOW_PATTERNS, QUALIFYING_QUESTIONS, PLATFORM
|
|
|
27
27
|
PROJECT_TYPES,
|
|
28
28
|
// Helper Functions
|
|
29
29
|
getAgentsByCategory, getAgentByName, getWidgetsForPersonaType, checkTypeCompatibility, getQualifyingQuestionsByCategory, getRequiredQualifyingQuestions, getConceptByTerm, suggestAgentsForUseCase, validateWorkflowPrompt,
|
|
30
|
-
// Workflow
|
|
31
|
-
parseWorkflowDef,
|
|
30
|
+
// Workflow Data Functions (LLM does analysis with rules)
|
|
31
|
+
parseWorkflowDef, validateWorkflowConnections,
|
|
32
32
|
// Validation Rules (Single Source of Truth)
|
|
33
33
|
VALIDATION_INPUT_RULES, ANTI_PATTERNS, OPTIMIZATION_RULES, findInputSourceRule, findAntiPatternByIssueType, generateMarkdownDocumentation, exportRulesAsJSON, } from "./knowledge.js";
|
|
34
34
|
// Workflow Compiler (Template-driven workflow generation)
|
|
@@ -57,8 +57,9 @@ export { VersionStorage, createVersionStorage, } from "./version-storage.js";
|
|
|
57
57
|
export { VersionPolicyEngine, createVersionPolicyEngine, } from "./version-policy.js";
|
|
58
58
|
// Workflow Execution Analyzer (Loop, multiple responder, redundant classifier detection)
|
|
59
59
|
export { analyzeExecutionFlow, detectLoops, detectMultipleResponders, detectRedundantClassifiers, analyzeDataFlow, findDeadCodePaths, generateASCIIFlow, } from "./workflow-execution-analyzer.js";
|
|
60
|
-
// Workflow Fixer
|
|
61
|
-
|
|
60
|
+
// Workflow Fixer - REMOVED
|
|
61
|
+
// autoFixWorkflow, suggestFixes removed as part of "MCP = data, LLM = logic" refactor
|
|
62
|
+
// LLM now applies rules from ema://rules/* and proposes fixes
|
|
62
63
|
// Intent Architect (WHY + WHAT, not HOW - with progressive enhancement)
|
|
63
64
|
// NOTE: intent-decomposition.ts and intent-decomposition-v2.ts were removed as part of consolidation.
|
|
64
65
|
// All intent processing now goes through the Intent Architect module.
|
|
@@ -86,12 +87,12 @@ runIntentArchitect, } from "./intent-architect.js";
|
|
|
86
87
|
export { analyzeOptimizations, summarizeOptimizationReport, } from "./workflow-optimizer.js";
|
|
87
88
|
// Workflow Tracer (Flow visualization & path analysis)
|
|
88
89
|
export { traceWorkflow, generateDetailedTrace, formatFlowTrace, formatDetailedTrace, } from "./workflow-tracer.js";
|
|
89
|
-
// Quality Gates (Pre-deploy validation)
|
|
90
|
-
export { runQualityGates,
|
|
90
|
+
// Quality Gates (Pre-deploy validation) - DEPRECATED, minimal implementation
|
|
91
|
+
export { runQualityGates, formatQualityReport, isDeploymentAllowed, getBlockingIssues, QUALITY_GATES, } from "./quality-gates.js";
|
|
91
92
|
// Structural Rules (LLM validation context)
|
|
92
93
|
export { STRUCTURAL_RULES_FOR_LLM, STRUCTURAL_INVARIANTS, EXECUTION_RULES, COMMON_STRUCTURAL_MISTAKES, getAllStructuralRules, getInvariantById, getCriticalInvariants, } from "./structural-rules.js";
|
|
93
94
|
// Action Schema Parser (Parse ema_backend/grpc definitions)
|
|
94
|
-
export { parseTextproto, parseActionDirectory, loadDocumentation, generateSchemaBundle, isTypeCompatible as isSchemaTypeCompatible,
|
|
95
|
+
export { parseTextproto, parseActionDirectory, loadDocumentation, generateSchemaBundle, isTypeCompatible as isSchemaTypeCompatible, SCHEMA_TYPE_COMPATIBILITY, } from "./action-schema-parser.js";
|
|
95
96
|
// Workflow Merge (Brownfield workflow comparison, merging, validation)
|
|
96
97
|
export { compareWorkflows, mergeWorkflows, validateMergedWorkflow, } from "./workflow-merge.js";
|
|
97
98
|
// Auto Builder Prompt Generation
|