@ema.co/mcp-toolkit 2026.1.25 → 2026.1.26-4
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 +47 -18
- package/dist/mcp/handlers/persona/index.js +14 -11
- package/dist/mcp/handlers/persona/update.js +4 -2
- package/dist/mcp/handlers/persona/version.js +234 -0
- 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/deploy.js +73 -0
- package/dist/mcp/handlers/workflow/generate.js +350 -0
- package/dist/mcp/handlers/workflow/index.js +294 -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 +30 -0
- package/dist/mcp/handlers-consolidated.js +73 -2696
- package/dist/mcp/prompts.js +83 -43
- package/dist/mcp/resources.js +382 -57
- package/dist/mcp/server.js +199 -391
- package/dist/mcp/{tools-v2.js → tools.js} +20 -54
- package/dist/mcp/workflow-operations.js +2 -2
- package/dist/sdk/client-adapter.js +267 -32
- package/dist/sdk/client.js +45 -16
- package/dist/sdk/ema-client.js +183 -0
- package/dist/sdk/generated/deprecated-actions.js +171 -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 +139 -86
- package/dist/sdk/workflow-intent.js +27 -0
- package/dist/sdk/workflow-transformer.js +0 -342
- package/docs/mcp-tools-guide.md +37 -45
- package/package.json +10 -4
- package/dist/mcp/handlers/persona/analyze.js +0 -275
- package/dist/mcp/handlers/persona/compare.js +0 -32
- package/dist/mcp/tools-consolidated.js +0 -875
- 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/demos/ap-invoice-generation.md +0 -347
- package/docs/demos/ap-invoice-processing.md +0 -271
- 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/demo-kits/README.md +0 -175
- package/resources/demo-kits/finance-ap/manifest.json +0 -150
- package/resources/demo-kits/tags.json +0 -91
- 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
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
# LLM-Native Workflow Transformation Design
|
|
2
|
-
|
|
3
|
-
## The Problem
|
|
4
|
-
|
|
5
|
-
Current `workflow(mode="extend")` uses keyword matching:
|
|
6
|
-
```typescript
|
|
7
|
-
// handlers-consolidated.ts - FRAGILE APPROACH
|
|
8
|
-
if (lowerInput.includes("consolidat") || lowerInput.includes("merge")) {
|
|
9
|
-
intent = "consolidate multiple nodes into one";
|
|
10
|
-
// ... pattern matching logic
|
|
11
|
-
}
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
This is backwards - we're **sidelining the LLM** and using brittle string matching.
|
|
15
|
-
|
|
16
|
-
## The Solution
|
|
17
|
-
|
|
18
|
-
**Let the LLM BE the transformation engine.**
|
|
19
|
-
|
|
20
|
-
Workflows are just JSON. LLMs excel at:
|
|
21
|
-
1. Understanding natural language intent
|
|
22
|
-
2. Transforming structured data
|
|
23
|
-
3. Following schemas and rules
|
|
24
|
-
|
|
25
|
-
### New Architecture
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
29
|
-
│ USER REQUEST │
|
|
30
|
-
│ "Fix all email nodes to use entity_extraction output" │
|
|
31
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
32
|
-
│
|
|
33
|
-
▼
|
|
34
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
35
|
-
│ DECOMPILE WORKFLOW │
|
|
36
|
-
│ workflow_def JSON → WorkflowSpec │
|
|
37
|
-
│ │
|
|
38
|
-
│ • Typed nodes, inputs, outputs │
|
|
39
|
-
│ • Human-readable structure │
|
|
40
|
-
│ • Easy for LLM to reason about │
|
|
41
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
42
|
-
│
|
|
43
|
-
▼
|
|
44
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
45
|
-
│ LLM TRANSFORMATION │
|
|
46
|
-
│ │
|
|
47
|
-
│ Context provided: │
|
|
48
|
-
│ • Current WorkflowSpec │
|
|
49
|
-
│ • WORKFLOW_SCHEMA_FOR_LLM (full schema documentation) │
|
|
50
|
-
│ • User request │
|
|
51
|
-
│ │
|
|
52
|
-
│ LLM outputs: │
|
|
53
|
-
│ • Modified WorkflowSpec JSON │
|
|
54
|
-
│ │
|
|
55
|
-
│ This is WHERE THE MAGIC HAPPENS - LLM understands intent │
|
|
56
|
-
│ and transforms the spec accordingly. │
|
|
57
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
58
|
-
│
|
|
59
|
-
▼
|
|
60
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
61
|
-
│ COMPILE & VALIDATE │
|
|
62
|
-
│ WorkflowSpec → workflow_def JSON │
|
|
63
|
-
│ │
|
|
64
|
-
│ • compileWorkflow() generates deployment-ready JSON │
|
|
65
|
-
│ • detectWorkflowIssues() validates result │
|
|
66
|
-
│ • Type system catches errors │
|
|
67
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
68
|
-
│
|
|
69
|
-
▼
|
|
70
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
71
|
-
│ DEPLOY │
|
|
72
|
-
│ client.updateAiEmployee() │
|
|
73
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Key Components
|
|
77
|
-
|
|
78
|
-
#### 1. WorkflowSpec (Typed Schema)
|
|
79
|
-
```typescript
|
|
80
|
-
interface WorkflowSpec {
|
|
81
|
-
name: string;
|
|
82
|
-
description: string;
|
|
83
|
-
personaType: "voice" | "chat" | "dashboard";
|
|
84
|
-
nodes: Node[];
|
|
85
|
-
resultMappings: ResultMapping[];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
interface Node {
|
|
89
|
-
id: string;
|
|
90
|
-
actionType: ActionType; // "search" | "call_llm" | "send_email_agent" | ...
|
|
91
|
-
displayName: string;
|
|
92
|
-
inputs?: Record<string, InputBinding>;
|
|
93
|
-
runIf?: RunIfCondition;
|
|
94
|
-
categories?: Category[];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
interface InputBinding {
|
|
98
|
-
type: "action_output" | "inline_string" | ...;
|
|
99
|
-
actionName?: string; // Source node
|
|
100
|
-
output?: string; // Source output
|
|
101
|
-
value?: string; // Inline value
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
#### 2. WORKFLOW_SCHEMA_FOR_LLM
|
|
106
|
-
A comprehensive schema document (~300 lines) that includes:
|
|
107
|
-
- All type definitions
|
|
108
|
-
- Available action types and their inputs/outputs
|
|
109
|
-
- Common patterns (RAG, Intent Routing, Email with HITL)
|
|
110
|
-
- Transformation rules
|
|
111
|
-
|
|
112
|
-
This is injected into the LLM context so it knows exactly how to modify workflows.
|
|
113
|
-
|
|
114
|
-
#### 3. decompileWorkflow()
|
|
115
|
-
```typescript
|
|
116
|
-
function decompileWorkflow(
|
|
117
|
-
workflowDef: Record<string, unknown>,
|
|
118
|
-
personaType: PersonaType
|
|
119
|
-
): WorkflowSpec
|
|
120
|
-
```
|
|
121
|
-
Converts raw JSON to typed spec for LLM to work with.
|
|
122
|
-
|
|
123
|
-
#### 4. transformWorkflow()
|
|
124
|
-
```typescript
|
|
125
|
-
function transformWorkflow(
|
|
126
|
-
originalDef: Record<string, unknown>,
|
|
127
|
-
modifiedSpec: WorkflowSpec
|
|
128
|
-
): TransformResult
|
|
129
|
-
```
|
|
130
|
-
Takes the LLM's modified spec and compiles it back to deployment JSON.
|
|
131
|
-
|
|
132
|
-
### Example: Fixing Email Wiring
|
|
133
|
-
|
|
134
|
-
**Before (Current Approach)**
|
|
135
|
-
```
|
|
136
|
-
User: "Wire entity_extraction to email"
|
|
137
|
-
↓
|
|
138
|
-
analyzeModificationRequest() ← Keyword matching
|
|
139
|
-
↓
|
|
140
|
-
"rewire connections" detected
|
|
141
|
-
↓
|
|
142
|
-
applyWorkflowModifications() ← Can't handle complex wiring
|
|
143
|
-
↓
|
|
144
|
-
FAILURE ❌
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
**After (LLM-Native Approach)**
|
|
148
|
-
```
|
|
149
|
-
User: "Wire entity_extraction to email"
|
|
150
|
-
↓
|
|
151
|
-
decompileWorkflow() → WorkflowSpec
|
|
152
|
-
↓
|
|
153
|
-
LLM receives spec + schema + request
|
|
154
|
-
↓
|
|
155
|
-
LLM outputs modified spec:
|
|
156
|
-
{
|
|
157
|
-
nodes: [
|
|
158
|
-
...
|
|
159
|
-
{
|
|
160
|
-
id: "send_email_1",
|
|
161
|
-
inputs: {
|
|
162
|
-
to_email: {
|
|
163
|
-
type: "action_output",
|
|
164
|
-
actionName: "entity_extraction_1", // ← Changed
|
|
165
|
-
output: "extracted_entities" // ← Changed
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
]
|
|
170
|
-
}
|
|
171
|
-
↓
|
|
172
|
-
transformWorkflow() → Compiled JSON
|
|
173
|
-
↓
|
|
174
|
-
SUCCESS ✅
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Why This Works
|
|
178
|
-
|
|
179
|
-
1. **Language models understand intent** - No keyword matching needed
|
|
180
|
-
2. **Structured data transformation** - JSON in, JSON out
|
|
181
|
-
3. **Schema as documentation** - LLM knows the rules
|
|
182
|
-
4. **Type safety** - Compiler catches errors
|
|
183
|
-
5. **Composable** - Each piece does one thing well
|
|
184
|
-
|
|
185
|
-
### Integration Path
|
|
186
|
-
|
|
187
|
-
1. **Short term**: Use `createModificationPrompt()` to generate LLM prompts
|
|
188
|
-
2. **Medium term**: Integrate with MCP handler for `workflow(mode="extend")`
|
|
189
|
-
3. **Long term**: Replace `analyzeModificationRequest` entirely
|
|
190
|
-
|
|
191
|
-
### Files
|
|
192
|
-
|
|
193
|
-
- `src/sdk/workflow-transformer.ts` - Decompiler, transformer, schema
|
|
194
|
-
- `src/sdk/workflow-generator.ts` - Compiler (existing)
|
|
195
|
-
- `test/workflow-transformer.test.ts` - Tests proving the approach
|
|
196
|
-
|
|
197
|
-
### The Cursor/MCP Integration
|
|
198
|
-
|
|
199
|
-
When a user asks to modify a workflow, the MCP handler should:
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
async function handleExtend(args, client) {
|
|
203
|
-
// 1. Get current workflow
|
|
204
|
-
const persona = await client.getPersonaById(args.persona_id);
|
|
205
|
-
const workflowDef = persona.workflow_def;
|
|
206
|
-
|
|
207
|
-
// 2. Decompile to spec
|
|
208
|
-
const currentSpec = decompileWorkflow(workflowDef, persona.type);
|
|
209
|
-
|
|
210
|
-
// 3. Create prompt for LLM
|
|
211
|
-
const prompt = createModificationPrompt(currentSpec, args.input);
|
|
212
|
-
|
|
213
|
-
// 4. Return prompt + context for LLM to process
|
|
214
|
-
// The LLM (Cursor) will see this and output the modified spec
|
|
215
|
-
return {
|
|
216
|
-
mode: "extend",
|
|
217
|
-
prompt,
|
|
218
|
-
current_spec: currentSpec,
|
|
219
|
-
schema: WORKFLOW_SCHEMA_FOR_LLM,
|
|
220
|
-
instruction: "Modify the spec and call workflow(mode='apply', spec=<modified_spec>)"
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
async function handleApply(args, client) {
|
|
225
|
-
// 5. LLM calls back with modified spec
|
|
226
|
-
const modifiedSpec = args.spec;
|
|
227
|
-
|
|
228
|
-
// 6. Transform and deploy
|
|
229
|
-
const result = transformWorkflow(originalDef, modifiedSpec);
|
|
230
|
-
|
|
231
|
-
if (result.success && !args.preview) {
|
|
232
|
-
await client.updateAiEmployee({
|
|
233
|
-
persona_id: args.persona_id,
|
|
234
|
-
workflow: result.workflow_def
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return result;
|
|
239
|
-
}
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### Success Criteria
|
|
243
|
-
|
|
244
|
-
With this approach, the following should have **near 100% success rate**:
|
|
245
|
-
- Rewiring connections between nodes
|
|
246
|
-
- Adding/removing nodes
|
|
247
|
-
- Adding conditional execution (runIf)
|
|
248
|
-
- Adding HITL approval flows
|
|
249
|
-
- Modifying categories
|
|
250
|
-
- Consolidating multiple nodes
|
|
251
|
-
|
|
252
|
-
All because the LLM (not keyword matching) does the thinking.
|