genesis-ai-cli 7.4.5

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 (227) hide show
  1. package/.env.example +78 -0
  2. package/README.md +282 -0
  3. package/dist/src/active-inference/actions.d.ts +75 -0
  4. package/dist/src/active-inference/actions.js +250 -0
  5. package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
  6. package/dist/src/active-inference/autonomous-loop.js +289 -0
  7. package/dist/src/active-inference/core.d.ts +85 -0
  8. package/dist/src/active-inference/core.js +555 -0
  9. package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
  10. package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
  11. package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
  12. package/dist/src/active-inference/demo-value-integration.js +174 -0
  13. package/dist/src/active-inference/index.d.ts +32 -0
  14. package/dist/src/active-inference/index.js +88 -0
  15. package/dist/src/active-inference/integration.d.ts +114 -0
  16. package/dist/src/active-inference/integration.js +698 -0
  17. package/dist/src/active-inference/memory-integration.d.ts +51 -0
  18. package/dist/src/active-inference/memory-integration.js +232 -0
  19. package/dist/src/active-inference/observations.d.ts +67 -0
  20. package/dist/src/active-inference/observations.js +147 -0
  21. package/dist/src/active-inference/test-active-inference.d.ts +8 -0
  22. package/dist/src/active-inference/test-active-inference.js +320 -0
  23. package/dist/src/active-inference/test-value-integration.d.ts +6 -0
  24. package/dist/src/active-inference/test-value-integration.js +168 -0
  25. package/dist/src/active-inference/types.d.ts +150 -0
  26. package/dist/src/active-inference/types.js +59 -0
  27. package/dist/src/active-inference/value-integration.d.ts +164 -0
  28. package/dist/src/active-inference/value-integration.js +459 -0
  29. package/dist/src/agents/base-agent.d.ts +53 -0
  30. package/dist/src/agents/base-agent.js +178 -0
  31. package/dist/src/agents/builder.d.ts +67 -0
  32. package/dist/src/agents/builder.js +537 -0
  33. package/dist/src/agents/critic.d.ts +35 -0
  34. package/dist/src/agents/critic.js +322 -0
  35. package/dist/src/agents/ethicist.d.ts +54 -0
  36. package/dist/src/agents/ethicist.js +393 -0
  37. package/dist/src/agents/explorer.d.ts +26 -0
  38. package/dist/src/agents/explorer.js +216 -0
  39. package/dist/src/agents/feeling.d.ts +41 -0
  40. package/dist/src/agents/feeling.js +320 -0
  41. package/dist/src/agents/index.d.ts +111 -0
  42. package/dist/src/agents/index.js +222 -0
  43. package/dist/src/agents/memory.d.ts +69 -0
  44. package/dist/src/agents/memory.js +404 -0
  45. package/dist/src/agents/message-bus.d.ts +88 -0
  46. package/dist/src/agents/message-bus.js +267 -0
  47. package/dist/src/agents/narrator.d.ts +90 -0
  48. package/dist/src/agents/narrator.js +473 -0
  49. package/dist/src/agents/planner.d.ts +38 -0
  50. package/dist/src/agents/planner.js +341 -0
  51. package/dist/src/agents/predictor.d.ts +73 -0
  52. package/dist/src/agents/predictor.js +506 -0
  53. package/dist/src/agents/sensor.d.ts +88 -0
  54. package/dist/src/agents/sensor.js +377 -0
  55. package/dist/src/agents/test-agents.d.ts +6 -0
  56. package/dist/src/agents/test-agents.js +73 -0
  57. package/dist/src/agents/types.d.ts +194 -0
  58. package/dist/src/agents/types.js +7 -0
  59. package/dist/src/brain/index.d.ts +185 -0
  60. package/dist/src/brain/index.js +843 -0
  61. package/dist/src/brain/trace.d.ts +91 -0
  62. package/dist/src/brain/trace.js +327 -0
  63. package/dist/src/brain/types.d.ts +165 -0
  64. package/dist/src/brain/types.js +51 -0
  65. package/dist/src/cli/chat.d.ts +237 -0
  66. package/dist/src/cli/chat.js +1959 -0
  67. package/dist/src/cli/dispatcher.d.ts +182 -0
  68. package/dist/src/cli/dispatcher.js +718 -0
  69. package/dist/src/cli/human-loop.d.ts +170 -0
  70. package/dist/src/cli/human-loop.js +543 -0
  71. package/dist/src/cli/index.d.ts +12 -0
  72. package/dist/src/cli/index.js +28 -0
  73. package/dist/src/cli/interactive.d.ts +141 -0
  74. package/dist/src/cli/interactive.js +757 -0
  75. package/dist/src/cli/ui.d.ts +205 -0
  76. package/dist/src/cli/ui.js +632 -0
  77. package/dist/src/consciousness/attention-schema.d.ts +154 -0
  78. package/dist/src/consciousness/attention-schema.js +432 -0
  79. package/dist/src/consciousness/global-workspace.d.ts +149 -0
  80. package/dist/src/consciousness/global-workspace.js +422 -0
  81. package/dist/src/consciousness/index.d.ts +186 -0
  82. package/dist/src/consciousness/index.js +476 -0
  83. package/dist/src/consciousness/phi-calculator.d.ts +119 -0
  84. package/dist/src/consciousness/phi-calculator.js +445 -0
  85. package/dist/src/consciousness/phi-decisions.d.ts +169 -0
  86. package/dist/src/consciousness/phi-decisions.js +383 -0
  87. package/dist/src/consciousness/phi-monitor.d.ts +153 -0
  88. package/dist/src/consciousness/phi-monitor.js +465 -0
  89. package/dist/src/consciousness/types.d.ts +260 -0
  90. package/dist/src/consciousness/types.js +44 -0
  91. package/dist/src/daemon/dream-mode.d.ts +115 -0
  92. package/dist/src/daemon/dream-mode.js +470 -0
  93. package/dist/src/daemon/index.d.ts +162 -0
  94. package/dist/src/daemon/index.js +542 -0
  95. package/dist/src/daemon/maintenance.d.ts +139 -0
  96. package/dist/src/daemon/maintenance.js +549 -0
  97. package/dist/src/daemon/process.d.ts +82 -0
  98. package/dist/src/daemon/process.js +442 -0
  99. package/dist/src/daemon/scheduler.d.ts +90 -0
  100. package/dist/src/daemon/scheduler.js +494 -0
  101. package/dist/src/daemon/types.d.ts +213 -0
  102. package/dist/src/daemon/types.js +50 -0
  103. package/dist/src/epistemic/index.d.ts +74 -0
  104. package/dist/src/epistemic/index.js +225 -0
  105. package/dist/src/grounding/epistemic-stack.d.ts +100 -0
  106. package/dist/src/grounding/epistemic-stack.js +408 -0
  107. package/dist/src/grounding/feedback.d.ts +98 -0
  108. package/dist/src/grounding/feedback.js +276 -0
  109. package/dist/src/grounding/index.d.ts +123 -0
  110. package/dist/src/grounding/index.js +224 -0
  111. package/dist/src/grounding/verifier.d.ts +149 -0
  112. package/dist/src/grounding/verifier.js +484 -0
  113. package/dist/src/healing/detector.d.ts +110 -0
  114. package/dist/src/healing/detector.js +436 -0
  115. package/dist/src/healing/fixer.d.ts +138 -0
  116. package/dist/src/healing/fixer.js +572 -0
  117. package/dist/src/healing/index.d.ts +23 -0
  118. package/dist/src/healing/index.js +43 -0
  119. package/dist/src/hooks/index.d.ts +135 -0
  120. package/dist/src/hooks/index.js +317 -0
  121. package/dist/src/index.d.ts +23 -0
  122. package/dist/src/index.js +1266 -0
  123. package/dist/src/kernel/index.d.ts +155 -0
  124. package/dist/src/kernel/index.js +795 -0
  125. package/dist/src/kernel/invariants.d.ts +153 -0
  126. package/dist/src/kernel/invariants.js +355 -0
  127. package/dist/src/kernel/test-kernel.d.ts +6 -0
  128. package/dist/src/kernel/test-kernel.js +108 -0
  129. package/dist/src/kernel/test-real-mcp.d.ts +10 -0
  130. package/dist/src/kernel/test-real-mcp.js +295 -0
  131. package/dist/src/llm/index.d.ts +146 -0
  132. package/dist/src/llm/index.js +428 -0
  133. package/dist/src/llm/router.d.ts +136 -0
  134. package/dist/src/llm/router.js +510 -0
  135. package/dist/src/mcp/index.d.ts +85 -0
  136. package/dist/src/mcp/index.js +657 -0
  137. package/dist/src/mcp/resilient.d.ts +139 -0
  138. package/dist/src/mcp/resilient.js +417 -0
  139. package/dist/src/memory/cache.d.ts +118 -0
  140. package/dist/src/memory/cache.js +356 -0
  141. package/dist/src/memory/cognitive-workspace.d.ts +231 -0
  142. package/dist/src/memory/cognitive-workspace.js +521 -0
  143. package/dist/src/memory/consolidation.d.ts +99 -0
  144. package/dist/src/memory/consolidation.js +443 -0
  145. package/dist/src/memory/episodic.d.ts +114 -0
  146. package/dist/src/memory/episodic.js +394 -0
  147. package/dist/src/memory/forgetting.d.ts +134 -0
  148. package/dist/src/memory/forgetting.js +324 -0
  149. package/dist/src/memory/index.d.ts +211 -0
  150. package/dist/src/memory/index.js +367 -0
  151. package/dist/src/memory/indexer.d.ts +123 -0
  152. package/dist/src/memory/indexer.js +479 -0
  153. package/dist/src/memory/procedural.d.ts +136 -0
  154. package/dist/src/memory/procedural.js +479 -0
  155. package/dist/src/memory/semantic.d.ts +132 -0
  156. package/dist/src/memory/semantic.js +497 -0
  157. package/dist/src/memory/types.d.ts +193 -0
  158. package/dist/src/memory/types.js +15 -0
  159. package/dist/src/orchestrator.d.ts +65 -0
  160. package/dist/src/orchestrator.js +317 -0
  161. package/dist/src/persistence/index.d.ts +257 -0
  162. package/dist/src/persistence/index.js +763 -0
  163. package/dist/src/pipeline/executor.d.ts +51 -0
  164. package/dist/src/pipeline/executor.js +695 -0
  165. package/dist/src/pipeline/index.d.ts +7 -0
  166. package/dist/src/pipeline/index.js +11 -0
  167. package/dist/src/self-production.d.ts +67 -0
  168. package/dist/src/self-production.js +205 -0
  169. package/dist/src/subagents/executor.d.ts +58 -0
  170. package/dist/src/subagents/executor.js +283 -0
  171. package/dist/src/subagents/index.d.ts +37 -0
  172. package/dist/src/subagents/index.js +53 -0
  173. package/dist/src/subagents/registry.d.ts +23 -0
  174. package/dist/src/subagents/registry.js +167 -0
  175. package/dist/src/subagents/types.d.ts +79 -0
  176. package/dist/src/subagents/types.js +14 -0
  177. package/dist/src/tools/bash.d.ts +139 -0
  178. package/dist/src/tools/bash.js +583 -0
  179. package/dist/src/tools/edit.d.ts +125 -0
  180. package/dist/src/tools/edit.js +424 -0
  181. package/dist/src/tools/git.d.ts +179 -0
  182. package/dist/src/tools/git.js +504 -0
  183. package/dist/src/tools/index.d.ts +21 -0
  184. package/dist/src/tools/index.js +163 -0
  185. package/dist/src/types.d.ts +145 -0
  186. package/dist/src/types.js +7 -0
  187. package/dist/src/world-model/decoder.d.ts +163 -0
  188. package/dist/src/world-model/decoder.js +517 -0
  189. package/dist/src/world-model/digital-twin.d.ts +219 -0
  190. package/dist/src/world-model/digital-twin.js +695 -0
  191. package/dist/src/world-model/encoder.d.ts +141 -0
  192. package/dist/src/world-model/encoder.js +564 -0
  193. package/dist/src/world-model/index.d.ts +221 -0
  194. package/dist/src/world-model/index.js +772 -0
  195. package/dist/src/world-model/predictor.d.ts +161 -0
  196. package/dist/src/world-model/predictor.js +681 -0
  197. package/dist/src/world-model/test-value-jepa.d.ts +8 -0
  198. package/dist/src/world-model/test-value-jepa.js +430 -0
  199. package/dist/src/world-model/types.d.ts +341 -0
  200. package/dist/src/world-model/types.js +69 -0
  201. package/dist/src/world-model/value-jepa.d.ts +247 -0
  202. package/dist/src/world-model/value-jepa.js +622 -0
  203. package/dist/test/brain.test.d.ts +11 -0
  204. package/dist/test/brain.test.js +358 -0
  205. package/dist/test/cli/dispatcher.test.d.ts +4 -0
  206. package/dist/test/cli/dispatcher.test.js +332 -0
  207. package/dist/test/cli/human-loop.test.d.ts +4 -0
  208. package/dist/test/cli/human-loop.test.js +270 -0
  209. package/dist/test/grounding/feedback.test.d.ts +4 -0
  210. package/dist/test/grounding/feedback.test.js +462 -0
  211. package/dist/test/grounding/verifier.test.d.ts +4 -0
  212. package/dist/test/grounding/verifier.test.js +442 -0
  213. package/dist/test/grounding.test.d.ts +6 -0
  214. package/dist/test/grounding.test.js +246 -0
  215. package/dist/test/healing/detector.test.d.ts +4 -0
  216. package/dist/test/healing/detector.test.js +266 -0
  217. package/dist/test/healing/fixer.test.d.ts +4 -0
  218. package/dist/test/healing/fixer.test.js +369 -0
  219. package/dist/test/integration.test.d.ts +5 -0
  220. package/dist/test/integration.test.js +290 -0
  221. package/dist/test/tools/bash.test.d.ts +4 -0
  222. package/dist/test/tools/bash.test.js +348 -0
  223. package/dist/test/tools/edit.test.d.ts +4 -0
  224. package/dist/test/tools/edit.test.js +350 -0
  225. package/dist/test/tools/git.test.d.ts +4 -0
  226. package/dist/test/tools/git.test.js +350 -0
  227. package/package.json +60 -0
