@animus-labs/cortex 0.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 (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/budget-guard.d.ts +75 -0
  4. package/dist/budget-guard.d.ts.map +1 -0
  5. package/dist/budget-guard.js +142 -0
  6. package/dist/budget-guard.js.map +1 -0
  7. package/dist/compaction/compaction.d.ts +99 -0
  8. package/dist/compaction/compaction.d.ts.map +1 -0
  9. package/dist/compaction/compaction.js +302 -0
  10. package/dist/compaction/compaction.js.map +1 -0
  11. package/dist/compaction/failsafe.d.ts +57 -0
  12. package/dist/compaction/failsafe.d.ts.map +1 -0
  13. package/dist/compaction/failsafe.js +135 -0
  14. package/dist/compaction/failsafe.js.map +1 -0
  15. package/dist/compaction/index.d.ts +381 -0
  16. package/dist/compaction/index.d.ts.map +1 -0
  17. package/dist/compaction/index.js +979 -0
  18. package/dist/compaction/index.js.map +1 -0
  19. package/dist/compaction/microcompaction.d.ts +219 -0
  20. package/dist/compaction/microcompaction.d.ts.map +1 -0
  21. package/dist/compaction/microcompaction.js +536 -0
  22. package/dist/compaction/microcompaction.js.map +1 -0
  23. package/dist/compaction/observational/buffering.d.ts +225 -0
  24. package/dist/compaction/observational/buffering.d.ts.map +1 -0
  25. package/dist/compaction/observational/buffering.js +354 -0
  26. package/dist/compaction/observational/buffering.js.map +1 -0
  27. package/dist/compaction/observational/constants.d.ts +70 -0
  28. package/dist/compaction/observational/constants.d.ts.map +1 -0
  29. package/dist/compaction/observational/constants.js +507 -0
  30. package/dist/compaction/observational/constants.js.map +1 -0
  31. package/dist/compaction/observational/index.d.ts +219 -0
  32. package/dist/compaction/observational/index.d.ts.map +1 -0
  33. package/dist/compaction/observational/index.js +641 -0
  34. package/dist/compaction/observational/index.js.map +1 -0
  35. package/dist/compaction/observational/observer.d.ts +97 -0
  36. package/dist/compaction/observational/observer.d.ts.map +1 -0
  37. package/dist/compaction/observational/observer.js +424 -0
  38. package/dist/compaction/observational/observer.js.map +1 -0
  39. package/dist/compaction/observational/recall-tool.d.ts +27 -0
  40. package/dist/compaction/observational/recall-tool.d.ts.map +1 -0
  41. package/dist/compaction/observational/recall-tool.js +93 -0
  42. package/dist/compaction/observational/recall-tool.js.map +1 -0
  43. package/dist/compaction/observational/reflector.d.ts +94 -0
  44. package/dist/compaction/observational/reflector.d.ts.map +1 -0
  45. package/dist/compaction/observational/reflector.js +167 -0
  46. package/dist/compaction/observational/reflector.js.map +1 -0
  47. package/dist/compaction/observational/types.d.ts +271 -0
  48. package/dist/compaction/observational/types.d.ts.map +1 -0
  49. package/dist/compaction/observational/types.js +15 -0
  50. package/dist/compaction/observational/types.js.map +1 -0
  51. package/dist/context-manager.d.ts +134 -0
  52. package/dist/context-manager.d.ts.map +1 -0
  53. package/dist/context-manager.js +170 -0
  54. package/dist/context-manager.js.map +1 -0
  55. package/dist/cortex-agent.d.ts +1020 -0
  56. package/dist/cortex-agent.d.ts.map +1 -0
  57. package/dist/cortex-agent.js +3589 -0
  58. package/dist/cortex-agent.js.map +1 -0
  59. package/dist/error-classifier.d.ts +48 -0
  60. package/dist/error-classifier.d.ts.map +1 -0
  61. package/dist/error-classifier.js +152 -0
  62. package/dist/error-classifier.js.map +1 -0
  63. package/dist/event-bridge.d.ts +166 -0
  64. package/dist/event-bridge.d.ts.map +1 -0
  65. package/dist/event-bridge.js +381 -0
  66. package/dist/event-bridge.js.map +1 -0
  67. package/dist/index.d.ts +55 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +57 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/mcp-client.d.ts +119 -0
  72. package/dist/mcp-client.d.ts.map +1 -0
  73. package/dist/mcp-client.js +474 -0
  74. package/dist/mcp-client.js.map +1 -0
  75. package/dist/model-wrapper.d.ts +58 -0
  76. package/dist/model-wrapper.d.ts.map +1 -0
  77. package/dist/model-wrapper.js +86 -0
  78. package/dist/model-wrapper.js.map +1 -0
  79. package/dist/noop-logger.d.ts +4 -0
  80. package/dist/noop-logger.d.ts.map +1 -0
  81. package/dist/noop-logger.js +8 -0
  82. package/dist/noop-logger.js.map +1 -0
  83. package/dist/prompt-diagnostics.d.ts +47 -0
  84. package/dist/prompt-diagnostics.d.ts.map +1 -0
  85. package/dist/prompt-diagnostics.js +230 -0
  86. package/dist/prompt-diagnostics.js.map +1 -0
  87. package/dist/provider-manager.d.ts +224 -0
  88. package/dist/provider-manager.d.ts.map +1 -0
  89. package/dist/provider-manager.js +563 -0
  90. package/dist/provider-manager.js.map +1 -0
  91. package/dist/provider-registry.d.ts +115 -0
  92. package/dist/provider-registry.d.ts.map +1 -0
  93. package/dist/provider-registry.js +305 -0
  94. package/dist/provider-registry.js.map +1 -0
  95. package/dist/schema-converter.d.ts +20 -0
  96. package/dist/schema-converter.d.ts.map +1 -0
  97. package/dist/schema-converter.js +48 -0
  98. package/dist/schema-converter.js.map +1 -0
  99. package/dist/skill-preprocessor.d.ts +46 -0
  100. package/dist/skill-preprocessor.d.ts.map +1 -0
  101. package/dist/skill-preprocessor.js +237 -0
  102. package/dist/skill-preprocessor.js.map +1 -0
  103. package/dist/skill-registry.d.ts +107 -0
  104. package/dist/skill-registry.d.ts.map +1 -0
  105. package/dist/skill-registry.js +330 -0
  106. package/dist/skill-registry.js.map +1 -0
  107. package/dist/skill-tool.d.ts +54 -0
  108. package/dist/skill-tool.d.ts.map +1 -0
  109. package/dist/skill-tool.js +88 -0
  110. package/dist/skill-tool.js.map +1 -0
  111. package/dist/sub-agent-manager.d.ts +90 -0
  112. package/dist/sub-agent-manager.d.ts.map +1 -0
  113. package/dist/sub-agent-manager.js +192 -0
  114. package/dist/sub-agent-manager.js.map +1 -0
  115. package/dist/token-estimator.d.ts +23 -0
  116. package/dist/token-estimator.d.ts.map +1 -0
  117. package/dist/token-estimator.js +27 -0
  118. package/dist/token-estimator.js.map +1 -0
  119. package/dist/tool-contract.d.ts +68 -0
  120. package/dist/tool-contract.d.ts.map +1 -0
  121. package/dist/tool-contract.js +35 -0
  122. package/dist/tool-contract.js.map +1 -0
  123. package/dist/tool-result-persistence.d.ts +89 -0
  124. package/dist/tool-result-persistence.d.ts.map +1 -0
  125. package/dist/tool-result-persistence.js +152 -0
  126. package/dist/tool-result-persistence.js.map +1 -0
  127. package/dist/tools/bash/index.d.ts +71 -0
  128. package/dist/tools/bash/index.d.ts.map +1 -0
  129. package/dist/tools/bash/index.js +485 -0
  130. package/dist/tools/bash/index.js.map +1 -0
  131. package/dist/tools/bash/interactive.d.ts +47 -0
  132. package/dist/tools/bash/interactive.d.ts.map +1 -0
  133. package/dist/tools/bash/interactive.js +262 -0
  134. package/dist/tools/bash/interactive.js.map +1 -0
  135. package/dist/tools/bash/safety.d.ts +149 -0
  136. package/dist/tools/bash/safety.d.ts.map +1 -0
  137. package/dist/tools/bash/safety.js +1116 -0
  138. package/dist/tools/bash/safety.js.map +1 -0
  139. package/dist/tools/edit.d.ts +57 -0
  140. package/dist/tools/edit.d.ts.map +1 -0
  141. package/dist/tools/edit.js +310 -0
  142. package/dist/tools/edit.js.map +1 -0
  143. package/dist/tools/glob.d.ts +34 -0
  144. package/dist/tools/glob.d.ts.map +1 -0
  145. package/dist/tools/glob.js +268 -0
  146. package/dist/tools/glob.js.map +1 -0
  147. package/dist/tools/grep.d.ts +53 -0
  148. package/dist/tools/grep.d.ts.map +1 -0
  149. package/dist/tools/grep.js +673 -0
  150. package/dist/tools/grep.js.map +1 -0
  151. package/dist/tools/index.d.ts +62 -0
  152. package/dist/tools/index.d.ts.map +1 -0
  153. package/dist/tools/index.js +52 -0
  154. package/dist/tools/index.js.map +1 -0
  155. package/dist/tools/read.d.ts +43 -0
  156. package/dist/tools/read.d.ts.map +1 -0
  157. package/dist/tools/read.js +459 -0
  158. package/dist/tools/read.js.map +1 -0
  159. package/dist/tools/runtime.d.ts +62 -0
  160. package/dist/tools/runtime.d.ts.map +1 -0
  161. package/dist/tools/runtime.js +116 -0
  162. package/dist/tools/runtime.js.map +1 -0
  163. package/dist/tools/shared/cwd-tracker.d.ts +32 -0
  164. package/dist/tools/shared/cwd-tracker.d.ts.map +1 -0
  165. package/dist/tools/shared/cwd-tracker.js +44 -0
  166. package/dist/tools/shared/cwd-tracker.js.map +1 -0
  167. package/dist/tools/shared/edit-history.d.ts +55 -0
  168. package/dist/tools/shared/edit-history.d.ts.map +1 -0
  169. package/dist/tools/shared/edit-history.js +72 -0
  170. package/dist/tools/shared/edit-history.js.map +1 -0
  171. package/dist/tools/shared/edit-matcher.d.ts +83 -0
  172. package/dist/tools/shared/edit-matcher.d.ts.map +1 -0
  173. package/dist/tools/shared/edit-matcher.js +359 -0
  174. package/dist/tools/shared/edit-matcher.js.map +1 -0
  175. package/dist/tools/shared/file-mutation-lock.d.ts +22 -0
  176. package/dist/tools/shared/file-mutation-lock.d.ts.map +1 -0
  177. package/dist/tools/shared/file-mutation-lock.js +35 -0
  178. package/dist/tools/shared/file-mutation-lock.js.map +1 -0
  179. package/dist/tools/shared/gitignore.d.ts +17 -0
  180. package/dist/tools/shared/gitignore.d.ts.map +1 -0
  181. package/dist/tools/shared/gitignore.js +59 -0
  182. package/dist/tools/shared/gitignore.js.map +1 -0
  183. package/dist/tools/shared/pdf-extractor.d.ts +96 -0
  184. package/dist/tools/shared/pdf-extractor.d.ts.map +1 -0
  185. package/dist/tools/shared/pdf-extractor.js +196 -0
  186. package/dist/tools/shared/pdf-extractor.js.map +1 -0
  187. package/dist/tools/shared/read-registry.d.ts +66 -0
  188. package/dist/tools/shared/read-registry.d.ts.map +1 -0
  189. package/dist/tools/shared/read-registry.js +65 -0
  190. package/dist/tools/shared/read-registry.js.map +1 -0
  191. package/dist/tools/shared/safe-env.d.ts +18 -0
  192. package/dist/tools/shared/safe-env.d.ts.map +1 -0
  193. package/dist/tools/shared/safe-env.js +70 -0
  194. package/dist/tools/shared/safe-env.js.map +1 -0
  195. package/dist/tools/sub-agent.d.ts +91 -0
  196. package/dist/tools/sub-agent.d.ts.map +1 -0
  197. package/dist/tools/sub-agent.js +89 -0
  198. package/dist/tools/sub-agent.js.map +1 -0
  199. package/dist/tools/task-output.d.ts +38 -0
  200. package/dist/tools/task-output.d.ts.map +1 -0
  201. package/dist/tools/task-output.js +186 -0
  202. package/dist/tools/task-output.js.map +1 -0
  203. package/dist/tools/tool-search/index.d.ts +40 -0
  204. package/dist/tools/tool-search/index.d.ts.map +1 -0
  205. package/dist/tools/tool-search/index.js +110 -0
  206. package/dist/tools/tool-search/index.js.map +1 -0
  207. package/dist/tools/tool-search/registry.d.ts +82 -0
  208. package/dist/tools/tool-search/registry.d.ts.map +1 -0
  209. package/dist/tools/tool-search/registry.js +238 -0
  210. package/dist/tools/tool-search/registry.js.map +1 -0
  211. package/dist/tools/undo-edit.d.ts +51 -0
  212. package/dist/tools/undo-edit.d.ts.map +1 -0
  213. package/dist/tools/undo-edit.js +231 -0
  214. package/dist/tools/undo-edit.js.map +1 -0
  215. package/dist/tools/web-fetch/cache.d.ts +49 -0
  216. package/dist/tools/web-fetch/cache.d.ts.map +1 -0
  217. package/dist/tools/web-fetch/cache.js +89 -0
  218. package/dist/tools/web-fetch/cache.js.map +1 -0
  219. package/dist/tools/web-fetch/index.d.ts +53 -0
  220. package/dist/tools/web-fetch/index.d.ts.map +1 -0
  221. package/dist/tools/web-fetch/index.js +513 -0
  222. package/dist/tools/web-fetch/index.js.map +1 -0
  223. package/dist/tools/write.d.ts +59 -0
  224. package/dist/tools/write.d.ts.map +1 -0
  225. package/dist/tools/write.js +316 -0
  226. package/dist/tools/write.js.map +1 -0
  227. package/dist/types.d.ts +881 -0
  228. package/dist/types.d.ts.map +1 -0
  229. package/dist/types.js +16 -0
  230. package/dist/types.js.map +1 -0
  231. package/dist/working-tags.d.ts +44 -0
  232. package/dist/working-tags.d.ts.map +1 -0
  233. package/dist/working-tags.js +103 -0
  234. package/dist/working-tags.js.map +1 -0
  235. package/package.json +87 -0
  236. package/src/budget-guard.ts +170 -0
  237. package/src/compaction/compaction.ts +386 -0
  238. package/src/compaction/failsafe.ts +185 -0
  239. package/src/compaction/index.ts +1199 -0
  240. package/src/compaction/microcompaction.ts +709 -0
  241. package/src/compaction/observational/buffering.ts +430 -0
  242. package/src/compaction/observational/constants.ts +532 -0
  243. package/src/compaction/observational/index.ts +837 -0
  244. package/src/compaction/observational/observer.ts +510 -0
  245. package/src/compaction/observational/recall-tool.ts +130 -0
  246. package/src/compaction/observational/reflector.ts +221 -0
  247. package/src/compaction/observational/types.ts +343 -0
  248. package/src/context-manager.ts +237 -0
  249. package/src/cortex-agent.ts +4297 -0
  250. package/src/error-classifier.ts +199 -0
  251. package/src/event-bridge.ts +508 -0
  252. package/src/index.ts +292 -0
  253. package/src/mcp-client.ts +582 -0
  254. package/src/model-wrapper.ts +128 -0
  255. package/src/noop-logger.ts +9 -0
  256. package/src/prompt-diagnostics.ts +296 -0
  257. package/src/provider-manager.ts +823 -0
  258. package/src/provider-registry.ts +386 -0
  259. package/src/schema-converter.ts +51 -0
  260. package/src/skill-preprocessor.ts +314 -0
  261. package/src/skill-registry.ts +378 -0
  262. package/src/skill-tool.ts +130 -0
  263. package/src/sub-agent-manager.ts +236 -0
  264. package/src/token-estimator.ts +26 -0
  265. package/src/tool-contract.ts +113 -0
  266. package/src/tool-result-persistence.ts +197 -0
  267. package/src/tools/bash/index.ts +633 -0
  268. package/src/tools/bash/interactive.ts +302 -0
  269. package/src/tools/bash/safety.ts +1297 -0
  270. package/src/tools/edit.ts +422 -0
  271. package/src/tools/glob.ts +330 -0
  272. package/src/tools/grep.ts +819 -0
  273. package/src/tools/index.ts +110 -0
  274. package/src/tools/read.ts +580 -0
  275. package/src/tools/runtime.ts +173 -0
  276. package/src/tools/shared/cwd-tracker.ts +50 -0
  277. package/src/tools/shared/edit-history.ts +96 -0
  278. package/src/tools/shared/edit-matcher.ts +457 -0
  279. package/src/tools/shared/file-mutation-lock.ts +40 -0
  280. package/src/tools/shared/gitignore.ts +61 -0
  281. package/src/tools/shared/pdf-extractor.ts +290 -0
  282. package/src/tools/shared/read-registry.ts +93 -0
  283. package/src/tools/shared/safe-env.ts +82 -0
  284. package/src/tools/sub-agent.ts +171 -0
  285. package/src/tools/task-output.ts +236 -0
  286. package/src/tools/tool-search/index.ts +167 -0
  287. package/src/tools/tool-search/registry.ts +278 -0
  288. package/src/tools/undo-edit.ts +314 -0
  289. package/src/tools/web-fetch/cache.ts +112 -0
  290. package/src/tools/web-fetch/index.ts +604 -0
  291. package/src/tools/write.ts +385 -0
  292. package/src/types.ts +1057 -0
  293. package/src/working-tags.ts +118 -0
@@ -0,0 +1,474 @@
1
+ /**
2
+ * McpClientManager: connects to MCP servers and wraps discovered tools
3
+ * as AgentTool objects for registration with pi-agent-core.
4
+ *
5
+ * Handles two transport types:
6
+ * - Stdio: spawns a subprocess, communicates via stdin/stdout
7
+ * - HTTP: connects to an already-running Streamable HTTP server
8
+ *
9
+ * Tool discovery via tools/list, tool execution via tools/call.
10
+ * Connections are persistent (kept alive between ticks) with health monitoring.
11
+ * Reconnect on subprocess crash (3 attempts before deregistering).
12
+ *
13
+ * References:
14
+ * - docs/cortex/mcp-integration.md
15
+ * - docs/cortex/plans/phase-3-plugin-tools.md
16
+ */
17
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
18
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
19
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
20
+ import { Type } from 'typebox';
21
+ import { NOOP_LOGGER } from './noop-logger.js';
22
+ import { buildSafeEnv } from './tools/shared/safe-env.js';
23
+ // ---------------------------------------------------------------------------
24
+ // Constants
25
+ // ---------------------------------------------------------------------------
26
+ const MAX_RECONNECT_ATTEMPTS = 3;
27
+ // ---------------------------------------------------------------------------
28
+ // McpClientManager
29
+ // ---------------------------------------------------------------------------
30
+ export class McpClientManager {
31
+ connections = new Map();
32
+ /**
33
+ * Callback invoked whenever the aggregate tool set changes.
34
+ * CortexAgent uses this to resync live tools after connect/disconnect/reconnect.
35
+ */
36
+ onToolsChanged;
37
+ /**
38
+ * Callback invoked when a subprocess is spawned (for PID tracking).
39
+ * The consumer (CortexAgent) uses this to track PIDs for exit cleanup.
40
+ */
41
+ onSubprocessSpawned;
42
+ /**
43
+ * Callback invoked when a subprocess exits (for PID tracking).
44
+ */
45
+ onSubprocessExited;
46
+ /**
47
+ * Consumer-set environment variable overrides that bypass the security blocklist.
48
+ * Merged ON TOP of the sanitized environment for all stdio subprocesses.
49
+ * Used for macOS dock icon suppression vars (DYLD_INSERT_LIBRARIES, etc.).
50
+ */
51
+ envOverrides;
52
+ /** Logger for MCP diagnostics. Set by CortexAgent after construction. */
53
+ logger = NOOP_LOGGER;
54
+ /**
55
+ * Connect to an MCP server and discover its tools.
56
+ *
57
+ * Spawns a subprocess (stdio) or connects to a URL (http), performs
58
+ * the MCP handshake, calls tools/list, and wraps each discovered
59
+ * tool as an AgentTool with namespaced name.
60
+ *
61
+ * @param serverName - Unique name for this server (used for tool namespacing)
62
+ * @param config - Transport configuration
63
+ * @throws Error if connection or tool discovery fails
64
+ */
65
+ async connect(serverName, config) {
66
+ // Disconnect existing connection with this name first
67
+ if (this.connections.has(serverName)) {
68
+ await this.disconnect(serverName);
69
+ }
70
+ this.logger.info('[MCP] connecting', { serverName, transport: config.transport });
71
+ const transport = this.createTransport(config);
72
+ const client = new Client({ name: `cortex-${serverName}`, version: '1.0.0' }, { capabilities: {} });
73
+ try {
74
+ await client.connect(transport);
75
+ }
76
+ catch (err) {
77
+ this.logger.error('[MCP] connection failed', { serverName, error: err instanceof Error ? err.message : String(err) });
78
+ throw new Error(`MCP connection failed for "${serverName}": ${err instanceof Error ? err.message : String(err)}`);
79
+ }
80
+ // Track subprocess PID for stdio transports
81
+ let pid = null;
82
+ if (transport instanceof StdioClientTransport) {
83
+ pid = transport.pid;
84
+ if (pid != null) {
85
+ this.onSubprocessSpawned?.(pid);
86
+ }
87
+ }
88
+ // Discover tools
89
+ let tools;
90
+ try {
91
+ tools = await this.discoverTools(serverName, client);
92
+ }
93
+ catch (err) {
94
+ this.logger.error('[MCP] tool discovery failed', { serverName, error: err instanceof Error ? err.message : String(err) });
95
+ // Close the connection since tool discovery failed
96
+ try {
97
+ await client.close();
98
+ }
99
+ catch {
100
+ // Best-effort cleanup
101
+ }
102
+ if (pid != null) {
103
+ this.onSubprocessExited?.(pid);
104
+ }
105
+ throw new Error(`MCP tool discovery failed for "${serverName}": ${err instanceof Error ? err.message : String(err)}`);
106
+ }
107
+ const connection = {
108
+ serverName,
109
+ config,
110
+ client,
111
+ transport,
112
+ tools,
113
+ connected: true,
114
+ reconnectAttempts: 0,
115
+ pid,
116
+ };
117
+ // Wire close handler for reconnect on unexpected disconnect
118
+ transport.onclose = () => {
119
+ this.handleDisconnect(serverName);
120
+ };
121
+ this.connections.set(serverName, connection);
122
+ this.logger.info('[MCP] connected', { serverName, toolCount: tools.length, tools: tools.map(t => t.name) });
123
+ this.onToolsChanged?.();
124
+ }
125
+ /**
126
+ * Disconnect from a specific MCP server.
127
+ * Closes the transport and removes all tools from that server.
128
+ *
129
+ * @param serverName - The server name to disconnect
130
+ */
131
+ async disconnect(serverName) {
132
+ const conn = this.connections.get(serverName);
133
+ if (!conn)
134
+ return;
135
+ this.logger.info('[MCP] disconnecting', { serverName });
136
+ conn.connected = false;
137
+ try {
138
+ await conn.client.close();
139
+ }
140
+ catch (err) {
141
+ this.logger.warn('[MCP] error closing client', { serverName, error: err instanceof Error ? err.message : String(err) });
142
+ }
143
+ if (conn.pid != null) {
144
+ this.onSubprocessExited?.(conn.pid);
145
+ }
146
+ this.connections.delete(serverName);
147
+ this.onToolsChanged?.();
148
+ }
149
+ /**
150
+ * Close all MCP connections.
151
+ * Kills all stdio subprocesses and closes HTTP connections.
152
+ */
153
+ async closeAll() {
154
+ const names = [...this.connections.keys()];
155
+ const results = await Promise.allSettled(names.map(name => this.disconnect(name)));
156
+ for (let i = 0; i < results.length; i++) {
157
+ const result = results[i];
158
+ if (result.status === 'rejected') {
159
+ this.logger.warn('[MCP] failed to disconnect', { serverName: names[i], error: String(result.reason) });
160
+ }
161
+ }
162
+ }
163
+ /**
164
+ * Get all AgentTool objects from all connected MCP servers.
165
+ * Returns tools namespaced as serverName__toolName.
166
+ */
167
+ getTools() {
168
+ const allTools = [];
169
+ for (const conn of this.connections.values()) {
170
+ if (conn.connected) {
171
+ allTools.push(...conn.tools);
172
+ }
173
+ }
174
+ return allTools;
175
+ }
176
+ /**
177
+ * Get tool names from a specific server.
178
+ */
179
+ getServerToolNames(serverName) {
180
+ const conn = this.connections.get(serverName);
181
+ if (!conn || !conn.connected)
182
+ return [];
183
+ return conn.tools.map(t => t.name);
184
+ }
185
+ /**
186
+ * Get the connection state for all servers.
187
+ */
188
+ getConnectionStates() {
189
+ const states = [];
190
+ for (const conn of this.connections.values()) {
191
+ states.push({
192
+ serverName: conn.serverName,
193
+ config: conn.config,
194
+ connected: conn.connected,
195
+ reconnectAttempts: conn.reconnectAttempts,
196
+ toolNames: conn.tools.map(t => t.name),
197
+ });
198
+ }
199
+ return states;
200
+ }
201
+ /**
202
+ * Check if a specific server is connected.
203
+ */
204
+ isConnected(serverName) {
205
+ const conn = this.connections.get(serverName);
206
+ return conn?.connected ?? false;
207
+ }
208
+ /**
209
+ * Get the number of active connections.
210
+ */
211
+ get connectionCount() {
212
+ let count = 0;
213
+ for (const conn of this.connections.values()) {
214
+ if (conn.connected)
215
+ count++;
216
+ }
217
+ return count;
218
+ }
219
+ // -----------------------------------------------------------------------
220
+ // Private: Transport creation
221
+ // -----------------------------------------------------------------------
222
+ createTransport(config) {
223
+ if (config.transport === 'stdio') {
224
+ return this.createStdioTransport(config);
225
+ }
226
+ return this.createHttpTransport(config);
227
+ }
228
+ createStdioTransport(config) {
229
+ // Sanitize environment variables for the subprocess.
230
+ // Strip dangerous vars (LD_PRELOAD, NODE_OPTIONS, etc.) to prevent
231
+ // injection via environment. Uses the same blocklist as the Bash tool.
232
+ // envOverrides are merged ON TOP, bypassing the blocklist for
233
+ // consumer-specified variables (e.g., macOS dock icon suppression).
234
+ const baseEnv = config.env ?? process.env;
235
+ const safeEnv = buildSafeEnv(baseEnv, undefined, this.envOverrides);
236
+ // Build params object, only including defined optional fields to satisfy
237
+ // exactOptionalPropertyTypes
238
+ const params = {
239
+ command: config.command,
240
+ args: config.args ?? [],
241
+ env: safeEnv,
242
+ stderr: 'pipe',
243
+ };
244
+ if (config.cwd !== undefined)
245
+ params.cwd = config.cwd;
246
+ return new StdioClientTransport(params);
247
+ }
248
+ createHttpTransport(config) {
249
+ const url = new URL(config.url);
250
+ if (config.headers && Object.keys(config.headers).length > 0) {
251
+ return new StreamableHTTPClientTransport(url, {
252
+ requestInit: {
253
+ headers: config.headers,
254
+ },
255
+ });
256
+ }
257
+ return new StreamableHTTPClientTransport(url);
258
+ }
259
+ // -----------------------------------------------------------------------
260
+ // Private: Tool discovery and wrapping
261
+ // -----------------------------------------------------------------------
262
+ /**
263
+ * Discover tools from a connected MCP server and wrap them as AgentTools.
264
+ */
265
+ async discoverTools(serverName, client) {
266
+ const response = await client.listTools();
267
+ const tools = [];
268
+ for (const mcpTool of response.tools) {
269
+ tools.push(this.wrapMcpTool(serverName, {
270
+ name: mcpTool.name,
271
+ description: mcpTool.description,
272
+ inputSchema: mcpTool.inputSchema,
273
+ }, client));
274
+ }
275
+ return tools;
276
+ }
277
+ /**
278
+ * Wrap a single MCP tool definition as an AgentTool.
279
+ *
280
+ * Key details:
281
+ * - Name is prefixed with serverName__ for namespacing
282
+ * - JSON Schema from MCP is wrapped via Type.Unsafe() for TypeBox
283
+ * - execute() calls tools/call on the MCP connection using the original name
284
+ * - Errors are caught and returned as error results (not thrown)
285
+ */
286
+ wrapMcpTool(serverName, mcpTool, client) {
287
+ const namespacedName = `${serverName}__${mcpTool.name}`;
288
+ // Wrap the MCP JSON Schema as a TypeBox type via Type.Unsafe()
289
+ const inputSchema = mcpTool.inputSchema ?? { type: 'object', properties: {} };
290
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
291
+ const parameters = Type.Unsafe(inputSchema);
292
+ return {
293
+ name: namespacedName,
294
+ description: mcpTool.description ?? '',
295
+ parameters,
296
+ // Marks this tool as MCP-sourced so CortexAgent's deferred-tool
297
+ // partitioning can identify it without rechecking by name prefix.
298
+ isMcp: true,
299
+ execute: async (args) => {
300
+ try {
301
+ const result = await client.callTool({
302
+ name: mcpTool.name, // Original name (no prefix)
303
+ arguments: (args ?? {}),
304
+ });
305
+ // Return text content from MCP result
306
+ if (result.isError) {
307
+ const errorText = Array.isArray(result.content)
308
+ ? result.content
309
+ .filter((c) => typeof c === 'object' && c !== null && 'type' in c && c.type === 'text')
310
+ .map(c => c.text)
311
+ .join('\n')
312
+ : String(result.content);
313
+ throw new Error(errorText || 'MCP tool call failed');
314
+ }
315
+ const normalizedContent = [];
316
+ if (Array.isArray(result.content)) {
317
+ for (const item of result.content) {
318
+ if (!item || typeof item !== 'object') {
319
+ normalizedContent.push({ type: 'text', text: String(item) });
320
+ continue;
321
+ }
322
+ const block = item;
323
+ const type = block['type'];
324
+ if (type === 'text' && typeof block['text'] === 'string') {
325
+ normalizedContent.push({ type: 'text', text: block['text'] });
326
+ continue;
327
+ }
328
+ if (type === 'image' &&
329
+ typeof block['data'] === 'string' &&
330
+ typeof block['mimeType'] === 'string') {
331
+ normalizedContent.push({
332
+ type: 'image',
333
+ data: block['data'],
334
+ mimeType: block['mimeType'],
335
+ });
336
+ continue;
337
+ }
338
+ normalizedContent.push({
339
+ type: 'text',
340
+ text: JSON.stringify(block, null, 2),
341
+ });
342
+ }
343
+ }
344
+ if (normalizedContent.length === 0) {
345
+ const structuredContent = result['structuredContent'];
346
+ if (structuredContent !== undefined) {
347
+ normalizedContent.push({
348
+ type: 'text',
349
+ text: JSON.stringify(structuredContent, null, 2),
350
+ });
351
+ }
352
+ else {
353
+ normalizedContent.push({
354
+ type: 'text',
355
+ text: String(result.content ?? ''),
356
+ });
357
+ }
358
+ }
359
+ return {
360
+ content: normalizedContent,
361
+ details: {
362
+ structuredContent: result['structuredContent'] ?? null,
363
+ rawContent: result.content ?? null,
364
+ },
365
+ };
366
+ }
367
+ catch (err) {
368
+ // Re-throw as a standard error for pi-agent-core to handle
369
+ if (err instanceof Error)
370
+ throw err;
371
+ throw new Error(`MCP tool call "${mcpTool.name}" failed: ${String(err)}`);
372
+ }
373
+ },
374
+ };
375
+ }
376
+ // -----------------------------------------------------------------------
377
+ // Private: Reconnect handling
378
+ // -----------------------------------------------------------------------
379
+ /**
380
+ * Handle unexpected disconnection from an MCP server.
381
+ * Attempts reconnection up to MAX_RECONNECT_ATTEMPTS times.
382
+ */
383
+ handleDisconnect(serverName) {
384
+ const conn = this.connections.get(serverName);
385
+ if (!conn)
386
+ return;
387
+ // Already disconnected intentionally
388
+ if (!conn.connected)
389
+ return;
390
+ conn.connected = false;
391
+ conn.reconnectAttempts++;
392
+ if (conn.pid != null) {
393
+ this.onSubprocessExited?.(conn.pid);
394
+ conn.pid = null;
395
+ }
396
+ this.logger.warn('[MCP] unexpected disconnect', { serverName, attempt: conn.reconnectAttempts, maxAttempts: MAX_RECONNECT_ATTEMPTS });
397
+ if (conn.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
398
+ this.logger.error('[MCP] reconnect exhausted, deregistering', { serverName, maxAttempts: MAX_RECONNECT_ATTEMPTS });
399
+ this.connections.delete(serverName);
400
+ this.onToolsChanged?.();
401
+ return;
402
+ }
403
+ // Attempt reconnect asynchronously
404
+ this.attemptReconnect(serverName, conn.config).catch((err) => {
405
+ this.logger.error('[MCP] reconnect attempt failed', { serverName, error: err instanceof Error ? err.message : String(err) });
406
+ });
407
+ }
408
+ /**
409
+ * Attempt to reconnect to an MCP server.
410
+ */
411
+ async attemptReconnect(serverName, config) {
412
+ // Brief delay before reconnect
413
+ await new Promise(resolve => setTimeout(resolve, 1000));
414
+ const existing = this.connections.get(serverName);
415
+ if (!existing)
416
+ return; // Was deregistered during delay
417
+ let client = null;
418
+ let pid = null;
419
+ try {
420
+ // Attempt fresh connection
421
+ const transport = this.createTransport(config);
422
+ client = new Client({ name: `cortex-${serverName}`, version: '1.0.0' }, { capabilities: {} });
423
+ await client.connect(transport);
424
+ // Track subprocess PID
425
+ if (transport instanceof StdioClientTransport) {
426
+ pid = transport.pid;
427
+ if (pid != null) {
428
+ this.onSubprocessSpawned?.(pid);
429
+ }
430
+ }
431
+ // Rediscover tools
432
+ const tools = await this.discoverTools(serverName, client);
433
+ // Wire close handler
434
+ transport.onclose = () => {
435
+ this.handleDisconnect(serverName);
436
+ };
437
+ // Update connection record
438
+ existing.client = client;
439
+ existing.transport = transport;
440
+ existing.tools = tools;
441
+ existing.connected = true;
442
+ existing.pid = pid;
443
+ // Keep reconnectAttempts as-is (reset only on fresh connect)
444
+ this.logger.info('[MCP] reconnected', { serverName, toolCount: tools.length });
445
+ this.onToolsChanged?.();
446
+ }
447
+ catch (err) {
448
+ // Clean up resources from partial connection
449
+ if (client) {
450
+ try {
451
+ await client.close();
452
+ }
453
+ catch { /* best-effort */ }
454
+ }
455
+ if (pid != null) {
456
+ this.onSubprocessExited?.(pid);
457
+ }
458
+ this.logger.warn('[MCP] reconnect failed', { serverName, error: err instanceof Error ? err.message : String(err) });
459
+ existing.reconnectAttempts++;
460
+ if (existing.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
461
+ this.logger.error('[MCP] max reconnect attempts exceeded, deregistering', { serverName });
462
+ this.connections.delete(serverName);
463
+ this.onToolsChanged?.();
464
+ }
465
+ else {
466
+ // Schedule another attempt since transport.onclose may not fire
467
+ this.attemptReconnect(serverName, config).catch((retryErr) => {
468
+ this.logger.error('[MCP] subsequent reconnect failed', { serverName, error: retryErr instanceof Error ? retryErr.message : String(retryErr) });
469
+ });
470
+ }
471
+ }
472
+ }
473
+ }
474
+ //# sourceMappingURL=mcp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * CortexModel: branded opaque type for type-safe model passing.
3
+ *
4
+ * Wraps pi-ai's Model<any> with a branded type to prevent consumers
5
+ * from accidentally passing raw pi-ai models where cortex models
6
+ * are expected (and vice versa).
7
+ *
8
+ * The consumer can read provider, modelId, and contextWindow for
9
+ * display and configuration. The underlying pi-ai Model object is
10
+ * accessed internally by CortexAgent when constructing the
11
+ * pi-agent-core Agent.
12
+ *
13
+ * Reference: provider-manager.md
14
+ */
15
+ /**
16
+ * Opaque model handle. The consumer receives this from ProviderManager
17
+ * and passes it to CortexAgent. The consumer never inspects its internals
18
+ * beyond the declared fields.
19
+ *
20
+ * Internally, this wraps pi-ai's Model<T> type.
21
+ */
22
+ export interface CortexModel {
23
+ /** @internal Brand tag for nominal type safety. */
24
+ readonly __brand: 'CortexModel';
25
+ /** Provider identifier (e.g., 'anthropic', 'openai', 'google'). */
26
+ readonly provider: string;
27
+ /** Model identifier (e.g., 'claude-sonnet-4-20250514'). */
28
+ readonly modelId: string;
29
+ /** Context window size in tokens. */
30
+ readonly contextWindow: number;
31
+ }
32
+ /**
33
+ * Wrap a pi-ai Model object into a CortexModel.
34
+ *
35
+ * @param model - The pi-ai Model object to wrap
36
+ * @param provider - The provider identifier
37
+ * @param modelId - The model identifier
38
+ * @param contextWindow - The context window size (default: 200000)
39
+ * @returns An opaque CortexModel handle
40
+ */
41
+ export declare function wrapModel(model: unknown, provider: string, modelId: string, contextWindow?: number): CortexModel;
42
+ /**
43
+ * Unwrap a CortexModel to retrieve the underlying pi-ai Model object.
44
+ *
45
+ * @param cortexModel - The CortexModel to unwrap
46
+ * @returns The underlying pi-ai Model object
47
+ * @throws Error if the object is not a valid CortexModel
48
+ */
49
+ export declare function unwrapModel(cortexModel: CortexModel): unknown;
50
+ /**
51
+ * Check whether a value is a valid CortexModel (has the correct brand
52
+ * and contains a wrapped inner model).
53
+ *
54
+ * @param value - The value to check
55
+ * @returns True if the value is a valid CortexModel
56
+ */
57
+ export declare function isCortexModel(value: unknown): value is CortexModel;
58
+ //# sourceMappingURL=model-wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-wrapper.d.ts","sourceRoot":"","sources":["../src/model-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,WAAW,CASb;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAK7D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAUlE"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * CortexModel: branded opaque type for type-safe model passing.
3
+ *
4
+ * Wraps pi-ai's Model<any> with a branded type to prevent consumers
5
+ * from accidentally passing raw pi-ai models where cortex models
6
+ * are expected (and vice versa).
7
+ *
8
+ * The consumer can read provider, modelId, and contextWindow for
9
+ * display and configuration. The underlying pi-ai Model object is
10
+ * accessed internally by CortexAgent when constructing the
11
+ * pi-agent-core Agent.
12
+ *
13
+ * Reference: provider-manager.md
14
+ */
15
+ // The symbol key used to store the underlying pi-ai model.
16
+ const INNER_MODEL = Symbol.for('cortex.innerModel');
17
+ // ---------------------------------------------------------------------------
18
+ // Public API
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Wrap a pi-ai Model object into a CortexModel.
22
+ *
23
+ * @param model - The pi-ai Model object to wrap
24
+ * @param provider - The provider identifier
25
+ * @param modelId - The model identifier
26
+ * @param contextWindow - The context window size (default: 200000)
27
+ * @returns An opaque CortexModel handle
28
+ */
29
+ export function wrapModel(model, provider, modelId, contextWindow) {
30
+ const wrapped = {
31
+ __brand: 'CortexModel',
32
+ provider,
33
+ modelId,
34
+ contextWindow: contextWindow ?? extractContextWindow(model) ?? 200_000,
35
+ [INNER_MODEL]: model,
36
+ };
37
+ return wrapped;
38
+ }
39
+ /**
40
+ * Unwrap a CortexModel to retrieve the underlying pi-ai Model object.
41
+ *
42
+ * @param cortexModel - The CortexModel to unwrap
43
+ * @returns The underlying pi-ai Model object
44
+ * @throws Error if the object is not a valid CortexModel
45
+ */
46
+ export function unwrapModel(cortexModel) {
47
+ if (!isCortexModel(cortexModel)) {
48
+ throw new Error('Expected a CortexModel created by wrapModel()');
49
+ }
50
+ return cortexModel[INNER_MODEL];
51
+ }
52
+ /**
53
+ * Check whether a value is a valid CortexModel (has the correct brand
54
+ * and contains a wrapped inner model).
55
+ *
56
+ * @param value - The value to check
57
+ * @returns True if the value is a valid CortexModel
58
+ */
59
+ export function isCortexModel(value) {
60
+ if (!value || typeof value !== 'object')
61
+ return false;
62
+ const obj = value;
63
+ return (obj['__brand'] === 'CortexModel' &&
64
+ typeof obj['provider'] === 'string' &&
65
+ typeof obj['modelId'] === 'string' &&
66
+ typeof obj['contextWindow'] === 'number' &&
67
+ INNER_MODEL in obj);
68
+ }
69
+ // ---------------------------------------------------------------------------
70
+ // Internal helpers
71
+ // ---------------------------------------------------------------------------
72
+ /**
73
+ * Attempt to extract the context window size from a pi-ai Model object.
74
+ * Pi-ai models expose contextWindow as a property.
75
+ */
76
+ function extractContextWindow(model) {
77
+ if (model && typeof model === 'object') {
78
+ const obj = model;
79
+ const cw = obj['contextWindow'];
80
+ if (typeof cw === 'number') {
81
+ return cw;
82
+ }
83
+ }
84
+ return undefined;
85
+ }
86
+ //# sourceMappingURL=model-wrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-wrapper.js","sourceRoot":"","sources":["../src/model-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAwBH,2DAA2D;AAC3D,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAUpD,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CACvB,KAAc,EACd,QAAgB,EAChB,OAAe,EACf,aAAsB;IAEtB,MAAM,OAAO,GAAiB;QAC5B,OAAO,EAAE,aAAsB;QAC/B,QAAQ;QACR,OAAO;QACP,aAAa,EAAE,aAAa,IAAI,oBAAoB,CAAC,KAAK,CAAC,IAAI,OAAO;QACtE,CAAC,WAAW,CAAC,EAAE,KAAK;KACrB,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,WAAwB;IAClD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,OAAQ,WAA4B,CAAC,WAAW,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,KAAyC,CAAC;IACtD,OAAO,CACL,GAAG,CAAC,SAAS,CAAC,KAAK,aAAa;QAChC,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,QAAQ;QACnC,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ;QAClC,OAAO,GAAG,CAAC,eAAe,CAAC,KAAK,QAAQ;QACxC,WAAW,IAAI,GAAG,CACnB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,KAAgC,CAAC;QAC7C,MAAM,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC;QAChC,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC3B,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { CortexLogger } from './types.js';
2
+ /** Silent logger used when no consumer logger is provided. */
3
+ export declare const NOOP_LOGGER: CortexLogger;
4
+ //# sourceMappingURL=noop-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noop-logger.d.ts","sourceRoot":"","sources":["../src/noop-logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,8DAA8D;AAC9D,eAAO,MAAM,WAAW,EAAE,YAKzB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /** Silent logger used when no consumer logger is provided. */
2
+ export const NOOP_LOGGER = {
3
+ debug() { },
4
+ info() { },
5
+ warn() { },
6
+ error() { },
7
+ };
8
+ //# sourceMappingURL=noop-logger.js.map