@ema.co/mcp-toolkit 2026.1.24 → 2026.1.26-3
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/README.md +10 -2
- package/dist/mcp/handlers/action/index.js +3 -18
- package/dist/mcp/handlers/data/index.js +385 -41
- package/dist/mcp/handlers/data/templates.js +107 -0
- package/dist/mcp/handlers/deprecation.js +50 -0
- package/dist/mcp/handlers/env/index.js +8 -4
- package/dist/mcp/handlers/knowledge/index.js +44 -237
- package/dist/mcp/handlers/persona/create.js +5 -11
- package/dist/mcp/handlers/persona/index.js +5 -1
- package/dist/mcp/handlers/persona/version.js +234 -0
- package/dist/mcp/handlers/reference/index.js +101 -1
- package/dist/mcp/handlers/sync/index.js +3 -18
- package/dist/mcp/handlers/template/index.js +75 -10
- package/dist/mcp/handlers/workflow/analyze.js +171 -0
- package/dist/mcp/handlers/workflow/compare.js +70 -0
- package/dist/mcp/handlers/workflow/compile.js +39 -0
- package/dist/mcp/handlers/workflow/deploy.js +73 -0
- package/dist/mcp/handlers/workflow/generate.js +350 -0
- package/dist/mcp/handlers/workflow/index.js +136 -0
- package/dist/mcp/handlers/workflow/modify.js +456 -0
- package/dist/mcp/handlers/workflow/optimize.js +136 -0
- package/dist/mcp/handlers/workflow/types.js +4 -0
- package/dist/mcp/handlers/workflow/utils.js +132 -0
- package/dist/mcp/handlers-consolidated.js +62 -2691
- package/dist/mcp/prompts.js +13 -14
- package/dist/mcp/resources.js +55 -54
- package/dist/mcp/server.js +93 -124
- package/dist/mcp/{tools-v2.js → tools.js} +1 -1
- package/dist/mcp/workflow-operations.js +2 -2
- package/dist/sdk/client-adapter.js +267 -32
- package/dist/sdk/client.js +31 -15
- package/dist/sdk/ema-client.js +183 -0
- package/dist/sdk/generated/template-fallbacks.js +123 -0
- package/dist/sdk/guidance.js +65 -11
- package/dist/sdk/index.js +3 -1
- package/dist/sdk/knowledge.js +16 -86
- package/dist/sdk/workflow-intent.js +27 -0
- package/dist/sdk/workflow-transformer.js +0 -342
- package/docs/DEBUG-ANALYSIS-unused-category-type-mismatch.md +481 -0
- package/docs/TODO-fix-analyzer-and-modify.md +182 -0
- package/package.json +9 -4
- package/dist/mcp/tools-consolidated.js +0 -866
- package/dist/mcp/tools-legacy.js +0 -736
- package/docs/CODEBASE-ANALYSIS-2026-01-23.md +0 -936
- package/docs/CODEBASE-ANALYSIS-PRIORITIZED.md +0 -774
- package/docs/api-contracts.md +0 -216
- package/docs/auto-builder-analysis.md +0 -271
- package/docs/blog/mcp-tool-design-lessons.md +0 -309
- package/docs/data-architecture.md +0 -166
- package/docs/ema-auto-builder-guide.html +0 -394
- package/docs/lessons-learned.md +0 -209
- package/docs/llm-native-workflow-design.md +0 -252
- package/docs/local-generation.md +0 -508
- package/docs/mcp-flow-diagram.md +0 -135
- package/docs/migration/action-composition-migration.md +0 -270
- package/docs/naming-conventions.md +0 -278
- package/docs/proposals/HANDOFF-tool-restructure.md +0 -526
- package/docs/proposals/action-composition.md +0 -490
- package/docs/proposals/explicit-method-restructure.md +0 -328
- package/docs/proposals/mcp-tool-restructure-2026-01.md +0 -366
- package/docs/proposals/self-contained-guidance.md +0 -427
- package/docs/proto-sdk-generation.md +0 -242
- package/docs/release-impact.md +0 -102
- package/docs/release-process.md +0 -157
- package/docs/staging.RULE.md +0 -142
- package/docs/test-persona-creation.md +0 -196
- package/docs/tool-consolidation-v2.md +0 -225
- package/docs/tool-response-standards.md +0 -256
- package/resources/docs/getting-started.md +0 -97
- package/resources/templates/auto-builder-rules.md +0 -224
- package/resources/templates/chat-ai/README.md +0 -119
- package/resources/templates/chat-ai/persona-config.json +0 -111
- package/resources/templates/dashboard-ai/README.md +0 -156
- package/resources/templates/dashboard-ai/persona-config.json +0 -180
- package/resources/templates/demo-scenarios/README.md +0 -63
- package/resources/templates/demo-scenarios/test-published-package.md +0 -116
- package/resources/templates/document-gen-ai/README.md +0 -132
- package/resources/templates/document-gen-ai/persona-config.json +0 -316
- package/resources/templates/voice-ai/README.md +0 -123
- package/resources/templates/voice-ai/persona-config.json +0 -74
- package/resources/templates/voice-ai/workflow-prompt.md +0 -121
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for workflow handlers
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get the type/category of an action node
|
|
6
|
+
*/
|
|
7
|
+
export function getActionType(action) {
|
|
8
|
+
const name = action.name;
|
|
9
|
+
if (!name)
|
|
10
|
+
return "unknown";
|
|
11
|
+
// Categorize by action name patterns
|
|
12
|
+
if (name.includes("hitl") || name.includes("human"))
|
|
13
|
+
return "hitl";
|
|
14
|
+
if (name.includes("email") || name.includes("send"))
|
|
15
|
+
return "communication";
|
|
16
|
+
if (name.includes("search") || name.includes("retrieve"))
|
|
17
|
+
return "retrieval";
|
|
18
|
+
if (name.includes("classify") || name.includes("categorize"))
|
|
19
|
+
return "classification";
|
|
20
|
+
if (name.includes("generate") || name.includes("compose"))
|
|
21
|
+
return "generation";
|
|
22
|
+
if (name.includes("output") || name === "WORKFLOW_OUTPUT")
|
|
23
|
+
return "output";
|
|
24
|
+
if (name.includes("input") || name === "WORKFLOW_INPUT")
|
|
25
|
+
return "input";
|
|
26
|
+
return "processing";
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Sanitize workflow for deployment
|
|
30
|
+
* Removes internal-only fields, validates structure
|
|
31
|
+
*/
|
|
32
|
+
export function sanitizeWorkflowForDeploy(workflow) {
|
|
33
|
+
const sanitized = { ...workflow };
|
|
34
|
+
// Remove internal fields that shouldn't be sent to API
|
|
35
|
+
delete sanitized._internal;
|
|
36
|
+
delete sanitized._metadata;
|
|
37
|
+
delete sanitized._debug;
|
|
38
|
+
// Ensure actions array exists
|
|
39
|
+
if (!sanitized.actions) {
|
|
40
|
+
sanitized.actions = [];
|
|
41
|
+
}
|
|
42
|
+
// Validate and clean actions
|
|
43
|
+
const actions = sanitized.actions;
|
|
44
|
+
sanitized.actions = actions.filter(a => {
|
|
45
|
+
// Must have name
|
|
46
|
+
if (!a.name || typeof a.name !== "string")
|
|
47
|
+
return false;
|
|
48
|
+
// Must have id
|
|
49
|
+
if (!a.id && !a.name)
|
|
50
|
+
return false;
|
|
51
|
+
return true;
|
|
52
|
+
});
|
|
53
|
+
return sanitized;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if a node has a path to the output
|
|
57
|
+
*/
|
|
58
|
+
export function checkNodeHasPath(nodeId, connections, outputNodeId, visited = new Set()) {
|
|
59
|
+
if (nodeId === outputNodeId)
|
|
60
|
+
return true;
|
|
61
|
+
if (visited.has(nodeId))
|
|
62
|
+
return false;
|
|
63
|
+
visited.add(nodeId);
|
|
64
|
+
const outgoing = connections.filter(c => c.from === nodeId);
|
|
65
|
+
for (const conn of outgoing) {
|
|
66
|
+
if (checkNodeHasPath(conn.to, connections, outputNodeId, visited)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Find orphan nodes (nodes with no path to output)
|
|
74
|
+
*/
|
|
75
|
+
export function findOrphanNodes(workflow) {
|
|
76
|
+
const actions = workflow.actions;
|
|
77
|
+
if (!actions || actions.length === 0)
|
|
78
|
+
return [];
|
|
79
|
+
// Find output node
|
|
80
|
+
const outputNode = actions.find(a => a.name?.includes("OUTPUT") ||
|
|
81
|
+
a.id?.includes("OUTPUT"));
|
|
82
|
+
if (!outputNode) {
|
|
83
|
+
// No output node - can't determine orphans
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const outputId = (outputNode.id ?? outputNode.name);
|
|
87
|
+
// Build connection list
|
|
88
|
+
const connections = [];
|
|
89
|
+
for (const action of actions) {
|
|
90
|
+
const inputs = action.inputs;
|
|
91
|
+
if (inputs) {
|
|
92
|
+
const actionId = (action.id ?? action.name);
|
|
93
|
+
for (const [_key, value] of Object.entries(inputs)) {
|
|
94
|
+
if (typeof value === "string" && value.includes(".")) {
|
|
95
|
+
const sourceAction = value.split(".")[0];
|
|
96
|
+
connections.push({ from: sourceAction, to: actionId });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Find orphans
|
|
102
|
+
const orphans = [];
|
|
103
|
+
for (const action of actions) {
|
|
104
|
+
const actionId = (action.id ?? action.name);
|
|
105
|
+
const actionName = action.name;
|
|
106
|
+
if (actionId === outputId)
|
|
107
|
+
continue; // Skip output node
|
|
108
|
+
if (!checkNodeHasPath(actionId, connections, outputId)) {
|
|
109
|
+
orphans.push({
|
|
110
|
+
id: actionId,
|
|
111
|
+
name: actionName,
|
|
112
|
+
reason: "No path to output node",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return orphans;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Extract enum type name from a value
|
|
120
|
+
*/
|
|
121
|
+
export function extractEnumTypeName(value) {
|
|
122
|
+
if (typeof value === "object" && value !== null) {
|
|
123
|
+
const obj = value;
|
|
124
|
+
if (typeof obj.name === "string")
|
|
125
|
+
return obj.name;
|
|
126
|
+
if (typeof obj.type === "string")
|
|
127
|
+
return obj.type;
|
|
128
|
+
}
|
|
129
|
+
if (typeof value === "string")
|
|
130
|
+
return value;
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|