@ema.co/mcp-toolkit 2026.2.5 → 2026.2.19

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/LICENSE +29 -21
  4. package/README.md +58 -35
  5. package/dist/mcp/domain/loop-detection.js +97 -0
  6. package/dist/mcp/domain/proto-constraints.js +284 -0
  7. package/dist/mcp/domain/structural-rules.js +12 -5
  8. package/dist/mcp/domain/validation-rules.js +107 -20
  9. package/dist/mcp/domain/workflow-graph-optimizer.js +235 -0
  10. package/dist/mcp/domain/workflow-graph-transforms.js +808 -0
  11. package/dist/mcp/domain/workflow-graph.js +374 -0
  12. package/dist/mcp/domain/workflow-optimizer.js +10 -4
  13. package/dist/mcp/guidance.js +54 -31
  14. package/dist/mcp/handlers/feedback/index.js +139 -0
  15. package/dist/mcp/handlers/feedback/store.js +262 -0
  16. package/dist/mcp/handlers/persona/index.js +237 -8
  17. package/dist/mcp/handlers/persona/schema.js +27 -0
  18. package/dist/mcp/handlers/reference/index.js +6 -4
  19. package/dist/mcp/handlers/workflow/index.js +25 -28
  20. package/dist/mcp/handlers/workflow/optimize.js +73 -33
  21. package/dist/mcp/handlers/workflow/validation.js +1 -1
  22. package/dist/mcp/knowledge-types.js +7 -0
  23. package/dist/mcp/knowledge.js +146 -834
  24. package/dist/mcp/resources.js +610 -18
  25. package/dist/mcp/server.js +233 -2156
  26. package/dist/mcp/tools.js +91 -5
  27. package/dist/sdk/generated/agent-catalog.js +615 -0
  28. package/dist/sdk/generated/deprecated-actions.js +182 -96
  29. package/dist/sdk/generated/proto-fields.js +2 -1
  30. package/dist/sdk/generated/protos/service/agent_qa/v1/agent_qa_pb.js +460 -21
  31. package/dist/sdk/generated/protos/service/auth/v1/auth_pb.js +11 -1
  32. package/dist/sdk/generated/protos/service/dataingest/v1/dataingest_pb.js +173 -66
  33. package/dist/sdk/generated/protos/service/feedback/v1/feedback_pb.js +43 -1
  34. package/dist/sdk/generated/protos/service/llmservice/v1/llmservice_pb.js +26 -21
  35. package/dist/sdk/generated/protos/service/persona/v1/persona_config_pb.js +100 -89
  36. package/dist/sdk/generated/protos/service/persona/v1/persona_pb.js +126 -116
  37. package/dist/sdk/generated/protos/service/persona/v1/shared_widgets/widget_types_pb.js +33 -1
  38. package/dist/sdk/generated/protos/service/persona/v1/voicebot_widgets/widget_types_pb.js +60 -11
  39. package/dist/sdk/generated/protos/service/tenant/v1/tenant_pb.js +1 -1
  40. package/dist/sdk/generated/protos/service/user/v1/user_pb.js +1 -1
  41. package/dist/sdk/generated/protos/service/utils/v1/agent_qa_pb.js +35 -0
  42. package/dist/sdk/generated/protos/service/workflows/v1/action_registry_pb.js +1 -1
  43. package/dist/sdk/generated/protos/service/workflows/v1/action_type_pb.js +6 -1
  44. package/dist/sdk/generated/protos/service/workflows/v1/chatbot_pb.js +106 -11
  45. package/dist/sdk/generated/protos/service/workflows/v1/common_forms_pb.js +1 -1
  46. package/dist/sdk/generated/protos/service/workflows/v1/coordinator_pb.js +1 -1
  47. package/dist/sdk/generated/protos/service/workflows/v1/external_actions_pb.js +31 -1
  48. package/dist/sdk/generated/protos/service/workflows/v1/well_known_pb.js +5 -1
  49. package/dist/sdk/generated/protos/service/workflows/v1/workflow_pb.js +1 -1
  50. package/dist/sdk/generated/protos/util/tracking_metadata_pb.js +1 -1
  51. package/dist/sdk/generated/widget-catalog.js +60 -0
  52. package/docs/README.md +17 -9
  53. package/package.json +2 -2
  54. package/.context/public/guides/dashboard-operations.md +0 -286
  55. package/.context/public/guides/email-patterns.md +0 -125
  56. package/dist/mcp/domain/intent-architect.js +0 -914
  57. package/dist/mcp/domain/quality-gates.js +0 -110
  58. package/dist/mcp/domain/workflow-execution-analyzer.js +0 -412
  59. package/dist/mcp/domain/workflow-intent.js +0 -1806
  60. package/dist/mcp/domain/workflow-merge.js +0 -449
  61. package/dist/mcp/domain/workflow-tracer.js +0 -648
  62. package/dist/mcp/domain/workflow-transformer.js +0 -742
  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,286 +0,0 @@
