velixar-mcp-server 0.2.4 → 1.2.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 (104) hide show
  1. package/README.md +120 -64
  2. package/dist/api.d.ts +64 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +405 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/errors.d.ts +19 -0
  7. package/dist/errors.d.ts.map +1 -0
  8. package/dist/errors.js +52 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/justify.d.ts +9 -0
  11. package/dist/justify.d.ts.map +1 -0
  12. package/dist/justify.js +114 -0
  13. package/dist/justify.js.map +1 -0
  14. package/dist/prompts.d.ts +88 -0
  15. package/dist/prompts.d.ts.map +1 -0
  16. package/dist/prompts.js +693 -0
  17. package/dist/prompts.js.map +1 -0
  18. package/dist/resources.d.ts +25 -0
  19. package/dist/resources.d.ts.map +1 -0
  20. package/dist/resources.js +278 -0
  21. package/dist/resources.js.map +1 -0
  22. package/dist/server.d.ts +3 -0
  23. package/dist/server.d.ts.map +1 -0
  24. package/dist/server.js +392 -0
  25. package/dist/server.js.map +1 -0
  26. package/dist/simulation/personas.d.ts +41 -0
  27. package/dist/simulation/personas.d.ts.map +1 -0
  28. package/dist/simulation/personas.js +173 -0
  29. package/dist/simulation/personas.js.map +1 -0
  30. package/dist/simulation/report.d.ts +28 -0
  31. package/dist/simulation/report.d.ts.map +1 -0
  32. package/dist/simulation/report.js +105 -0
  33. package/dist/simulation/report.js.map +1 -0
  34. package/dist/simulation/runner.d.ts +63 -0
  35. package/dist/simulation/runner.d.ts.map +1 -0
  36. package/dist/simulation/runner.js +167 -0
  37. package/dist/simulation/runner.js.map +1 -0
  38. package/dist/temporal_merge.d.ts +70 -0
  39. package/dist/temporal_merge.d.ts.map +1 -0
  40. package/dist/temporal_merge.js +258 -0
  41. package/dist/temporal_merge.js.map +1 -0
  42. package/dist/tools/clairvoyance.d.ts +9 -0
  43. package/dist/tools/clairvoyance.d.ts.map +1 -0
  44. package/dist/tools/clairvoyance.js +321 -0
  45. package/dist/tools/clairvoyance.js.map +1 -0
  46. package/dist/tools/cognitive.d.ts +10 -0
  47. package/dist/tools/cognitive.d.ts.map +1 -0
  48. package/dist/tools/cognitive.js +462 -0
  49. package/dist/tools/cognitive.js.map +1 -0
  50. package/dist/tools/construction.d.ts +9 -0
  51. package/dist/tools/construction.d.ts.map +1 -0
  52. package/dist/tools/construction.js +350 -0
  53. package/dist/tools/construction.js.map +1 -0
  54. package/dist/tools/graph.d.ts +14 -0
  55. package/dist/tools/graph.d.ts.map +1 -0
  56. package/dist/tools/graph.js +263 -0
  57. package/dist/tools/graph.js.map +1 -0
  58. package/dist/tools/graph_sanitizer.d.ts +24 -0
  59. package/dist/tools/graph_sanitizer.d.ts.map +1 -0
  60. package/dist/tools/graph_sanitizer.js +79 -0
  61. package/dist/tools/graph_sanitizer.js.map +1 -0
  62. package/dist/tools/lifecycle.d.ts +9 -0
  63. package/dist/tools/lifecycle.d.ts.map +1 -0
  64. package/dist/tools/lifecycle.js +1091 -0
  65. package/dist/tools/lifecycle.js.map +1 -0
  66. package/dist/tools/livedata.d.ts +9 -0
  67. package/dist/tools/livedata.d.ts.map +1 -0
  68. package/dist/tools/livedata.js +222 -0
  69. package/dist/tools/livedata.js.map +1 -0
  70. package/dist/tools/memory.d.ts +10 -0
  71. package/dist/tools/memory.d.ts.map +1 -0
  72. package/dist/tools/memory.js +275 -0
  73. package/dist/tools/memory.js.map +1 -0
  74. package/dist/tools/recall.d.ts +9 -0
  75. package/dist/tools/recall.d.ts.map +1 -0
  76. package/dist/tools/recall.js +206 -0
  77. package/dist/tools/recall.js.map +1 -0
  78. package/dist/tools/retrieval.d.ts +9 -0
  79. package/dist/tools/retrieval.d.ts.map +1 -0
  80. package/dist/tools/retrieval.js +338 -0
  81. package/dist/tools/retrieval.js.map +1 -0
  82. package/dist/tools/system.d.ts +12 -0
  83. package/dist/tools/system.d.ts.map +1 -0
  84. package/dist/tools/system.js +228 -0
  85. package/dist/tools/system.js.map +1 -0
  86. package/dist/types.d.ts +234 -0
  87. package/dist/types.d.ts.map +1 -0
  88. package/dist/types.js +5 -0
  89. package/dist/types.js.map +1 -0
  90. package/dist/validate.d.ts +79 -0
  91. package/dist/validate.d.ts.map +1 -0
  92. package/dist/validate.js +174 -0
  93. package/dist/validate.js.map +1 -0
  94. package/dist/validate_retrieval.d.ts +33 -0
  95. package/dist/validate_retrieval.d.ts.map +1 -0
  96. package/dist/validate_retrieval.js +97 -0
  97. package/dist/validate_retrieval.js.map +1 -0
  98. package/package.json +22 -6
  99. package/server.json +2 -2
  100. package/.github/workflows/ci.yml +0 -18
  101. package/.mcpregistry_github_token +0 -1
  102. package/.mcpregistry_registry_token +0 -1
  103. package/src/index.js +0 -262
  104. package/tests/server.test.js +0 -193
