luca 2.0.0 → 3.0.2

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 (532) hide show
  1. package/.github/workflows/release.yaml +170 -0
  2. package/AGENTS.md +99 -0
  3. package/CLAUDE.md +123 -0
  4. package/CNAME +1 -0
  5. package/README.md +275 -9
  6. package/RUNME.md +56 -0
  7. package/assistants/codingAssistant/ABOUT.md +5 -0
  8. package/assistants/codingAssistant/CORE.md +33 -0
  9. package/assistants/codingAssistant/hooks.ts +21 -0
  10. package/assistants/codingAssistant/tools.ts +12 -0
  11. package/assistants/inkbot/ABOUT.md +16 -0
  12. package/assistants/inkbot/CORE.md +330 -0
  13. package/assistants/inkbot/hooks.ts +6 -0
  14. package/assistants/inkbot/tools.ts +53 -0
  15. package/assistants/researcher/ABOUT.md +5 -0
  16. package/assistants/researcher/CORE.md +46 -0
  17. package/assistants/researcher/hooks.ts +16 -0
  18. package/assistants/researcher/tools.ts +237 -0
  19. package/bun.lock +2667 -0
  20. package/bunfig.toml +3 -0
  21. package/commands/audit-docs.ts +740 -0
  22. package/commands/build-bootstrap.ts +117 -0
  23. package/commands/build-python-bridge.ts +42 -0
  24. package/commands/build-scaffolds.ts +175 -0
  25. package/commands/bundle-consumer-project.ts +521 -0
  26. package/commands/generate-api-docs.ts +114 -0
  27. package/commands/inkbot.ts +874 -0
  28. package/commands/release.ts +80 -0
  29. package/commands/try-all-challenges.ts +543 -0
  30. package/commands/try-challenge.ts +100 -0
  31. package/dist/agi/container.server.d.ts +63 -0
  32. package/dist/agi/container.server.d.ts.map +1 -0
  33. package/dist/agi/endpoints/ask.d.ts +20 -0
  34. package/dist/agi/endpoints/ask.d.ts.map +1 -0
  35. package/dist/agi/endpoints/conversations/[id].d.ts +27 -0
  36. package/dist/agi/endpoints/conversations/[id].d.ts.map +1 -0
  37. package/dist/agi/endpoints/conversations.d.ts +18 -0
  38. package/dist/agi/endpoints/conversations.d.ts.map +1 -0
  39. package/dist/agi/endpoints/experts.d.ts +8 -0
  40. package/dist/agi/endpoints/experts.d.ts.map +1 -0
  41. package/dist/agi/feature.d.ts +9 -0
  42. package/dist/agi/feature.d.ts.map +1 -0
  43. package/dist/agi/features/assistant.d.ts +509 -0
  44. package/dist/agi/features/assistant.d.ts.map +1 -0
  45. package/dist/agi/features/assistants-manager.d.ts +236 -0
  46. package/dist/agi/features/assistants-manager.d.ts.map +1 -0
  47. package/dist/agi/features/autonomous-assistant.d.ts +281 -0
  48. package/dist/agi/features/autonomous-assistant.d.ts.map +1 -0
  49. package/dist/agi/features/browser-use.d.ts +479 -0
  50. package/dist/agi/features/browser-use.d.ts.map +1 -0
  51. package/dist/agi/features/claude-code.d.ts +824 -0
  52. package/dist/agi/features/claude-code.d.ts.map +1 -0
  53. package/dist/agi/features/conversation-history.d.ts +245 -0
  54. package/dist/agi/features/conversation-history.d.ts.map +1 -0
  55. package/dist/agi/features/conversation.d.ts +464 -0
  56. package/dist/agi/features/conversation.d.ts.map +1 -0
  57. package/dist/agi/features/docs-reader.d.ts +72 -0
  58. package/dist/agi/features/docs-reader.d.ts.map +1 -0
  59. package/dist/agi/features/file-tools.d.ts +110 -0
  60. package/dist/agi/features/file-tools.d.ts.map +1 -0
  61. package/dist/agi/features/luca-coder.d.ts +323 -0
  62. package/dist/agi/features/luca-coder.d.ts.map +1 -0
  63. package/dist/agi/features/openai-codex.d.ts +381 -0
  64. package/dist/agi/features/openai-codex.d.ts.map +1 -0
  65. package/dist/agi/features/openapi.d.ts +200 -0
  66. package/dist/agi/features/openapi.d.ts.map +1 -0
  67. package/dist/agi/features/skills-library.d.ts +167 -0
  68. package/dist/agi/features/skills-library.d.ts.map +1 -0
  69. package/dist/agi/index.d.ts +5 -0
  70. package/dist/agi/index.d.ts.map +1 -0
  71. package/dist/agi/lib/interceptor-chain.d.ts +44 -0
  72. package/dist/agi/lib/interceptor-chain.d.ts.map +1 -0
  73. package/dist/agi/lib/token-counter.d.ts +13 -0
  74. package/dist/agi/lib/token-counter.d.ts.map +1 -0
  75. package/dist/bootstrap/generated.d.ts +5 -0
  76. package/dist/bootstrap/generated.d.ts.map +1 -0
  77. package/dist/browser.d.ts +12 -0
  78. package/dist/browser.d.ts.map +1 -0
  79. package/dist/bus.d.ts +29 -0
  80. package/dist/bus.d.ts.map +1 -0
  81. package/dist/cli/build-info.d.ts +4 -0
  82. package/dist/cli/build-info.d.ts.map +1 -0
  83. package/dist/cli/cli.d.ts +3 -12
  84. package/dist/cli/cli.d.ts.map +1 -0
  85. package/dist/client.d.ts +60 -0
  86. package/dist/client.d.ts.map +1 -0
  87. package/dist/clients/civitai/index.d.ts +472 -0
  88. package/dist/clients/civitai/index.d.ts.map +1 -0
  89. package/dist/clients/client-template.d.ts +30 -0
  90. package/dist/clients/client-template.d.ts.map +1 -0
  91. package/dist/clients/comfyui/index.d.ts +281 -0
  92. package/dist/clients/comfyui/index.d.ts.map +1 -0
  93. package/dist/clients/elevenlabs/index.d.ts +197 -0
  94. package/dist/clients/elevenlabs/index.d.ts.map +1 -0
  95. package/dist/clients/graph.d.ts +64 -0
  96. package/dist/clients/graph.d.ts.map +1 -0
  97. package/dist/clients/openai/index.d.ts +247 -0
  98. package/dist/clients/openai/index.d.ts.map +1 -0
  99. package/dist/clients/rest.d.ts +92 -0
  100. package/dist/clients/rest.d.ts.map +1 -0
  101. package/dist/clients/supabase/index.d.ts +176 -0
  102. package/dist/clients/supabase/index.d.ts.map +1 -0
  103. package/dist/clients/websocket.d.ts +127 -0
  104. package/dist/clients/websocket.d.ts.map +1 -0
  105. package/dist/command.d.ts +163 -0
  106. package/dist/command.d.ts.map +1 -0
  107. package/dist/commands/bootstrap.d.ts +20 -0
  108. package/dist/commands/bootstrap.d.ts.map +1 -0
  109. package/dist/commands/chat.d.ts +37 -0
  110. package/dist/commands/chat.d.ts.map +1 -0
  111. package/dist/commands/code.d.ts +28 -0
  112. package/dist/commands/code.d.ts.map +1 -0
  113. package/dist/commands/console.d.ts +22 -0
  114. package/dist/commands/console.d.ts.map +1 -0
  115. package/dist/commands/describe.d.ts +50 -0
  116. package/dist/commands/describe.d.ts.map +1 -0
  117. package/dist/commands/eval.d.ts +23 -0
  118. package/dist/commands/eval.d.ts.map +1 -0
  119. package/dist/commands/help.d.ts +25 -0
  120. package/dist/commands/help.d.ts.map +1 -0
  121. package/dist/commands/index.d.ts +18 -0
  122. package/dist/commands/index.d.ts.map +1 -0
  123. package/dist/commands/introspect.d.ts +24 -0
  124. package/dist/commands/introspect.d.ts.map +1 -0
  125. package/dist/commands/mcp.d.ts +35 -0
  126. package/dist/commands/mcp.d.ts.map +1 -0
  127. package/dist/commands/prompt.d.ts +38 -0
  128. package/dist/commands/prompt.d.ts.map +1 -0
  129. package/dist/commands/run.d.ts +24 -0
  130. package/dist/commands/run.d.ts.map +1 -0
  131. package/dist/commands/sandbox-mcp.d.ts +34 -0
  132. package/dist/commands/sandbox-mcp.d.ts.map +1 -0
  133. package/dist/commands/save-api-docs.d.ts +21 -0
  134. package/dist/commands/save-api-docs.d.ts.map +1 -0
  135. package/dist/commands/scaffold.d.ts +24 -0
  136. package/dist/commands/scaffold.d.ts.map +1 -0
  137. package/dist/commands/select.d.ts +22 -0
  138. package/dist/commands/select.d.ts.map +1 -0
  139. package/dist/commands/serve.d.ts +29 -0
  140. package/dist/commands/serve.d.ts.map +1 -0
  141. package/dist/container-describer.d.ts +144 -0
  142. package/dist/container-describer.d.ts.map +1 -0
  143. package/dist/container.d.ts +451 -0
  144. package/dist/container.d.ts.map +1 -0
  145. package/dist/endpoint.d.ts +113 -0
  146. package/dist/endpoint.d.ts.map +1 -0
  147. package/dist/feature.d.ts +47 -0
  148. package/dist/feature.d.ts.map +1 -0
  149. package/dist/graft.d.ts +29 -0
  150. package/dist/graft.d.ts.map +1 -0
  151. package/dist/hash-object.d.ts +8 -0
  152. package/dist/hash-object.d.ts.map +1 -0
  153. package/dist/helper.d.ts +209 -0
  154. package/dist/helper.d.ts.map +1 -0
  155. package/dist/introspection/generated.node.d.ts +44623 -0
  156. package/dist/introspection/generated.node.d.ts.map +1 -0
  157. package/dist/introspection/generated.web.d.ts +1412 -0
  158. package/dist/introspection/generated.web.d.ts.map +1 -0
  159. package/dist/introspection/index.d.ts +156 -0
  160. package/dist/introspection/index.d.ts.map +1 -0
  161. package/dist/introspection/scan.d.ts +147 -0
  162. package/dist/introspection/scan.d.ts.map +1 -0
  163. package/dist/node/container.d.ts +256 -0
  164. package/dist/node/container.d.ts.map +1 -0
  165. package/dist/node/feature.d.ts +9 -0
  166. package/dist/node/feature.d.ts.map +1 -0
  167. package/dist/node/features/container-link.d.ts +213 -0
  168. package/dist/node/features/container-link.d.ts.map +1 -0
  169. package/dist/node/features/content-db.d.ts +354 -0
  170. package/dist/node/features/content-db.d.ts.map +1 -0
  171. package/dist/node/features/disk-cache.d.ts +236 -0
  172. package/dist/node/features/disk-cache.d.ts.map +1 -0
  173. package/dist/node/features/dns.d.ts +511 -0
  174. package/dist/node/features/dns.d.ts.map +1 -0
  175. package/dist/node/features/docker.d.ts +485 -0
  176. package/dist/node/features/docker.d.ts.map +1 -0
  177. package/dist/node/features/downloader.d.ts +73 -0
  178. package/dist/node/features/downloader.d.ts.map +1 -0
  179. package/dist/node/features/figlet-fonts.d.ts +4 -0
  180. package/dist/node/features/figlet-fonts.d.ts.map +1 -0
  181. package/dist/node/features/file-manager.d.ts +177 -0
  182. package/dist/node/features/file-manager.d.ts.map +1 -0
  183. package/dist/node/features/fs.d.ts +635 -0
  184. package/dist/node/features/fs.d.ts.map +1 -0
  185. package/dist/node/features/git.d.ts +329 -0
  186. package/dist/node/features/git.d.ts.map +1 -0
  187. package/dist/node/features/google-auth.d.ts +200 -0
  188. package/dist/node/features/google-auth.d.ts.map +1 -0
  189. package/dist/node/features/google-calendar.d.ts +194 -0
  190. package/dist/node/features/google-calendar.d.ts.map +1 -0
  191. package/dist/node/features/google-docs.d.ts +138 -0
  192. package/dist/node/features/google-docs.d.ts.map +1 -0
  193. package/dist/node/features/google-drive.d.ts +202 -0
  194. package/dist/node/features/google-drive.d.ts.map +1 -0
  195. package/dist/node/features/google-mail.d.ts +221 -0
  196. package/dist/node/features/google-mail.d.ts.map +1 -0
  197. package/dist/node/features/google-sheets.d.ts +157 -0
  198. package/dist/node/features/google-sheets.d.ts.map +1 -0
  199. package/dist/node/features/grep.d.ts +207 -0
  200. package/dist/node/features/grep.d.ts.map +1 -0
  201. package/dist/node/features/helpers.d.ts +236 -0
  202. package/dist/node/features/helpers.d.ts.map +1 -0
  203. package/dist/node/features/ink.d.ts +332 -0
  204. package/dist/node/features/ink.d.ts.map +1 -0
  205. package/dist/node/features/ipc-socket.d.ts +298 -0
  206. package/dist/node/features/ipc-socket.d.ts.map +1 -0
  207. package/dist/node/features/json-tree.d.ts +140 -0
  208. package/dist/node/features/json-tree.d.ts.map +1 -0
  209. package/dist/node/features/networking.d.ts +373 -0
  210. package/dist/node/features/networking.d.ts.map +1 -0
  211. package/dist/node/features/nlp.d.ts +125 -0
  212. package/dist/node/features/nlp.d.ts.map +1 -0
  213. package/dist/node/features/opener.d.ts +93 -0
  214. package/dist/node/features/opener.d.ts.map +1 -0
  215. package/dist/node/features/os.d.ts +168 -0
  216. package/dist/node/features/os.d.ts.map +1 -0
  217. package/dist/node/features/package-finder.d.ts +419 -0
  218. package/dist/node/features/package-finder.d.ts.map +1 -0
  219. package/dist/node/features/postgres.d.ts +173 -0
  220. package/dist/node/features/postgres.d.ts.map +1 -0
  221. package/dist/node/features/proc.d.ts +285 -0
  222. package/dist/node/features/proc.d.ts.map +1 -0
  223. package/dist/node/features/process-manager.d.ts +427 -0
  224. package/dist/node/features/process-manager.d.ts.map +1 -0
  225. package/dist/node/features/python.d.ts +477 -0
  226. package/dist/node/features/python.d.ts.map +1 -0
  227. package/dist/node/features/redis.d.ts +247 -0
  228. package/dist/node/features/redis.d.ts.map +1 -0
  229. package/dist/node/features/repl.d.ts +84 -0
  230. package/dist/node/features/repl.d.ts.map +1 -0
  231. package/dist/node/features/runpod.d.ts +527 -0
  232. package/dist/node/features/runpod.d.ts.map +1 -0
  233. package/dist/node/features/secure-shell.d.ts +145 -0
  234. package/dist/node/features/secure-shell.d.ts.map +1 -0
  235. package/dist/node/features/semantic-search.d.ts +207 -0
  236. package/dist/node/features/semantic-search.d.ts.map +1 -0
  237. package/dist/node/features/sqlite.d.ts +180 -0
  238. package/dist/node/features/sqlite.d.ts.map +1 -0
  239. package/dist/node/features/telegram.d.ts +173 -0
  240. package/dist/node/features/telegram.d.ts.map +1 -0
  241. package/dist/node/features/transpiler.d.ts +51 -0
  242. package/dist/node/features/transpiler.d.ts.map +1 -0
  243. package/dist/node/features/tts.d.ts +108 -0
  244. package/dist/node/features/tts.d.ts.map +1 -0
  245. package/dist/node/features/ui.d.ts +562 -0
  246. package/dist/node/features/ui.d.ts.map +1 -0
  247. package/dist/node/features/vault.d.ts +90 -0
  248. package/dist/node/features/vault.d.ts.map +1 -0
  249. package/dist/node/features/vm.d.ts +285 -0
  250. package/dist/node/features/vm.d.ts.map +1 -0
  251. package/dist/node/features/yaml-tree.d.ts +118 -0
  252. package/dist/node/features/yaml-tree.d.ts.map +1 -0
  253. package/dist/node/features/yaml.d.ts +127 -0
  254. package/dist/node/features/yaml.d.ts.map +1 -0
  255. package/dist/node.d.ts +67 -0
  256. package/dist/node.d.ts.map +1 -0
  257. package/dist/python/generated.d.ts +2 -0
  258. package/dist/python/generated.d.ts.map +1 -0
  259. package/dist/react/index.d.ts +36 -0
  260. package/dist/react/index.d.ts.map +1 -0
  261. package/dist/registry.d.ts +97 -0
  262. package/dist/registry.d.ts.map +1 -0
  263. package/dist/scaffolds/generated.d.ts +13 -0
  264. package/dist/scaffolds/generated.d.ts.map +1 -0
  265. package/dist/scaffolds/template.d.ts +11 -0
  266. package/dist/scaffolds/template.d.ts.map +1 -0
  267. package/dist/schemas/base.d.ts +254 -0
  268. package/dist/schemas/base.d.ts.map +1 -0
  269. package/dist/selector.d.ts +130 -0
  270. package/dist/selector.d.ts.map +1 -0
  271. package/dist/server.d.ts +89 -0
  272. package/dist/server.d.ts.map +1 -0
  273. package/dist/servers/express.d.ts +104 -0
  274. package/dist/servers/express.d.ts.map +1 -0
  275. package/dist/servers/mcp.d.ts +201 -0
  276. package/dist/servers/mcp.d.ts.map +1 -0
  277. package/dist/servers/socket.d.ts +121 -0
  278. package/dist/servers/socket.d.ts.map +1 -0
  279. package/dist/state.d.ts +24 -0
  280. package/dist/state.d.ts.map +1 -0
  281. package/dist/web/clients/socket.d.ts +37 -0
  282. package/dist/web/clients/socket.d.ts.map +1 -0
  283. package/dist/web/container.d.ts +55 -0
  284. package/dist/web/container.d.ts.map +1 -0
  285. package/dist/web/extension.d.ts +4 -0
  286. package/dist/web/extension.d.ts.map +1 -0
  287. package/dist/web/feature.d.ts +8 -0
  288. package/dist/web/feature.d.ts.map +1 -0
  289. package/dist/web/features/asset-loader.d.ts +35 -0
  290. package/dist/web/features/asset-loader.d.ts.map +1 -0
  291. package/dist/web/features/container-link.d.ts +167 -0
  292. package/dist/web/features/container-link.d.ts.map +1 -0
  293. package/dist/web/features/esbuild.d.ts +51 -0
  294. package/dist/web/features/esbuild.d.ts.map +1 -0
  295. package/dist/web/features/helpers.d.ts +140 -0
  296. package/dist/web/features/helpers.d.ts.map +1 -0
  297. package/dist/web/features/network.d.ts +69 -0
  298. package/dist/web/features/network.d.ts.map +1 -0
  299. package/dist/web/features/speech.d.ts +71 -0
  300. package/dist/web/features/speech.d.ts.map +1 -0
  301. package/dist/web/features/vault.d.ts +62 -0
  302. package/dist/web/features/vault.d.ts.map +1 -0
  303. package/dist/web/features/vm.d.ts +48 -0
  304. package/dist/web/features/vm.d.ts.map +1 -0
  305. package/dist/web/features/voice-recognition.d.ts +96 -0
  306. package/dist/web/features/voice-recognition.d.ts.map +1 -0
  307. package/dist/web/shims/isomorphic-vm.d.ts +22 -0
  308. package/dist/web/shims/isomorphic-vm.d.ts.map +1 -0
  309. package/index.html +1457 -0
  310. package/index.ts +1 -0
  311. package/install.sh +84 -0
  312. package/luca.cli.ts +16 -0
  313. package/luca.console.ts +9 -0
  314. package/main.py +6 -0
  315. package/package.json +219 -58
  316. package/public/index.html +1457 -0
  317. package/public/slides-ai-native.html +902 -0
  318. package/public/slides-intro.html +974 -0
  319. package/pyproject.toml +7 -0
  320. package/scripts/build-web.ts +28 -0
  321. package/scripts/examples/ask-luca-expert.ts +42 -0
  322. package/scripts/examples/assistant-questions.ts +12 -0
  323. package/scripts/examples/excalidraw-expert.ts +75 -0
  324. package/scripts/examples/expert-chat.ts +0 -0
  325. package/scripts/examples/file-manager.ts +14 -0
  326. package/scripts/examples/ideas.ts +12 -0
  327. package/scripts/examples/interactive-chat.ts +20 -0
  328. package/scripts/examples/openai-tool-calls.ts +113 -0
  329. package/scripts/examples/opening-a-web-browser.ts +5 -0
  330. package/scripts/examples/telegram-bot.ts +79 -0
  331. package/scripts/examples/using-assistant-with-mcp.ts +555 -0
  332. package/scripts/examples/using-claude-code.ts +10 -0
  333. package/scripts/examples/using-contentdb.ts +35 -0
  334. package/scripts/examples/using-conversations.ts +35 -0
  335. package/scripts/examples/using-disk-cache.ts +10 -0
  336. package/scripts/examples/using-docker-shell.ts +75 -0
  337. package/scripts/examples/using-elevenlabs.ts +25 -0
  338. package/scripts/examples/using-google-calendar.ts +57 -0
  339. package/scripts/examples/using-google-docs.ts +74 -0
  340. package/scripts/examples/using-google-drive.ts +74 -0
  341. package/scripts/examples/using-google-sheets.ts +89 -0
  342. package/scripts/examples/using-nlp.ts +55 -0
  343. package/scripts/examples/using-ollama.ts +11 -0
  344. package/scripts/examples/using-postgres.ts +55 -0
  345. package/scripts/examples/using-runpod.ts +32 -0
  346. package/scripts/examples/using-tts.ts +40 -0
  347. package/scripts/scaffold.ts +391 -0
  348. package/scripts/scratch.ts +15 -0
  349. package/scripts/stamp-build.sh +12 -0
  350. package/scripts/test-assistant-hooks.ts +13 -0
  351. package/scripts/test-docs-reader.ts +10 -0
  352. package/scripts/test-linux-binary.sh +80 -0
  353. package/scripts/update-introspection-data.ts +58 -0
  354. package/src/agi/README.md +14 -0
  355. package/src/agi/container.server.ts +156 -0
  356. package/src/agi/feature.ts +13 -0
  357. package/src/agi/features/agent-memory.ts +694 -0
  358. package/src/agi/features/assistant.ts +1653 -0
  359. package/src/agi/features/assistants-manager.ts +534 -0
  360. package/src/agi/features/autonomous-assistant.ts +431 -0
  361. package/src/agi/features/browser-use.ts +672 -0
  362. package/src/agi/features/claude-code.ts +1584 -0
  363. package/src/agi/features/coding-tools.ts +175 -0
  364. package/src/agi/features/conversation-history.ts +672 -0
  365. package/src/agi/features/conversation.ts +1494 -0
  366. package/src/agi/features/docs-reader.ts +167 -0
  367. package/src/agi/features/file-tools.ts +340 -0
  368. package/src/agi/features/luca-coder.ts +641 -0
  369. package/src/agi/features/mcp-bridge.ts +532 -0
  370. package/src/agi/features/openai-codex.ts +651 -0
  371. package/src/agi/features/openapi.ts +445 -0
  372. package/src/agi/features/skills-library.ts +557 -0
  373. package/src/agi/index.ts +6 -0
  374. package/src/agi/lib/interceptor-chain.ts +89 -0
  375. package/src/agi/lib/token-counter.ts +202 -0
  376. package/src/bootstrap/generated.ts +9791 -0
  377. package/src/browser.ts +25 -0
  378. package/src/bus.ts +122 -0
  379. package/src/cli/build-info.ts +4 -0
  380. package/src/cli/cli.ts +355 -0
  381. package/src/client.ts +170 -0
  382. package/src/clients/civitai/index.ts +537 -0
  383. package/src/clients/client-template.ts +41 -0
  384. package/src/clients/comfyui/index.ts +604 -0
  385. package/src/clients/elevenlabs/index.ts +317 -0
  386. package/src/clients/graph.ts +87 -0
  387. package/src/clients/openai/index.ts +456 -0
  388. package/src/clients/rest.ts +207 -0
  389. package/src/clients/supabase/index.ts +357 -0
  390. package/src/clients/voicebox/index.ts +300 -0
  391. package/src/clients/websocket.ts +251 -0
  392. package/src/command.ts +506 -0
  393. package/src/commands/bootstrap.ts +244 -0
  394. package/src/commands/chat.ts +309 -0
  395. package/src/commands/code.ts +371 -0
  396. package/src/commands/console.ts +189 -0
  397. package/src/commands/describe.ts +243 -0
  398. package/src/commands/eval.ts +67 -0
  399. package/src/commands/help.ts +240 -0
  400. package/src/commands/index.ts +19 -0
  401. package/src/commands/introspect.ts +218 -0
  402. package/src/commands/mcp.ts +64 -0
  403. package/src/commands/prompt.ts +1014 -0
  404. package/src/commands/run.ts +278 -0
  405. package/src/commands/sandbox-mcp.ts +343 -0
  406. package/src/commands/save-api-docs.ts +51 -0
  407. package/src/commands/scaffold.ts +225 -0
  408. package/src/commands/select.ts +99 -0
  409. package/src/commands/serve.ts +208 -0
  410. package/src/container-describer.ts +1091 -0
  411. package/src/container.ts +1199 -0
  412. package/src/endpoint.ts +365 -0
  413. package/src/entity.ts +173 -0
  414. package/src/feature.ts +118 -0
  415. package/src/graft.ts +181 -0
  416. package/src/hash-object.ts +97 -0
  417. package/src/helper.ts +849 -0
  418. package/src/introspection/generated.agi.ts +41200 -0
  419. package/src/introspection/generated.node.ts +28773 -0
  420. package/src/introspection/generated.web.ts +2272 -0
  421. package/src/introspection/index.ts +296 -0
  422. package/src/introspection/scan.ts +1136 -0
  423. package/src/node/container.ts +409 -0
  424. package/src/node/feature.ts +13 -0
  425. package/src/node/features/container-link.ts +559 -0
  426. package/src/node/features/content-db.ts +849 -0
  427. package/src/node/features/disk-cache.ts +388 -0
  428. package/src/node/features/display-result.ts +57 -0
  429. package/src/node/features/dns.ts +669 -0
  430. package/src/node/features/docker.ts +921 -0
  431. package/src/node/features/downloader.ts +79 -0
  432. package/src/node/features/figlet-fonts.ts +600 -0
  433. package/src/node/features/file-manager.ts +535 -0
  434. package/src/node/features/fs.ts +1050 -0
  435. package/src/node/features/git.ts +592 -0
  436. package/src/node/features/google-auth.ts +504 -0
  437. package/src/node/features/google-calendar.ts +306 -0
  438. package/src/node/features/google-docs.ts +412 -0
  439. package/src/node/features/google-drive.ts +346 -0
  440. package/src/node/features/google-mail.ts +540 -0
  441. package/src/node/features/google-sheets.ts +286 -0
  442. package/src/node/features/grep.ts +427 -0
  443. package/src/node/features/helpers.ts +762 -0
  444. package/src/node/features/ink.ts +490 -0
  445. package/src/node/features/ipc-socket.ts +649 -0
  446. package/src/node/features/json-tree.ts +170 -0
  447. package/src/node/features/networking.ts +961 -0
  448. package/src/node/features/nlp.ts +212 -0
  449. package/src/node/features/opener.ts +180 -0
  450. package/src/node/features/os.ts +403 -0
  451. package/src/node/features/package-finder.ts +540 -0
  452. package/src/node/features/postgres.ts +289 -0
  453. package/src/node/features/proc.ts +503 -0
  454. package/src/node/features/process-manager.ts +844 -0
  455. package/src/node/features/python.ts +912 -0
  456. package/src/node/features/redis.ts +446 -0
  457. package/src/node/features/repl.ts +212 -0
  458. package/src/node/features/runpod.ts +811 -0
  459. package/src/node/features/secure-shell.ts +261 -0
  460. package/src/node/features/semantic-search.ts +935 -0
  461. package/src/node/features/sqlite.ts +289 -0
  462. package/src/node/features/telegram.ts +343 -0
  463. package/src/node/features/transpiler.ts +160 -0
  464. package/src/node/features/tts.ts +185 -0
  465. package/src/node/features/ui.ts +791 -0
  466. package/src/node/features/vault.ts +153 -0
  467. package/src/node/features/vm.ts +462 -0
  468. package/src/node/features/yaml-tree.ts +148 -0
  469. package/src/node/features/yaml.ts +133 -0
  470. package/src/node.ts +76 -0
  471. package/src/python/bridge.py +220 -0
  472. package/src/python/generated.ts +226 -0
  473. package/src/react/index.ts +175 -0
  474. package/src/registry.ts +210 -0
  475. package/src/scaffolds/generated.ts +1814 -0
  476. package/src/scaffolds/template.ts +46 -0
  477. package/src/schemas/base.ts +296 -0
  478. package/src/selector.ts +352 -0
  479. package/src/server.ts +229 -0
  480. package/src/servers/express.ts +283 -0
  481. package/src/servers/mcp.ts +802 -0
  482. package/src/servers/socket.ts +258 -0
  483. package/src/state.ts +101 -0
  484. package/src/web/clients/socket.ts +99 -0
  485. package/src/web/container.ts +75 -0
  486. package/src/web/extension.ts +30 -0
  487. package/src/web/feature.ts +12 -0
  488. package/src/web/features/asset-loader.ts +72 -0
  489. package/src/web/features/container-link.ts +382 -0
  490. package/src/web/features/esbuild.ts +93 -0
  491. package/src/web/features/helpers.ts +291 -0
  492. package/src/web/features/network.ts +85 -0
  493. package/src/web/features/speech.ts +104 -0
  494. package/src/web/features/vault.ts +207 -0
  495. package/src/web/features/vm.ts +85 -0
  496. package/src/web/features/voice-recognition.ts +161 -0
  497. package/src/web/shims/isomorphic-vm.ts +149 -0
  498. package/tsconfig.build.json +12 -0
  499. package/tsconfig.json +58 -0
  500. package/uv.lock +8 -0
  501. package/LICENSE +0 -21
  502. package/dist/cli/cli.js +0 -48
  503. package/dist/cli/common.d.ts +0 -2
  504. package/dist/cli/common.js +0 -6
  505. package/dist/cli/index.d.ts +0 -2
  506. package/dist/cli/index.js +0 -5
  507. package/dist/cli/run.d.ts +0 -1
  508. package/dist/cli/run.js +0 -38
  509. package/dist/core/index.d.ts +0 -4
  510. package/dist/core/index.js +0 -32
  511. package/dist/core/read.d.ts +0 -2
  512. package/dist/core/read.js +0 -29
  513. package/dist/core/request.d.ts +0 -1
  514. package/dist/core/request.js +0 -2
  515. package/dist/core/write.d.ts +0 -2
  516. package/dist/core/write.js +0 -21
  517. package/dist/index.d.ts +0 -1
  518. package/dist/index.js +0 -5
  519. package/dist/utils/common.d.ts +0 -9
  520. package/dist/utils/common.js +0 -57
  521. package/dist/utils/consts.d.ts +0 -3
  522. package/dist/utils/consts.js +0 -11
  523. package/dist/utils/dict.d.ts +0 -1
  524. package/dist/utils/dict.js +0 -7
  525. package/dist/utils/index.d.ts +0 -5
  526. package/dist/utils/index.js +0 -21
  527. package/dist/utils/log.d.ts +0 -1
  528. package/dist/utils/log.js +0 -5
  529. package/dist/utils/types.d.ts +0 -1
  530. package/dist/utils/types.js +0 -2
  531. package/dist/utils/utils.test.d.ts +0 -1
  532. package/dist/utils/utils.test.js +0 -7