1
- ---
2
- title: "Dashboard Operations"
3
- date: 2026-01-27
4
- audience: public
5
- ---
6
- # Dashboard Operations
7
-
8
- ## Overview
9
-
10
- Dashboard-type AI Employees process data in batches. Each row in a dashboard represents one execution of the workflow with specific inputs.
11
-
12
- ## Architecture
13
-
14
- ```
15
- ┌─────────────────────────────────────────────────────────────────┐
16
- │ Dashboard Persona │
17
- ├─────────────────────────────────────────────────────────────────┤
18
- │ workflow_dashboard_id: "dashboard-uuid" │
19
- │ trigger_type: DOCUMENT_TRIGGER │
20
- └─────────────────────────────────────────────────────────────────┘
21
-
22
-
23
- ┌─────────────────────────────────────────────────────────────────┐
24
- │ Dashboard │
25
- ├────────────┬──────────────┬─────────────┬──────────────────────┤
26
- │ Schema │ Input Cols │ Output Cols │ Rows │
27
- ├────────────┼──────────────┼─────────────┼──────────────────────┤
28
- │ columnId │ name, type │ name, type │ id, state, values │
29
- └────────────┴──────────────┴─────────────┴──────────────────────┘
30
- ```
31
-
32
- ## SDK Methods
33
-
34
- | Method | Purpose | Key Parameters |
35
- |--------|---------|----------------|
36
- | `getDashboardRows()` | List rows with schema | `dashboardId`, `personaId`, `{ limit }` |
37
- | `getDashboardRowResult()` | Get single row | `personaId`, `rowId`, `includeFileContents?` |
38
- | `uploadAndRunDashboardRow()` | Create new row | `personaId`, `inputs[]` |
39
- | `rerunDashboardRow()` | Re-execute workflow | `personaId`, `rowId` |
40
-
41
- ### Input Types (DashboardInput)
42
-
43
- ```typescript
44
- type DashboardInput = {
45
- name: string; // Column name (required)
46
- string_value?: string; // Text input
47
- number_value?: number; // Numeric input
48
- boolean_value?: boolean; // Boolean input
49
- document_value?: Array<{ // File input
50
- name: string; // Filename
51
- contents: string; // Base64-encoded content
52
- is_base64_encoded: boolean; // Always true for documents
53
- mime_type: string; // e.g., "application/pdf"
54
- }>;
55
- };
56
- ```
57
-
58
- ## MCP Tool: Data Operations
59
-
60
- ### Purpose
61
- Clone rows from one dashboard persona to another. Useful for:
62
- - Creating demo environments with real data structure
63
- - Testing with sanitized production data
64
- - Duplicating configurations across personas
65
-
66
- ### Recommended: Action Composition
67
-
68
- Use the `actions` array when creating/cloning personas:
69
-
70
- ```typescript
71
- // Clone persona with data copy and sanitization
72
- persona(
73
- method="create",
74
- from="source-persona-uuid",
75
- name="Demo Dashboard",
76
- actions=[
77
- {tool:"data", args:{method:"copy", from:"$source"}},
78
- {tool:"data", args:{method:"sanitize", examples:["john@acme.com", "Acme Corp"]}},
79
- ]
80
- )
81
-
82
- // Or use built-in alias
83
- persona(method="create", from="source-persona-uuid", name="Demo Dashboard", actions=["copy-and-sanitize"])
84
- ```
85
-
86
- ### Direct Data Operations
87
-
88
- For operations on existing personas, use the `data` sub-resource:
89
-
90
- ```typescript
91
- // Copy data from another persona
92
- persona(id="target-persona-uuid", data={method:"copy", from:"source-persona-uuid", sanitize:true})
93
-
94
- // List data items
95
- persona(id="persona-uuid", data={method:"list"})
96
-
97
- // Get input schema
98
- persona(id="persona-uuid", data={method:"schema"})
99
- ```
100
-
101
- ### Upload Dashboard Rows with Files
102
-
103
- Create new dashboard rows with file attachments (triggers workflow execution):
104
-
105
- ```javascript
106
- persona(id="dashboard-uuid", data={
107
- method: "upload",
108
- items: [
109
- {
110
- "Input Document": { file: "/path/to/invoice.pdf" },
111
- "Customer Name": "Acme Corp",
112
- "Amount": 1500.00,
113
- "Priority": true
114
- }
115
- ]
116
- })
117
- ```
118
-
119
- **Supported value types in `items`:**
120
-
121
- | Type | Format | Result |
122
- |------|--------|--------|
123
- | String | `"value"` | `string_value` |
124
- | Number | `123.45` | `number_value` |
125
- | Boolean | `true` | `boolean_value` |
126
- | File | `{ file: "/path/to/doc.pdf" }` | `document_value` (auto base64) |
127
- | Inline Doc | `{ contents: "...", mime_type: "text/plain" }` | `document_value` |
128
-
129
- **Key differences from knowledge base upload:**
130
-
131
- | Operation | Target | Use Case |
132
- |-----------|--------|----------|
133
- | `data={method:"upload", path:"..."}` | Knowledge Base | Chat personas, RAG search |
134
- | `data={method:"upload", items:[...]}` | Dashboard Rows | Dashboard personas, per-row workflow |
135
-
136
- ### Legacy Syntax (still works)
137
-
138
- ```
139
- knowledge(
140
- persona_id="target-persona-uuid",
141
- source_persona_id="source-persona-uuid",
142
- mode="dashboard_clone",
143
- sanitize=true,
144
- sanitize_examples=["john@acme.com", "Acme Corp"]
145
- )
146
- ```
147
-
148
- ### Response
149
-
150
- ```json
151
- {
152
- "success": true,
153
- "source_persona": "Source Dashboard",
154
- "target_persona": "Target Dashboard",
155
- "cloned_count": 5,
156
- "skipped_count": 0,
157
- "details": [
158
- {
159
- "source_row_id": "row-1",
160
- "target_row_id": "new-row-1",
161
- "status": "cloned"
162
- }
163
- ],
164
- "notes": [
165
- "Dashboard clone creates NEW rows in the target dashboard",
166
- "Workflows will re-run on the new rows to generate output columns"
167
- ]
168
- }
169
- ```
170
-
171
- ## Document Handling
172
-
173
- ### How Document Cloning Works
174
-
175
- 1. **Fetch source row** with file contents:
176
- ```typescript
177
- const rowResult = await client.getDashboardRowResult(
178
- sourcePersonaId,
179
- rowId,
180
- true // includeFileContents
181
- );
182
- ```
183
-
184
- 2. **Extract file content** from `additional_column_details`:
185
- ```typescript
186
- const fileContent = rowResult.additional_column_details?.find(
187
- d => d.column_id === columnId
188
- )?.file_contents; // Base64 encoded
189
- ```
190
-
191
- 3. **Build document input** for target:
192
- ```typescript
193
- const input: DashboardInput = {
194
- name: "Document Input",
195
- document_value: [{
196
- name: "filename.pdf",
197
- contents: fileContent,
198
- is_base64_encoded: true,
199
- mime_type: "application/pdf",
200
- }],
201
- };
202
- ```
203
-
204
- 4. **Upload to target dashboard**:
205
- ```typescript
206
- await client.uploadAndRunDashboardRow(targetPersonaId, [input]);
207
- ```
208
-
209
- ### MIME Type Inference
210
-
211
- When document `type` is not available, inferred from extension:
212
-
213
- | Extension | MIME Type |
214
- |-----------|-----------|
215
- | `.pdf` | `application/pdf` |
216
- | `.docx` | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` |
217
- | `.xlsx` | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
218
- | `.csv` | `text/csv` |
219
- | `.txt` | `text/plain` |
220
- | `.png` | `image/png` |
221
- | `.jpg`/`.jpeg` | `image/jpeg` |
222
- | Other | `application/octet-stream` |
223
-
224
- ## Common Patterns
225
-
226
- ### List Dashboard Rows
227
-
228
- ```
229
- knowledge(persona_id="...", mode="dashboard_rows", limit=10)
230
- ```
231
-
232
- ### Clone with Sanitization
233
-
234
- **Recommended (action composition):**
235
-
236
- ```typescript
237
- persona(
238
- method="create",
239
- from="source",
240
- name="Demo Dashboard",
241
- actions=[
242
- {tool:"data", args:{method:"copy", from:"$source"}},
243
- {tool:"data", args:{method:"sanitize", examples:["real-email@company.com", "Real Company Name"]}},
244
- ]
245
- )
246
- ```
247
-
248
- **Legacy syntax (still works):**
249
-
250
- ```
251
- knowledge(
252
- persona_id="target",
253
- source_persona_id="source",
254
- mode="dashboard_clone",
255
- sanitize=true,
256
- sanitize_examples=["real-email@company.com", "Real Company Name"]
257
- )
258
- ```
259
-
260
- ### Manual Row Upload
261
-
262
- Use `uploadAndRunDashboardRow` directly for programmatic row creation:
263
-
264
- ```typescript
265
- await client.uploadAndRunDashboardRow(personaId, [
266
- { name: "Input Column", string_value: "test data" },
267
- { name: "Document Column", document_value: [...] },
268
- ]);
269
- ```
270
-
271
- ## Error Handling
272
-
273
- | Error | Cause | Solution |
274
- |-------|-------|----------|
275
- | "Persona has no dashboard" | Wrong persona type | Use only with DOCUMENT_TRIGGER personas |
276
- | "Document content not available" | `includeFileContents` returned empty | Source document may have been deleted |
277
- | "Source persona not found" | Invalid `source_persona_id` | Verify persona exists in environment |
278
-
279
- ## Related Files
280
-
281
- | File | Purpose |
282
- |------|---------|
283
- | `src/sdk/client.ts` | SDK methods for dashboard operations |
284
- | `src/mcp/handlers-consolidated.ts` | MCP handlers (dashboard_rows, dashboard_clone) |
285
- | `test/integration/dashboard-clone.integration.test.ts` | Integration tests |
286
- | `test/handlers-consolidated.test.ts` | Unit tests for cloning logic |
@@ -1,125 +0,0 @@
1
- ---
2
- title: "Email Field Extraction Patterns"
3
- date: 2026-01-27
4
- audience: public
5
- ---
6
- # Email Field Extraction Patterns
7
-
8
- ## Problem
9
-
10
- `send_email_agent.to_email` expects a text email address, but `entity_extraction` outputs `extraction_columns` (a JSON object), not individual fields.
11
-
12
- **This does NOT work:**
13
- ```
14
- entity_extraction.extraction_columns → send_email.to_email
15
- ```
16
-
17
- The types are incompatible:
18
- - `extraction_columns` = `WELL_KNOWN_TYPE_ANY` (JSON object)
19
- - `to_email` = `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` (text)
20
-
21
- ## Solution Pattern
22
-
23
- ```
24
- entity_extraction.extraction_columns
25
- → fixed_response (template: "{{email}}")
26
- → send_email.to_email
27
- ```
28
-
29
- ### Why This Works
30
-
31
- 1. `entity_extraction` extracts structured data into JSON: `{"email": "user@example.com", "name": "John"}`
32
- 2. `fixed_response` with `{{email}}` template extracts the field and outputs plain text
33
- 3. `fixed_response` output type is `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` - compatible with `to_email`
34
-
35
- ### WorkflowSpec Example
36
-
37
- ```typescript
38
- {
39
- nodes: [
40
- {
41
- id: "extract_entities_abc123",
42
- actionType: "entity_extraction_with_documents",
43
- displayName: "Extract Contact Info",
44
- // outputs: extraction_columns (JSON)
45
- },
46
- {
47
- id: "format_email_def456",
48
- actionType: "fixed_response",
49
- displayName: "Format Email Address",
50
- inputs: {
51
- query: {
52
- type: "action_output",
53
- actionName: "extract_entities_abc123",
54
- output: "extraction_columns"
55
- }
56
- },
57
- config: {
58
- response_template: "{{email}}" // Extracts email field
59
- }
60
- // outputs: response (text)
61
- },
62
- {
63
- id: "send_email_ghi789",
64
- actionType: "send_email_agent",
65
- displayName: "Send Email",
66
- inputs: {
67
- to_email: {
68
- type: "action_output",
69
- actionName: "format_email_def456",
70
- output: "response"
71
- },
72
- // ... other inputs
73
- }
74
- }
75
- ]
76
- }
77
- ```
78
-
79
- ## Alternative: JSON Mapper
80
-
81
- For complex extraction or multiple fields:
82
-
83
- ```
84
- entity_extraction.extraction_columns
85
- → json_mapper (extracts specific fields)
86
- → fixed_response (formats as text)
87
- → send_email.to_email
88
- ```
89
-
90
- **Note:** `json_mapper` is not in the WorkflowSpec compiler's supported action types. Use `applySpecToWorkflow()` for workflows containing `json_mapper`.
91
-
92
- ## Common Mistakes
93
-
94
- ### 1. Direct Wiring
95
- ```
96
- ❌ entity_extraction → send_email.to_email
97
- ```
98
- Type mismatch. JSON object cannot be used as email address.
99
-
100
- ### 2. Assuming `.email_address` Output Exists
101
- ```
102
- ❌ entity_extraction.email_address → send_email.to_email
103
- ```
104
- This output doesn't exist. `entity_extraction` only outputs `extraction_columns`.
105
-
106
- ### 3. Skipping Template Step
107
- ```
108
- ❌ entity_extraction → json_mapper → send_email.to_email
109
- ```
110
- Even `json_mapper` output may not be the right type. Always use `fixed_response` as the final step before `send_email` inputs.
111
-
112
- ## Type Reference
113
-
114
- | Action | Output | Type |
115
- |--------|--------|------|
116
- | `entity_extraction` | `extraction_columns` | `WELL_KNOWN_TYPE_ANY` (JSON) |
117
- | `json_mapper` | varies | depends on mapping |
118
- | `fixed_response` | `response` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
119
- | `call_llm` | `response` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
120
-
121
- | Input | Expected Type |
122
- |-------|---------------|
123
- | `send_email.to_email` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
124
- | `send_email.subject` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
125
- | `send_email.body` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |