@ema.co/mcp-toolkit 2026.1.27 → 2026.1.28-2

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 (35) hide show
  1. package/dist/mcp/handlers/data/index.js +3 -0
  2. package/dist/mcp/handlers/persona/create.js +16 -0
  3. package/dist/mcp/handlers/persona/list.js +9 -4
  4. package/dist/mcp/handlers/persona/update.js +24 -2
  5. package/dist/mcp/handlers/workflow/deploy.js +20 -2
  6. package/dist/mcp/handlers/workflow/generate.js +39 -2
  7. package/dist/mcp/handlers/workflow/index.js +8 -3
  8. package/dist/mcp/handlers/workflow/modify.js +34 -7
  9. package/dist/mcp/handlers/workflow/validate.js +85 -0
  10. package/dist/mcp/handlers/workflow/validation.js +160 -0
  11. package/dist/mcp/resources.js +286 -4
  12. package/dist/mcp/server.js +16 -3
  13. package/dist/mcp/tools.js +32 -11
  14. package/dist/sdk/client.js +36 -9
  15. package/dist/sdk/ema-client.js +32 -4
  16. package/dist/sdk/index.js +3 -1
  17. package/dist/sdk/knowledge.js +5 -5
  18. package/dist/sdk/structural-rules.js +498 -0
  19. package/dist/sdk/workflow-generator.js +2 -1
  20. package/dist/sdk/workflow-intent.js +28 -96
  21. package/dist/sdk/workflow-path-enumerator.js +278 -0
  22. package/dist/sdk/workflow-static-validator.js +291 -0
  23. package/dist/sdk/workflow-validation-types.js +7 -0
  24. package/docs/README.md +14 -0
  25. package/docs/go-validator-analysis.md +323 -0
  26. package/docs/rule-format-specification.md +346 -0
  27. package/docs/validation-contract.md +397 -0
  28. package/docs/validation-error-format.md +326 -0
  29. package/package.json +1 -1
  30. package/dist/mcp/workflow-operations.js +0 -100
  31. package/dist/sdk/workflow-fixer.js +0 -48
  32. package/docs/dashboard-operations.md +0 -281
  33. package/docs/ema-user-guide.md +0 -1201
  34. package/docs/email-patterns.md +0 -120
  35. package/docs/mcp-tools-guide.md +0 -575
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ema.co/mcp-toolkit",
3
- "version": "2026.1.27",
3
+ "version": "2026.1.28-2",
4
4
  "description": "Ema AI Employee toolkit - MCP server, CLI, and SDK for managing AI Employees across environments",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,100 +0,0 @@