@@ -0,0 +1,802 @@
1
+ import type { NodeContainer } from '../node/container.js'
2
+ import { z } from 'zod'
3
+ import { MCPServerStateSchema, MCPServerOptionsSchema, MCPServerEventsSchema } from '../schemas/base.js'
4
+ import { Server } from '../server.js'
5
+ import { Server as MCPProtocolServer } from '@modelcontextprotocol/sdk/server/index.js'
6
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
7
+ import {
8
+ ListToolsRequestSchema,
9
+ CallToolRequestSchema,
10
+ ListResourcesRequestSchema,
11
+ ReadResourceRequestSchema,
12
+ ListPromptsRequestSchema,
13
+ GetPromptRequestSchema,
14
+ JSONRPCMessageSchema,
15
+ } from '@modelcontextprotocol/sdk/types.js'
16
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'
17
+
18
+ declare module '../server' {
19
+ interface AvailableServers {
20
+ mcp: typeof MCPServer
21
+ }
22
+ }
23
+
24
+ export type MCPServerOptions = z.infer<typeof MCPServerOptionsSchema>
25
+ export type MCPServerState = z.infer<typeof MCPServerStateSchema>
26
+
27
+ /** Context object passed to all MCP tool, resource, and prompt handlers. */
28
+ export type MCPContext = {
29
+ container: NodeContainer
30
+ }
31
+
32
+ /** A registered MCP tool with its schema, handler, and pre-computed JSON Schema. */
33
+ export interface RegisteredTool {
34
+ name: string
35
+ description?: string
36
+ schema?: z.ZodType
37
+ jsonSchema?: Record<string, any>
38
+ handler: Function
39
+ }
40
+
41
+ /** A registered MCP resource with its URI, metadata, and handler. */
42
+ export interface RegisteredResource {
43
+ uri: string
44
+ name?: string
45
+ description?: string
46
+ mimeType?: string
47
+ handler: (uri: string, ctx: MCPContext) => Promise<string> | string
48
+ }
49
+
50
+ /** A registered MCP prompt with its argument schemas and handler. */
51
+ export interface RegisteredPrompt {
52
+ name: string
53
+ description?: string
54
+ args?: Record<string, z.ZodType>
55
+ handler: (args: Record<string, string | undefined>, ctx: MCPContext) => Promise<PromptMessage[]> | PromptMessage[]
56
+ }
57
+
58
+ export type PromptMessage = {
59
+ role: 'user' | 'assistant'
60
+ content: string
61
+ }
62
+
63
+ type ToolRegistrationOptions = {
64
+ schema?: z.ZodType
65
+ description?: string
66
+ handler?: Function | ((args: any, ctx: any) => any)
67
+ }
68
+
69
+ type ResourceRegistrationOptions = {
70
+ name?: string
71
+ description?: string
72
+ mimeType?: string
73
+ handler: (uri: string, ctx: MCPContext) => Promise<string> | string
74
+ }
75
+
76
+ type PromptRegistrationOptions = {
77
+ description?: string
78
+ args?: Record<string, z.ZodType>
79
+ handler: (args: Record<string, string | undefined>, ctx: MCPContext) => Promise<PromptMessage[]> | PromptMessage[]
80
+ }
81
+
82
+ type MCPCompatMode = 'standard' | 'codex'
83
+ type StdioCompatMode = 'standard' | 'codex' | 'auto'
84
+
85
+ const SKIP_MESSAGE = Symbol('skip-message')
86
+
87
+ class CompatStdioServerTransport {
88
+ private _readBuffer: Buffer | undefined
89
+ private _started = false
90
+ private _inputFormat: 'framed' | 'line' | undefined
91
+
92
+ onmessage?: (message: any) => void
93
+ onerror?: (error: Error) => void
94
+ onclose?: () => void
95
+
96
+ constructor(
97
+ private readonly mode: Exclude<StdioCompatMode, 'standard'>,
98
+ private readonly _stdin = process.stdin,
99
+ private readonly _stdout = process.stdout,
100
+ ) {}
101
+
102
+ private _ondata = (chunk: Buffer) => {
103
+ this._readBuffer = this._readBuffer ? Buffer.concat([this._readBuffer, chunk]) : chunk
104
+ this.processReadBuffer()
105
+ }
106
+
107
+ private _onerror = (error: Error) => {
108
+ this.onerror?.(error)
109
+ }
110
+
111
+ async start() {
112
+ if (this._started) {
113
+ throw new Error('CompatStdioServerTransport already started')
114
+ }
115
+
116
+ this._started = true
117
+ this._stdin.on('data', this._ondata)
118
+ this._stdin.on('error', this._onerror)
119
+ }
120
+
121
+ private processReadBuffer() {
122
+ while (true) {
123
+ try {
124
+ const message = this._tryReadMessage()
125
+ if (message === null) break
126
+ if (message === SKIP_MESSAGE) continue
127
+ this.onmessage?.(message)
128
+ } catch (error) {
129
+ this.onerror?.(error as Error)
130
+ }
131
+ }
132
+ }
133
+
134
+ private _tryReadMessage(): any | typeof SKIP_MESSAGE | null {
135
+ if (!this._readBuffer || this._readBuffer.length === 0) {
136
+ return null
137
+ }
138
+
139
+ const format = this._resolveInputFormat()
140
+ if (!format) return null
141
+
142
+ if (format === 'framed') {
143
+ return this._readFramedMessage()
144
+ }
145
+
146
+ return this._readLineMessage()
147
+ }
148
+
149
+ private _resolveInputFormat(): 'framed' | 'line' | undefined {
150
+ if (this._inputFormat) {
151
+ return this._inputFormat
152
+ }
153
+
154
+ if (!this._readBuffer || this._readBuffer.length === 0) {
155
+ return undefined
156
+ }
157
+
158
+ const prefix = this._readBuffer.toString('utf8', 0, Math.min(this._readBuffer.length, 128))
159
+ if (/^\s*Content-Length\s*:/i.test(prefix)) {
160
+ this._inputFormat = 'framed'
161
+ return this._inputFormat
162
+ }
163
+
164
+ const firstByte = this._readBuffer.find((b) => ![0x20, 0x09, 0x0d, 0x0a].includes(b))
165
+ if (firstByte === undefined) return undefined
166
+
167
+ if (firstByte === 0x7b || firstByte === 0x5b) {
168
+ this._inputFormat = 'line'
169
+ return this._inputFormat
170
+ }
171
+
172
+ if (this._readBuffer.indexOf('\n') !== -1) {
173
+ this._inputFormat = 'line'
174
+ return this._inputFormat
175
+ }
176
+
177
+ return undefined
178
+ }
179
+
180
+ private _readFramedMessage(): any | null {
181
+ if (!this._readBuffer) return null
182
+
183
+ const crlfHeaderEnd = this._readBuffer.indexOf('\r\n\r\n')
184
+ const lfHeaderEnd = this._readBuffer.indexOf('\n\n')
185
+
186
+ if (crlfHeaderEnd === -1 && lfHeaderEnd === -1) {
187
+ return null
188
+ }
189
+
190
+ let headerEnd = crlfHeaderEnd
191
+ let headerSeparatorLength = 4
192
+
193
+ if (headerEnd === -1 || (lfHeaderEnd !== -1 && lfHeaderEnd < headerEnd)) {
194
+ headerEnd = lfHeaderEnd
195
+ headerSeparatorLength = 2
196
+ }
197
+
198
+ const headerText = this._readBuffer.toString('utf8', 0, headerEnd)
199
+ const headers = headerText.split(/\r?\n/)
200
+ const lengthHeader = headers.find((line) => /^content-length\s*:/i.test(line))
201
+ if (!lengthHeader) {
202
+ throw new Error('Missing Content-Length header in framed stdio message')
203
+ }
204
+
205
+ const length = Number(lengthHeader.split(':')[1]?.trim())
206
+ if (!Number.isFinite(length) || length < 0) {
207
+ throw new Error(`Invalid Content-Length value: ${lengthHeader}`)
208
+ }
209
+
210
+ const bodyStart = headerEnd + headerSeparatorLength
211
+ const bodyEnd = bodyStart + length
212
+ if (this._readBuffer.length < bodyEnd) {
213
+ return null
214
+ }
215
+
216
+ const body = this._readBuffer.toString('utf8', bodyStart, bodyEnd)
217
+ this._readBuffer = this._readBuffer.subarray(bodyEnd)
218
+
219
+ return JSONRPCMessageSchema.parse(JSON.parse(body))
220
+ }
221
+
222
+ private _readLineMessage(): any | typeof SKIP_MESSAGE | null {
223
+ if (!this._readBuffer) return null
224
+
225
+ const newlineIndex = this._readBuffer.indexOf('\n')
226
+ if (newlineIndex === -1) {
227
+ return null
228
+ }
229
+
230
+ const line = this._readBuffer.toString('utf8', 0, newlineIndex).replace(/\r$/, '')
231
+ this._readBuffer = this._readBuffer.subarray(newlineIndex + 1)
232
+
233
+ if (line.trim() === '') {
234
+ return SKIP_MESSAGE
235
+ }
236
+
237
+ return JSONRPCMessageSchema.parse(JSON.parse(line))
238
+ }
239
+
240
+ async close() {
241
+ this._stdin.off('data', this._ondata)
242
+ this._stdin.off('error', this._onerror)
243
+
244
+ if (this._stdin.listenerCount('data') === 0) {
245
+ this._stdin.pause()
246
+ }
247
+
248
+ this._readBuffer = undefined
249
+ this.onclose?.()
250
+ }
251
+
252
+ send(message: any) {
253
+ return new Promise<void>((resolve) => {
254
+ const json = JSON.stringify(message)
255
+ const useFramed = this._inputFormat === 'line'
256
+ ? false
257
+ : (this.mode === 'codex' || this._inputFormat === 'framed')
258
+ const payload = useFramed
259
+ ? `Content-Length: ${Buffer.byteLength(json, 'utf8')}\r\n\r\n${json}`
260
+ : `${json}\n`
261
+
262
+ if (this._stdout.write(payload)) {
263
+ resolve()
264
+ } else {
265
+ this._stdout.once('drain', resolve)
266
+ }
267
+ })
268
+ }
269
+ }
270
+
271
+ /**
272
+ * MCP (Model Context Protocol) server for exposing tools, resources, and prompts
273
+ * to AI clients like Claude Code. Uses the low-level MCP SDK Server class directly
274
+ * with Zod 4 native JSON Schema conversion.
275
+ *
276
+ * Register tools, resources, and prompts programmatically, then start the server
277
+ * over stdio (for CLI integration) or HTTP (for remote access).
278
+ *
279
+ * @example
280
+ * ```ts
281
+ * const mcp = container.server('mcp', { serverName: 'my-server', serverVersion: '1.0.0' })
282
+ *
283
+ * mcp.tool('search_files', {
284
+ * schema: z.object({ pattern: z.string() }),
285
+ * description: 'Search for files',
286
+ * handler: async (args, ctx) => {
287
+ * return ctx.container.feature('fs').walk('.', { include: [args.pattern] }).files.join('\n')
288
+ * }
289
+ * })
290
+ *
291
+ * await mcp.start()
292
+ * ```
293
+ */
294
+ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
295
+ static override shortcut = 'servers.mcp' as const
296
+ static override stateSchema = MCPServerStateSchema
297
+ static override optionsSchema = MCPServerOptionsSchema
298
+ static override eventsSchema = MCPServerEventsSchema
299
+
300
+ static { Server.register(this, 'mcp') }
301
+
302
+ _mcpServer?: MCPProtocolServer
303
+ _tools: Map<string, RegisteredTool> = new Map()
304
+ _resources: Map<string, RegisteredResource> = new Map()
305
+ _prompts: Map<string, RegisteredPrompt> = new Map()
306
+
307
+ override get initialState(): MCPServerState {
308
+ return {
309
+ port: this.options.port,
310
+ listening: false,
311
+ configured: false,
312
+ stopped: false,
313
+ transport: undefined,
314
+ toolCount: 0,
315
+ resourceCount: 0,
316
+ promptCount: 0,
317
+ }
318
+ }
319
+
320
+ /** The underlying MCP protocol server instance. Created during configure(). */
321
+ get mcpServer(): MCPProtocolServer {
322
+ if (!this._mcpServer) {
323
+ this.configure()
324
+ }
325
+ return this._mcpServer!
326
+ }
327
+
328
+ /** The handler context passed to all tool, resource, and prompt handlers. */
329
+ get handlerContext(): MCPContext {
330
+ return { container: this.container }
331
+ }
332
+
333
+ /**
334
+ * Register an MCP tool. The tool's Zod schema is converted to JSON Schema
335
+ * for the protocol listing, and used for runtime argument validation.
336
+ *
337
+ * Tool handlers can return a string (auto-wrapped as text content) or a
338
+ * full CallToolResult object for advanced responses (images, errors, etc).
339
+ *
340
+ * @param name - Unique tool name
341
+ * @param options - Tool schema, description, and handler
342
+ */
343
+ override tool(name: string, options: ToolRegistrationOptions): this {
344
+ let jsonSchema: Record<string, any> | undefined
345
+
346
+ if (options.schema) {
347
+ const full = (options.schema as any).toJSONSchema() as Record<string, any>
348
+ jsonSchema = {
349
+ type: full.type || 'object',
350
+ properties: full.properties || {},
351
+ ...(full.required ? { required: full.required } : {}),
352
+ }
353
+ }
354
+
355
+ const registered: RegisteredTool = {
356
+ name,
357
+ description: options.description,
358
+ schema: options.schema,
359
+ jsonSchema,
360
+ handler: options.handler ?? (() => {}),
361
+ }
362
+
363
+ this._tools.set(name, registered)
364
+ this.state.set('toolCount', this._tools.size)
365
+ this.emit('toolRegistered', name)
366
+
367
+ return this
368
+ }
369
+
370
+ /**
371
+ * Register an MCP resource. Resources expose data (files, configs, etc)
372
+ * that AI clients can read by URI.
373
+ *
374
+ * Accepts either a handler function directly or an options object with
375
+ * additional metadata (name, description, mimeType).
376
+ *
377
+ * @param uri - Unique resource URI (e.g. "project://readme")
378
+ * @param handlerOrOptions - Handler function or options object with handler
379
+ */
380
+ resource(
381
+ uri: string,
382
+ handlerOrOptions: ResourceRegistrationOptions['handler'] | ResourceRegistrationOptions
383
+ ): this {
384
+ let registered: RegisteredResource
385
+
386
+ if (typeof handlerOrOptions === 'function') {
387
+ registered = { uri, handler: handlerOrOptions }
388
+ } else {
389
+ registered = {
390
+ uri,
391
+ name: handlerOrOptions.name,
392
+ description: handlerOrOptions.description,
393
+ mimeType: handlerOrOptions.mimeType,
394
+ handler: handlerOrOptions.handler,
395
+ }
396
+ }
397
+
398
+ this._resources.set(uri, registered)
399
+ this.state.set('resourceCount', this._resources.size)
400
+ this.emit('resourceRegistered', uri)
401
+
402
+ return this
403
+ }
404
+
405
+ /**
406
+ * Register an MCP prompt. Prompts are reusable message templates that
407
+ * AI clients can invoke with optional string arguments.
408
+ *
409
+ * @param name - Unique prompt name
410
+ * @param options - Prompt handler, optional args schema, and description
411
+ */
412
+ prompt(name: string, options: PromptRegistrationOptions): this {
413
+ const registered: RegisteredPrompt = {
414
+ name,
415
+ description: options.description,
416
+ args: options.args,
417
+ handler: options.handler,
418
+ }
419
+
420
+ this._prompts.set(name, registered)
421
+ this.state.set('promptCount', this._prompts.size)
422
+ this.emit('promptRegistered', name)
423
+
424
+ return this
425
+ }
426
+
427
+ /**
428
+ * Configure the MCP protocol server and register all protocol handlers.
429
+ * Called automatically before start() if not already configured.
430
+ */
431
+ override async configure(): Promise<this> {
432
+ if (this.isConfigured) return this
433
+
434
+ const serverName = this.options.serverName || this.container.manifest?.name || 'luca-mcp'
435
+ const serverVersion = this.options.serverVersion || this.container.manifest?.version || '1.0.0'
436
+
437
+ this._mcpServer = new MCPProtocolServer(
438
+ { name: serverName, version: serverVersion },
439
+ {
440
+ capabilities: {
441
+ tools: {},
442
+ resources: {},
443
+ prompts: {},
444
+ },
445
+ }
446
+ )
447
+
448
+ this._registerToolHandlers()
449
+ this._registerResourceHandlers()
450
+ this._registerPromptHandlers()
451
+
452
+ this._mcpServer.onerror = (error) => {
453
+ console.error('[MCP Server Error]', error)
454
+ }
455
+
456
+ this.state.set('configured', true)
457
+ return this
458
+ }
459
+
460
+ /**
461
+ * Start the MCP server with the specified transport.
462
+ *
463
+ * @param options - Transport configuration. Defaults to stdio.
464
+ * @param options.transport - 'stdio' for CLI integration, 'http' for remote access
465
+ * @param options.port - Port for HTTP transport (default 3001)
466
+ */
467
+ override async start(options?: {
468
+ transport?: 'stdio' | 'http'
469
+ port?: number
470
+ host?: string
471
+ mcpCompat?: MCPCompatMode
472
+ stdioCompat?: StdioCompatMode
473
+ }): Promise<this> {
474
+ if (this.isListening) return this
475
+ await this._drainPendingPlugins()
476
+ if (!this.isConfigured) await this.configure()
477
+
478
+ const transport = options?.transport || this.options.transport || 'stdio'
479
+
480
+ if (transport === 'stdio') {
481
+ const stdioCompat = this._resolveStdioCompat(options?.stdioCompat)
482
+ const stdioTransport = stdioCompat === 'standard'
483
+ ? new StdioServerTransport()
484
+ : new CompatStdioServerTransport(stdioCompat)
485
+ await this.mcpServer.connect(stdioTransport)
486
+ this.state.set('transport', 'stdio')
487
+ } else if (transport === 'http') {
488
+ const port = options?.port || this.options.port || 3001
489
+ const compat = this._resolveMCPCompat(options?.mcpCompat)
490
+ await this._startHTTPTransport(port, compat)
491
+ this.state.set('transport', 'http')
492
+ this.state.set('port', port)
493
+ }
494
+
495
+ this.state.set('listening', true)
496
+ return this
497
+ }
498
+
499
+ /**
500
+ * Stop the MCP server and close all connections.
501
+ */
502
+ override async stop(): Promise<this> {
503
+ if (this.isStopped) return this
504
+
505
+ if (this._mcpServer) {
506
+ await this._mcpServer.close()
507
+ }
508
+
509
+ this.state.set('listening', false)
510
+ this.state.set('stopped', true)
511
+ return this
512
+ }
513
+
514
+ /** Register tools/list and tools/call protocol handlers on the MCP server. */
515
+ private _registerToolHandlers() {
516
+ this.mcpServer.setRequestHandler(ListToolsRequestSchema, async () => {
517
+ const tools = Array.from(this._tools.values()).map((t) => ({
518
+ name: t.name,
519
+ description: t.description || '',
520
+ inputSchema: t.jsonSchema || { type: 'object' as const, properties: {} },
521
+ }))
522
+
523
+ return { tools }
524
+ })
525
+
526
+ this.mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
527
+ const { name, arguments: args = {} } = request.params
528
+
529
+ const tool = this._tools.get(name)
530
+ if (!tool) {
531
+ return {
532
+ content: [{ type: 'text' as const, text: `Unknown tool: ${name}` }],
533
+ isError: true,
534
+ }
535
+ }
536
+
537
+ try {
538
+ // Validate arguments with Zod schema if provided
539
+ const validatedArgs = tool.schema ? tool.schema.parse(args) : args
540
+
541
+ this.emit('toolCalled', name, validatedArgs)
542
+
543
+ const result = await tool.handler(validatedArgs, this.handlerContext)
544
+
545
+ // Auto-wrap string results into text content
546
+ if (typeof result === 'string') {
547
+ return {
548
+ content: [{ type: 'text' as const, text: result }],
549
+ }
550
+ }
551
+
552
+ // Assume it's already a CallToolResult
553
+ return result as CallToolResult
554
+ } catch (error: any) {
555
+ return {
556
+ content: [{ type: 'text' as const, text: `Error calling tool ${name}: ${error.message}` }],
557
+ isError: true,
558
+ }
559
+ }
560
+ })
561
+ }
562
+
563
+ /** Register resources/list and resources/read protocol handlers on the MCP server. */
564
+ private _registerResourceHandlers() {
565
+ this.mcpServer.setRequestHandler(ListResourcesRequestSchema, async () => {
566
+ const resources = Array.from(this._resources.values()).map((r) => ({
567
+ uri: r.uri,
568
+ name: r.name || r.uri,
569
+ description: r.description,
570
+ mimeType: r.mimeType,
571
+ }))
572
+
573
+ return { resources }
574
+ })
575
+
576
+ this.mcpServer.setRequestHandler(ReadResourceRequestSchema, async (request) => {
577
+ const { uri } = request.params
578
+
579
+ const resource = this._resources.get(uri)
580
+ if (!resource) {
581
+ throw new Error(`Unknown resource: ${uri}`)
582
+ }
583
+
584
+ const text = await resource.handler(uri, this.handlerContext)
585
+
586
+ return {
587
+ contents: [{
588
+ uri,
589
+ mimeType: resource.mimeType || 'text/plain',
590
+ text,
591
+ }],
592
+ }
593
+ })
594
+ }
595
+
596
+ /** Register prompts/list and prompts/get protocol handlers on the MCP server. */
597
+ private _registerPromptHandlers() {
598
+ this.mcpServer.setRequestHandler(ListPromptsRequestSchema, async () => {
599
+ const prompts = Array.from(this._prompts.values()).map((p) => ({
600
+ name: p.name,
601
+ description: p.description,
602
+ arguments: p.args
603
+ ? Object.entries(p.args).map(([argName, schema]) => ({
604
+ name: argName,
605
+ description: (schema as any)._zod?.def?.description || '',
606
+ required: !(schema as any).isOptional?.(),
607
+ }))
608
+ : undefined,
609
+ }))
610
+
611
+ return { prompts }
612
+ })
613
+
614
+ this.mcpServer.setRequestHandler(GetPromptRequestSchema, async (request) => {
615
+ const { name, arguments: args = {} } = request.params
616
+
617
+ const prompt = this._prompts.get(name)
618
+ if (!prompt) {
619
+ throw new Error(`Unknown prompt: ${name}`)
620
+ }
621
+
622
+ const messages = await prompt.handler(args as Record<string, string | undefined>, this.handlerContext)
623
+
624
+ return {
625
+ messages: messages.map((m) => ({
626
+ role: m.role,
627
+ content: { type: 'text' as const, text: m.content },
628
+ })),
629
+ }
630
+ })
631
+ }
632
+
633
+ /** Start an HTTP transport using StreamableHTTPServerTransport. */
634
+ private async _startHTTPTransport(port: number, compat: MCPCompatMode): Promise<void> {
635
+ const { createServer } = await import('node:http')
636
+ const { StreamableHTTPServerTransport } = await import(
637
+ '@modelcontextprotocol/sdk/server/streamableHttp.js'
638
+ )
639
+ const { randomUUID } = await import('node:crypto')
640
+
641
+ const transport = new StreamableHTTPServerTransport({
642
+ sessionIdGenerator: compat === 'codex' ? undefined : () => randomUUID(),
643
+ enableJsonResponse: compat === 'codex',
644
+ })
645
+
646
+ const httpServer = createServer(async (req, res) => {
647
+ if (compat === 'codex') {
648
+ this._normalizeCodexRequest(req)
649
+ this._ensureJSONContentType(res)
650
+ }
651
+
652
+ // Only handle the /mcp path
653
+ const url = new URL(req.url || '/', `http://localhost:${port}`)
654
+
655
+ if (url.pathname === '/mcp') {
656
+ // Parse body for POST requests
657
+ if (req.method === 'POST') {
658
+ const chunks: Buffer[] = []
659
+ for await (const chunk of req) {
660
+ chunks.push(chunk as Buffer)
661
+ }
662
+ const body = JSON.parse(Buffer.concat(chunks).toString())
663
+ await transport.handleRequest(req, res, body)
664
+ } else {
665
+ await transport.handleRequest(req, res)
666
+ }
667
+ } else {
668
+ res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' })
669
+ res.end(JSON.stringify({
670
+ jsonrpc: '2.0',
671
+ error: { code: -32004, message: 'Not found' },
672
+ id: null,
673
+ }))
674
+ }
675
+ })
676
+
677
+ await this.mcpServer.connect(transport)
678
+
679
+ await new Promise<void>((resolve) => {
680
+ httpServer.listen(port, () => resolve())
681
+ })
682
+ }
683
+
684
+ private _resolveMCPCompat(explicit?: MCPCompatMode): MCPCompatMode {
685
+ if (explicit === 'codex' || explicit === 'standard') {
686
+ return explicit
687
+ }
688
+
689
+ if (this.options.mcpCompat === 'codex' || this.options.mcpCompat === 'standard') {
690
+ return this.options.mcpCompat
691
+ }
692
+
693
+ const envValue = process.env.MCP_HTTP_COMPAT?.toLowerCase()
694
+ if (envValue === 'codex') {
695
+ return 'codex'
696
+ }
697
+
698
+ return 'standard'
699
+ }
700
+
701
+ private _resolveStdioCompat(explicit?: StdioCompatMode): StdioCompatMode {
702
+ if (explicit === 'codex' || explicit === 'auto' || explicit === 'standard') {
703
+ return explicit
704
+ }
705
+
706
+ if (
707
+ this.options.stdioCompat === 'codex'
708
+ || this.options.stdioCompat === 'auto'
709
+ || this.options.stdioCompat === 'standard'
710
+ ) {
711
+ return this.options.stdioCompat
712
+ }
713
+
714
+ const envValue = process.env.MCP_STDIO_COMPAT?.toLowerCase()
715
+ if (envValue === 'codex' || envValue === 'auto') {
716
+ return envValue
717
+ }
718
+
719
+ return 'standard'
720
+ }
721
+
722
+ private _normalizeCodexRequest(req: any) {
723
+ if (req.method !== 'POST') return
724
+
725
+ const accept = req.headers.accept
726
+
727
+ if (typeof accept === 'string') {
728
+ if (!accept.includes('application/json')) {
729
+ req.headers.accept = `application/json, ${accept}`
730
+ }
731
+ if (!req.headers.accept.includes('text/event-stream')) {
732
+ req.headers.accept = `${req.headers.accept}, text/event-stream`
733
+ }
734
+ return
735
+ }
736
+
737
+ if (Array.isArray(accept)) {
738
+ const joined = accept.join(', ')
739
+ req.headers.accept = `${joined}, text/event-stream`
740
+ if (!req.headers.accept.includes('application/json')) {
741
+ req.headers.accept = `application/json, ${req.headers.accept}`
742
+ }
743
+ return
744
+ }
745
+
746
+ req.headers.accept = 'application/json, text/event-stream'
747
+ }
748
+
749
+ private _ensureJSONContentType(res: any) {
750
+ const originalWriteHead = res.writeHead.bind(res)
751
+
752
+ res.writeHead = ((statusCode: number, ...args: any[]) => {
753
+ let statusMessage: string | undefined
754
+ let headers: any
755
+
756
+ if (typeof args[0] === 'string') {
757
+ statusMessage = args[0]
758
+ headers = args[1]
759
+ } else {
760
+ headers = args[0]
761
+ }
762
+
763
+ const hasContentType = (input: any): boolean => {
764
+ if (!input) return false
765
+
766
+ if (Array.isArray(input)) {
767
+ for (let i = 0; i < input.length; i += 2) {
768
+ const key = String(input[i] || '').toLowerCase()
769
+ if (key === 'content-type') return true
770
+ }
771
+ return false
772
+ }
773
+
774
+ return Object.keys(input).some((k) => k.toLowerCase() === 'content-type')
775
+ }
776
+
777
+ if (headers && !hasContentType(headers)) {
778
+ if (Array.isArray(headers)) {
779
+ headers = [...headers, 'Content-Type', 'application/json; charset=utf-8']
780
+ } else {
781
+ headers = { ...headers, 'Content-Type': 'application/json; charset=utf-8' }
782
+ }
783
+ } else if (!headers && !res.hasHeader('content-type')) {
784
+ res.setHeader('Content-Type', 'application/json; charset=utf-8')
785
+ }
786
+
787
+ if (statusMessage !== undefined && headers !== undefined) {
788
+ return originalWriteHead(statusCode, statusMessage, headers)
789
+ }
790
+ if (statusMessage !== undefined) {
791
+ return originalWriteHead(statusCode, statusMessage)
792
+ }
793
+ if (headers !== undefined) {
794
+ return originalWriteHead(statusCode, headers)
795
+ }
796
+
797
+ return originalWriteHead(statusCode)
798
+ }) as typeof res.writeHead
799
+ }
800
+ }
801
+
802
+ export default MCPServer