@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,936 +0,0 @@
1
- # Comprehensive Codebase Analysis Report
2
-
3
- **Date**: January 23, 2026
4
- **Scope**: Full ema-mcp-toolkit codebase
5
- **Analysts**: Architecture, Security, API, SDK, MCP, Test, Performance, Quality experts
6
-
7
- ---
8
-
9
- ## Executive Summary
10
-
11
- | Dimension | Health Score | Status |
12
- | ------------- | ------------ | --------------------------------------------- |
13
- | Architecture | 7/10 | 🟡 Good structure, circular dependency issue |
14
- | Security | 6/10 | 🟡 Foundation solid, input validation gaps |
15
- | API Contracts | 7/10 | 🟡 Good generation, type assertion overuse |
16
- | SDK Layer | 6/10 | 🟡 Architectural debt, error handling gaps |
17
- | MCP Layer | 7/10 | 🟡 Well-structured, missing graceful shutdown |
18
- | Test Coverage | 5/10 | 🟠 Handler coverage good, SDK gaps |
19
- | Performance | 5/10 | 🟠 N+1 patterns, sync file I/O |
20
- | Code Quality | 6.5/10 | 🟡 Type safety gaps, code duplication |
21
-
22
- **Overall Health**: 6.2/10 🟡
23
-
24
- **Critical Issues**: 8
25
- **High Priority**: 23
26
- **Medium Priority**: 34
27
- **Low Priority**: 18
28
-
29
- ---
30
-
31
- ## Table of Contents
32
-
33
- 1. [Critical Issues (Fix Immediately)](#1-critical-issues-fix-immediately)
34
- 2. [High Priority Issues](#2-high-priority-issues)
35
- 3. [Medium Priority Issues](#3-medium-priority-issues)
36
- 4. [Architecture Analysis](#4-architecture-analysis)
37
- 5. [Security Analysis](#5-security-analysis)
38
- 6. [API Contracts Analysis](#6-api-contracts-analysis)
39
- 7. [SDK Layer Analysis](#7-sdk-layer-analysis)
40
- 8. [MCP Layer Analysis](#8-mcp-layer-analysis)
41
- 9. [Test Coverage Analysis](#9-test-coverage-analysis)
42
- 10. [Performance Analysis](#10-performance-analysis)
43
- 11. [Code Quality Analysis](#11-code-quality-analysis)
44
- 12. [Recommended Action Plan](#12-recommended-action-plan)
45
-
46
- ---
47
-
48
- ## 1. Critical Issues (Fix Immediately)
49
-
50
- ### CRIT-001: Circular Dependency - sync.ts ↔ sdk/sync.ts
51
-
52
- **Location**: `src/sync.ts` ↔ `src/sdk/sync.ts`
53
- **Impact**: Module initialization failures, undefined exports, runtime errors
54
- **Category**: Architecture
55
-
56
- ```typescript
57
- // src/sync.ts imports SDK
58
- import type { AppConfig } from "./sdk/config.js";
59
- import { EmaClient } from "./sdk/client.js";
60
-
61
- // src/sdk/sync.ts imports root sync
62
- import { fingerprintPersona, syncOnce } from "../sync.js";
63
- ```
64
-
65
- **Fix**:
66
-
67
- 1. Move `fingerprintPersona`, `syncOnce`, `transformWorkflowForTarget` into `src/sdk/sync-engine.ts`
68
- 2. Have `src/sdk/sync.ts` re-export from sync-engine
69
- 3. Remove `src/sync.ts` or make it a thin wrapper
70
-
71
- ---
72
-
73
- ### CRIT-002: Synchronous File I/O Blocking Event Loop
74
-
75
- **Location**: `src/sdk/version-storage.ts` (entire file)
76
- **Impact**: Blocks Node.js event loop, poor concurrency, request timeouts
77
- **Category**: Performance
78
-
79
- Found 15+ synchronous calls:
80
-
81
- - `fs.readFileSync()` (lines 118, 188, 232, 305, 352, 396)
82
- - `fs.writeFileSync()` (lines 163, 198, 221, 263, 267, 438)
83
- - `fs.existsSync()` (lines 95, 107, 116, 183, 220, 227, 300, 347, 394)
84
-
85
- **Fix**: Migrate all file operations to `fs/promises`:
86
-
87
- ```typescript
88
- // Before
89
- const content = fs.readFileSync(path, "utf8");
90
-
91
- // After
92
- const content = await fs.readFile(path, "utf8");
93
- ```
94
-
95
- ---
96
-
97
- ### CRIT-003: N+1 Query Pattern in Sync Loop
98
-
99
- **Location**: `src/sync.ts:259-273`
100
- **Impact**: For 100 personas, 100 sequential API calls (~10-30 seconds)
101
- **Category**: Performance
102
-
103
- ```typescript
104
- for (let p of personas) {
105
- if (!p.workflow_def) {
106
- const fullPersona = await masterClient.getPersonaById(p.id); // Sequential!
107
- }
108
- }
109
- ```
110
-
111
- **Fix**: Batch fetch in parallel:
112
-
113
- ```typescript
114
- const missingIds = personas.filter((p) => !p.workflow_def).map((p) => p.id);
115
- const fullPersonas = await Promise.all(
116
- missingIds.map((id) => masterClient.getPersonaById(id)),
117
- );
118
- ```
119
-
120
- ---
121
-
122
- ### CRIT-004: Path Traversal Vulnerability in File Upload
123
-
124
- **Location**: `src/mcp/server.ts:3930-3937`
125
- **Impact**: Potential unauthorized file system access
126
- **Category**: Security
127
-
128
- ```typescript
129
- // File path from user input used directly without normalization
130
- const filename = path.basename(filePath); // basename used but path not validated first
131
- ```
132
-
133
- **Fix**:
134
-
135
- ```typescript
136
- function validateFilePath(userPath: string, baseDir: string): string {
137
- const normalized = path.normalize(path.resolve(baseDir, userPath));
138
- if (!normalized.startsWith(path.resolve(baseDir))) {
139
- throw new Error("Path traversal detected");
140
- }
141
- return normalized;
142
- }
143
- ```
144
-
145
- ---
146
-
147
- ### CRIT-005: Missing Graceful Shutdown Handler
148
-
149
- **Location**: `src/mcp/server.ts:5762`
150
- **Impact**: Resource leaks, incomplete operations, data corruption
151
- **Category**: MCP Layer
152
-
153
- No SIGTERM/SIGINT handlers found for:
154
-
155
- - Client connection cleanup
156
- - Cache persistence
157
- - In-flight request completion
158
-
159
- **Fix**:
160
-
161
- ```typescript
162
- process.on("SIGTERM", async () => {
163
- console.log("Shutting down gracefully...");
164
- await server.close();
165
- clientCache.clear();
166
- process.exit(0);
167
- });
168
-
169
- process.on("SIGINT", async () => {
170
- console.log("Received SIGINT, shutting down...");
171
- await server.close();
172
- process.exit(0);
173
- });
174
- ```
175
-
176
- ---
177
-
178
- ### CRIT-006: Workflow Namespace Validation Missing
179
-
180
- **Location**: `src/sdk/workflow-transformer.ts:552`
181
- **Impact**: Silent deployment failures
182
- **Category**: SDK Layer
183
-
184
- ```typescript
185
- // Preserves namespace but doesn't validate structure
186
- compiled.workflow_def.workflowName = originalDef.workflowName;
187
- // If originalDef.workflowName is malformed, deployment fails silently
188
- ```
189
-
190
- **Fix**: Add namespace structure validation:
191
-
192
- ```typescript
193
- function validateWorkflowNamespace(namespace: unknown): boolean {
194
- if (!namespace || typeof namespace !== "object") return false;
195
- const ns = namespace as { namespaces?: unknown[]; name?: string };
196
- return Array.isArray(ns.namespaces) && typeof ns.name === "string";
197
- }
198
- ```
199
-
200
- ---
201
-
202
- ### CRIT-007: Insufficient Input Validation in Handlers
203
-
204
- **Location**: `src/mcp/handlers-consolidated.ts:1762-2254`
205
- **Impact**: Injection risks, API errors, data corruption
206
- **Category**: Security
207
-
208
- User inputs passed to APIs without strict validation. No schema validation before API calls.
209
-
210
- **Fix**: Add Zod validation at handler entry:
211
-
212
- ```typescript
213
- const PersonaUpdateSchema = z.object({
214
- id: z.string().uuid(),
215
- name: z.string().min(1).max(255).optional(),
216
- workflow_spec: WorkflowSpecSchema.optional(),
217
- });
218
-
219
- // In handler
220
- const validated = PersonaUpdateSchema.parse(input);
221
- ```
222
-
223
- ---
224
-
225
- ### CRIT-008: Error Messages Expose Sensitive Information
226
-
227
- **Location**: `src/mcp/server.ts:5829`, `src/sdk/client.ts:532-613`
228
- **Impact**: Information disclosure, security vulnerability
229
- **Category**: Security
230
-
231
- Error messages include API response bodies that may contain sensitive data:
232
-
233
- ```typescript
234
- // Full error details serialized to JSON in responses
235
- message: `API error (${response.status}): ${response.statusText}`,
236
- body: responseData, // May contain sensitive info
237
- ```
238
-
239
- **Fix**: Sanitize error messages before returning:
240
-
241
- ```typescript
242
- function sanitizeErrorForResponse(error: EmaApiError): string {
243
- // Return generic message, log full details internally
244
- logger.error("API Error", { details: error.body });
245
- return `API error (${error.statusCode}): Operation failed`;
246
- }
247
- ```
248
-
249
- ---
250
-
251
- ## 2. High Priority Issues
252
-
253
- ### HIGH-001: Large Monolithic Files
254
-
255
- | File | Lines | Issue |
256
- | ---------------------------------- | ------ | ------------------------------------ |
257
- | `src/mcp/server.ts` | ~5,914 | Contains handlers, helpers, auto-fix |
258
- | `src/mcp/handlers-consolidated.ts` | ~3,381 | Incomplete modularization |
259
- | `src/sdk/client.ts` | ~2,717 | Legacy + current mixed |
260
-
261
- **Fix**: Complete handler extraction to `src/mcp/handlers/`
262
-
263
- ---
264
-
265
- ### HIGH-002: Manual Type Assertions Bypassing Safety
266
-
267
- **Found**: 19 instances of `as unknown` or `as any` in SDK
268
-
269
- | Location | Issue |
270
- | ------------------------------------------ | ------------------------------- |
271
- | `src/sdk/workflow-fixer.ts:70,199,337,376` | `as unknown[]` casts |
272
- | `src/sdk/intent-architect.ts:490` | `as unknown as IntentSpec` |
273
- | `src/sdk/grpc-client.ts:253` | `as unknown as Parameters<...>` |
274
- | `src/sdk/client.ts:1479` | `as unknown as BodyInit` |
275
-
276
- **Fix**: Replace with proper types or runtime validation:
277
-
278
- ```typescript
279
- // Before
280
- const def = workflowDef as Record<string, unknown>;
281
-
282
- // After
283
- function isWorkflowDef(obj: unknown): obj is WorkflowDef {
284
- return typeof obj === "object" && obj !== null && "actions" in obj;
285
- }
286
- if (!isWorkflowDef(workflowDef)) throw new Error("Invalid workflow");
287
- ```
288
-
289
- ---
290
-
291
- ### HIGH-003: Duplicate EmaApiError Class
292
-
293
- **Locations**:
294
-
295
- - `src/sdk/client.ts:83-93`
296
- - `src/sdk/ema-client.ts:55-65`
297
-
298
- Identical implementations causing maintenance burden.
299
-
300
- **Fix**: Extract to `src/sdk/errors.ts`:
301
-
302
- ```typescript
303
- // src/sdk/errors.ts
304
- export class EmaApiError extends Error {
305
- constructor(
306
- message: string,
307
- public readonly statusCode: number,
308
- public readonly body: unknown,
309
- ) {
310
- super(message);
311
- this.name = "EmaApiError";
312
- }
313
- }
314
- ```
315
-
316
- ---
317
-
318
- ### HIGH-004: Sequential Target Environment Sync
319
-
320
- **Location**: `src/sync.ts:316-334`
321
- **Impact**: For 3 targets, 3x slower than necessary
322
-
323
- **Fix**: Use `Promise.allSettled()`:
324
-
325
- ```typescript
326
- const results = await Promise.allSettled(
327
- targets.map((target) => syncToTarget(persona, target)),
328
- );
329
- ```
330
-
331
- ---
332
-
333
- ### HIGH-005: Double API Call in getPersonaById
334
-
335
- **Location**: `src/sdk/client.ts:369-406`
336
- **Impact**: 2x API calls per persona fetch
337
-
338
- Always tries primary endpoint then fallback, even if primary succeeds.
339
-
340
- **Fix**: Only call fallback if primary fails or returns incomplete data.
341
-
342
- ---
343
-
344
- ### HIGH-006: Excessive Deep Cloning
345
-
346
- **Locations**:
347
-
348
- - `src/sdk/client.ts:494` - workflow namespace fix
349
- - `src/mcp/handlers-consolidated.ts:1137` - workflow cloning
350
- - `src/sync.ts:149` - workflow transformation
351
-
352
- Large workflows (50-500KB) cloned via `JSON.parse(JSON.stringify())`.
353
-
354
- **Fix**: Use `structuredClone()`:
355
-
356
- ```typescript
357
- // Before
358
- const cloned = JSON.parse(JSON.stringify(workflow));
359
-
360
- // After
361
- const cloned = structuredClone(workflow);
362
- ```
363
-
364
- ---
365
-
366
- ### HIGH-007: Unknown Action Type Falls Back to call_llm
367
-
368
- **Location**: `src/sdk/workflow-transformer.ts:392-415`
369
-
370
- ```typescript
371
- function mapToActionType(rawName: string): ActionType {
372
- const mapping: Record<string, ActionType> = { ... };
373
- return mapping[rawName] || ("call_llm" as ActionType); // Silent fallback!
374
- }
375
- ```
376
-
377
- **Impact**: Unknown action types silently converted, causing runtime errors.
378
-
379
- **Fix**: Return `'unknown'` type or throw error for unmapped actions.
380
-
381
- ---
382
-
383
- ### HIGH-008: Core SDK Files Missing Unit Tests
384
-
385
- | File | Lines | Status |
386
- | --------------------------- | ------ | ---------------- |
387
- | `src/sdk/client.ts` | ~2,400 | No unit tests |
388
- | `src/sdk/ema-client.ts` | ~405 | No unit tests |
389
- | `src/sdk/grpc-client.ts` | ~300 | Integration only |
390
- | `src/sdk/client-adapter.ts` | ~200 | No tests |
391
- | `src/sdk/knowledge.ts` | ~400 | No tests |
392
- | `src/sdk/sync.ts` | ~250 | Integration only |
393
-
394
- **Impact**: Core API client functionality untested.
395
-
396
- **Fix**: Add comprehensive unit tests with mocked API responses.
397
-
398
- ---
399
-
400
- ### HIGH-009: Field Name Mismatch - workflow_def vs workflow
401
-
402
- **Locations**: `src/sdk/client.ts`, `src/sdk/ema-client.ts`
403
-
404
- GET returns `workflow_def`, UPDATE expects `workflow`. Handled in code but not typed consistently.
405
-
406
- **Fix**: Standardize on one name or add explicit type aliases:
407
-
408
- ```typescript
409
- type WorkflowField = "workflow_def" | "workflow";
410
- interface PersonaResponse {
411
- workflow_def?: WorkflowDef; // GET response
412
- }
413
- interface PersonaUpdateRequest {
414
- workflow?: WorkflowDef; // UPDATE request
415
- }
416
- ```
417
-
418
- ---
419
-
420
- ### HIGH-010: Contract Validation Script Too Shallow
421
-
422
- **Location**: `scripts/check-api-contracts.ts:66-75`
423
-
424
- Only compares schema names and field counts, not:
425
-
426
- - Field types
427
- - Enum value changes
428
- - Required field changes
429
-
430
- **Fix**: Add deep JSON comparison with type awareness.
431
-
432
- ---
433
-
434
- ## 3. Medium Priority Issues
435
-
436
- ### Error Handling
437
-
438
- | ID | Issue | Location |
439
- | ------- | ---------------------------- | ---------------------------------- |
440
- | MED-001 | Inconsistent error patterns | Multiple files |
441
- | MED-002 | Swallowed errors in handlers | `handlers/persona/create.ts:94-96` |
442
- | MED-003 | Missing error context | `client.ts:323-330` |
443
- | MED-004 | Error propagation gaps | `workflow-validator.ts:150-151` |
444
-
445
- ### Performance
446
-
447
- | ID | Issue | Location |
448
- | ------- | ------------------------------ | ------------------- |
449
- | MED-005 | Pre-fetch in updateAiEmployee | `client.ts:476-550` |
450
- | MED-006 | No persona caching | Multiple handlers |
451
- | MED-007 | Prepared statements not cached | `state.ts` |
452
- | MED-008 | File size limits missing | `server.ts:4230` |
453
-
454
- ### Type Safety
455
-
456
- | ID | Issue | Location |
457
- | ------- | --------------------- | ------------------------- |
458
- | MED-009 | Excessive `any` usage | 102 instances in 32 files |
459
- | MED-010 | Type assertions | 2000+ instances |
460
- | MED-011 | Non-null assertions | 1415 instances |
461
- | MED-012 | Missing return types | 7 functions |
462
-
463
- ### Code Quality
464
-
465
- | ID | Issue | Location |
466
- | ------- | ----------------------------------- | ---------------------------------- |
467
- | MED-013 | Duplicate `checkDeprecatedParams()` | 3 files |
468
- | MED-014 | Duplicate `SanitizationSession` | `dashboard-clone.ts` |
469
- | MED-015 | Deprecated params without warnings | `handlers/persona/create.ts:67-69` |
470
- | MED-016 | 354 TODO/FIXME comments | Throughout codebase |
471
-
472
- ### Security
473
-
474
- | ID | Issue | Location |
475
- | ------- | -------------------------------- | ----------------------- |
476
- | MED-017 | Debug logging may expose tokens | `client.ts:105,512-535` |
477
- | MED-018 | Secret detection false negatives | `resources.ts:123-124` |
478
- | MED-019 | HTTPS enforcement not explicit | `ema-client.ts:72` |
479
-
480
- ### Testing
481
-
482
- | ID | Issue | Location |
483
- | ------- | ---------------------------------------- | ------------------ |
484
- | MED-020 | No coverage thresholds | `vitest.config.ts` |
485
- | MED-021 | Integration tests excluded from coverage | Config |
486
- | MED-022 | 15+ SDK files with no tests | Multiple |
487
-
488
- ---
489
-
490
- ## 4. Architecture Analysis
491
-
492
- ### Layer Separation (Score: 7/10)
493
-
494
- **Strengths**:
495
-
496
- - Clear SDK/MCP separation
497
- - MCP correctly imports from SDK
498
- - Centralized types prevent circular dependencies
499
- - Good handler dispatch pattern
500
-
501
- **Weaknesses**:
502
-
503
- - `src/sync.ts` violates SDK ownership (should be in SDK)
504
- - Circular dependency between `sync.ts` ↔ `sdk/sync.ts`
505
- - Incomplete handler modularization
506
-
507
- ### File Structure
508
-
509
- ```
510
- src/
511
- ├── index.ts # HTTP sync server (Fastify)
512
- ├── sync.ts # ⚠️ Should be in sdk/
513
- ├── ui.ts # Dashboard UI
514
- ├── cli/ # CLI tool
515
- ├── mcp/ # MCP server layer
516
- │ ├── server.ts # ⚠️ 5,914 lines - too large
517
- │ ├── handlers-consolidated.ts # ⚠️ 3,381 lines - incomplete modularization
518
- │ ├── handlers/ # ✓ Modular handlers (in progress)
519
- │ ├── tools-*.ts # Tool definitions
520
- │ ├── prompts.ts # MCP prompts
521
- │ └── resources.ts # MCP resources
522
- └── sdk/ # Core SDK layer
523
- ├── client.ts # ⚠️ Deprecated, still maintained
524
- ├── ema-client.ts # ✓ New primary client
525
- ├── workflow-*.ts # Workflow transformation
526
- ├── state.ts # SQLite state management
527
- └── generated/ # Proto/OpenAPI generated
528
- ```
529
-
530
- ### Module Dependencies
531
-
532
- ```mermaid
533
- graph TD
534
- MCP[src/mcp/*] --> SDK[src/sdk/*]
535
- CLI[src/cli/*] --> SDK
536
- CLI --> SYNC[src/sync.ts]
537
- MCP --> SYNC
538
- SYNC --> SDK
539
- SDK_SYNC[src/sdk/sync.ts] --> SYNC
540
- SDK_SYNC --> SDK
541
-
542
- style SYNC fill:#ff6b6b,stroke:#333
543
- style SDK_SYNC fill:#ff6b6b,stroke:#333
544
- ```
545
-
546
- **Issue**: Circular dependency `SYNC ↔ SDK_SYNC`
547
-
548
- ---
549
-
550
- ## 5. Security Analysis
551
-
552
- ### Authentication (Score: 7/10)
553
-
554
- **Strengths**:
555
-
556
- - Tokens read from environment variables
557
- - No hardcoded secrets found
558
- - Config validation via Zod schemas
559
- - Token refresh with caching
560
-
561
- **Weaknesses**:
562
-
563
- - Token may be exposed in error messages
564
- - No explicit token rotation
565
-
566
- ### Input Validation (Score: 5/10)
567
-
568
- **Strengths**:
569
-
570
- - Path traversal protection in resources handler
571
- - Some sanitization exists for persona data
572
-
573
- **Weaknesses**:
574
-
575
- - Insufficient validation in most handlers
576
- - File paths not consistently validated
577
- - No rate limiting
578
-
579
- ### Data Exposure (Score: 6/10)
580
-
581
- **Strengths**:
582
-
583
- - Secret detection patterns in resources
584
- - Blocked files list for sensitive files
585
-
586
- **Weaknesses**:
587
-
588
- - Error messages may contain sensitive data
589
- - Debug logging may expose tokens
590
- - Full API responses in errors
591
-
592
- ### Recommendations
593
-
594
- 1. **Immediate**: Add input validation to all handlers
595
- 2. **Immediate**: Sanitize error messages
596
- 3. **Short-term**: Add rate limiting
597
- 4. **Short-term**: Add request size limits
598
- 5. **Long-term**: Security audit of all file operations
599
-
600
- ---
601
-
602
- ## 6. API Contracts Analysis
603
-
604
- ### Proto Files (Score: 8/10)
605
-
606
- **Strengths**:
607
-
608
- - Complete proto-generated types
609
- - Proper deprecation markers (345+ instances)
610
- - Uses `@bufbuild/protobuf` codegen v2
611
-
612
- **Weaknesses**:
613
-
614
- - 30+ TODO comments indicating future changes
615
- - Some deprecated fields still in use
616
-
617
- ### OpenAPI Spec (Score: 8/10)
618
-
619
- **Strengths**:
620
-
621
- - OpenAPI 3.1.0 spec present and cached
622
- - 8000+ lines covering all REST endpoints
623
- - Types include proper nullable handling
624
-
625
- **Weaknesses**:
626
-
627
- - Contract validation script too shallow
628
- - Manual type assertions bypass safety
629
-
630
- ### Field Naming Issues
631
-
632
- | API Context | Field Name | Issue |
633
- | --------------- | ------------------------------- | --------------------------- |
634
- | GET Persona | `workflow_def` | Different from UPDATE |
635
- | UPDATE Persona | `workflow` | Different from GET |
636
- | Widget Format | `{ name, type, [name]: {...} }` | Complex structure not typed |
637
- | Results Mapping | `"<actionName>.<outputName>"` | String keys, not object |
638
-
639
- ---
640
-
641
- ## 7. SDK Layer Analysis
642
-
643
- ### Client Architecture
644
-
645
- ```
646
- EmaClientV2 (ema-client.ts) ← Primary, uses generated OpenAPI client
647
-
648
- EmaClientAdapter (client-adapter.ts)
649
-
650
- EmaClient (client.ts) ← Deprecated, legacy compatibility
651
-
652
- GrpcClient (grpc-client.ts) ← gRPC for Connect-ES
653
- ```
654
-
655
- **Issue**: Both `EmaClient` and `EmaClientV2` actively maintained despite deprecation.
656
-
657
- ### Workflow System
658
-
659
- | File | Lines | Test Coverage | Issues |
660
- | ------------------------- | ----- | ------------- | ---------------------------------- |
661
- | `workflow-transformer.ts` | ~600 | ✓ Good | Silent fallback for unknown types |
662
- | `workflow-generator.ts` | ~400 | ✓ Good | Enum validation incomplete |
663
- | `workflow-validator.ts` | ~200 | ✗ None | Untested |
664
- | `workflow-fixer.ts` | ~500 | ✓ Good | Multiple `as unknown` casts |
665
- | `workflow-optimizer.ts` | ~300 | ✗ None | Performance issue for large graphs |
666
- | `workflow-merge.ts` | ~350 | ✓ Good | Force replace breaks downstream |
667
-
668
- ### State Management
669
-
670
- **File**: `src/sdk/state.ts`
671
-
672
- **Strengths**:
673
-
674
- - SQLite with WAL mode
675
- - ON CONFLICT for upserts
676
-
677
- **Weaknesses**:
678
-
679
- - No prepared statement caching
680
- - Database connection never closed
681
- - No transaction batching
682
- - Missing error handling
683
-
684
- ---
685
-
686
- ## 8. MCP Layer Analysis
687
-
688
- ### Handler Structure (Score: 7/10)
689
-
690
- **Modularized Handlers** (in `src/mcp/handlers/`):
691
-
692
- - ✅ persona: get, list, create, update, delete, compare
693
- - ✅ data: list, upload, delete, sanitize, replicate
694
- - ✅ action, env, template, reference, sync
695
-
696
- **Remaining in `handlers-consolidated.ts`**:
697
-
698
- - ❌ version\_\* modes (330 lines)
699
- - ❌ handleWorkflow (962 lines)
700
-
701
- ### Server Setup Issues
702
-
703
- 1. **No graceful shutdown** - SIGTERM/SIGINT not handled
704
- 2. **No error recovery** - No retry/backoff for API failures
705
- 3. **Unbounded caches** - clientCache, agentCatalogCache never cleared
706
-
707
- ### Response Consistency
708
-
709
- | Handler | Shape | Issue |
710
- | ---------------- | ---------------------------- | ------------ |
711
- | `handleGet` | Flat object | Inconsistent |
712
- | `handleCreate` | Nested with `actions_result` | Inconsistent |
713
- | `handleWorkflow` | Varies by mode | Inconsistent |
714
-
715
- **Fix**: Standardize on consistent response shape with `_tip`, `_next_step`, `_metadata`.
716
-
717
- ---
718
-
719
- ## 9. Test Coverage Analysis
720
-
721
- ### Coverage Summary
722
-
723
- | Category | Files | Tested | Coverage |
724
- | ----------- | ----- | ------ | -------- |
725
- | Handlers | 10 | 8 | 80% |
726
- | SDK Core | 15 | 6 | 40% |
727
- | Workflow | 8 | 5 | 63% |
728
- | Integration | 7 | 7 | 100% |
729
-
730
- **Total Test Cases**: ~1,423
731
-
732
- ### Critical Gaps
733
-
734
- | File | Lines | Impact |
735
- | ------------------------------- | ----- | -------------------- |
736
- | `src/sdk/client.ts` | 2,400 | Core API client |
737
- | `src/sdk/ema-client.ts` | 405 | New primary client |
738
- | `src/sdk/grpc-client.ts` | 300 | gRPC operations |
739
- | `src/sdk/client-adapter.ts` | 200 | V1/V2 bridging |
740
- | `src/sdk/knowledge.ts` | 400 | Knowledge management |
741
- | `src/sdk/workflow-validator.ts` | 200 | Validation logic |
742
-
743
- ### Missing Test Types
744
-
745
- 1. **Error handling tests** - Network failures, timeouts
746
- 2. **Edge case tests** - Empty inputs, malformed data
747
- 3. **Concurrent operation tests** - Race conditions
748
- 4. **Security tests** - Injection, traversal
749
-
750
- ### Configuration Gap
751
-
752
- No coverage thresholds in `vitest.config.ts`:
753
-
754
- ```typescript
755
- // Recommended addition
756
- coverage: {
757
- thresholds: {
758
- lines: 80,
759
- functions: 80,
760
- branches: 75,
761
- statements: 80
762
- }
763
- }
764
- ```
765
-
766
- ---
767
-
768
- ## 10. Performance Analysis
769
-
770
- ### API Call Patterns
771
-
772
- | Issue | Impact | Location |
773
- | ---------------------- | ----------------------- | ------------------- |
774
- | N+1 in sync loop | 10-30s for 100 personas | `sync.ts:259-273` |
775
- | Sequential target sync | 3x slower | `sync.ts:316-334` |
776
- | Double fetch in update | 2x API calls | `client.ts:476-550` |
777
- | Pre-fetch always | Extra call per update | `client.ts:369-406` |
778
-
779
- ### Memory Issues
780
-
781
- | Issue | Impact | Location |
782
- | -------------------- | -------------------------------------- | --------------------------- |
783
- | Deep clone with JSON | 3-5x memory for large workflows | Multiple |
784
- | Unbounded caches | Memory leak in long-running | `resources.ts`, `server.ts` |
785
- | Version storage | 50-100MB per persona for 1000 versions | `version-storage.ts` |
786
-
787
- ### File I/O Issues
788
-
789
- **All file operations in `version-storage.ts` are synchronous**:
790
-
791
- - 6 `readFileSync` calls
792
- - 6 `writeFileSync` calls
793
- - 9 `existsSync` calls
794
-
795
- **Impact**: Blocks event loop, poor concurrency.
796
-
797
- ### SQLite Issues
798
-
799
- | Issue | Impact | Fix |
800
- | --------------------------- | ---------------------------- | ---------------- |
801
- | No prepared statement cache | Compilation overhead | Cache statements |
802
- | No transaction batching | Extra I/O | Use transactions |
803
- | Single connection | Multiple connections created | Use singleton |
804
-
805
- ---
806
-
807
- ## 11. Code Quality Analysis
808
-
809
- ### Type Safety Metrics
810
-
811
- | Metric | Count | Severity |
812
- | ------------------------- | ----- | -------- |
813
- | `any` types | 102 | HIGH |
814
- | Type assertions (`as`) | 2000+ | HIGH |
815
- | Non-null assertions (`!`) | 1415 | MEDIUM |
816
- | Missing return types | 7 | MEDIUM |
817
-
818
- ### Code Duplication
819
-
820
- | Duplicate | Locations | Fix |
821
- | ------------------------- | -------------------------- | -------------------- |
822
- | `checkDeprecatedParams()` | 3 files | Extract to utils |
823
- | `SanitizationSession` | `dashboard-clone.ts` + SDK | Use SDK version |
824
- | `EmaApiError` | 2 files | Extract to errors.ts |
825
-
826
- ### Documentation
827
-
828
- - **JSDoc Coverage**: 23,151 comments across 172 files
829
- - **TODO/FIXME**: 354 instances
830
- - **Commented code**: 100+ lines in `server.ts`
831
-
832
- ### Configuration Quality
833
-
834
- ```json
835
- // tsconfig.json - Good but could be stricter
836
- {
837
- "strict": true // ✓
838
- // Missing recommended flags:
839
- // "noUnusedLocals": true,
840
- // "noUnusedParameters": true
841
- }
842
- ```
843
-
844
- ---
845
-
846
- ## 12. Recommended Action Plan
847
-
848
- ### Phase 1: Critical (Week 1-2)
849
-
850
- | Priority | Issue | Effort | Files |
851
- | -------- | --------------------------- | ------ | -------------------------- |
852
- | P0 | Fix circular dependency | 2h | `sync.ts`, `sdk/sync.ts` |
853
- | P0 | Add input validation | 4h | `handlers-consolidated.ts` |
854
- | P0 | Fix path traversal | 2h | `server.ts` |
855
- | P0 | Add graceful shutdown | 2h | `server.ts` |
856
- | P0 | Sanitize error messages | 3h | `client.ts`, `server.ts` |
857
- | P0 | Migrate to async file I/O | 4h | `version-storage.ts` |
858
- | P0 | Fix N+1 query pattern | 2h | `sync.ts` |
859
- | P0 | Validate workflow namespace | 1h | `workflow-transformer.ts` |
860
-
861
- **Estimated Total**: 20 hours
862
-
863
- ### Phase 2: High Priority (Week 3-4)
864
-
865
- | Priority | Issue | Effort | Files |
866
- | -------- | ------------------------------- | ------ | ---------------------------- |
867
- | P1 | Complete handler modularization | 8h | `handlers-consolidated.ts` |
868
- | P1 | Extract shared error class | 1h | Create `sdk/errors.ts` |
869
- | P1 | Add SDK unit tests | 16h | `client.ts`, `ema-client.ts` |
870
- | P1 | Replace type assertions | 8h | `workflow-fixer.ts`, etc. |
871
- | P1 | Add coverage thresholds | 1h | `vitest.config.ts` |
872
- | P1 | Fix double API call | 2h | `client.ts` |
873
- | P1 | Use structuredClone | 2h | Multiple |
874
-
875
- **Estimated Total**: 38 hours
876
-
877
- ### Phase 3: Medium Priority (Week 5-8)
878
-
879
- | Priority | Issue | Effort | Files |
880
- | -------- | ---------------------------- | ------ | ------------------------ |
881
- | P2 | Consolidate duplicate code | 4h | Multiple |
882
- | P2 | Standardize error handling | 6h | All handlers |
883
- | P2 | Add prepared statement cache | 3h | `state.ts` |
884
- | P2 | Improve contract validation | 4h | `check-api-contracts.ts` |
885
- | P2 | Add deprecation warnings | 2h | Handlers |
886
- | P2 | Standardize response format | 4h | All handlers |
887
-
888
- **Estimated Total**: 23 hours
889
-
890
- ### Phase 4: Technical Debt (Ongoing)
891
-
892
- - Remove 100+ lines of commented code
893
- - Address 354 TODO/FIXME comments
894
- - Reduce `any` usage from 102 to <20
895
- - Add JSDoc to internal functions
896
- - Enable additional TypeScript strict flags
897
-
898
- ---
899
-
900
- ## Appendix A: Files Requiring Immediate Attention
901
-
902
- | File | Issues | Priority |
903
- | ---------------------------------- | -------------------------------- | -------- |
904
- | `src/sync.ts` | Circular dependency, N+1 queries | P0 |
905
- | `src/mcp/server.ts` | Size, shutdown, path traversal | P0 |
906
- | `src/sdk/version-storage.ts` | Sync file I/O | P0 |
907
- | `src/mcp/handlers-consolidated.ts` | Size, validation | P0-P1 |
908
- | `src/sdk/client.ts` | Duplicate class, double fetch | P1 |
909
- | `src/sdk/workflow-transformer.ts` | Namespace validation | P0 |
910
- | `src/sdk/workflow-fixer.ts` | Type assertions | P1 |
911
-
912
- ## Appendix B: Metrics Summary
913
-
914
- ```
915
- ┌─────────────────────────────────────────────────────────────┐
916
- │ Codebase Metrics │
917
- ├─────────────────────────────────────────────────────────────┤
918
- │ Total TypeScript Files: 172 │
919
- │ Total Lines of Code: ~45,000 │
920
- │ Test Files: 59 │
921
- │ Test Cases: ~1,423 │
922
- │ Dependencies: 10 production, 11 dev │
923
- ├─────────────────────────────────────────────────────────────┤
924
- │ Critical Issues: 8 │
925
- │ High Priority: 23 │
926
- │ Medium Priority: 34 │
927
- │ Low Priority: 18 │
928
- ├─────────────────────────────────────────────────────────────┤
929
- │ Overall Health Score: 6.2/10 │
930
- └─────────────────────────────────────────────────────────────┘
931
- ```
932
-
933
- ---
934
-
935
- _Report generated by comprehensive static analysis_
936
- _Last updated: January 23, 2026_