@@ -0,0 +1,657 @@
1
+ "use strict";
2
+ /**
3
+ * Genesis 6.8 - Real MCP Client Module
4
+ *
5
+ * Connects to actual MCP servers using @modelcontextprotocol/sdk.
6
+ * Spawns servers on demand and manages connections.
7
+ *
8
+ * Environment Variables:
9
+ * - GENESIS_MCP_MODE: 'real' | 'simulated' | 'hybrid' (default: 'simulated')
10
+ * - GENESIS_MCP_TIMEOUT: Timeout in ms (default: 30000)
11
+ * - GENESIS_MCP_LOG: Enable MCP call logging (default: false)
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
25
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.MCP_SERVER_REGISTRY = exports.mcpClient = void 0;
29
+ exports.getMCPClient = getMCPClient;
30
+ exports.resetMCPClient = resetMCPClient;
31
+ exports.isSimulatedMode = isSimulatedMode;
32
+ exports.isSimulatedResult = isSimulatedResult;
33
+ exports.logMCPMode = logMCPMode;
34
+ // Re-export Phase 8: Resilient MCP Wrapper
35
+ __exportStar(require("./resilient.js"), exports);
36
+ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
37
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
38
+ const crypto_1 = require("crypto");
39
+ /**
40
+ * Registry of MCP servers and how to spawn them.
41
+ * These are the 13 MCP servers Genesis uses.
42
+ *
43
+ * Package sources (verified on npm):
44
+ * - Official: @modelcontextprotocol/server-*
45
+ * - Third-party: arxiv-mcp-server, @brave/brave-search-mcp-server, etc.
46
+ */
47
+ const MCP_SERVER_REGISTRY = {
48
+ // KNOWLEDGE
49
+ 'arxiv': {
50
+ command: 'npx',
51
+ args: ['-y', '@iflow-mcp/arxiv-paper-mcp@latest'],
52
+ tools: ['search_arxiv', 'parse_paper_content', 'get_recent_ai_papers', 'get_arxiv_pdf_url'],
53
+ },
54
+ 'semantic-scholar': {
55
+ command: 'npx',
56
+ args: ['-y', 'researchmcp', 'semantic'],
57
+ tools: ['search_semantic_scholar', 'get_semantic_scholar_paper', 'get_paper_citations', 'semantic_scholar_to_bibtex'],
58
+ },
59
+ 'context7': {
60
+ command: 'npx',
61
+ args: ['-y', '@upstash/context7-mcp@latest'],
62
+ tools: ['resolve-library-id', 'query-docs'],
63
+ },
64
+ 'wolfram': {
65
+ command: 'npx',
66
+ args: ['-y', 'wolfram-mcp'],
67
+ envVars: () => ({ WOLFRAM_APP_ID: process.env.WOLFRAM_APP_ID || '' }),
68
+ tools: ['wolfram_query'],
69
+ },
70
+ // RESEARCH
71
+ 'gemini': {
72
+ command: 'npx',
73
+ args: ['-y', 'mcp-gemini-web'],
74
+ envVars: () => ({ GOOGLE_API_KEY: process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY || '' }),
75
+ tools: ['web_search', 'web_search_batch', 'health_check'],
76
+ },
77
+ 'brave-search': {
78
+ command: 'npx',
79
+ args: () => ['-y', '@brave/brave-search-mcp-server', '--brave-api-key', process.env.BRAVE_API_KEY || ''],
80
+ tools: ['brave_web_search', 'brave_local_search', 'brave_news_search', 'brave_image_search', 'brave_video_search'],
81
+ },
82
+ 'exa': {
83
+ command: 'npx',
84
+ args: ['-y', 'exa-mcp-server'],
85
+ envVars: () => ({ EXA_API_KEY: process.env.EXA_API_KEY || '' }),
86
+ tools: ['web_search_exa', 'get_code_context_exa'],
87
+ },
88
+ 'firecrawl': {
89
+ command: 'npx',
90
+ args: ['-y', 'firecrawl-mcp'],
91
+ envVars: () => ({ FIRECRAWL_API_KEY: process.env.FIRECRAWL_API_KEY || '' }),
92
+ tools: ['firecrawl_scrape', 'firecrawl_search', 'firecrawl_map', 'firecrawl_crawl', 'firecrawl_extract'],
93
+ },
94
+ // CREATION
95
+ 'openai': {
96
+ command: 'npx',
97
+ args: ['-y', '@mzxrai/mcp-openai'],
98
+ envVars: () => ({ OPENAI_API_KEY: process.env.OPENAI_API_KEY || '' }),
99
+ tools: ['openai_chat'],
100
+ },
101
+ 'github': {
102
+ command: 'npx',
103
+ args: ['-y', '@modelcontextprotocol/server-github'],
104
+ // v7.3: Accept both variable names for compatibility
105
+ envVars: () => ({
106
+ GITHUB_PERSONAL_ACCESS_TOKEN: process.env.GITHUB_PERSONAL_ACCESS_TOKEN || process.env.GITHUB_TOKEN || ''
107
+ }),
108
+ tools: ['create_repository', 'search_repositories', 'create_issue', 'create_pull_request', 'get_file_contents'],
109
+ },
110
+ // VISUAL
111
+ 'stability-ai': {
112
+ command: 'npx',
113
+ args: ['-y', 'mcp-server-stability-ai'],
114
+ envVars: () => ({ STABILITY_AI_API_KEY: process.env.STABILITY_AI_API_KEY || '' }),
115
+ tools: ['stability-ai-generate-image', 'stability-ai-generate-image-sd35', 'stability-ai-0-list-resources'],
116
+ },
117
+ // STORAGE
118
+ 'memory': {
119
+ command: 'npx',
120
+ args: ['-y', '@modelcontextprotocol/server-memory'],
121
+ tools: ['create_entities', 'create_relations', 'search_nodes', 'read_graph', 'add_observations'],
122
+ },
123
+ 'filesystem': {
124
+ command: 'npx',
125
+ args: () => ['-y', '@modelcontextprotocol/server-filesystem', process.env.HOME || '/tmp'],
126
+ tools: ['read_file', 'read_text_file', 'write_file', 'list_directory', 'search_files', 'create_directory'],
127
+ },
128
+ };
129
+ exports.MCP_SERVER_REGISTRY = MCP_SERVER_REGISTRY;
130
+ class MCPConnectionManager {
131
+ connections = new Map();
132
+ connecting = new Map();
133
+ timeout;
134
+ logCalls;
135
+ constructor(timeout = 30000, logCalls = false) {
136
+ this.timeout = timeout;
137
+ this.logCalls = logCalls;
138
+ }
139
+ /**
140
+ * Get or create connection to MCP server
141
+ */
142
+ async getConnection(server) {
143
+ // Return existing connection if available
144
+ const existing = this.connections.get(server);
145
+ if (existing?.connected) {
146
+ existing.lastUsed = new Date();
147
+ return existing;
148
+ }
149
+ // Check if already connecting
150
+ const pending = this.connecting.get(server);
151
+ if (pending) {
152
+ return pending;
153
+ }
154
+ // Create new connection
155
+ const connectPromise = this.createConnection(server);
156
+ this.connecting.set(server, connectPromise);
157
+ try {
158
+ const connection = await connectPromise;
159
+ this.connections.set(server, connection);
160
+ return connection;
161
+ }
162
+ finally {
163
+ this.connecting.delete(server);
164
+ }
165
+ }
166
+ /**
167
+ * Create new connection to MCP server
168
+ */
169
+ async createConnection(server) {
170
+ const serverInfo = MCP_SERVER_REGISTRY[server];
171
+ if (!serverInfo) {
172
+ throw new Error(`Unknown MCP server: ${server}`);
173
+ }
174
+ // v7.3: Check required API keys before spawning
175
+ const missingKey = this.checkRequiredKeys(server);
176
+ if (missingKey) {
177
+ throw new Error(`MCP server '${server}' requires ${missingKey} to be set. Please add it to your .env file.`);
178
+ }
179
+ // Resolve args and envVars at connection time (supports functions for dynamic values)
180
+ const args = typeof serverInfo.args === 'function' ? serverInfo.args() : serverInfo.args;
181
+ const envVars = typeof serverInfo.envVars === 'function' ? serverInfo.envVars() : serverInfo.envVars;
182
+ if (this.logCalls) {
183
+ console.log(`[MCP] Spawning ${server}: ${serverInfo.command} ${args.join(' ')}`);
184
+ }
185
+ const client = new index_js_1.Client({
186
+ name: `genesis-${server}`,
187
+ version: '6.0.0',
188
+ });
189
+ // Build environment, filtering out undefined values
190
+ const env = {};
191
+ for (const [key, value] of Object.entries(process.env)) {
192
+ if (value !== undefined) {
193
+ env[key] = value;
194
+ }
195
+ }
196
+ if (envVars) {
197
+ Object.assign(env, envVars);
198
+ }
199
+ const transport = new stdio_js_1.StdioClientTransport({
200
+ command: serverInfo.command,
201
+ args,
202
+ env,
203
+ });
204
+ await client.connect(transport);
205
+ if (this.logCalls) {
206
+ console.log(`[MCP] Connected to ${server}`);
207
+ }
208
+ return {
209
+ client,
210
+ transport,
211
+ connected: true,
212
+ lastUsed: new Date(),
213
+ };
214
+ }
215
+ /**
216
+ * Call a tool on an MCP server
217
+ */
218
+ async callTool(server, tool, args) {
219
+ const connection = await this.getConnection(server);
220
+ if (this.logCalls) {
221
+ console.log(`[MCP] ${server}.${tool}(${JSON.stringify(args).slice(0, 100)}...)`);
222
+ }
223
+ const result = await connection.client.callTool({
224
+ name: tool,
225
+ arguments: args,
226
+ });
227
+ // Parse result content
228
+ const content = result.content;
229
+ if (content && content.length > 0) {
230
+ const first = content[0];
231
+ if (first.type === 'text' && typeof first.text === 'string') {
232
+ try {
233
+ return JSON.parse(first.text);
234
+ }
235
+ catch {
236
+ return first.text;
237
+ }
238
+ }
239
+ }
240
+ return result;
241
+ }
242
+ /**
243
+ * List available tools on an MCP server (names only)
244
+ */
245
+ async listTools(server) {
246
+ const connection = await this.getConnection(server);
247
+ const result = await connection.client.listTools();
248
+ return result.tools.map((t) => t.name);
249
+ }
250
+ /**
251
+ * List available tools with full schema (for dynamic prompt building)
252
+ */
253
+ async listToolsWithSchema(server) {
254
+ const connection = await this.getConnection(server);
255
+ const result = await connection.client.listTools();
256
+ return result.tools.map((t) => ({
257
+ name: t.name,
258
+ description: t.description,
259
+ inputSchema: t.inputSchema,
260
+ }));
261
+ }
262
+ /**
263
+ * Check if a server is available (can connect)
264
+ */
265
+ async isAvailable(server) {
266
+ try {
267
+ await this.getConnection(server);
268
+ return true;
269
+ }
270
+ catch {
271
+ return false;
272
+ }
273
+ }
274
+ /**
275
+ * Close connection to a server
276
+ */
277
+ async closeConnection(server) {
278
+ const connection = this.connections.get(server);
279
+ if (connection) {
280
+ try {
281
+ await connection.client.close();
282
+ }
283
+ catch {
284
+ // Ignore close errors
285
+ }
286
+ connection.connected = false;
287
+ this.connections.delete(server);
288
+ }
289
+ }
290
+ /**
291
+ * Close all connections
292
+ */
293
+ async closeAll() {
294
+ const servers = Array.from(this.connections.keys());
295
+ await Promise.all(servers.map((s) => this.closeConnection(s)));
296
+ }
297
+ /**
298
+ * v7.3: Check if required API keys are set for a server
299
+ * Returns the name of the missing key, or null if all keys are present
300
+ */
301
+ checkRequiredKeys(server) {
302
+ // Map of servers to their required environment variables
303
+ const requiredKeys = {
304
+ 'wolfram': ['WOLFRAM_APP_ID'],
305
+ 'brave-search': ['BRAVE_API_KEY'],
306
+ 'exa': ['EXA_API_KEY'],
307
+ 'firecrawl': ['FIRECRAWL_API_KEY'],
308
+ 'openai': ['OPENAI_API_KEY'],
309
+ 'github': ['GITHUB_PERSONAL_ACCESS_TOKEN', 'GITHUB_TOKEN'], // Either one
310
+ 'stability-ai': ['STABILITY_AI_API_KEY'],
311
+ 'gemini': ['GOOGLE_API_KEY', 'GEMINI_API_KEY'], // Either one
312
+ // These don't need API keys:
313
+ // 'arxiv', 'semantic-scholar', 'context7', 'memory', 'filesystem'
314
+ };
315
+ const keys = requiredKeys[server];
316
+ if (!keys)
317
+ return null; // No required keys
318
+ // For servers that accept either of multiple keys (like github, gemini)
319
+ // Check if at least one is set
320
+ const hasAtLeastOne = keys.some(key => !!process.env[key]);
321
+ if (!hasAtLeastOne) {
322
+ return keys.join(' or ');
323
+ }
324
+ return null; // All required keys present
325
+ }
326
+ }
327
+ // ============================================================================
328
+ // Real MCP Client
329
+ // ============================================================================
330
+ class RealMCPClient {
331
+ manager;
332
+ mode = 'real';
333
+ config;
334
+ constructor(config = {}) {
335
+ this.config = {
336
+ mode: 'real',
337
+ timeout: 30000,
338
+ logCalls: false,
339
+ ...config,
340
+ };
341
+ this.mode = this.config.mode;
342
+ this.manager = new MCPConnectionManager(this.config.timeout, this.config.logCalls);
343
+ }
344
+ async call(server, tool, params, options = {}) {
345
+ const startTime = Date.now();
346
+ if (this.config.onCall) {
347
+ this.config.onCall(server, tool, params);
348
+ }
349
+ try {
350
+ const data = await this.manager.callTool(server, tool, params);
351
+ const result = {
352
+ success: true,
353
+ data,
354
+ server,
355
+ tool,
356
+ mode: 'real',
357
+ latency: Date.now() - startTime,
358
+ timestamp: new Date(),
359
+ };
360
+ if (this.config.onResult) {
361
+ this.config.onResult(result);
362
+ }
363
+ return result;
364
+ }
365
+ catch (error) {
366
+ const result = {
367
+ success: false,
368
+ error: error instanceof Error ? error.message : String(error),
369
+ server,
370
+ tool,
371
+ mode: 'real',
372
+ latency: Date.now() - startTime,
373
+ timestamp: new Date(),
374
+ };
375
+ if (this.config.onResult) {
376
+ this.config.onResult(result);
377
+ }
378
+ return result;
379
+ }
380
+ }
381
+ async listTools(server) {
382
+ return this.manager.listTools(server);
383
+ }
384
+ async listToolsWithSchema(server) {
385
+ return this.manager.listToolsWithSchema(server);
386
+ }
387
+ async discoverAllTools() {
388
+ const result = {};
389
+ const servers = Object.keys(MCP_SERVER_REGISTRY);
390
+ // Discover tools from all servers in parallel
391
+ await Promise.allSettled(servers.map(async (server) => {
392
+ try {
393
+ result[server] = await this.listToolsWithSchema(server);
394
+ }
395
+ catch {
396
+ // Server not available, use registry fallback
397
+ result[server] = MCP_SERVER_REGISTRY[server].tools.map(name => ({ name }));
398
+ }
399
+ }));
400
+ return result;
401
+ }
402
+ async isAvailable(server) {
403
+ return this.manager.isAvailable(server);
404
+ }
405
+ getMode() {
406
+ return this.mode;
407
+ }
408
+ setMode(mode) {
409
+ this.mode = mode;
410
+ }
411
+ async close() {
412
+ await this.manager.closeAll();
413
+ }
414
+ }
415
+ // ============================================================================
416
+ // Simulated MCP Client (for testing without real servers)
417
+ // ============================================================================
418
+ class SimulatedMCPClient {
419
+ mode = 'simulated';
420
+ config;
421
+ constructor(config = {}) {
422
+ this.config = {
423
+ mode: 'simulated',
424
+ timeout: 30000,
425
+ logCalls: false,
426
+ ...config,
427
+ };
428
+ this.mode = this.config.mode;
429
+ }
430
+ async call(server, tool, params, options = {}) {
431
+ const startTime = Date.now();
432
+ if (this.config.onCall) {
433
+ this.config.onCall(server, tool, params);
434
+ }
435
+ if (this.config.logCalls) {
436
+ console.log(`[MCP:SIM] ${server}.${tool}(${JSON.stringify(params).slice(0, 100)}...)`);
437
+ }
438
+ // Simulate latency
439
+ await new Promise((r) => setTimeout(r, 50 + Math.random() * 150));
440
+ const data = this.generateSimulatedResponse(server, tool, params);
441
+ const result = {
442
+ success: true,
443
+ data,
444
+ server,
445
+ tool,
446
+ mode: 'simulated',
447
+ latency: Date.now() - startTime,
448
+ timestamp: new Date(),
449
+ };
450
+ if (this.config.onResult) {
451
+ this.config.onResult(result);
452
+ }
453
+ return result;
454
+ }
455
+ async listTools(server) {
456
+ return MCP_SERVER_REGISTRY[server]?.tools || [];
457
+ }
458
+ async listToolsWithSchema(server) {
459
+ // In simulated mode, return basic tool info from registry
460
+ const tools = MCP_SERVER_REGISTRY[server]?.tools || [];
461
+ return tools.map(name => ({
462
+ name,
463
+ description: `[Simulated] ${name} tool`,
464
+ }));
465
+ }
466
+ async discoverAllTools() {
467
+ const result = {};
468
+ const servers = Object.keys(MCP_SERVER_REGISTRY);
469
+ for (const server of servers) {
470
+ result[server] = await this.listToolsWithSchema(server);
471
+ }
472
+ return result;
473
+ }
474
+ async isAvailable(server) {
475
+ return true; // Always available in simulated mode
476
+ }
477
+ getMode() {
478
+ return this.mode;
479
+ }
480
+ setMode(mode) {
481
+ this.mode = mode;
482
+ }
483
+ async close() {
484
+ // No-op for simulated
485
+ }
486
+ generateSimulatedResponse(server, tool, params) {
487
+ const query = params.query || params.q || params.input || 'query';
488
+ switch (server) {
489
+ case 'arxiv':
490
+ return {
491
+ papers: [{
492
+ id: 'arxiv:' + (0, crypto_1.randomUUID)().slice(0, 8),
493
+ title: `[SIM] Research on ${query}`,
494
+ authors: ['Author A', 'Author B'],
495
+ abstract: `Simulated paper about ${query}.`,
496
+ url: `https://arxiv.org/abs/${(0, crypto_1.randomUUID)().slice(0, 8)}`,
497
+ }],
498
+ _simulated: true,
499
+ };
500
+ case 'semantic-scholar':
501
+ return {
502
+ papers: [{
503
+ paperId: (0, crypto_1.randomUUID)().slice(0, 8),
504
+ title: `[SIM] ${query} Study`,
505
+ citationCount: Math.floor(Math.random() * 100),
506
+ }],
507
+ _simulated: true,
508
+ };
509
+ case 'brave-search':
510
+ case 'gemini':
511
+ case 'exa':
512
+ return {
513
+ results: [{
514
+ title: `[SIM] ${query} Result`,
515
+ url: 'https://example.com/sim',
516
+ description: `Simulated result for ${query}`,
517
+ }],
518
+ _simulated: true,
519
+ };
520
+ case 'firecrawl':
521
+ return {
522
+ content: `[SIM] Scraped content for ${params.url || query}`,
523
+ _simulated: true,
524
+ };
525
+ case 'memory':
526
+ return { entities: [], relations: [], _simulated: true };
527
+ case 'filesystem':
528
+ return { content: `[SIM] File content`, _simulated: true };
529
+ default:
530
+ return { success: true, _simulated: true };
531
+ }
532
+ }
533
+ }
534
+ // ============================================================================
535
+ // Hybrid MCP Client
536
+ // ============================================================================
537
+ class HybridMCPClient {
538
+ realClient;
539
+ simClient;
540
+ mode = 'hybrid';
541
+ config;
542
+ constructor(config = {}) {
543
+ this.config = {
544
+ mode: 'hybrid',
545
+ timeout: 30000,
546
+ logCalls: false,
547
+ ...config,
548
+ };
549
+ this.realClient = new RealMCPClient(config);
550
+ this.simClient = new SimulatedMCPClient(config);
551
+ }
552
+ async call(server, tool, params, options = {}) {
553
+ // Try real first
554
+ const result = await this.realClient.call(server, tool, params, options);
555
+ // Fallback to simulated if real fails
556
+ if (!result.success && (options.fallbackToSimulated ?? true)) {
557
+ if (this.config.logCalls) {
558
+ console.log(`[MCP] Real call failed, falling back to simulated: ${result.error}`);
559
+ }
560
+ return this.simClient.call(server, tool, params, options);
561
+ }
562
+ return result;
563
+ }
564
+ async listTools(server) {
565
+ try {
566
+ return await this.realClient.listTools(server);
567
+ }
568
+ catch {
569
+ return this.simClient.listTools(server);
570
+ }
571
+ }
572
+ async listToolsWithSchema(server) {
573
+ try {
574
+ return await this.realClient.listToolsWithSchema(server);
575
+ }
576
+ catch {
577
+ return this.simClient.listToolsWithSchema(server);
578
+ }
579
+ }
580
+ async discoverAllTools() {
581
+ try {
582
+ return await this.realClient.discoverAllTools();
583
+ }
584
+ catch {
585
+ return this.simClient.discoverAllTools();
586
+ }
587
+ }
588
+ async isAvailable(server) {
589
+ return (await this.realClient.isAvailable(server)) ||
590
+ (await this.simClient.isAvailable(server));
591
+ }
592
+ getMode() {
593
+ return this.mode;
594
+ }
595
+ setMode(mode) {
596
+ this.mode = mode;
597
+ }
598
+ async close() {
599
+ await this.realClient.close();
600
+ }
601
+ }
602
+ // ============================================================================
603
+ // Factory & Singleton
604
+ // ============================================================================
605
+ function createMCPClient(config = {}) {
606
+ // v7.0: Default changed from 'simulated' to 'real'
607
+ const mode = process.env.GENESIS_MCP_MODE || config.mode || 'real';
608
+ const timeout = parseInt(process.env.GENESIS_MCP_TIMEOUT || '') || config.timeout || 30000;
609
+ const logCalls = process.env.GENESIS_MCP_LOG === 'true' || config.logCalls || false;
610
+ const fullConfig = {
611
+ ...config,
612
+ mode,
613
+ timeout,
614
+ logCalls,
615
+ };
616
+ // Log mode for transparency
617
+ if (logCalls) {
618
+ console.log(`[MCP] Mode: ${mode} (timeout: ${timeout}ms)`);
619
+ }
620
+ switch (mode) {
621
+ case 'real':
622
+ return new RealMCPClient(fullConfig);
623
+ case 'hybrid':
624
+ return new HybridMCPClient(fullConfig);
625
+ case 'simulated':
626
+ default:
627
+ return new SimulatedMCPClient(fullConfig);
628
+ }
629
+ }
630
+ let mcpClientInstance = null;
631
+ function getMCPClient(config) {
632
+ if (!mcpClientInstance) {
633
+ mcpClientInstance = createMCPClient(config);
634
+ }
635
+ return mcpClientInstance;
636
+ }
637
+ function resetMCPClient() {
638
+ if (mcpClientInstance) {
639
+ mcpClientInstance.close().catch(() => { });
640
+ }
641
+ mcpClientInstance = null;
642
+ }
643
+ exports.mcpClient = getMCPClient();
644
+ // ============================================================================
645
+ // Utilities
646
+ // ============================================================================
647
+ function isSimulatedMode() {
648
+ return exports.mcpClient.getMode() === 'simulated';
649
+ }
650
+ function isSimulatedResult(result) {
651
+ return result.mode === 'simulated' || result.data?._simulated === true;
652
+ }
653
+ function logMCPMode() {
654
+ const mode = exports.mcpClient.getMode();
655
+ const emoji = mode === 'real' ? '🔌' : mode === 'hybrid' ? '🔀' : '🎭';
656
+ console.log(`[Genesis] MCP Mode: ${emoji} ${mode.toUpperCase()}`);
657
+ }