@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.

Files changed (87) hide show
  1. package/README.md +10 -2
  2. package/dist/mcp/handlers/action/index.js +3 -18
  3. package/dist/mcp/handlers/data/index.js +385 -41
  4. package/dist/mcp/handlers/data/templates.js +107 -0
  5. package/dist/mcp/handlers/deprecation.js +50 -0
  6. package/dist/mcp/handlers/env/index.js +8 -4
  7. package/dist/mcp/handlers/knowledge/index.js +44 -237
  8. package/dist/mcp/handlers/persona/create.js +47 -18
  9. package/dist/mcp/handlers/persona/index.js +14 -11
  10. package/dist/mcp/handlers/persona/update.js +4 -2
  11. package/dist/mcp/handlers/persona/version.js +234 -0
  12. package/dist/mcp/handlers/sync/index.js +3 -18
  13. package/dist/mcp/handlers/template/index.js +75 -10
  14. package/dist/mcp/handlers/workflow/analyze.js +171 -0
  15. package/dist/mcp/handlers/workflow/compare.js +70 -0
  16. package/dist/mcp/handlers/workflow/deploy.js +73 -0
  17. package/dist/mcp/handlers/workflow/generate.js +350 -0
  18. package/dist/mcp/handlers/workflow/index.js +294 -0
  19. package/dist/mcp/handlers/workflow/modify.js +456 -0
  20. package/dist/mcp/handlers/workflow/optimize.js +136 -0
  21. package/dist/mcp/handlers/workflow/types.js +4 -0
  22. package/dist/mcp/handlers/workflow/utils.js +30 -0
  23. package/dist/mcp/handlers-consolidated.js +73 -2696
  24. package/dist/mcp/prompts.js +83 -43
  25. package/dist/mcp/resources.js +382 -57
  26. package/dist/mcp/server.js +199 -391
  27. package/dist/mcp/{tools-v2.js → tools.js} +20 -54
  28. package/dist/mcp/workflow-operations.js +2 -2
  29. package/dist/sdk/client-adapter.js +267 -32
  30. package/dist/sdk/client.js +45 -16
  31. package/dist/sdk/ema-client.js +183 -0
  32. package/dist/sdk/generated/deprecated-actions.js +171 -0
  33. package/dist/sdk/generated/template-fallbacks.js +123 -0
  34. package/dist/sdk/guidance.js +65 -11
  35. package/dist/sdk/index.js +3 -1
  36. package/dist/sdk/knowledge.js +139 -86
  37. package/dist/sdk/workflow-intent.js +27 -0
  38. package/dist/sdk/workflow-transformer.js +0 -342
  39. package/docs/mcp-tools-guide.md +37 -45
  40. package/package.json +10 -4
  41. package/dist/mcp/handlers/persona/analyze.js +0 -275
  42. package/dist/mcp/handlers/persona/compare.js +0 -32
  43. package/dist/mcp/tools-consolidated.js +0 -875
  44. package/dist/mcp/tools-legacy.js +0 -736
  45. package/docs/CODEBASE-ANALYSIS-2026-01-23.md +0 -936
  46. package/docs/CODEBASE-ANALYSIS-PRIORITIZED.md +0 -774
  47. package/docs/api-contracts.md +0 -216
  48. package/docs/auto-builder-analysis.md +0 -271
  49. package/docs/blog/mcp-tool-design-lessons.md +0 -309
  50. package/docs/data-architecture.md +0 -166
  51. package/docs/demos/ap-invoice-generation.md +0 -347
  52. package/docs/demos/ap-invoice-processing.md +0 -271
  53. package/docs/ema-auto-builder-guide.html +0 -394
  54. package/docs/lessons-learned.md +0 -209
  55. package/docs/llm-native-workflow-design.md +0 -252
  56. package/docs/local-generation.md +0 -508
  57. package/docs/mcp-flow-diagram.md +0 -135
  58. package/docs/migration/action-composition-migration.md +0 -270
  59. package/docs/naming-conventions.md +0 -278
  60. package/docs/proposals/HANDOFF-tool-restructure.md +0 -526
  61. package/docs/proposals/action-composition.md +0 -490
  62. package/docs/proposals/explicit-method-restructure.md +0 -328
  63. package/docs/proposals/mcp-tool-restructure-2026-01.md +0 -366
  64. package/docs/proposals/self-contained-guidance.md +0 -427
  65. package/docs/proto-sdk-generation.md +0 -242
  66. package/docs/release-impact.md +0 -102
  67. package/docs/release-process.md +0 -157
  68. package/docs/staging.RULE.md +0 -142
  69. package/docs/test-persona-creation.md +0 -196
  70. package/docs/tool-consolidation-v2.md +0 -225
  71. package/docs/tool-response-standards.md +0 -256
  72. package/resources/demo-kits/README.md +0 -175
  73. package/resources/demo-kits/finance-ap/manifest.json +0 -150
  74. package/resources/demo-kits/tags.json +0 -91
  75. package/resources/docs/getting-started.md +0 -97
  76. package/resources/templates/auto-builder-rules.md +0 -224
  77. package/resources/templates/chat-ai/README.md +0 -119
  78. package/resources/templates/chat-ai/persona-config.json +0 -111
  79. package/resources/templates/dashboard-ai/README.md +0 -156
  80. package/resources/templates/dashboard-ai/persona-config.json +0 -180
  81. package/resources/templates/demo-scenarios/README.md +0 -63
  82. package/resources/templates/demo-scenarios/test-published-package.md +0 -116
  83. package/resources/templates/document-gen-ai/README.md +0 -132
  84. package/resources/templates/document-gen-ai/persona-config.json +0 -316
  85. package/resources/templates/voice-ai/README.md +0 -123
  86. package/resources/templates/voice-ai/persona-config.json +0 -74
  87. package/resources/templates/voice-ai/workflow-prompt.md +0 -121
@@ -1,309 +0,0 @@
1
- # Designing MCP Tools for How People Actually Use Them
2
-
3
- *Lessons from restructuring an MCP server from 7 "super tools" to 20 focused operations*
4
-
5
- ---
6
-
7
- ## The Starting Point
8
-
9
- We had built an MCP (Model Context Protocol) server for managing AI Employees on the Ema platform. It worked. Users could create personas, manage workflows, sync across environments. But something felt off.
10
-
11
- Our server had consolidated ~45 original tools into just 7 "super tools" using a `mode` parameter:
12
-
13
- ```typescript
14
- // What we had
15
- persona(mode="list")
16
- persona(mode="get", id="abc-123")
17
- persona(mode="create", name="Sales Bot", type="voice", input="...")
18
- persona(mode="analyze", id="abc-123", fix=true, include=["workflow", "config"])
19
- ```
20
-
21
- Fewer tools seemed better, right? Unix philosophy: do one thing well. Except each tool had 30+ parameters, and the LLM had to figure out which parameters applied to which mode.
22
-
23
- It was clever engineering. It was also wrong.
24
-
25
- ---
26
-
27
- ## The Problems We Discovered
28
-
29
- ### Problem 1: Parameter Sprawl
30
-
31
- Every time an LLM called our `persona` tool, it saw this schema:
32
-
33
- ```json
34
- {
35
- "properties": {
36
- "mode": { "enum": ["list", "get", "create", "update", "clone", "analyze", "sanitize", "templates", ...] },
37
- "id": { "description": "Persona ID" },
38
- "name": { "description": "Name for new persona" },
39
- "type": { "enum": ["voice", "chat", "dashboard"] },
40
- "from": { "description": "Template or persona to clone from" },
41
- "input": { "description": "Natural language description" },
42
- "include_data": { "description": "Include data when cloning" },
43
- "sanitize": { "description": "Remove PII" },
44
- "fix": { "description": "Auto-fix issues" },
45
- "include": { "description": "What to include in analysis" },
46
- "proto_config": { "description": "Override config" },
47
- "workflow": { "description": "Direct workflow JSON" },
48
- // ... 20 more parameters
49
- }
50
- }
51
- ```
52
-
53
- The LLM saw 30 parameters when it only needed 2 for a simple "get me this persona" request. Confusion ensued.
54
-
55
- ### Problem 2: Inconsistent Patterns
56
-
57
- We had three different patterns across our 7 tools:
58
-
59
- | Tool | Pattern |
60
- |------|---------|
61
- | `persona` | `mode` parameter required |
62
- | `action` | Flag-based (`all=true`, `suggest="..."`) |
63
- | `reference` | Hybrid (`type` enum + individual flags) |
64
-
65
- Which pattern should the LLM use? It depended on which tool. This meant the LLM had to learn 3 different interaction styles.
66
-
67
- ### Problem 3: We Designed for the Wrong User
68
-
69
- Here's the insight that changed everything:
70
-
71
- > **We designed tools as if humans would read the schemas. But LLMs read the schemas.**
72
-
73
- We thought about developer ergonomics: fewer tools, consistent naming, Unix-like. But LLMs don't care about those things. They care about:
74
-
75
- 1. **Does the tool name match the user's intent?**
76
- 2. **Are the parameters relevant to what I'm trying to do?**
77
- 3. **Is the description clear about when to use this?**
78
-
79
- ---
80
-
81
- ## The Key Insight: Users Speak, LLMs Choose
82
-
83
- When we observed actual usage, we saw this pattern:
84
-
85
- ```
86
- User: "Clone the Sales SDR with its data and clean it up for demo"
87
-
88
-
89
- LLM parses intent
90
-
91
-
92
- LLM searches available tools
93
-
94
-
95
- LLM selects: persona(mode="clone", from="...", include_data=true, sanitize=true)
96
- ```
97
-
98
- The user never typed a tool name. They never selected from a menu. They just described what they wanted in natural language.
99
-
100
- **This means tool design is really about one thing: making it easy for LLMs to match natural language intent to the right tool with the right parameters.**
101
-
102
- ---
103
-
104
- ## What About Prompts?
105
-
106
- MCP has two mechanisms: **Tools** and **Prompts**. We initially thought prompts could help—maybe `persona.create` as a prompt that guides the creation flow?
107
-
108
- But the MCP spec is clear about the distinction:
109
-
110
- | Mechanism | Who Controls | How Triggered |
111
- |-----------|--------------|---------------|
112
- | **Tools** | Model-controlled | LLM invokes automatically |
113
- | **Prompts** | User-controlled | User explicitly selects (slash commands) |
114
-
115
- Prompts are like slash commands (`/create_voice_ai`). They're for explicit, user-initiated workflows.
116
-
117
- **In practice, users rarely use slash commands.** They just talk. Which means tools are what matter for 95% of interactions.
118
-
119
- > **Design for natural language, not for slash commands. The LLM is the interface. Tools are the API.**
120
-
121
- ---
122
-
123
- ## The Redesign
124
-
125
- ### Principle 1: One Operation, One Tool
126
-
127
- Instead of modes, each operation gets its own tool:
128
-
129
- ```typescript
130
- // Before: mode-based
131
- persona(mode="list")
132
- persona(mode="get", id="abc")
133
- persona(mode="create", name="Bot", ...)
134
-
135
- // After: operation-based
136
- persona() // list (no params = list)
137
- persona(id="abc") // get (id = get one)
138
- persona_create(name="Bot", ...)
139
- persona_clone(from="abc", ...)
140
- ```
141
-
142
- Each tool has only the parameters relevant to that operation. When the LLM calls `persona_create`, it sees 5 relevant parameters, not 30.
143
-
144
- ### Principle 2: Names Match Natural Language
145
-
146
- Tool names should match how users describe their intent:
147
-
148
- | User Says | Tool Name |
149
- |-----------|-----------|
150
- | "show me my personas" | `persona` |
151
- | "create a voice AI" | `persona_create` |
152
- | "clone it with data" | `persona_clone` |
153
- | "what's wrong with it" | `persona_analyze` |
154
- | "push to staging" | `sync_run` |
155
-
156
- The LLM matches "clone it with data" to `persona_clone(include_data=true)` because the tool name and flag names align with natural language.
157
-
158
- ### Principle 3: Flags for Common Combinations
159
-
160
- Users often want compound operations: "clone with data AND sanitize." Instead of requiring multiple tool calls, common combinations become flags:
161
-
162
- ```typescript
163
- persona_clone(
164
- from: "abc",
165
- name: "Demo Copy",
166
- include_data: true, // Clone data files too
167
- sanitize: true // Remove PII
168
- )
169
- ```
170
-
171
- This handles 80% of cases in one call. For the other 20%, the LLM can chain tools.
172
-
173
- ### Principle 4: Hierarchy in Names
174
-
175
- Data and workflows are persona-specific. The naming reflects this:
176
-
177
- ```
178
- persona # list/get personas
179
- persona_create # create
180
- persona_clone # clone
181
-
182
- persona_data # list data for a persona
183
- persona_data_upload # upload to a persona
184
- persona_data_sanitize # sanitize data only
185
-
186
- persona_workflow # get workflow
187
- persona_workflow_modify # modify workflow
188
- persona_workflow_sanitize # sanitize workflow only
189
- ```
190
-
191
- This makes scope explicit: `persona_sanitize` does everything, `persona_data_sanitize` does just the data.
192
-
193
- ### Principle 5: Cross-Platform Compatibility
194
-
195
- We almost used dot notation (`persona.data.upload`) because it looks cleaner and the MCP spec allows it. Then we discovered:
196
-
197
- | Spec | Allows Dots? |
198
- |------|--------------|
199
- | MCP | Yes (`admin.tools.list` is valid) |
200
- | OpenAI API | No (`^[a-zA-Z0-9_-]+$`) |
201
-
202
- Many MCP clients bridge to OpenAI-compatible APIs. Dot notation would break those integrations. **Snake case (`_`) is the safe choice.**
203
-
204
- ---
205
-
206
- ## The Result
207
-
208
- ### Before: 7 Tools, 30+ Params Each
209
-
210
- ```
211
- persona(mode, id, name, type, from, input, include_data, sanitize, fix, include, ...)
212
- data(persona_id, mode, file_id, file, ...)
213
- action(id, all, query, category, suggest, ...)
214
- ...
215
- ```
216
-
217
- ### After: 20 Focused Tools
218
-
219
- ```
220
- # Core
221
- persona persona_create persona_clone
222
- persona_update persona_analyze persona_sanitize
223
-
224
- # Data (persona-scoped)
225
- persona_data persona_data_upload persona_data_generate
226
- persona_data_delete persona_data_sanitize
227
-
228
- # Workflow (persona-scoped)
229
- persona_workflow persona_workflow_modify persona_workflow_sanitize
230
-
231
- # Versions
232
- persona_version persona_version_create persona_version_restore
233
-
234
- # Other
235
- action action_suggest
236
- sync_run sync_status
237
- env
238
- ```
239
-
240
- Each tool has 3-8 parameters. The LLM sees only what's relevant.
241
-
242
- ---
243
-
244
- ## Key Takeaways
245
-
246
- ### 1. Design for LLM Selection, Not Human Browsing
247
-
248
- Your tool names and descriptions are an API for LLMs. They need to match natural language patterns so the LLM can find the right tool when the user says "clone this and clean it up."
249
-
250
- ### 2. Users Speak Natural Language, Not Slash Commands
251
-
252
- Prompts (user-triggered workflows) are a nice-to-have. Tools (model-selected operations) are the core experience. Invest accordingly.
253
-
254
- ### 3. Fewer Parameters Beats Fewer Tools
255
-
256
- A tool with 30 parameters is harder for an LLM to use correctly than 5 tools with 6 parameters each. The LLM has to filter out irrelevant options with every call.
257
-
258
- ### 4. Flag Names Are Natural Language
259
-
260
- When you name a flag `include_data`, you're not just documenting—you're making it matchable to "with data" or "include the files." Name flags like users talk.
261
-
262
- ### 5. Interoperability Matters
263
-
264
- The MCP spec is flexible, but your tools might be bridged to OpenAI, Anthropic, or other APIs. Stick to the common denominator: alphanumeric plus underscore and hyphen.
265
-
266
- ---
267
-
268
- ## The Mental Model
269
-
270
- ```
271
- ┌─────────────────────────────────────────────────────────────────┐
272
- │ USER │
273
- │ "Clone the sales bot with data and sanitize for demo" │
274
- └─────────────────────────────────────────────────────────────────┘
275
-
276
-
277
- ┌─────────────────────────────────────────────────────────────────┐
278
- │ LLM │
279
- │ Parses intent → Searches tools → Matches parameters │
280
- └─────────────────────────────────────────────────────────────────┘
281
-
282
-
283
- ┌─────────────────────────────────────────────────────────────────┐
284
- │ TOOL SELECTION │
285
- │ persona_clone(from="sales-bot", name="Demo", include_data=true,│
286
- │ sanitize=true) │
287
- └─────────────────────────────────────────────────────────────────┘
288
-
289
-
290
- ┌─────────────────────────────────────────────────────────────────┐
291
- │ MCP SERVER │
292
- │ Executes operation → Returns result │
293
- └─────────────────────────────────────────────────────────────────┘
294
- ```
295
-
296
- The user never sees tool names. The LLM is the interface. **Design your tools for the LLM, and the LLM will serve the user.**
297
-
298
- ---
299
-
300
- ## References
301
-
302
- - [MCP Specification - Tools](https://modelcontextprotocol.io/specification/2025-11-25/server/tools)
303
- - [MCP Specification - Prompts](https://modelcontextprotocol.io/specification/2025-11-25/server/prompts)
304
- - [Awesome MCP Servers](https://mcpservers.org/) - Industry patterns
305
- - [Playwright MCP](https://github.com/microsoft/playwright-mcp) - Reference implementation
306
-
307
- ---
308
-
309
- *Have thoughts on MCP tool design? We'd love to hear what patterns work for you.*
@@ -1,166 +0,0 @@
1
- # Data Architecture & Sourcing Strategy
2
-
3
- > **Principle**: MCP serves all data. Cursor rules are policy/flow only.
4
-
5
- ---
6
-
7
- ## Data Sourcing Hierarchy
8
-
9
- For any data that MCP exposes, follow this resolution order:
10
-
11
- ```
12
- 1. Ema API (live, authoritative) ← PREFERRED
13
- 2. resources/** (repo files) ← FILE FALLBACK
14
- 3. src/sdk/*.ts (embedded constants) ← CODE FALLBACK
15
- 4. NEVER: .cursor/rules/** ← POLICY ONLY, NO DATA
16
- ```
17
-
18
- ---
19
-
20
- ## Current State Audit
21
-
22
- ### ✅ DYNAMIC (API-First)
23
-
24
- | Resource | Source | Fallback | Notes |
25
- |----------|--------|----------|-------|
26
- | `ema://catalog/agents` | `listActions()` API | `AGENT_CATALOG` | Cached 60s, env-aware |
27
- | `ema://catalog/agents-summary` | `listActions()` API | `AGENT_CATALOG` | Markdown format |
28
- | `ema://catalog/templates` | `getPersonaTemplates()` API | Empty (use file-backed) | Cached 60s, env-aware |
29
- | `ema://catalog/templates-summary` | `getPersonaTemplates()` API | Empty | Markdown format |
30
- | `action(...)` tool | `listActions()` API | Embedded docs | Full API integration |
31
-
32
- ### ⚠️ HARDCODED (Embedded in Code)
33
-
34
- | Resource | Source | Can Be Dynamic? | Priority |
35
- |----------|--------|-----------------|----------|
36
- | `ema://catalog/patterns` | `WORKFLOW_PATTERNS` | Yes - could query "template personas" | Medium |
37
- | `ema://catalog/widgets` | `WIDGET_CATALOG` | Yes - could query API | Low |
38
- | `ema://rules/input-sources` | `INPUT_SOURCE_RULES` | Unlikely - validation logic | Low |
39
- | `ema://rules/anti-patterns` | `ANTI_PATTERNS` | Unlikely - validation logic | Low |
40
- | `ema://rules/optimizations` | `OPTIMIZATION_RULES` | Unlikely - validation logic | Low |
41
-
42
- ### 📁 FILE-BACKED (Repo Files - Fallback)
43
-
44
- | Resource | Path | Notes |
45
- |----------|------|-------|
46
- | `ema://templates/voice-ai/*` | `resources/templates/voice-ai/` | Fallback when API unavailable |
47
- | `ema://templates/chat-ai/*` | `resources/templates/chat-ai/` | Fallback when API unavailable |
48
- | `ema://templates/dashboard-ai/*` | `resources/templates/dashboard-ai/` | Fallback when API unavailable |
49
- | `ema://docs/*` | `docs/*.md` | Repo documentation |
50
-
51
- **Note**: For templates, prefer `ema://catalog/templates` (API-first) over file-backed `ema://templates/*`.
52
-
53
- ---
54
-
55
- ## Making More Things Dynamic
56
-
57
- ### ✅ DONE: Templates
58
-
59
- Templates are now API-first via `getPersonaTemplates()`:
60
-
61
- ```typescript
62
- // EmaClient method
63
- async getPersonaTemplates(): Promise<PersonaTemplateDTO[]>
64
-
65
- // MCP Resources (API-first with cache)
66
- ema://catalog/templates // Full template data
67
- ema://catalog/templates-summary // Markdown summary
68
- ```
69
-
70
- ### Medium Priority: Workflow Patterns
71
-
72
- Patterns could be derived from analyzing existing personas:
73
-
74
- ```typescript
75
- // Future: Pattern extraction from existing personas
76
- async function getPatterns() {
77
- // 1. Query personas tagged as "template" or "pattern"
78
- const templatePersonas = await client.getPersonasWithTag("template");
79
- if (templatePersonas.length > 0) {
80
- return extractPatternsFromPersonas(templatePersonas);
81
- }
82
-
83
- // 2. Fallback to embedded patterns
84
- return WORKFLOW_PATTERNS;
85
- }
86
- ```
87
-
88
- ### Low Priority: Validation Rules
89
-
90
- These are internal logic, not external data. Keep embedded unless Ema provides a validation API.
91
-
92
- ---
93
-
94
- ## Where Data Lives
95
-
96
- ```
97
- ema-mcp-toolkit/
98
- ├── src/
99
- │ ├── mcp/
100
- │ │ ├── resources.ts # Resource registry + dynamic fetching
101
- │ │ ├── server.ts # Tool handlers (API calls)
102
- │ │ └── prompts.ts # Prompt definitions (structured guidance)
103
- │ └── sdk/
104
- │ ├── client.ts # EmaClient (API wrapper)
105
- │ ├── knowledge.ts # AGENT_CATALOG, WORKFLOW_PATTERNS, WIDGET_CATALOG
106
- │ └── validation-rules.ts # INPUT_SOURCE_RULES, ANTI_PATTERNS, OPTIMIZATION_RULES
107
- ├── resources/
108
- │ └── templates/ # File-backed templates (canonical location)
109
- │ ├── voice-ai/
110
- │ ├── chat-ai/
111
- │ └── dashboard-ai/
112
- └── .cursor/
113
- └── rules/ # POLICY/FLOW ONLY - NO DATA
114
- ├── base/naming/ # Naming conventions
115
- ├── ema/ # MCP usage guidance
116
- └── platforms/ema/ # Platform-specific flows
117
- ```
118
-
119
- ---
120
-
121
- ## Cursor Rules Policy
122
-
123
- ### ✅ ALLOWED in Cursor Rules
124
-
125
- - **Process flows**: "How to create an AI Employee"
126
- - **Decision trees**: "When to use HITL"
127
- - **Tool usage guidance**: "Use `workflow(mode='analyze')` for..."
128
- - **References to MCP**: "Fetch from `ema://catalog/agents`"
129
- - **Best practices**: "Always extract email recipients via entity_extraction"
130
-
131
- ### ❌ NOT ALLOWED in Cursor Rules
132
-
133
- - **Agent definitions**: Use `ema://catalog/agents`
134
- - **Template content**: Use `ema://templates/*`
135
- - **Validation rules data**: Use `ema://rules/*`
136
- - **Hardcoded patterns**: Use `ema://catalog/patterns`
137
- - **Any data that can change**: Must come from MCP
138
-
139
- ---
140
-
141
- ## Implementation Checklist
142
-
143
- ### Already Done ✅
144
-
145
- - [x] Agent catalog is API-first (`getDynamicAgentCatalog()`)
146
- - [x] Templates moved from `.cursor/` to `resources/`
147
- - [x] `action(...)` tool uses API with docs fallback
148
- - [x] Resources support `?env=` parameter
149
- - [x] **Persona templates are API-first** (`getDynamicPersonaTemplates()`)
150
- - [x] Added `EmaClient.getPersonaTemplates()` method
151
- - [x] Added `ema://catalog/templates` and `ema://catalog/templates-summary` resources
152
-
153
- ### To Do (Future)
154
-
155
- - [ ] Extract workflow patterns from template `workflow_definition` fields
156
- - [ ] Consider caching strategy improvements (longer TTL for stable data)
157
- - [ ] Add health check for API availability
158
-
159
- ---
160
-
161
- ## Related Documentation
162
-
163
- - `docs/mcp-tools-guide.md` - Tool usage
164
- - `docs/naming-conventions.md` - Naming standards
165
- - `.cursor/rules/base/naming/RULE.md` - Naming enforcement
166
- - `.cursor/rules/ema/RULE.md` - MCP source-of-truth policy