1
- /**
2
- * Workflow Operations - Single Source of Truth
3
- *
4
- * This file defines supported workflow modification operations.
5
- * Used by:
6
- * - analyzeModificationRequest() in handlers-consolidated.ts
7
- * - Tool descriptions in tools.ts
8
- * - Tests to verify capabilities
9
- *
10
- * Add new operations here, and they'll automatically appear in tool docs.
11
- */
12
- /**
13
- * Supported incremental workflow modifications.
14
- * These are what `persona(method="update", input="...")` can handle.
15
- */
16
- export const SUPPORTED_OPERATIONS = [
17
- {
18
- type: "add",
19
- name: "Add HITL/approval",
20
- triggers: ["add hitl", "add approval", "confirm before", "human review"],
21
- example: "add HITL before email",
22
- notes: "Adds general_hitl node before specified action",
23
- },
24
- {
25
- type: "remove",
26
- name: "Remove nodes",
27
- triggers: ["remove", "delete", "clean up orphan"],
28
- example: "remove the search node",
29
- notes: "Can remove specific nodes or orphan nodes",
30
- },
31
- {
32
- type: "replace",
33
- name: "Replace nodes",
34
- triggers: ["replace X with Y", "swap", "use instead of"],
35
- example: "replace LLM extraction with entity_extraction",
36
- },
37
- {
38
- type: "consolidate",
39
- name: "Consolidate nodes",
40
- triggers: ["consolidate", "merge", "combine into one"],
41
- example: "consolidate the 8 custom agents into one",
42
- },
43
- {
44
- type: "rewire",
45
- name: "Rewire connections",
46
- triggers: ["connect", "wire", "link X to Y"],
47
- example: "connect search output to response",
48
- },
49
- ];
50
- /**
51
- * Limitations of INCREMENTAL modifications (persona method="update" with input).
52
- * For complex workflows, use the workflow tool instead.
53
- */
54
- export const LIMITATIONS = [
55
- "Build complex multi-node workflows from scratch → use workflow(mode='generate')",
56
- "Add multiple interconnected nodes at once → use workflow(mode='generate')",
57
- ];
58
- /**
59
- * Alternative approaches for complex workflows.
60
- */
61
- export const ALTERNATIVES = {
62
- complexWorkflow: "workflow(mode='generate', input='...') for multi-node generation",
63
- cloneExisting: "persona(method='create', from='similar-persona-id', name='New Name')",
64
- };
65
- /**
66
- * Generate tool description for the `input` parameter.
67
- * Called by tools.ts to ensure description matches actual capabilities.
68
- */
69
- export function generateInputDescription() {
70
- const ops = SUPPORTED_OPERATIONS.map(op => op.example).join("', '");
71
- return `Incremental workflow changes. Supports: '${ops}'. For complex multi-node workflows, clone from existing persona instead.`;
72
- }
73
- /**
74
- * Generate detailed capabilities for tool help text.
75
- */
76
- export function generateCapabilitiesHelp() {
77
- const lines = [
78
- "## Supported Workflow Modifications",
79
- "",
80
- "The `input` parameter supports these INCREMENTAL changes:",
81
- "",
82
- ];
83
- for (const op of SUPPORTED_OPERATIONS) {
84
- lines.push(`- **${op.name}**: \`${op.example}\``);
85
- if (op.notes) {
86
- lines.push(` - ${op.notes}`);
87
- }
88
- }
89
- lines.push("");
90
- lines.push("## NOT Supported (use clone instead)");
91
- lines.push("");
92
- for (const limit of LIMITATIONS) {
93
- lines.push(`- ${limit}`);
94
- }
95
- lines.push("");
96
- lines.push("## For Complex Workflows");
97
- lines.push("");
98
- lines.push(`Clone from existing: \`${ALTERNATIVES.complexWorkflow}\``);
99
- return lines.join("\n");
100
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * Workflow Fixer (SDK)
3
- *
4
- * DEPRECATED: This module used detectWorkflowIssues which has been removed.
5
- *
6
- * The LLM should analyze workflows using rules from:
7
- * - ema://rules/anti-patterns
8
- * - ema://rules/input-sources
9
- * - ema://rules/optimizations
10
- *
11
- * And then make structured modifications via:
12
- * - workflow(mode="deploy", workflow_def={...})
13
- * - persona(mode="update", operations=[...])
14
- *
15
- * This file is kept for backwards compatibility with minimal functionality.
16
- */
17
- // ═══════════════════════════════════════════════════════════════════════════
18
- // DEPRECATED FUNCTIONS (no-ops)
19
- // ═══════════════════════════════════════════════════════════════════════════
20
- /**
21
- * DEPRECATED: Auto-fix workflow issues.
22
- *
23
- * This function now returns the workflow unchanged with a deprecation warning.
24
- * Use LLM analysis with ema://rules/* instead.
25
- */
26
- export function autoFixWorkflow(workflowDef) {
27
- return {
28
- workflowDef: workflowDef,
29
- fixesApplied: [],
30
- success: true,
31
- warnings: [
32
- "DEPRECATED: autoFixWorkflow() no longer auto-fixes issues.",
33
- "Use LLM analysis with ema://rules/anti-patterns instead.",
34
- ],
35
- };
36
- }
37
- /**
38
- * DEPRECATED: Suggest fixes for workflow issues.
39
- *
40
- * This function now returns empty results with a deprecation warning.
41
- * Use LLM analysis with ema://rules/* instead.
42
- */
43
- export function suggestFixes(_workflowDef) {
44
- return {
45
- standardFixes: [],
46
- multiResponderFixes: [],
47
- };
48
- }
@@ -1,281 +0,0 @@
1
- # Dashboard Operations
2
-
3
- ## Overview
4
-
5
- Dashboard-type AI Employees process data in batches. Each row in a dashboard represents one execution of the workflow with specific inputs.
6
-
7
- ## Architecture
8
-
9
- ```
10
- ┌─────────────────────────────────────────────────────────────────┐
11
- │ Dashboard Persona │
12
- ├─────────────────────────────────────────────────────────────────┤
13
- │ workflow_dashboard_id: "dashboard-uuid" │
14
- │ trigger_type: DOCUMENT_TRIGGER │
15
- └─────────────────────────────────────────────────────────────────┘
16
-
17
-
18
- ┌─────────────────────────────────────────────────────────────────┐
19
- │ Dashboard │
20
- ├────────────┬──────────────┬─────────────┬──────────────────────┤
21
- │ Schema │ Input Cols │ Output Cols │ Rows │
22
- ├────────────┼──────────────┼─────────────┼──────────────────────┤
23
- │ columnId │ name, type │ name, type │ id, state, values │
24
- └────────────┴──────────────┴─────────────┴──────────────────────┘
25
- ```
26
-
27
- ## SDK Methods
28
-
29
- | Method | Purpose | Key Parameters |
30
- |--------|---------|----------------|
31
- | `getDashboardRows()` | List rows with schema | `dashboardId`, `personaId`, `{ limit }` |
32
- | `getDashboardRowResult()` | Get single row | `personaId`, `rowId`, `includeFileContents?` |
33
- | `uploadAndRunDashboardRow()` | Create new row | `personaId`, `inputs[]` |
34
- | `rerunDashboardRow()` | Re-execute workflow | `personaId`, `rowId` |
35
-
36
- ### Input Types (DashboardInput)
37
-
38
- ```typescript
39
- type DashboardInput = {
40
- name: string; // Column name (required)
41
- string_value?: string; // Text input
42
- number_value?: number; // Numeric input
43
- boolean_value?: boolean; // Boolean input
44
- document_value?: Array<{ // File input
45
- name: string; // Filename
46
- contents: string; // Base64-encoded content
47
- is_base64_encoded: boolean; // Always true for documents
48
- mime_type: string; // e.g., "application/pdf"
49
- }>;
50
- };
51
- ```
52
-
53
- ## MCP Tool: Data Operations
54
-
55
- ### Purpose
56
- Clone rows from one dashboard persona to another. Useful for:
57
- - Creating demo environments with real data structure
58
- - Testing with sanitized production data
59
- - Duplicating configurations across personas
60
-
61
- ### Recommended: Action Composition
62
-
63
- Use the `actions` array when creating/cloning personas:
64
-
65
- ```typescript
66
- // Clone persona with data copy and sanitization
67
- persona(
68
- method="create",
69
- from="source-persona-uuid",
70
- name="Demo Dashboard",
71
- actions=[
72
- {tool:"data", args:{method:"copy", from:"$source"}},
73
- {tool:"data", args:{method:"sanitize", examples:["john@acme.com", "Acme Corp"]}},
74
- ]
75
- )
76
-
77
- // Or use built-in alias
78
- persona(method="create", from="source-persona-uuid", name="Demo Dashboard", actions=["copy-and-sanitize"])
79
- ```
80
-
81
- ### Direct Data Operations
82
-
83
- For operations on existing personas, use the `data` sub-resource:
84
-
85
- ```typescript
86
- // Copy data from another persona
87
- persona(id="target-persona-uuid", data={method:"copy", from:"source-persona-uuid", sanitize:true})
88
-
89
- // List data items
90
- persona(id="persona-uuid", data={method:"list"})
91
-
92
- // Get input schema
93
- persona(id="persona-uuid", data={method:"schema"})
94
- ```
95
-
96
- ### Upload Dashboard Rows with Files
97
-
98
- Create new dashboard rows with file attachments (triggers workflow execution):
99
-
100
- ```javascript
101
- persona(id="dashboard-uuid", data={
102
- method: "upload",
103
- items: [
104
- {
105
- "Input Document": { file: "/path/to/invoice.pdf" },
106
- "Customer Name": "Acme Corp",
107
- "Amount": 1500.00,
108
- "Priority": true
109
- }
110
- ]
111
- })
112
- ```
113
-
114
- **Supported value types in `items`:**
115
-
116
- | Type | Format | Result |
117
- |------|--------|--------|
118
- | String | `"value"` | `string_value` |
119
- | Number | `123.45` | `number_value` |
120
- | Boolean | `true` | `boolean_value` |
121
- | File | `{ file: "/path/to/doc.pdf" }` | `document_value` (auto base64) |
122
- | Inline Doc | `{ contents: "...", mime_type: "text/plain" }` | `document_value` |
123
-
124
- **Key differences from knowledge base upload:**
125
-
126
- | Operation | Target | Use Case |
127
- |-----------|--------|----------|
128
- | `data={method:"upload", path:"..."}` | Knowledge Base | Chat personas, RAG search |
129
- | `data={method:"upload", items:[...]}` | Dashboard Rows | Dashboard personas, per-row workflow |
130
-
131
- ### Legacy Syntax (still works)
132
-
133
- ```
134
- knowledge(
135
- persona_id="target-persona-uuid",
136
- source_persona_id="source-persona-uuid",
137
- mode="dashboard_clone",
138
- sanitize=true,
139
- sanitize_examples=["john@acme.com", "Acme Corp"]
140
- )
141
- ```
142
-
143
- ### Response
144
-
145
- ```json
146
- {
147
- "success": true,
148
- "source_persona": "Source Dashboard",
149
- "target_persona": "Target Dashboard",
150
- "cloned_count": 5,
151
- "skipped_count": 0,
152
- "details": [
153
- {
154
- "source_row_id": "row-1",
155
- "target_row_id": "new-row-1",
156
- "status": "cloned"
157
- }
158
- ],
159
- "notes": [
160
- "Dashboard clone creates NEW rows in the target dashboard",
161
- "Workflows will re-run on the new rows to generate output columns"
162
- ]
163
- }
164
- ```
165
-
166
- ## Document Handling
167
-
168
- ### How Document Cloning Works
169
-
170
- 1. **Fetch source row** with file contents:
171
- ```typescript
172
- const rowResult = await client.getDashboardRowResult(
173
- sourcePersonaId,
174
- rowId,
175
- true // includeFileContents
176
- );
177
- ```
178
-
179
- 2. **Extract file content** from `additional_column_details`:
180
- ```typescript
181
- const fileContent = rowResult.additional_column_details?.find(
182
- d => d.column_id === columnId
183
- )?.file_contents; // Base64 encoded
184
- ```
185
-
186
- 3. **Build document input** for target:
187
- ```typescript
188
- const input: DashboardInput = {
189
- name: "Document Input",
190
- document_value: [{
191
- name: "filename.pdf",
192
- contents: fileContent,
193
- is_base64_encoded: true,
194
- mime_type: "application/pdf",
195
- }],
196
- };
197
- ```
198
-
199
- 4. **Upload to target dashboard**:
200
- ```typescript
201
- await client.uploadAndRunDashboardRow(targetPersonaId, [input]);
202
- ```
203
-
204
- ### MIME Type Inference
205
-
206
- When document `type` is not available, inferred from extension:
207
-
208
- | Extension | MIME Type |
209
- |-----------|-----------|
210
- | `.pdf` | `application/pdf` |
211
- | `.docx` | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` |
212
- | `.xlsx` | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
213
- | `.csv` | `text/csv` |
214
- | `.txt` | `text/plain` |
215
- | `.png` | `image/png` |
216
- | `.jpg`/`.jpeg` | `image/jpeg` |
217
- | Other | `application/octet-stream` |
218
-
219
- ## Common Patterns
220
-
221
- ### List Dashboard Rows
222
-
223
- ```
224
- knowledge(persona_id="...", mode="dashboard_rows", limit=10)
225
- ```
226
-
227
- ### Clone with Sanitization
228
-
229
- **Recommended (action composition):**
230
-
231
- ```typescript
232
- persona(
233
- method="create",
234
- from="source",
235
- name="Demo Dashboard",
236
- actions=[
237
- {tool:"data", args:{method:"copy", from:"$source"}},
238
- {tool:"data", args:{method:"sanitize", examples:["real-email@company.com", "Real Company Name"]}},
239
- ]
240
- )
241
- ```
242
-
243
- **Legacy syntax (still works):**
244
-
245
- ```
246
- knowledge(
247
- persona_id="target",
248
- source_persona_id="source",
249
- mode="dashboard_clone",
250
- sanitize=true,
251
- sanitize_examples=["real-email@company.com", "Real Company Name"]
252
- )
253
- ```
254
-
255
- ### Manual Row Upload
256
-
257
- Use `uploadAndRunDashboardRow` directly for programmatic row creation:
258
-
259
- ```typescript
260
- await client.uploadAndRunDashboardRow(personaId, [
261
- { name: "Input Column", string_value: "test data" },
262
- { name: "Document Column", document_value: [...] },
263
- ]);
264
- ```
265
-
266
- ## Error Handling
267
-
268
- | Error | Cause | Solution |
269
- |-------|-------|----------|
270
- | "Persona has no dashboard" | Wrong persona type | Use only with DOCUMENT_TRIGGER personas |
271
- | "Document content not available" | `includeFileContents` returned empty | Source document may have been deleted |
272
- | "Source persona not found" | Invalid `source_persona_id` | Verify persona exists in environment |
273
-
274
- ## Related Files
275
-
276
- | File | Purpose |
277
- |------|---------|
278
- | `src/sdk/client.ts` | SDK methods for dashboard operations |
279
- | `src/mcp/handlers-consolidated.ts` | MCP handlers (dashboard_rows, dashboard_clone) |
280
- | `test/integration/dashboard-clone.integration.test.ts` | Integration tests |
281
- | `test/handlers-consolidated.test.ts` | Unit tests for cloning logic |