coaiajs 0.1.0

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.
Files changed (162) hide show
  1. package/CLAUDE.md +56 -0
  2. package/KINSHIP.md +63 -0
  3. package/README.md +148 -0
  4. package/articles/academic/creative-orientation-vs-problem-solving.md +177 -0
  5. package/articles/academic/jsonl-knowledge-graphs-agent-memory.md +142 -0
  6. package/articles/academic/langfuse-observability-llm-pipelines.md +144 -0
  7. package/articles/academic/medicine-wheel-software-architecture.md +163 -0
  8. package/articles/academic/mmot-autonomous-agents.md +156 -0
  9. package/articles/academic/model-context-protocol-interagent.md +161 -0
  10. package/articles/academic/pde-prompt-decomposition.md +186 -0
  11. package/articles/academic/structural-tension-in-ai-agents.md +134 -0
  12. package/articles/reviews/mcp-protocol-design-review.md +170 -0
  13. package/articles/reviews/observability-ai-systems-review.md +176 -0
  14. package/articles/reviews/prompt-engineering-decomposition-review.md +184 -0
  15. package/articles/surveys/agent-orchestration-survey.md +186 -0
  16. package/articles/surveys/knowledge-graph-storage-survey.md +204 -0
  17. package/articles/surveys/structural-tension-methodology-survey.md +154 -0
  18. package/articles/technical/aws-sdk-v3-polly.md +270 -0
  19. package/articles/technical/commander-cli-framework.md +262 -0
  20. package/articles/technical/dotenv-config-patterns.md +360 -0
  21. package/articles/technical/ioredis-vs-redis.md +142 -0
  22. package/articles/technical/langfuse-js-sdk-vs-rest.md +191 -0
  23. package/articles/technical/mcp-sdk-typescript.md +291 -0
  24. package/articles/technical/octokit-github-api.md +293 -0
  25. package/articles/technical/openai-sdk-modern.md +231 -0
  26. package/articles/technical/yaml-parsing-node.md +266 -0
  27. package/articles/technical/zod-runtime-validation.md +212 -0
  28. package/dist/mcp/config.d.ts +14 -0
  29. package/dist/mcp/config.js +185 -0
  30. package/dist/mcp/server.d.ts +3 -0
  31. package/dist/mcp/server.js +324 -0
  32. package/dist/mcp/tools/coaiapy-tools.d.ts +8 -0
  33. package/dist/mcp/tools/coaiapy-tools.js +326 -0
  34. package/dist/mcp/tools/index.d.ts +3 -0
  35. package/dist/mcp/tools/index.js +3 -0
  36. package/dist/src/audio.d.ts +12 -0
  37. package/dist/src/audio.js +57 -0
  38. package/dist/src/cli-helpers.d.ts +9 -0
  39. package/dist/src/cli-helpers.js +78 -0
  40. package/dist/src/cli.d.ts +3 -0
  41. package/dist/src/cli.js +1086 -0
  42. package/dist/src/config.d.ts +15 -0
  43. package/dist/src/config.js +145 -0
  44. package/dist/src/environment.d.ts +44 -0
  45. package/dist/src/environment.js +146 -0
  46. package/dist/src/github.d.ts +47 -0
  47. package/dist/src/github.js +79 -0
  48. package/dist/src/langfuse/client.d.ts +30 -0
  49. package/dist/src/langfuse/client.js +75 -0
  50. package/dist/src/langfuse/comments.d.ts +16 -0
  51. package/dist/src/langfuse/comments.js +36 -0
  52. package/dist/src/langfuse/datasets.d.ts +19 -0
  53. package/dist/src/langfuse/datasets.js +140 -0
  54. package/dist/src/langfuse/index.d.ts +13 -0
  55. package/dist/src/langfuse/index.js +10 -0
  56. package/dist/src/langfuse/media.d.ts +11 -0
  57. package/dist/src/langfuse/media.js +167 -0
  58. package/dist/src/langfuse/observations.d.ts +18 -0
  59. package/dist/src/langfuse/observations.js +113 -0
  60. package/dist/src/langfuse/prompts.d.ts +14 -0
  61. package/dist/src/langfuse/prompts.js +127 -0
  62. package/dist/src/langfuse/scores.d.ts +54 -0
  63. package/dist/src/langfuse/scores.js +366 -0
  64. package/dist/src/langfuse/traces.d.ts +29 -0
  65. package/dist/src/langfuse/traces.js +225 -0
  66. package/dist/src/llm.d.ts +23 -0
  67. package/dist/src/llm.js +76 -0
  68. package/dist/src/narrative/graph-manager.d.ts +106 -0
  69. package/dist/src/narrative/graph-manager.js +915 -0
  70. package/dist/src/narrative/index.d.ts +9 -0
  71. package/dist/src/narrative/index.js +7 -0
  72. package/dist/src/narrative/markdown-export.d.ts +21 -0
  73. package/dist/src/narrative/markdown-export.js +383 -0
  74. package/dist/src/narrative/tool-definitions.d.ts +21 -0
  75. package/dist/src/narrative/tool-definitions.js +588 -0
  76. package/dist/src/narrative/tool-handlers.d.ts +11 -0
  77. package/dist/src/narrative/tool-handlers.js +462 -0
  78. package/dist/src/narrative/types.d.ts +2 -0
  79. package/dist/src/narrative/types.js +2 -0
  80. package/dist/src/narrative/validation.d.ts +29 -0
  81. package/dist/src/narrative/validation.js +144 -0
  82. package/dist/src/pde/index.d.ts +8 -0
  83. package/dist/src/pde/index.js +8 -0
  84. package/dist/src/pde/mcp-handlers.d.ts +7 -0
  85. package/dist/src/pde/mcp-handlers.js +300 -0
  86. package/dist/src/pde/mcp-tools.d.ts +15 -0
  87. package/dist/src/pde/mcp-tools.js +191 -0
  88. package/dist/src/pde/session-manager.d.ts +32 -0
  89. package/dist/src/pde/session-manager.js +205 -0
  90. package/dist/src/pde/stc-mapper.d.ts +26 -0
  91. package/dist/src/pde/stc-mapper.js +234 -0
  92. package/dist/src/pipeline/index.d.ts +2 -0
  93. package/dist/src/pipeline/index.js +3 -0
  94. package/dist/src/pipeline/template-engine.d.ts +20 -0
  95. package/dist/src/pipeline/template-engine.js +361 -0
  96. package/dist/src/planning/index.d.ts +7 -0
  97. package/dist/src/planning/index.js +7 -0
  98. package/dist/src/planning/mcp-handlers.d.ts +7 -0
  99. package/dist/src/planning/mcp-handlers.js +310 -0
  100. package/dist/src/planning/mcp-tools.d.ts +15 -0
  101. package/dist/src/planning/mcp-tools.js +145 -0
  102. package/dist/src/planning/plan-parser.d.ts +35 -0
  103. package/dist/src/planning/plan-parser.js +506 -0
  104. package/dist/src/redis.d.ts +21 -0
  105. package/dist/src/redis.js +78 -0
  106. package/dist/src/types.d.ts +244 -0
  107. package/dist/src/types.js +8 -0
  108. package/mcp/config.ts +196 -0
  109. package/mcp/server.ts +402 -0
  110. package/mcp/tools/coaiapy-tools.ts +364 -0
  111. package/mcp/tools/index.ts +4 -0
  112. package/package.json +52 -0
  113. package/rispecs/00-coaiajs-platform.spec.md +102 -0
  114. package/rispecs/01-core-config.spec.md +89 -0
  115. package/rispecs/02-redis-module.spec.md +62 -0
  116. package/rispecs/03-langfuse-module.spec.md +101 -0
  117. package/rispecs/04-narrative-engine.spec.md +185 -0
  118. package/rispecs/05-pde-engine.spec.md +112 -0
  119. package/rispecs/06-planning-engine.spec.md +128 -0
  120. package/rispecs/07-pipeline-templates.spec.md +97 -0
  121. package/rispecs/08-cli-interface.spec.md +134 -0
  122. package/rispecs/09-mcp-server.spec.md +140 -0
  123. package/rispecs/10-audio-module.spec.md +63 -0
  124. package/rispecs/KINSHIP.md +56 -0
  125. package/rispecs/README.md +100 -0
  126. package/src/audio.ts +76 -0
  127. package/src/cli-helpers.ts +86 -0
  128. package/src/cli.ts +1223 -0
  129. package/src/config.ts +172 -0
  130. package/src/environment.ts +171 -0
  131. package/src/github.ts +143 -0
  132. package/src/langfuse/client.ts +105 -0
  133. package/src/langfuse/comments.ts +52 -0
  134. package/src/langfuse/datasets.ts +178 -0
  135. package/src/langfuse/index.ts +33 -0
  136. package/src/langfuse/media.ts +193 -0
  137. package/src/langfuse/observations.ts +131 -0
  138. package/src/langfuse/prompts.ts +157 -0
  139. package/src/langfuse/scores.ts +456 -0
  140. package/src/langfuse/traces.ts +276 -0
  141. package/src/llm.ts +106 -0
  142. package/src/narrative/graph-manager.ts +1358 -0
  143. package/src/narrative/index.ts +32 -0
  144. package/src/narrative/markdown-export.ts +535 -0
  145. package/src/narrative/tool-definitions.ts +635 -0
  146. package/src/narrative/tool-handlers.ts +528 -0
  147. package/src/narrative/types.ts +9 -0
  148. package/src/narrative/validation.ts +179 -0
  149. package/src/pde/index.ts +8 -0
  150. package/src/pde/mcp-handlers.ts +359 -0
  151. package/src/pde/mcp-tools.ts +201 -0
  152. package/src/pde/session-manager.ts +248 -0
  153. package/src/pde/stc-mapper.ts +298 -0
  154. package/src/pipeline/index.ts +7 -0
  155. package/src/pipeline/template-engine.ts +398 -0
  156. package/src/planning/index.ts +13 -0
  157. package/src/planning/mcp-handlers.ts +369 -0
  158. package/src/planning/mcp-tools.ts +155 -0
  159. package/src/planning/plan-parser.ts +587 -0
  160. package/src/redis.ts +97 -0
  161. package/src/types.ts +280 -0
  162. package/tsconfig.json +26 -0
package/mcp/server.ts ADDED
@@ -0,0 +1,402 @@
1
+ #!/usr/bin/env node
2
+ // coaiajs/mcp/server.ts — Unified MCP server
3
+ // Consolidates all tools: coaiapy-mcp (20) + narrative (28) + PDE (10) + planning (6) = 64+ tools
4
+
5
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
6
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
7
+ import {
8
+ CallToolRequestSchema,
9
+ ListToolsRequestSchema,
10
+ type CallToolResult,
11
+ } from '@modelcontextprotocol/sdk/types.js';
12
+
13
+ import { FeatureConfig } from './config.js';
14
+ import { getCoaiapyToolDefinitions } from './tools/index.js';
15
+ import type { ToolDefinition } from './tools/index.js';
16
+
17
+ // Langfuse imports
18
+ import {
19
+ addTrace, patchTraceOutput, listTraces, getTrace, formatTracesTable, formatTraceTree,
20
+ } from '../src/langfuse/traces.js';
21
+ import { addObservation, getObservation, formatObservationDisplay } from '../src/langfuse/observations.js';
22
+ import { listPrompts, getPrompt, formatPromptsTable, formatPromptDisplay } from '../src/langfuse/prompts.js';
23
+ import { listDatasets, getDataset, formatDatasetsTable } from '../src/langfuse/datasets.js';
24
+ import {
25
+ listScoreConfigs, getScoreConfig, applyScoreConfig,
26
+ formatScoreConfigsTable,
27
+ } from '../src/langfuse/scores.js';
28
+ import { listComments, getComment, createComment } from '../src/langfuse/comments.js';
29
+ import { uploadAndAttachMedia, getMedia, formatMediaDisplay } from '../src/langfuse/media.js';
30
+
31
+ // ─── Server Info ────────────────────────────────────────────────────
32
+
33
+ const SERVER_NAME = 'coaiajs-mcp';
34
+ const SERVER_VERSION = '0.1.0';
35
+
36
+ // ─── Parse CLI args ─────────────────────────────────────────────────
37
+
38
+ function parseArgs(): { memoryPath?: string; plansDir?: string; featureLevel?: string } {
39
+ const args = process.argv.slice(2);
40
+ const result: Record<string, string> = {};
41
+ for (let i = 0; i < args.length; i++) {
42
+ if (args[i] === '--memory-path' && args[i + 1]) {
43
+ result.memoryPath = args[++i];
44
+ } else if (args[i] === '--plans-dir' && args[i + 1]) {
45
+ result.plansDir = args[++i];
46
+ } else if (args[i] === '--features' && args[i + 1]) {
47
+ result.featureLevel = args[++i];
48
+ }
49
+ }
50
+ return result;
51
+ }
52
+
53
+ // ─── Tool Handler ───────────────────────────────────────────────────
54
+
55
+ type ToolArgs = Record<string, unknown>;
56
+
57
+ function textResult(text: string, isError = false): CallToolResult {
58
+ return { content: [{ type: 'text', text }], isError };
59
+ }
60
+
61
+ async function handleCoaiapyTool(name: string, args: ToolArgs): Promise<CallToolResult> {
62
+ try {
63
+ switch (name) {
64
+ // ── Redis ──
65
+ case 'coaia_tash': {
66
+ // Redis stash — defer to redis module if available, placeholder for now
67
+ return textResult(JSON.stringify({
68
+ success: false,
69
+ error: 'Redis module not yet wired. Use coaiapy-mcp for Redis operations.',
70
+ }));
71
+ }
72
+ case 'coaia_fetch': {
73
+ return textResult(JSON.stringify({
74
+ success: false,
75
+ error: 'Redis module not yet wired. Use coaiapy-mcp for Redis operations.',
76
+ }));
77
+ }
78
+
79
+ // ── Traces ──
80
+ case 'coaia_fuse_trace_create': {
81
+ const result = await addTrace({
82
+ traceId: args.trace_id as string,
83
+ userId: args.user_id as string | undefined,
84
+ sessionId: args.session_id as string | undefined,
85
+ name: args.name as string | undefined,
86
+ metadata: args.metadata as Record<string, unknown> | undefined,
87
+ inputData: args.input_data,
88
+ outputData: args.output_data,
89
+ });
90
+ return textResult(result);
91
+ }
92
+
93
+ case 'coaia_fuse_add_observation': {
94
+ const result = await addObservation({
95
+ observationId: args.observation_id as string,
96
+ traceId: args.trace_id as string,
97
+ name: args.name as string,
98
+ type: args.observation_type as string | undefined,
99
+ parentId: args.parent_id as string | undefined,
100
+ metadata: args.metadata as Record<string, unknown> | undefined,
101
+ inputData: args.input_data,
102
+ outputData: args.output_data,
103
+ startTime: args.start_time as string | undefined,
104
+ endTime: args.end_time as string | undefined,
105
+ });
106
+ return textResult(result);
107
+ }
108
+
109
+ case 'coaia_fuse_trace_patch_output': {
110
+ const result = await patchTraceOutput(
111
+ args.trace_id as string,
112
+ args.output_data,
113
+ );
114
+ return textResult(result);
115
+ }
116
+
117
+ case 'coaia_fuse_trace_get':
118
+ case 'coaia_fuse_trace_view': {
119
+ const traceJson = await getTrace(args.trace_id as string);
120
+ if (args.json_output) {
121
+ return textResult(traceJson);
122
+ }
123
+ const formatted = formatTraceTree(traceJson);
124
+ return textResult(formatted);
125
+ }
126
+
127
+ case 'coaia_fuse_observation_get': {
128
+ const obsJson = await getObservation(args.observation_id as string);
129
+ if (args.json_output) {
130
+ return textResult(obsJson);
131
+ }
132
+ return textResult(formatObservationDisplay(obsJson));
133
+ }
134
+
135
+ case 'coaia_fuse_traces_list': {
136
+ const result = await listTraces({
137
+ sessionId: args.session_id as string | undefined,
138
+ userId: args.user_id as string | undefined,
139
+ name: args.name as string | undefined,
140
+ tags: args.tags as string[] | undefined,
141
+ fromTimestamp: args.from_timestamp as string | undefined,
142
+ toTimestamp: args.to_timestamp as string | undefined,
143
+ orderBy: args.order_by as string | undefined,
144
+ page: args.page as number | undefined,
145
+ limit: args.limit as number | undefined,
146
+ });
147
+ return textResult(formatTracesTable(result));
148
+ }
149
+
150
+ case 'coaia_fuse_traces_session_view': {
151
+ const result = await listTraces({
152
+ sessionId: args.session_id as string,
153
+ });
154
+ if (args.json_output) return textResult(result);
155
+ return textResult(formatTracesTable(result));
156
+ }
157
+
158
+ // ── Prompts ──
159
+ case 'coaia_fuse_prompts_list': {
160
+ const result = await listPrompts();
161
+ return textResult(formatPromptsTable(result));
162
+ }
163
+
164
+ case 'coaia_fuse_prompts_get': {
165
+ const result = await getPrompt(
166
+ args.name as string,
167
+ args.label as string | undefined,
168
+ );
169
+ return textResult(formatPromptDisplay(result));
170
+ }
171
+
172
+ // ── Datasets ──
173
+ case 'coaia_fuse_datasets_list': {
174
+ const result = await listDatasets();
175
+ return textResult(formatDatasetsTable(result));
176
+ }
177
+
178
+ case 'coaia_fuse_datasets_get': {
179
+ const result = await getDataset(args.name as string);
180
+ return textResult(result);
181
+ }
182
+
183
+ // ── Score Configs ──
184
+ case 'coaia_fuse_score_configs_list': {
185
+ const result = await listScoreConfigs();
186
+ return textResult(formatScoreConfigsTable(result));
187
+ }
188
+
189
+ case 'coaia_fuse_score_configs_get': {
190
+ const result = await getScoreConfig(args.name_or_id as string);
191
+ return textResult(result);
192
+ }
193
+
194
+ case 'coaia_fuse_score_apply': {
195
+ const result = await applyScoreConfig(
196
+ args.config_name_or_id as string,
197
+ args.target_type as string,
198
+ args.target_id as string,
199
+ args.value as number,
200
+ args.observation_id as string | undefined,
201
+ args.comment as string | undefined,
202
+ );
203
+ return textResult(result);
204
+ }
205
+
206
+ // ── Comments ──
207
+ case 'coaia_fuse_comments_list': {
208
+ const result = await listComments({
209
+ objectType: args.object_type as string | undefined,
210
+ objectId: args.object_id as string | undefined,
211
+ authorUserId: args.author_user_id as string | undefined,
212
+ page: args.page as number | undefined,
213
+ limit: args.limit as number | undefined,
214
+ });
215
+ return textResult(result);
216
+ }
217
+
218
+ case 'coaia_fuse_comments_get': {
219
+ const result = await getComment(args.comment_id as string);
220
+ return textResult(result);
221
+ }
222
+
223
+ case 'coaia_fuse_comments_create': {
224
+ const result = await createComment({
225
+ text: args.text as string,
226
+ objectType: args.object_type as string,
227
+ objectId: args.object_id as string,
228
+ authorUserId: args.author_user_id as string | undefined,
229
+ });
230
+ return textResult(result);
231
+ }
232
+
233
+ // ── Media ──
234
+ case 'coaia_fuse_media_upload': {
235
+ const result = await uploadAndAttachMedia({
236
+ filePath: args.file_path as string,
237
+ traceId: args.trace_id as string,
238
+ field: args.field as string | undefined,
239
+ observationId: args.observation_id as string | undefined,
240
+ contentType: args.content_type as string | undefined,
241
+ });
242
+ return textResult(result);
243
+ }
244
+
245
+ case 'coaia_fuse_media_get': {
246
+ const result = await getMedia(args.media_id as string);
247
+ return textResult(formatMediaDisplay(result));
248
+ }
249
+
250
+ default:
251
+ return textResult(`Unknown tool: ${name}`, true);
252
+ }
253
+ } catch (error) {
254
+ const msg = error instanceof Error ? error.message : String(error);
255
+ return textResult(JSON.stringify({ error: msg }), true);
256
+ }
257
+ }
258
+
259
+ // ─── Narrative/PDE/Planning tool stubs ──────────────────────────────
260
+ // These modules will be wired by other direction agents (SOUTH/EAST/WEST).
261
+ // For now we register placeholder definitions so the server schema is complete.
262
+
263
+ function getNarrativeToolDefinitions(featureConfig: FeatureConfig): ToolDefinition[] {
264
+ const narrativeToolNames = [
265
+ 'create_structural_tension_chart', 'telescope_action_step', 'mark_action_complete',
266
+ 'get_chart_progress', 'list_active_charts', 'get_chart', 'get_action_step',
267
+ 'update_action_progress', 'update_current_reality', 'manage_action_step',
268
+ 'add_action_step', 'remove_action_step', 'update_desired_outcome',
269
+ 'perform_mmot_evaluation', 'init_llm_guidance',
270
+ 'create_narrative_beat', 'telescope_narrative_beat', 'list_narrative_beats',
271
+ 'add_observations', 'create_entities', 'create_relations', 'search_nodes',
272
+ 'open_nodes', 'read_graph', 'delete_entities', 'delete_relations',
273
+ 'delete_observations', 'merge_entities',
274
+ ];
275
+
276
+ return narrativeToolNames
277
+ .filter((name) => featureConfig.isToolEnabled(name))
278
+ .map((name) => ({
279
+ name,
280
+ description: `[Narrative] ${name.replace(/_/g, ' ')} — pending wiring from narrative module`,
281
+ inputSchema: { type: 'object' as const, properties: {} },
282
+ }));
283
+ }
284
+
285
+ function getPdeToolDefinitions(featureConfig: FeatureConfig): ToolDefinition[] {
286
+ const pdeToolNames = [
287
+ 'pde_decompose', 'pde_parse_response', 'pde_get', 'pde_list',
288
+ 'pde_export_markdown', 'import_pde', 'create_stc_from_pde',
289
+ 'pde_sessions_list', 'pde_sessions_create', 'pde_sessions_update',
290
+ ];
291
+
292
+ return pdeToolNames
293
+ .filter((name) => featureConfig.isToolEnabled(name))
294
+ .map((name) => ({
295
+ name,
296
+ description: `[PDE] ${name.replace(/_/g, ' ')} — pending wiring from PDE module`,
297
+ inputSchema: { type: 'object' as const, properties: {} },
298
+ }));
299
+ }
300
+
301
+ function getPlanningToolDefinitions(featureConfig: FeatureConfig): ToolDefinition[] {
302
+ const planToolNames = [
303
+ 'parse_plan', 'plan_to_stc', 'sync_plans', 'trace_plan', 'pde_to_plan', 'list_plans',
304
+ ];
305
+
306
+ return planToolNames
307
+ .filter((name) => featureConfig.isToolEnabled(name))
308
+ .map((name) => ({
309
+ name,
310
+ description: `[Planning] ${name.replace(/_/g, ' ')} — pending wiring from planning module`,
311
+ inputSchema: { type: 'object' as const, properties: {} },
312
+ }));
313
+ }
314
+
315
+ // ─── Server Creation ────────────────────────────────────────────────
316
+
317
+ function createServer(): Server {
318
+ const cliArgs = parseArgs();
319
+ const featureConfig = new FeatureConfig(
320
+ cliArgs.featureLevel as 'MINIMAL' | 'STANDARD' | 'OBSERVABILITY' | 'FULL' | undefined,
321
+ );
322
+
323
+ const server = new Server(
324
+ { name: SERVER_NAME, version: SERVER_VERSION },
325
+ { capabilities: { tools: {} } },
326
+ );
327
+
328
+ // Collect all tool definitions
329
+ const allToolDefs: ToolDefinition[] = [
330
+ ...getCoaiapyToolDefinitions(featureConfig),
331
+ ...getNarrativeToolDefinitions(featureConfig),
332
+ ...getPdeToolDefinitions(featureConfig),
333
+ ...getPlanningToolDefinitions(featureConfig),
334
+ ];
335
+
336
+ // ── list_tools handler ──
337
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
338
+ return {
339
+ tools: allToolDefs.map((t) => ({
340
+ name: t.name,
341
+ description: t.description,
342
+ inputSchema: t.inputSchema,
343
+ })),
344
+ };
345
+ });
346
+
347
+ // ── call_tool handler ──
348
+ server.setRequestHandler(CallToolRequestSchema, async (request, _extra) => {
349
+ const { name, arguments: args } = request.params;
350
+ const toolArgs = (args ?? {}) as ToolArgs;
351
+
352
+ // Route to coaiapy handler if it's a coaia_* tool
353
+ if (name.startsWith('coaia_')) {
354
+ return handleCoaiapyTool(name, toolArgs);
355
+ }
356
+
357
+ // Route to narrative/PDE/planning stubs
358
+ const stubModules = ['create_structural_tension_chart', 'telescope_action_step',
359
+ 'mark_action_complete', 'get_chart_progress', 'list_active_charts', 'get_chart',
360
+ 'get_action_step', 'update_action_progress', 'update_current_reality',
361
+ 'manage_action_step', 'add_action_step', 'remove_action_step',
362
+ 'update_desired_outcome', 'perform_mmot_evaluation', 'init_llm_guidance',
363
+ 'create_narrative_beat', 'telescope_narrative_beat', 'list_narrative_beats',
364
+ 'add_observations', 'create_entities', 'create_relations', 'search_nodes',
365
+ 'open_nodes', 'read_graph', 'delete_entities', 'delete_relations',
366
+ 'delete_observations', 'merge_entities',
367
+ 'pde_decompose', 'pde_parse_response', 'pde_get', 'pde_list',
368
+ 'pde_export_markdown', 'import_pde', 'create_stc_from_pde',
369
+ 'pde_sessions_list', 'pde_sessions_create', 'pde_sessions_update',
370
+ 'parse_plan', 'plan_to_stc', 'sync_plans', 'trace_plan', 'pde_to_plan', 'list_plans',
371
+ ];
372
+
373
+ if (stubModules.includes(name)) {
374
+ return textResult(JSON.stringify({
375
+ status: 'pending',
376
+ message: `Tool '${name}' is registered but not yet wired. Module integration pending.`,
377
+ args: toolArgs,
378
+ }));
379
+ }
380
+
381
+ return textResult(`Unknown tool: ${name}`, true);
382
+ });
383
+
384
+ return server;
385
+ }
386
+
387
+ // ─── Main ───────────────────────────────────────────────────────────
388
+
389
+ async function main(): Promise<void> {
390
+ const server = createServer();
391
+ const transport = new StdioServerTransport();
392
+ await server.connect(transport);
393
+
394
+ const featureConfig = new FeatureConfig();
395
+ const stats = featureConfig.getStats();
396
+ console.error(`${SERVER_NAME} v${SERVER_VERSION} started (${stats.level}: ${stats.tools} tools)`);
397
+ }
398
+
399
+ main().catch((error) => {
400
+ console.error('Fatal error:', error);
401
+ process.exit(1);
402
+ });