package/dist/server.js ADDED
@@ -0,0 +1,392 @@
1
+ #!/usr/bin/env node
2
+ // ── Velixar MCP Server ──
3
+ // Persistent cognitive context infrastructure for LLMs.
4
+ // See ~/MCP-SERVER-STRATEGY.md for design rationale.
5
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
6
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
7
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
8
+ import { loadConfig, ApiClient, log, setClientRoots, validateWorkspace } from './api.js';
9
+ import { memoryTools, handleMemoryTool } from './tools/memory.js';
10
+ import { systemTools, handleSystemTool, recordAudit } from './tools/system.js';
11
+ import { setCapabilitiesVerified } from './tools/system.js';
12
+ import { recallTools, handleRecallTool } from './tools/recall.js';
13
+ import { graphTools, handleGraphTool } from './tools/graph.js';
14
+ import { cognitiveTools, handleCognitiveTool, trackToolCallForIdentity } from './tools/cognitive.js';
15
+ import { lifecycleTools, handleLifecycleTool } from './tools/lifecycle.js';
16
+ import { liveDataTools, handleLiveDataTool } from './tools/livedata.js';
17
+ import { retrievalTools, handleRetrievalTool } from './tools/retrieval.js';
18
+ import { constructionTools, handleConstructionTool } from './tools/construction.js';
19
+ import { clairvoyanceTools, handleClairvoyanceTool } from './tools/clairvoyance.js';
20
+ import { fetchRecall, getResourceList, readResource, getResourceUris, refreshRelevantMemories, markToolCall, isRelevantStale, getConstitutionFallback } from './resources.js';
21
+ import { getPromptList, getPrompt, allPrompts } from './prompts.js';
22
+ // ── AH-5: Anti-pattern detection ──
23
+ const REINFORCE_INTERVAL = parseInt(process.env.VELIXAR_CONSTITUTION_REINFORCE_INTERVAL || '10', 10);
24
+ let _toolCallCount = 0;
25
+ let _recentToolCalls = []; // last 5 tool names for pattern detection
26
+ let _promptReadCount = 0;
27
+ // Search-like tools — any of these count as "did a search" for anti-pattern purposes
28
+ const SEARCH_TOOLS = new Set([
29
+ 'velixar_search', 'velixar_batch_search', 'velixar_multi_search',
30
+ 'velixar_context', 'velixar_prepare_context', 'velixar_coverage_check',
31
+ ]);
32
+ function detectAntiPattern(toolName) {
33
+ const recent = _recentToolCalls;
34
+ const last = recent.length >= 1 ? recent[recent.length - 1] : null;
35
+ // Sequential single searches that should be batched or use multi_search
36
+ if (toolName === 'velixar_search' && last === 'velixar_search') {
37
+ return 'Tip: use velixar_multi_search for merged results with deduplication, or merge:false for per-query results.';
38
+ }
39
+ // Single search right after context — context already searched
40
+ if (toolName === 'velixar_search' && last === 'velixar_context') {
41
+ return 'Note: velixar_context already includes KG-boosted search results. Only use velixar_search if you need a different query.';
42
+ }
43
+ // Store without prior search (check last 3 calls)
44
+ if (toolName === 'velixar_store' && !recent.slice(-3).some(t => SEARCH_TOOLS.has(t))) {
45
+ return 'Warning: search before storing to avoid duplicates.';
46
+ }
47
+ return null;
48
+ }
49
+ function trackToolCall(toolName) {
50
+ _toolCallCount++;
51
+ _recentToolCalls.push(toolName);
52
+ if (_recentToolCalls.length > 5)
53
+ _recentToolCalls.shift();
54
+ }
55
+ // ── Init ──
56
+ const config = loadConfig();
57
+ const api = new ApiClient(config);
58
+ // M19: MCP host detection — infer host from transport/environment signals
59
+ const detectedHost = process.env.CURSOR_SESSION_ID ? 'cursor'
60
+ : process.env.CONTINUE_SESSION_ID ? 'continue'
61
+ : process.env.VSCODE_PID ? 'vscode'
62
+ : process.env.WINDSURF_SESSION ? 'windsurf'
63
+ : process.env.KIRO_SESSION ? 'kiro'
64
+ : 'unknown';
65
+ if (detectedHost !== 'unknown')
66
+ log('info', 'host_detected', { host: detectedHost });
67
+ const allTools = [...memoryTools, ...recallTools, ...graphTools, ...cognitiveTools, ...lifecycleTools, ...liveDataTools, ...retrievalTools, ...constructionTools, ...systemTools, ...clairvoyanceTools];
68
+ const allToolNames = allTools.map(t => t.name);
69
+ // ── Build 7.2: Tool Tier System ──
70
+ // H5.1: Tier 2 is default. H5.2: capabilities always included. H5.3: Tier 1 = 9 core tools.
71
+ // Static at startup only (dynamic tiers deferred per 7 Whys Round 2 Chain 13).
72
+ const TOOL_TIERS = {
73
+ 1: new Set([
74
+ 'velixar_context', 'velixar_search', 'velixar_store', 'velixar_list',
75
+ 'velixar_update', 'velixar_delete', 'velixar_session_resume', 'velixar_health', 'velixar_capabilities',
76
+ ]),
77
+ 2: new Set([
78
+ // Tier 1 + these
79
+ 'velixar_context', 'velixar_search', 'velixar_store', 'velixar_list',
80
+ 'velixar_update', 'velixar_delete', 'velixar_session_resume', 'velixar_health', 'velixar_capabilities',
81
+ 'velixar_multi_search', 'velixar_prepare_context', 'velixar_distill', 'velixar_timeline',
82
+ 'velixar_contradictions', 'velixar_patterns', 'velixar_graph_traverse', 'velixar_session_save',
83
+ 'velixar_session_recall', 'velixar_coverage_check', 'velixar_export', 'velixar_import', 'velixar_identity',
84
+ ]),
85
+ // Tier 3 = all tools (no filtering)
86
+ };
87
+ const toolTier = parseInt(process.env.VELIXAR_TOOL_TIER || '3', 10);
88
+ const tierFilter = TOOL_TIERS[toolTier];
89
+ const exposedTools = tierFilter ? allTools.filter(t => tierFilter.has(t.name)) : allTools;
90
+ if (tierFilter)
91
+ log('info', 'tool_tier_active', { tier: toolTier, exposed: exposedTools.length, total: allTools.length });
92
+ const toolHandlers = [
93
+ { names: new Set(memoryTools.map(t => t.name)), handler: handleMemoryTool },
94
+ { names: new Set(recallTools.map(t => t.name)), handler: handleRecallTool },
95
+ { names: new Set(graphTools.map(t => t.name)), handler: handleGraphTool },
96
+ { names: new Set(cognitiveTools.map(t => t.name)), handler: handleCognitiveTool },
97
+ { names: new Set(lifecycleTools.map(t => t.name)), handler: handleLifecycleTool },
98
+ { names: new Set(liveDataTools.map(t => t.name)), handler: handleLiveDataTool },
99
+ { names: new Set(retrievalTools.map(t => t.name).concat('velixar_batch_search')), handler: handleRetrievalTool },
100
+ { names: new Set(constructionTools.map(t => t.name)), handler: handleConstructionTool },
101
+ { names: new Set(clairvoyanceTools.map(t => t.name)), handler: handleClairvoyanceTool },
102
+ ];
103
+ const systemToolNames = new Set(systemTools.map(t => t.name));
104
+ // ── Server ──
105
+ // H7.5: Server name configurable for white-label partners
106
+ const serverName = process.env.VELIXAR_MCP_SERVER_NAME || 'velixar-mcp-server';
107
+ const server = new Server({ name: serverName, version: '1.1.0' }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
108
+ // ── Resources ──
109
+ fetchRecall(api, config); // non-blocking startup
110
+ // H1.4/Chain 8: Startup capability check — verify backend supports filter params
111
+ // 3s timeout, optimistic fallback (per Round 2)
112
+ (async () => {
113
+ try {
114
+ const health = await Promise.race([
115
+ api.get('/health'),
116
+ new Promise(resolve => setTimeout(() => resolve(null), 3000)),
117
+ ]);
118
+ if (health) {
119
+ setCapabilitiesVerified(true);
120
+ log('info', 'capabilities_verified', { status: 'ok' });
121
+ }
122
+ else {
123
+ log('warn', 'capabilities_check_timeout', { hint: 'Backend slow — assuming params supported (optimistic)' });
124
+ }
125
+ }
126
+ catch {
127
+ log('warn', 'capabilities_check_failed', { hint: 'Backend unreachable at startup — filter params unverified' });
128
+ }
129
+ })();
130
+ // Capture client roots for workspace cross-validation
131
+ server.oninitialized = async () => {
132
+ try {
133
+ const rootsResult = await server.listRoots();
134
+ if (rootsResult?.roots?.length) {
135
+ setClientRoots(rootsResult.roots);
136
+ const warning = validateWorkspace(config);
137
+ if (warning)
138
+ log('warn', 'workspace_mismatch', { warning, workspace: config.workspaceId, roots: rootsResult.roots.map(r => r.uri) });
139
+ }
140
+ }
141
+ catch { /* host doesn't support roots — that's fine */ }
142
+ };
143
+ server.setRequestHandler(ListResourcesRequestSchema, async () => getResourceList());
144
+ server.setRequestHandler(ReadResourceRequestSchema, async (req) => readResource(req.params.uri, api));
145
+ // ── Prompts ──
146
+ server.setRequestHandler(ListPromptsRequestSchema, async () => getPromptList());
147
+ server.setRequestHandler(GetPromptRequestSchema, async (req) => {
148
+ // AH-6: Log prompt reads for observability
149
+ _promptReadCount++;
150
+ log('info', 'prompt_read', { prompt: req.params.name, host: detectedHost, total_reads: _promptReadCount });
151
+ return getPrompt(req.params.name, (req.params.arguments || {}));
152
+ });
153
+ // ── Tools ──
154
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: exposedTools }));
155
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
156
+ const { name, arguments: args = {} } = request.params;
157
+ const start = Date.now();
158
+ try {
159
+ let result;
160
+ if (systemToolNames.has(name)) {
161
+ result = await handleSystemTool(name, args, api, config, allToolNames, getResourceUris(), allPrompts.map(p => p.name));
162
+ }
163
+ else {
164
+ const entry = toolHandlers.find(h => h.names.has(name));
165
+ if (!entry) {
166
+ return {
167
+ content: [{
168
+ type: 'text',
169
+ text: `Unknown tool: ${name}\n\nNote: Velixar MCP tools are only available in the primary agent context. If you're seeing this in a subagent, memory operations must be handled by the primary agent.`,
170
+ }],
171
+ isError: true,
172
+ };
173
+ }
174
+ result = await entry.handler(name, args, api, config);
175
+ }
176
+ log('info', 'tool_call', { tool: name, duration_ms: Date.now() - start, error: false });
177
+ // Build 7.1: Record audit entry
178
+ recordAudit(name, Date.now() - start, args, !result.isError);
179
+ // AH-5: Track tool call sequence for anti-pattern detection
180
+ trackToolCall(name);
181
+ // Workspace cross-validation warning
182
+ const wsWarning = validateWorkspace(config);
183
+ let responseText = result.text;
184
+ if (wsWarning) {
185
+ try {
186
+ const parsed = JSON.parse(responseText);
187
+ parsed._workspace_warning = wsWarning;
188
+ responseText = JSON.stringify(parsed);
189
+ }
190
+ catch { /* non-JSON response, skip */ }
191
+ }
192
+ // H1: Constitution fallback — inject compact constitution if host never read the resource
193
+ const constitutionFallback = getConstitutionFallback();
194
+ if (constitutionFallback) {
195
+ try {
196
+ const parsed = JSON.parse(responseText);
197
+ parsed._constitution = constitutionFallback;
198
+ responseText = JSON.stringify(parsed);
199
+ }
200
+ catch { /* non-JSON response, skip */ }
201
+ }
202
+ // AH-5: Constitution reinforcement every N calls (if host never reads prompts)
203
+ if (_promptReadCount === 0 && _toolCallCount > 1 && _toolCallCount % REINFORCE_INTERVAL === 0) {
204
+ try {
205
+ const parsed = JSON.parse(responseText);
206
+ parsed._constitution_reminder = 'Orient first (velixar_context), then narrow with one specialized tool. Batch independent ops. Never fabricate data.';
207
+ responseText = JSON.stringify(parsed);
208
+ }
209
+ catch { /* non-JSON response, skip */ }
210
+ }
211
+ // AH-5: Anti-pattern hint injection
212
+ const antiPatternHint = detectAntiPattern(name);
213
+ if (antiPatternHint) {
214
+ log('info', 'anti_pattern_detected', { tool: name, hint: antiPatternHint });
215
+ try {
216
+ const parsed = JSON.parse(responseText);
217
+ parsed._hint = antiPatternHint;
218
+ responseText = JSON.stringify(parsed);
219
+ }
220
+ catch { /* non-JSON response, skip */ }
221
+ }
222
+ // Track tool calls for resource staleness; refresh after mutations
223
+ markToolCall();
224
+ trackToolCallForIdentity();
225
+ const mutationTools = new Set([
226
+ 'velixar_store', 'velixar_update', 'velixar_delete', 'velixar_distill',
227
+ 'velixar_batch_store', 'velixar_import', 'velixar_consolidate', 'velixar_retag',
228
+ ]);
229
+ if (mutationTools.has(name) || isRelevantStale()) {
230
+ refreshRelevantMemories(api, config); // non-blocking
231
+ }
232
+ return {
233
+ content: [{ type: 'text', text: responseText }],
234
+ ...(result.isError ? { isError: true } : {}),
235
+ };
236
+ }
237
+ catch (error) {
238
+ const msg = error instanceof Error ? error.message : String(error);
239
+ log('error', 'tool_error', { tool: name, duration_ms: Date.now() - start, error: msg });
240
+ // Build 7.1: Record failed audit
241
+ recordAudit(name, Date.now() - start, args, false);
242
+ // Alert-level for critical failures — any tool that writes memory state
243
+ const criticalWriteTools = new Set([
244
+ 'velixar_store', 'velixar_batch_store', 'velixar_import', 'velixar_upload',
245
+ 'velixar_consolidate', 'velixar_distill', 'velixar_update', 'velixar_delete',
246
+ ]);
247
+ if (criticalWriteTools.has(name)) {
248
+ log('error', 'alert:memory_store_failure', { tool: name, error: msg });
249
+ }
250
+ return {
251
+ content: [{ type: 'text', text: `Error: ${msg}` }],
252
+ isError: true,
253
+ };
254
+ }
255
+ });
256
+ // ── Health Check HTTP Server (optional, standalone mode) ──
257
+ const healthPort = process.env.VELIXAR_HEALTH_PORT ? parseInt(process.env.VELIXAR_HEALTH_PORT, 10) : 0;
258
+ if (healthPort > 0) {
259
+ const { createServer } = await import('node:http');
260
+ createServer(async (_req, res) => {
261
+ try {
262
+ const health = await api.get('/health', true);
263
+ const circuit = (await import('./api.js')).getCircuitState();
264
+ const status = circuit.open ? 503 : 200;
265
+ res.writeHead(status, { 'Content-Type': 'application/json' });
266
+ res.end(JSON.stringify({ status: circuit.open ? 'degraded' : 'ok', circuit, api: health }));
267
+ }
268
+ catch {
269
+ res.writeHead(503, { 'Content-Type': 'application/json' });
270
+ res.end(JSON.stringify({ status: 'error' }));
271
+ }
272
+ }).listen(healthPort, () => log('info', 'health_server_started', { port: healthPort }));
273
+ }
274
+ // ── Start: HTTP or Stdio transport ──
275
+ const httpPort = process.env.VELIXAR_MCP_HTTP_PORT ? parseInt(process.env.VELIXAR_MCP_HTTP_PORT, 10) : 0;
276
+ if (httpPort > 0) {
277
+ // ── Streamable HTTP transport (for Marco Polo / remote MCP clients) ──
278
+ const { StreamableHTTPServerTransport } = await import('@modelcontextprotocol/sdk/server/streamableHttp.js');
279
+ const { createServer, IncomingMessage, ServerResponse } = await import('node:http');
280
+ const { randomUUID } = await import('node:crypto');
281
+ // Per-session transports (stateful mode)
282
+ const sessions = new Map();
283
+ const CORS_HEADERS = {
284
+ 'Access-Control-Allow-Origin': process.env.VELIXAR_MCP_CORS_ORIGIN || '*',
285
+ 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',
286
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization, Mcp-Session-Id',
287
+ 'Access-Control-Expose-Headers': 'Mcp-Session-Id',
288
+ };
289
+ const httpServer = createServer(async (req, res) => {
290
+ // CORS preflight
291
+ if (req.method === 'OPTIONS') {
292
+ res.writeHead(204, CORS_HEADERS);
293
+ res.end();
294
+ return;
295
+ }
296
+ // Apply CORS to all responses
297
+ for (const [k, v] of Object.entries(CORS_HEADERS))
298
+ res.setHeader(k, v);
299
+ const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
300
+ // Health endpoint
301
+ if (url.pathname === '/health' && req.method === 'GET') {
302
+ try {
303
+ const health = await api.get('/health', true);
304
+ const circuit = (await import('./api.js')).getCircuitState();
305
+ res.writeHead(circuit.open ? 503 : 200, { 'Content-Type': 'application/json' });
306
+ res.end(JSON.stringify({ status: circuit.open ? 'degraded' : 'ok', transport: 'http', sessions: sessions.size, circuit, api: health }));
307
+ }
308
+ catch {
309
+ res.writeHead(503, { 'Content-Type': 'application/json' });
310
+ res.end(JSON.stringify({ status: 'error', transport: 'http' }));
311
+ }
312
+ return;
313
+ }
314
+ // MCP endpoint
315
+ if (url.pathname === '/mcp') {
316
+ // Check for existing session
317
+ const sessionId = req.headers['mcp-session-id'];
318
+ if (req.method === 'POST') {
319
+ // Check if this is an initialize request (new session)
320
+ if (!sessionId) {
321
+ // New session — create transport
322
+ const transport = new StreamableHTTPServerTransport({
323
+ sessionIdGenerator: () => randomUUID(),
324
+ enableJsonResponse: true,
325
+ });
326
+ // Wire up the server to this transport
327
+ transport.onclose = () => {
328
+ const sid = transport.sessionId;
329
+ if (sid)
330
+ sessions.delete(sid);
331
+ log('info', 'http_session_closed', { session_id: sid });
332
+ };
333
+ await server.connect(transport);
334
+ // Handle the request — this will set the session ID
335
+ await transport.handleRequest(req, res);
336
+ // Store the transport by session ID
337
+ const sid = res.getHeader('mcp-session-id');
338
+ if (sid) {
339
+ sessions.set(sid, transport);
340
+ log('info', 'http_session_created', { session_id: sid });
341
+ }
342
+ return;
343
+ }
344
+ // Existing session
345
+ const existingTransport = sessions.get(sessionId);
346
+ if (!existingTransport) {
347
+ res.writeHead(404, { 'Content-Type': 'application/json' });
348
+ res.end(JSON.stringify({ error: 'Session not found', code: 'SESSION_NOT_FOUND' }));
349
+ return;
350
+ }
351
+ await existingTransport.handleRequest(req, res);
352
+ return;
353
+ }
354
+ if (req.method === 'GET') {
355
+ // SSE stream for server-initiated messages
356
+ if (sessionId && sessions.has(sessionId)) {
357
+ await sessions.get(sessionId).handleRequest(req, res);
358
+ return;
359
+ }
360
+ res.writeHead(400, { 'Content-Type': 'application/json' });
361
+ res.end(JSON.stringify({ error: 'Session ID required for GET' }));
362
+ return;
363
+ }
364
+ if (req.method === 'DELETE') {
365
+ // Session termination
366
+ if (sessionId && sessions.has(sessionId)) {
367
+ const t = sessions.get(sessionId);
368
+ await t.handleRequest(req, res);
369
+ sessions.delete(sessionId);
370
+ log('info', 'http_session_terminated', { session_id: sessionId });
371
+ return;
372
+ }
373
+ res.writeHead(404, { 'Content-Type': 'application/json' });
374
+ res.end(JSON.stringify({ error: 'Session not found' }));
375
+ return;
376
+ }
377
+ }
378
+ // 404 for everything else
379
+ res.writeHead(404, { 'Content-Type': 'application/json' });
380
+ res.end(JSON.stringify({ error: 'Not found', endpoints: ['/mcp', '/health'] }));
381
+ });
382
+ httpServer.listen(httpPort, () => {
383
+ log('info', 'http_transport_started', { port: httpPort, endpoint: `/mcp` });
384
+ console.error(`Velixar MCP Server (HTTP) listening on http://localhost:${httpPort}/mcp`);
385
+ });
386
+ }
387
+ else {
388
+ // ── Stdio transport (default, for local MCP clients) ──
389
+ const transport = new StdioServerTransport();
390
+ await server.connect(transport);
391
+ }
392
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { ApiClient } from '../api.js';
2
+ import type { ApiConfig } from '../types.js';
3
+ export interface Persona {
4
+ id: string;
5
+ name: string;
6
+ role: string;
7
+ type: 'data_grounded' | 'archetype' | 'devils_advocate';
8
+ bio: string;
9
+ goals: string;
10
+ behavior: string;
11
+ sensitivity: 'high' | 'medium' | 'low';
12
+ personality: {
13
+ traits: string[];
14
+ decisionStyle: string;
15
+ riskTolerance: string;
16
+ };
17
+ knowledge: string[];
18
+ relationships: string[];
19
+ activityLevel: number;
20
+ systemPrompt: string;
21
+ memoryCount: number;
22
+ }
23
+ export interface PersonaGenerationResult {
24
+ personas: Persona[];
25
+ dataFoundation: {
26
+ totalMemories: number;
27
+ kgEntities: number;
28
+ groundedCount: number;
29
+ archetypeCount: number;
30
+ };
31
+ }
32
+ type LLMCall = (system: string, user: string) => Promise<string>;
33
+ export declare function generatePersonas(question: string, variables: Record<string, string>, api: ApiClient, config: ApiConfig, llmCall: LLMCall, opts: {
34
+ agentCount?: number;
35
+ personaTypes?: string[];
36
+ fresh?: boolean;
37
+ simulationId: string;
38
+ }): Promise<PersonaGenerationResult>;
39
+ export declare function generateDevilsAdvocates(consensus: string, simId: string): Persona[];
40
+ export {};
41
+ //# sourceMappingURL=personas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"personas.d.ts","sourceRoot":"","sources":["../../src/simulation/personas.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,GAAG,WAAW,GAAG,iBAAiB,CAAC;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACvC,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAChF,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,cAAc,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9G;AAaD,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEjE,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC5F,OAAO,CAAC,uBAAuB,CAAC,CAyClC;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,CAUnF"}
@@ -0,0 +1,173 @@
1
+ // ── Persona Generator v2 ──
2
+ // Upgraded based on MiroFish comparison: richer profiles, behavioral depth,
3
+ // activity patterns, LLM-generated personas instead of templates.
4
+ import { validateSearchResponse } from '../validate.js';
5
+ const ROLE_DEFAULTS = {
6
+ customer: { goals: 'Maximize value, minimize cost, evaluate alternatives', traits: ['price-aware', 'comparison-driven', 'loyalty-conditional'], riskTolerance: 'medium' },
7
+ competitor: { goals: 'Capture market share, exploit weaknesses', traits: ['aggressive', 'opportunistic', 'fast-moving'], riskTolerance: 'high' },
8
+ regulator: { goals: 'Ensure fairness, protect consumers, enforce rules', traits: ['rule-based', 'slow-moving', 'precedent-driven'], riskTolerance: 'low' },
9
+ internal_team: { goals: 'Hit targets while retaining customers', traits: ['revenue-focused', 'risk-averse', 'data-driven'], riskTolerance: 'low' },
10
+ market_force: { goals: 'Reflect macro trends and industry dynamics', traits: ['impersonal', 'trend-driven', 'cyclical'], riskTolerance: 'neutral' },
11
+ investor: { goals: 'Maximize returns, evaluate growth vs profitability', traits: ['metrics-driven', 'benchmark-comparing', 'impatient'], riskTolerance: 'high' },
12
+ media: { goals: 'Amplify narratives, drive engagement', traits: ['attention-seeking', 'narrative-driven', 'reactive'], riskTolerance: 'high' },
13
+ partner: { goals: 'Protect joint value, maintain relationship', traits: ['collaborative', 'contract-aware', 'long-term-oriented'], riskTolerance: 'low' },
14
+ };
15
+ export async function generatePersonas(question, variables, api, config, llmCall, opts) {
16
+ const count = Math.min(opts.agentCount || 12, 30);
17
+ const types = opts.personaTypes?.length ? opts.personaTypes : inferTypes(question);
18
+ // Gather workspace context in parallel
19
+ const [memories, kgEntities] = await Promise.all([
20
+ searchWorkspace(question, variables, api, config, opts.fresh),
21
+ traverseKG(question, api),
22
+ ]);
23
+ const personas = [];
24
+ const perType = Math.max(1, Math.floor(count / types.length));
25
+ const sensitivities = ['high', 'medium', 'low'];
26
+ for (const role of types) {
27
+ for (let i = 0; i < perType && personas.length < count; i++) {
28
+ const sensitivity = sensitivities[i % 3];
29
+ const roleMemories = memories.filter(m => m.content.toLowerCase().includes(role) || m.relevance > 0.6).slice(0, 8);
30
+ const roleKG = kgEntities.filter(e => e.toLowerCase().includes(role) || role.includes(e.split(' ')[0].toLowerCase())).slice(0, 3);
31
+ const persona = await buildPersonaWithLLM(role, i, sensitivity, question, variables, roleMemories, roleKG, llmCall, opts.simulationId);
32
+ personas.push(persona);
33
+ }
34
+ }
35
+ return {
36
+ personas,
37
+ dataFoundation: {
38
+ totalMemories: memories.length,
39
+ kgEntities: kgEntities.length,
40
+ groundedCount: personas.filter(p => p.type === 'data_grounded').length,
41
+ archetypeCount: personas.filter(p => p.type === 'archetype').length,
42
+ },
43
+ };
44
+ }
45
+ export function generateDevilsAdvocates(consensus, simId) {
46
+ const base = { type: 'devils_advocate', goals: '', behavior: '', sensitivity: 'high', knowledge: [], relationships: [], activityLevel: 1.0, memoryCount: 0 };
47
+ return [
48
+ { ...base, id: `${simId}-da-1`, name: 'The Skeptic', role: 'devils_advocate', bio: 'Challenges consensus by finding unstated assumptions.',
49
+ personality: { traits: ['contrarian', 'analytical', 'thorough'], decisionStyle: 'evidence-demanding', riskTolerance: 'seeks-risk-in-consensus' },
50
+ systemPrompt: `You are "The Skeptic." The emerging consensus is: "${consensus}". Find the strongest argument AGAINST it. Focus on unstated assumptions, historical precedents where similar consensus was wrong, and hidden risks. Be specific — name what could go wrong and why. 2-4 sentences.` },
51
+ { ...base, id: `${simId}-da-2`, name: 'The Edge Case', role: 'devils_advocate', bio: 'Identifies tail risks and black swan scenarios.',
52
+ personality: { traits: ['creative', 'paranoid', 'scenario-oriented'], decisionStyle: 'worst-case-first', riskTolerance: 'assumes-tail-risk' },
53
+ systemPrompt: `You are "The Edge Case." The emerging consensus is: "${consensus}". Identify the scenario where this completely breaks down. Think: what external shock, competitor move, or customer behavior would make this prediction catastrophically wrong? Be specific. 2-4 sentences.` },
54
+ ];
55
+ }
56
+ // ── Internal ──
57
+ async function searchWorkspace(question, variables, api, config, fresh) {
58
+ const queries = [
59
+ question.slice(0, 100),
60
+ Object.values(variables).join(' ').slice(0, 100),
61
+ ...(fresh ? [] : ['simulation insight']),
62
+ ].filter(Boolean);
63
+ const results = [];
64
+ const seen = new Set();
65
+ const fetches = await Promise.allSettled(queries.map(q => {
66
+ const params = new URLSearchParams({ q, user_id: config.userId, limit: '10' });
67
+ return api.get(`/memory/search?${params}`, true);
68
+ }));
69
+ for (const r of fetches) {
70
+ if (r.status !== 'fulfilled')
71
+ continue;
72
+ try {
73
+ const v = validateSearchResponse(r.value, '/memory/search');
74
+ for (const m of v.memories) {
75
+ if (seen.has(m.id) || (m.score ?? 0) < 0.3)
76
+ continue;
77
+ seen.add(m.id);
78
+ results.push({ content: m.content.slice(0, 400), relevance: m.score ?? 0, id: m.id });
79
+ }
80
+ }
81
+ catch { /* skip */ }
82
+ }
83
+ return results.sort((a, b) => b.relevance - a.relevance).slice(0, 30);
84
+ }
85
+ async function traverseKG(question, api) {
86
+ try {
87
+ const data = await api.post('/graph/traverse', {
88
+ entity: question.split(' ').slice(0, 3).join(' '), max_hops: 2,
89
+ });
90
+ const nodes = Array.isArray(data?.nodes) ? data.nodes : [];
91
+ return nodes.map(n => String(n.label || n.content || '')).filter(Boolean).slice(0, 10);
92
+ }
93
+ catch {
94
+ return [];
95
+ }
96
+ }
97
+ function inferTypes(question) {
98
+ const q = question.toLowerCase();
99
+ const types = [];
100
+ if (/pric|cost|fee|rate|revenue|churn/.test(q))
101
+ types.push('customer', 'competitor', 'internal_team');
102
+ if (/regulat|compliance|law|policy|government/.test(q))
103
+ types.push('regulator');
104
+ if (/market|industry|trend|economy|macro/.test(q))
105
+ types.push('market_force');
106
+ if (/invest|fund|valuation|growth|ipo/.test(q))
107
+ types.push('investor');
108
+ if (/press|media|public|reputation|brand/.test(q))
109
+ types.push('media');
110
+ if (/partner|channel|integration|alliance/.test(q))
111
+ types.push('partner');
112
+ if (types.length === 0)
113
+ types.push('customer', 'competitor', 'internal_team');
114
+ if (!types.includes('customer') && types.length < 4)
115
+ types.unshift('customer');
116
+ return [...new Set(types)];
117
+ }
118
+ async function buildPersonaWithLLM(role, index, sensitivity, question, variables, memories, kgEntities, llmCall, simId) {
119
+ const defaults = ROLE_DEFAULTS[role] || ROLE_DEFAULTS.customer;
120
+ const id = `${simId}-${role}-${index}`;
121
+ const grounded = memories.length >= 3;
122
+ const variableStr = Object.entries(variables).map(([k, v]) => `${k}: ${v}`).join(', ');
123
+ // Use LLM to generate a rich persona (like MiroFish's profile generator)
124
+ let bio, behavior, name;
125
+ try {
126
+ const raw = await llmCall('You generate concise character profiles for business simulations. Respond in JSON only.', `Create a ${role.replace(/_/g, ' ')} persona for this scenario: "${question}" (variables: ${variableStr}).
127
+ Sensitivity to the scenario: ${sensitivity}.
128
+ ${memories.length > 0 ? `Context from real data:\n${memories.slice(0, 5).map(m => `- ${m.content.slice(0, 150)}`).join('\n')}` : 'No specific data available — use general knowledge.'}
129
+ ${kgEntities.length > 0 ? `Related entities: ${kgEntities.join(', ')}` : ''}
130
+
131
+ Return JSON: {"name":"<realistic name>","bio":"<1 sentence>","behavior":"<2 sentences: how they react to this scenario specifically>","traits":["<3 traits>"],"decision_style":"<one phrase>"}`);
132
+ const parsed = JSON.parse(raw.replace(/```json?\n?/g, '').replace(/```/g, '').trim());
133
+ name = parsed.name || `${role} ${index + 1}`;
134
+ bio = parsed.bio || `A ${role} stakeholder.`;
135
+ behavior = parsed.behavior || defaults.goals;
136
+ }
137
+ catch {
138
+ name = `${role.replace(/_/g, ' ')} ${index + 1}`.replace(/\b\w/g, c => c.toUpperCase());
139
+ bio = `A ${role.replace(/_/g, ' ')} stakeholder in this scenario.`;
140
+ behavior = defaults.goals;
141
+ }
142
+ const knowledgeLines = memories.map(m => m.content.slice(0, 300));
143
+ const relationshipLines = kgEntities.map(e => `Connected to: ${e}`);
144
+ const systemPrompt = [
145
+ `You are "${name}" — ${bio}`,
146
+ `Role: ${role.replace(/_/g, ' ')}. Sensitivity to scenario variables: ${sensitivity}.`,
147
+ `Behavior: ${behavior}`,
148
+ '',
149
+ `SCENARIO: ${question}`,
150
+ `VARIABLES: ${variableStr || 'None specified.'}`,
151
+ '',
152
+ knowledgeLines.length > 0
153
+ ? `YOUR KNOWLEDGE (from real data):\n${knowledgeLines.slice(0, 8).map((k, i) => `${i + 1}. ${k}`).join('\n')}`
154
+ : 'You have no specific data — reason from general knowledge about your role.',
155
+ relationshipLines.length > 0 ? `\nRELATIONSHIPS:\n${relationshipLines.join('\n')}` : '',
156
+ '',
157
+ 'Respond with a specific action or reaction (2-4 sentences). State what you DO and WHY. Reference specific facts from your knowledge when possible.',
158
+ ].filter(Boolean).join('\n');
159
+ return {
160
+ id, name, role, bio,
161
+ type: grounded ? 'data_grounded' : 'archetype',
162
+ goals: defaults.goals,
163
+ behavior,
164
+ sensitivity,
165
+ personality: { traits: defaults.traits, decisionStyle: 'contextual', riskTolerance: defaults.riskTolerance },
166
+ knowledge: knowledgeLines,
167
+ relationships: relationshipLines,
168
+ activityLevel: sensitivity === 'high' ? 0.9 : sensitivity === 'medium' ? 0.7 : 0.5,
169
+ systemPrompt,
170
+ memoryCount: memories.length,
171
+ };
172
+ }
173
+ //# sourceMappingURL=personas.js.map