@datalayer/agent-runtimes 0.0.9 → 0.0.11

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 (291) hide show
  1. package/README.md +2 -1
  2. package/lib/{examples/components → components}/AgentConfiguration.d.ts +54 -9
  3. package/lib/components/AgentConfiguration.js +585 -0
  4. package/lib/{examples/components → components}/FooterMetrics.d.ts +1 -2
  5. package/lib/{examples/components → components}/Header.d.ts +1 -6
  6. package/lib/{examples/components → components}/Header.js +5 -39
  7. package/lib/{examples/components → components}/HeaderControls.d.ts +1 -2
  8. package/lib/{examples/components → components}/HeaderControls.js +1 -1
  9. package/lib/{examples/components → components}/LexicalEditor.d.ts +2 -3
  10. package/lib/{examples/components → components}/LexicalEditor.js +2 -2
  11. package/lib/components/MainContent.d.ts +34 -0
  12. package/lib/{examples/components → components}/MainContent.js +18 -9
  13. package/lib/components/McpServerManager.d.ts +30 -0
  14. package/lib/components/McpServerManager.js +331 -0
  15. package/lib/{examples/components → components}/MockFileBrowser.d.ts +1 -2
  16. package/lib/{examples/components → components}/SessionTabs.d.ts +2 -3
  17. package/lib/{examples/components → components}/TimeTravel.d.ts +1 -2
  18. package/lib/components/chat/components/AgentDetails.d.ts +3 -1
  19. package/lib/components/chat/components/AgentDetails.js +472 -22
  20. package/lib/components/chat/components/Chat.d.ts +37 -3
  21. package/lib/components/chat/components/Chat.js +29 -10
  22. package/lib/components/chat/components/ChatFloating.d.ts +27 -2
  23. package/lib/components/chat/components/ChatFloating.js +17 -10
  24. package/lib/components/chat/components/ChatPopupStandalone.js +1 -1
  25. package/lib/components/chat/components/ChatSidebar.d.ts +1 -1
  26. package/lib/components/chat/components/ChatStandalone.d.ts +1 -1
  27. package/lib/components/chat/components/ChatStandalone.js +1 -1
  28. package/lib/components/chat/components/ContextDistribution.d.ts +70 -6
  29. package/lib/components/chat/components/ContextDistribution.js +13 -6
  30. package/lib/components/chat/components/ContextInspector.d.ts +81 -0
  31. package/lib/components/chat/components/ContextInspector.js +263 -0
  32. package/lib/components/chat/components/ContextPanel.d.ts +112 -0
  33. package/lib/components/chat/components/ContextPanel.js +368 -0
  34. package/lib/components/chat/components/base/ChatBase.d.ts +74 -19
  35. package/lib/components/chat/components/base/ChatBase.js +296 -37
  36. package/lib/components/chat/components/index.d.ts +3 -1
  37. package/lib/components/chat/components/index.js +2 -0
  38. package/lib/components/chat/extensions/ExtensionRegistry.d.ts +1 -1
  39. package/lib/components/chat/extensions/index.d.ts +1 -0
  40. package/lib/components/chat/index.d.ts +3 -3
  41. package/lib/components/chat/protocols/AGUIAdapter.js +24 -4
  42. package/lib/components/chat/protocols/VercelAIAdapter.js +35 -1
  43. package/lib/components/chat/store/chatStore.d.ts +2 -3
  44. package/lib/components/chat/store/conversationStore.d.ts +83 -0
  45. package/lib/components/chat/store/conversationStore.js +174 -0
  46. package/lib/components/chat/store/index.d.ts +2 -1
  47. package/lib/components/chat/store/index.js +1 -0
  48. package/lib/components/chat/types/inference.d.ts +17 -0
  49. package/lib/components/chat/types/protocol.d.ts +10 -0
  50. package/lib/components/index.d.ts +23 -0
  51. package/lib/components/index.js +11 -0
  52. package/lib/config/agents/code-ai/agents.d.ts +25 -0
  53. package/lib/config/agents/code-ai/agents.js +70 -0
  54. package/lib/config/agents/code-ai/index.d.ts +1 -0
  55. package/lib/config/agents/code-ai/index.js +5 -0
  56. package/lib/config/agents/codemode-paper/agents.d.ts +29 -0
  57. package/lib/config/agents/codemode-paper/agents.js +288 -0
  58. package/lib/config/agents/codemode-paper/index.d.ts +1 -0
  59. package/lib/config/agents/codemode-paper/index.js +5 -0
  60. package/lib/config/agents/datalayer-ai/agents.d.ts +29 -0
  61. package/lib/config/agents/datalayer-ai/agents.js +267 -0
  62. package/lib/config/agents/datalayer-ai/index.d.ts +1 -0
  63. package/lib/config/agents/datalayer-ai/index.js +5 -0
  64. package/lib/config/agents/index.d.ts +19 -0
  65. package/lib/config/agents/index.js +38 -0
  66. package/lib/config/envvars.d.ts +28 -0
  67. package/lib/config/envvars.js +115 -0
  68. package/lib/config/index.d.ts +5 -0
  69. package/lib/config/index.js +9 -0
  70. package/lib/config/mcpServers.d.ts +18 -0
  71. package/lib/config/mcpServers.js +153 -0
  72. package/lib/config/skills.d.ts +27 -0
  73. package/lib/config/skills.js +60 -0
  74. package/lib/{lib → config}/utils.d.ts +1 -1
  75. package/lib/{lib → config}/utils.js +2 -2
  76. package/lib/examples/AgentRuntimeLexical2Example.d.ts +1 -0
  77. package/lib/examples/AgentRuntimeLexical2Example.js +3 -2
  78. package/lib/examples/AgentRuntimeLexicalExample.d.ts +1 -0
  79. package/lib/examples/AgentRuntimeLexicalExample.js +5 -3
  80. package/lib/examples/AgentRuntimeLexicalSidebarExample.d.ts +1 -0
  81. package/lib/examples/AgentRuntimeLexicalSidebarExample.js +3 -3
  82. package/lib/examples/AgentRuntimeNotebookExample.js +1 -1
  83. package/lib/examples/AgentSpaceFormExample.d.ts +2 -2
  84. package/lib/examples/AgentSpaceFormExample.js +215 -35
  85. package/lib/examples/CopilotKitLexicalExample.d.ts +1 -0
  86. package/lib/examples/CopilotKitLexicalExample.js +3 -2
  87. package/lib/examples/index.d.ts +1 -0
  88. package/lib/examples/stores/notebooks/NotebookExample2.ipynb.json +43 -43
  89. package/lib/hooks/useAGUI.d.ts +1 -1
  90. package/lib/hooks/useAGUI.js +1 -1
  91. package/lib/identity/types.d.ts +1 -1
  92. package/lib/index.d.ts +2 -0
  93. package/lib/index.js +1 -0
  94. package/lib/runtime/index.d.ts +3 -0
  95. package/lib/runtime/runtimeStore.d.ts +3 -4
  96. package/lib/runtime/useAgentConnection.d.ts +2 -3
  97. package/lib/runtime/useAgentRuntime.d.ts +2 -3
  98. package/lib/stories/Cell.stories.js +1 -1
  99. package/lib/tools/adapters/agent-runtimes/notebookHooks.js +1 -0
  100. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -0
  101. package/lib/types.d.ts +158 -0
  102. package/package.json +5 -6
  103. package/scripts/apply-patches.sh +1 -1
  104. package/scripts/codegen/generate_agents.py +863 -0
  105. package/scripts/codegen/generate_envvars.py +302 -0
  106. package/scripts/codegen/generate_mcp_servers.py +436 -0
  107. package/scripts/codegen/generate_skills.py +334 -0
  108. package/scripts/download-ai-elements.py +35 -20
  109. package/scripts/sync-jupyter.sh +6 -0
  110. package/lib/components/ui/accordion.d.ts +0 -7
  111. package/lib/components/ui/accordion.js +0 -22
  112. package/lib/components/ui/alert-dialog.d.ts +0 -14
  113. package/lib/components/ui/alert-dialog.js +0 -43
  114. package/lib/components/ui/alert.d.ts +0 -9
  115. package/lib/components/ui/alert.js +0 -24
  116. package/lib/components/ui/aspect-ratio.d.ts +0 -3
  117. package/lib/components/ui/aspect-ratio.js +0 -11
  118. package/lib/components/ui/avatar.d.ts +0 -6
  119. package/lib/components/ui/avatar.js +0 -18
  120. package/lib/components/ui/badge.d.ts +0 -9
  121. package/lib/components/ui/badge.js +0 -22
  122. package/lib/components/ui/breadcrumb.d.ts +0 -11
  123. package/lib/components/ui/breadcrumb.js +0 -27
  124. package/lib/components/ui/button-group.d.ts +0 -11
  125. package/lib/components/ui/button-group.js +0 -31
  126. package/lib/components/ui/button.d.ts +0 -13
  127. package/lib/components/ui/button.js +0 -39
  128. package/lib/components/ui/calendar.d.ts +0 -8
  129. package/lib/components/ui/calendar.js +0 -80
  130. package/lib/components/ui/card.d.ts +0 -9
  131. package/lib/components/ui/card.js +0 -24
  132. package/lib/components/ui/carousel.d.ts +0 -19
  133. package/lib/components/ui/carousel.js +0 -95
  134. package/lib/components/ui/chart.d.ts +0 -53
  135. package/lib/components/ui/chart.js +0 -136
  136. package/lib/components/ui/checkbox.d.ts +0 -4
  137. package/lib/components/ui/checkbox.js +0 -13
  138. package/lib/components/ui/collapsible.d.ts +0 -5
  139. package/lib/components/ui/collapsible.js +0 -17
  140. package/lib/components/ui/command.d.ts +0 -18
  141. package/lib/components/ui/command.js +0 -38
  142. package/lib/components/ui/context-menu.d.ts +0 -25
  143. package/lib/components/ui/context-menu.js +0 -55
  144. package/lib/components/ui/dialog.d.ts +0 -15
  145. package/lib/components/ui/dialog.js +0 -40
  146. package/lib/components/ui/drawer.d.ts +0 -13
  147. package/lib/components/ui/drawer.js +0 -39
  148. package/lib/components/ui/dropdown-menu.d.ts +0 -25
  149. package/lib/components/ui/dropdown-menu.js +0 -55
  150. package/lib/components/ui/empty.d.ts +0 -11
  151. package/lib/components/ui/empty.js +0 -37
  152. package/lib/components/ui/field.d.ts +0 -24
  153. package/lib/components/ui/field.js +0 -80
  154. package/lib/components/ui/form.d.ts +0 -24
  155. package/lib/components/ui/form.js +0 -63
  156. package/lib/components/ui/hover-card.d.ts +0 -6
  157. package/lib/components/ui/hover-card.js +0 -18
  158. package/lib/components/ui/input-group.d.ts +0 -19
  159. package/lib/components/ui/input-group.js +0 -69
  160. package/lib/components/ui/input-otp.d.ts +0 -11
  161. package/lib/components/ui/input-otp.js +0 -25
  162. package/lib/components/ui/input.d.ts +0 -3
  163. package/lib/components/ui/input.js +0 -6
  164. package/lib/components/ui/item.d.ts +0 -23
  165. package/lib/components/ui/item.js +0 -66
  166. package/lib/components/ui/kbd.d.ts +0 -3
  167. package/lib/components/ui/kbd.js +0 -13
  168. package/lib/components/ui/label.d.ts +0 -4
  169. package/lib/components/ui/label.js +0 -12
  170. package/lib/components/ui/menubar.d.ts +0 -26
  171. package/lib/components/ui/menubar.js +0 -58
  172. package/lib/components/ui/navigation-menu.d.ts +0 -14
  173. package/lib/components/ui/navigation-menu.js +0 -31
  174. package/lib/components/ui/pagination.d.ts +0 -13
  175. package/lib/components/ui/pagination.js +0 -29
  176. package/lib/components/ui/popover.d.ts +0 -7
  177. package/lib/components/ui/popover.js +0 -21
  178. package/lib/components/ui/progress.d.ts +0 -4
  179. package/lib/components/ui/progress.js +0 -12
  180. package/lib/components/ui/radio-group.d.ts +0 -5
  181. package/lib/components/ui/radio-group.js +0 -16
  182. package/lib/components/ui/resizable.d.ts +0 -8
  183. package/lib/components/ui/resizable.js +0 -19
  184. package/lib/components/ui/scroll-area.d.ts +0 -5
  185. package/lib/components/ui/scroll-area.js +0 -17
  186. package/lib/components/ui/select.d.ts +0 -15
  187. package/lib/components/ui/select.js +0 -42
  188. package/lib/components/ui/separator.d.ts +0 -4
  189. package/lib/components/ui/separator.js +0 -12
  190. package/lib/components/ui/sheet.d.ts +0 -13
  191. package/lib/components/ui/sheet.js +0 -44
  192. package/lib/components/ui/sidebar.d.ts +0 -69
  193. package/lib/components/ui/sidebar.js +0 -216
  194. package/lib/components/ui/skeleton.d.ts +0 -2
  195. package/lib/components/ui/skeleton.js +0 -10
  196. package/lib/components/ui/slider.d.ts +0 -4
  197. package/lib/components/ui/slider.js +0 -18
  198. package/lib/components/ui/sonner.d.ts +0 -3
  199. package/lib/components/ui/sonner.js +0 -25
  200. package/lib/components/ui/spinner.d.ts +0 -2
  201. package/lib/components/ui/spinner.js +0 -11
  202. package/lib/components/ui/switch.d.ts +0 -4
  203. package/lib/components/ui/switch.js +0 -12
  204. package/lib/components/ui/table.d.ts +0 -10
  205. package/lib/components/ui/table.js +0 -32
  206. package/lib/components/ui/tabs.d.ts +0 -7
  207. package/lib/components/ui/tabs.js +0 -21
  208. package/lib/components/ui/textarea.d.ts +0 -3
  209. package/lib/components/ui/textarea.js +0 -6
  210. package/lib/components/ui/toast.d.ts +0 -15
  211. package/lib/components/ui/toast.js +0 -38
  212. package/lib/components/ui/toaster.d.ts +0 -1
  213. package/lib/components/ui/toaster.js +0 -14
  214. package/lib/components/ui/toggle-group.d.ts +0 -9
  215. package/lib/components/ui/toggle-group.js +0 -26
  216. package/lib/components/ui/toggle.d.ts +0 -9
  217. package/lib/components/ui/toggle.js +0 -30
  218. package/lib/components/ui/tooltip.d.ts +0 -7
  219. package/lib/components/ui/tooltip.js +0 -21
  220. package/lib/components/vercel-ai-elements/artifact.d.ts +0 -23
  221. package/lib/components/vercel-ai-elements/artifact.js +0 -24
  222. package/lib/components/vercel-ai-elements/code-block.d.ts +0 -17
  223. package/lib/components/vercel-ai-elements/code-block.js +0 -94
  224. package/lib/components/vercel-ai-elements/conversation.d.ts +0 -15
  225. package/lib/components/vercel-ai-elements/conversation.js +0 -21
  226. package/lib/components/vercel-ai-elements/loader.d.ts +0 -5
  227. package/lib/components/vercel-ai-elements/loader.js +0 -8
  228. package/lib/components/vercel-ai-elements/message.d.ts +0 -46
  229. package/lib/components/vercel-ai-elements/message.js +0 -109
  230. package/lib/components/vercel-ai-elements/model-selector.d.ts +0 -35
  231. package/lib/components/vercel-ai-elements/model-selector.js +0 -22
  232. package/lib/components/vercel-ai-elements/prompt-input.d.ts +0 -195
  233. package/lib/components/vercel-ai-elements/prompt-input.js +0 -589
  234. package/lib/components/vercel-ai-elements/reasoning.d.ts +0 -26
  235. package/lib/components/vercel-ai-elements/reasoning.js +0 -80
  236. package/lib/components/vercel-ai-elements/shimmer.d.ts +0 -9
  237. package/lib/components/vercel-ai-elements/shimmer.js +0 -22
  238. package/lib/components/vercel-ai-elements/sources.d.ts +0 -12
  239. package/lib/components/vercel-ai-elements/sources.js +0 -13
  240. package/lib/components/vercel-ai-elements/suggestion.d.ts +0 -10
  241. package/lib/components/vercel-ai-elements/suggestion.js +0 -16
  242. package/lib/components/vercel-ai-elements/tool.d.ts +0 -23
  243. package/lib/components/vercel-ai-elements/tool.js +0 -52
  244. package/lib/examples/components/AgentConfiguration.js +0 -382
  245. package/lib/examples/components/MainContent.d.ts +0 -19
  246. package/lib/examples/components/index.d.ts +0 -10
  247. package/lib/examples/components/index.js +0 -13
  248. package/lib/examples/vercel-ai-elements/VercelAiElementsShowcase.d.ts +0 -12
  249. package/lib/examples/vercel-ai-elements/VercelAiElementsShowcase.js +0 -69
  250. package/lib/examples/vercel-ai-elements/components/ArtifactShowcase.d.ts +0 -1
  251. package/lib/examples/vercel-ai-elements/components/ArtifactShowcase.js +0 -85
  252. package/lib/examples/vercel-ai-elements/components/CodeBlockShowcase.d.ts +0 -1
  253. package/lib/examples/vercel-ai-elements/components/CodeBlockShowcase.js +0 -62
  254. package/lib/examples/vercel-ai-elements/components/ConversationShowcase.d.ts +0 -1
  255. package/lib/examples/vercel-ai-elements/components/ConversationShowcase.js +0 -51
  256. package/lib/examples/vercel-ai-elements/components/LoaderShowcase.d.ts +0 -1
  257. package/lib/examples/vercel-ai-elements/components/LoaderShowcase.js +0 -9
  258. package/lib/examples/vercel-ai-elements/components/MessageShowcase.d.ts +0 -1
  259. package/lib/examples/vercel-ai-elements/components/MessageShowcase.js +0 -56
  260. package/lib/examples/vercel-ai-elements/components/ModelSelectorShowcase.d.ts +0 -1
  261. package/lib/examples/vercel-ai-elements/components/ModelSelectorShowcase.js +0 -50
  262. package/lib/examples/vercel-ai-elements/components/PromptInputShowcase.d.ts +0 -1
  263. package/lib/examples/vercel-ai-elements/components/PromptInputShowcase.js +0 -16
  264. package/lib/examples/vercel-ai-elements/components/ReasoningShowcase.d.ts +0 -1
  265. package/lib/examples/vercel-ai-elements/components/ReasoningShowcase.js +0 -72
  266. package/lib/examples/vercel-ai-elements/components/ShimmerShowcase.d.ts +0 -1
  267. package/lib/examples/vercel-ai-elements/components/ShimmerShowcase.js +0 -9
  268. package/lib/examples/vercel-ai-elements/components/SourcesShowcase.d.ts +0 -1
  269. package/lib/examples/vercel-ai-elements/components/SourcesShowcase.js +0 -43
  270. package/lib/examples/vercel-ai-elements/components/SuggestionShowcase.d.ts +0 -1
  271. package/lib/examples/vercel-ai-elements/components/SuggestionShowcase.js +0 -31
  272. package/lib/examples/vercel-ai-elements/components/ToolShowcase.d.ts +0 -1
  273. package/lib/examples/vercel-ai-elements/components/ToolShowcase.js +0 -54
  274. package/lib/examples/vercel-ai-elements/index.d.ts +0 -13
  275. package/lib/examples/vercel-ai-elements/index.js +0 -17
  276. package/lib/examples/vercel-ai-elements/main.d.ts +0 -1
  277. package/lib/examples/vercel-ai-elements/main.js +0 -9
  278. package/lib/examples/vercel-ai-elements/showcase.css +0 -128
  279. package/lib/hooks/useToast.d.ts +0 -44
  280. package/lib/hooks/useToast.js +0 -128
  281. package/patches/@datalayer+jupyter-lexical+1.0.8.patch +0 -11628
  282. package/patches/@datalayer+jupyter-react+2.0.2.patch +0 -5338
  283. package/style/showcase-vercel-ai.css +0 -137
  284. /package/lib/{examples/components → components}/FooterMetrics.js +0 -0
  285. /package/lib/{examples/components → components}/MockFileBrowser.js +0 -0
  286. /package/lib/{examples/components → components}/SessionTabs.js +0 -0
  287. /package/lib/{examples/components → components}/TimeTravel.js +0 -0
  288. /package/lib/{models → types}/AIAgent.d.ts +0 -0
  289. /package/lib/{models → types}/AIAgent.js +0 -0
  290. /package/lib/{models → types}/index.d.ts +0 -0
  291. /package/lib/{models → types}/index.js +0 -0
@@ -0,0 +1,436 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2025-2026 Datalayer, Inc.
3
+ # Distributed under the terms of the Modified BSD License.
4
+
5
+ """
6
+ Generate Python and TypeScript code from YAML MCP server specifications.
7
+
8
+ Usage:
9
+ python generate_mcp_servers.py \\
10
+ --specs-dir specs/mcp-servers \\
11
+ --python-output agent_runtimes/mcp/catalog_mcp_servers.py \\
12
+ --typescript-output src/config/mcpServers.ts
13
+ """
14
+
15
+ import argparse
16
+ import sys
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ import yaml
21
+
22
+
23
+ def load_mcp_specs(specs_dir: Path) -> list[dict[str, Any]]:
24
+ """Load all MCP server YAML specifications from a directory."""
25
+ specs = []
26
+ for yaml_file in sorted(specs_dir.glob("*.yaml")):
27
+ with open(yaml_file) as f:
28
+ spec = yaml.safe_load(f)
29
+ specs.append(spec)
30
+ return specs
31
+
32
+
33
+ def generate_python_code(specs: list[dict[str, Any]]) -> str:
34
+ """Generate Python code from MCP server specifications."""
35
+ lines = [
36
+ "# Copyright (c) 2025-2026 Datalayer, Inc.",
37
+ "# Distributed under the terms of the Modified BSD License.",
38
+ '"""',
39
+ "MCP Server Catalog.",
40
+ "",
41
+ "Predefined MCP server configurations that can be used by agents.",
42
+ "Credentials are configured via environment variables.",
43
+ "",
44
+ "This file is AUTO-GENERATED from YAML specifications.",
45
+ "DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
46
+ '"""',
47
+ "",
48
+ "import os",
49
+ "import tempfile",
50
+ "from typing import Dict",
51
+ "",
52
+ "from agent_runtimes.types import MCPServer",
53
+ "",
54
+ "# " + "=" * 76,
55
+ "# MCP Server Definitions",
56
+ "# " + "=" * 76,
57
+ "",
58
+ ]
59
+
60
+ # Generate server constants
61
+ for spec in specs:
62
+ server_id = spec["id"]
63
+ const_name = f"{server_id.upper().replace('-', '_')}_MCP_SERVER"
64
+
65
+ # Format args properly
66
+ args_list = spec.get("args", [])
67
+ if args_list:
68
+ arg_items = []
69
+ for arg in args_list:
70
+ if arg == "$TMPDIR":
71
+ arg_items.append(" tempfile.gettempdir()")
72
+ else:
73
+ arg_items.append(f' "{arg}"')
74
+ args_formatted = "[\n" + ",\n".join(arg_items) + ",\n ]"
75
+ else:
76
+ args_formatted = "[]"
77
+
78
+ # Format env dict
79
+ env_dict = spec.get("env", {})
80
+ if env_dict:
81
+ env_formatted = (
82
+ "{\n"
83
+ + ",\n".join(
84
+ f' "{key}": "{value}"' for key, value in env_dict.items()
85
+ )
86
+ + ",\n }"
87
+ )
88
+ else:
89
+ env_formatted = None
90
+
91
+ # Format envvars
92
+ envvars = spec.get("envvars", [])
93
+ if envvars:
94
+ envvars_formatted = "[" + ", ".join(f'"{v}"' for v in envvars) + "]"
95
+ else:
96
+ envvars_formatted = "[]"
97
+
98
+ # Format optional fields
99
+ icon = f'"{spec.get("icon")}"' if spec.get("icon") else "None"
100
+ emoji = f'"{spec.get("emoji")}"' if spec.get("emoji") else "None"
101
+
102
+ lines.extend(
103
+ [
104
+ f"{const_name} = MCPServer(",
105
+ f' id="{server_id}",',
106
+ f' name="{spec["name"]}",',
107
+ f' description="{spec["description"]}",',
108
+ f" icon={icon},",
109
+ f" emoji={emoji},",
110
+ f' command="{spec["command"]}",',
111
+ f" args={args_formatted},",
112
+ f' transport="{spec.get("transport", "stdio")}",',
113
+ f" enabled={spec.get('enabled', True)},",
114
+ " tools=[],",
115
+ ]
116
+ )
117
+
118
+ # Add env field if present
119
+ if env_formatted:
120
+ lines.append(f" env={env_formatted},")
121
+
122
+ lines.extend(
123
+ [
124
+ f" required_env_vars={envvars_formatted},",
125
+ ")",
126
+ "",
127
+ ]
128
+ )
129
+
130
+ # Generate catalog dictionary
131
+ lines.extend(
132
+ [
133
+ "# " + "=" * 76,
134
+ "# MCP Server Catalog",
135
+ "# " + "=" * 76,
136
+ "",
137
+ "MCP_SERVER_CATALOG: Dict[str, MCPServer] = {",
138
+ ]
139
+ )
140
+
141
+ for spec in specs:
142
+ server_id = spec["id"]
143
+ const_name = f"{server_id.upper().replace('-', '_')}_MCP_SERVER"
144
+ lines.append(f' "{server_id}": {const_name},')
145
+
146
+ lines.extend(
147
+ [
148
+ "}",
149
+ "",
150
+ "",
151
+ "def check_env_vars_available(env_vars: list[str]) -> bool:",
152
+ ' """',
153
+ " Check if all required environment variables are set.",
154
+ "",
155
+ " Args:",
156
+ " env_vars: List of environment variable names to check.",
157
+ "",
158
+ " Returns:",
159
+ " True if all env vars are set (non-empty), False otherwise.",
160
+ ' """',
161
+ " if not env_vars:",
162
+ " return True # No env vars required",
163
+ " return all(os.environ.get(var) for var in env_vars)",
164
+ "",
165
+ "",
166
+ "def get_catalog_server(server_id: str) -> MCPServer | None:",
167
+ ' """',
168
+ " Get a catalog MCP server by ID.",
169
+ "",
170
+ " Args:",
171
+ " server_id: The unique identifier of the MCP server.",
172
+ "",
173
+ " Returns:",
174
+ " The MCPServer configuration, or None if not found.",
175
+ ' """',
176
+ " return MCP_SERVER_CATALOG.get(server_id)",
177
+ "",
178
+ "",
179
+ "def list_catalog_servers() -> list[MCPServer]:",
180
+ ' """',
181
+ " List all catalog MCP servers with availability status.",
182
+ "",
183
+ " For each server, checks if the required environment variables are set",
184
+ " and updates the `is_available` field accordingly.",
185
+ "",
186
+ " Returns:",
187
+ " List of all catalog MCPServer configurations with updated availability.",
188
+ ' """',
189
+ " servers = []",
190
+ " for server in MCP_SERVER_CATALOG.values():",
191
+ " # Create a copy with updated availability",
192
+ " server_copy = server.model_copy()",
193
+ " server_copy.is_available = check_env_vars_available(server.required_env_vars)",
194
+ " servers.append(server_copy)",
195
+ " return servers",
196
+ "",
197
+ ]
198
+ )
199
+
200
+ return "\n".join(lines)
201
+
202
+
203
+ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
204
+ """Generate TypeScript code from MCP server specifications."""
205
+ lines = [
206
+ "/*",
207
+ " * Copyright (c) 2025-2026 Datalayer, Inc.",
208
+ " * Distributed under the terms of the Modified BSD License.",
209
+ " */",
210
+ "",
211
+ "/**",
212
+ " * MCP Server Catalog",
213
+ " *",
214
+ " * Predefined MCP server configurations.",
215
+ " *",
216
+ " * This file is AUTO-GENERATED from YAML specifications.",
217
+ " * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
218
+ " */",
219
+ "",
220
+ "import type { MCPServer } from '../types';",
221
+ "",
222
+ "// " + "=" * 76,
223
+ "// MCP Server Definitions",
224
+ "// " + "=" * 76,
225
+ "",
226
+ ]
227
+
228
+ # Generate server constants
229
+ for spec in specs:
230
+ server_id = spec["id"]
231
+ const_name = f"{server_id.upper().replace('-', '_')}_MCP_SERVER"
232
+
233
+ # Format args
234
+ args_list = spec.get("args", [])
235
+ args_formatted = "[" + ", ".join(f"'{arg}'" for arg in args_list) + "]"
236
+
237
+ # Format envvars
238
+ envvars = spec.get("envvars", [])
239
+ if envvars:
240
+ envvars_formatted = "[" + ", ".join(f"'{v}'" for v in envvars) + "]"
241
+ else:
242
+ envvars_formatted = "[]"
243
+
244
+ # Format optional fields
245
+ icon = f"'{spec.get('icon')}'" if spec.get("icon") else "undefined"
246
+ emoji = f"'{spec.get('emoji')}'" if spec.get("emoji") else "undefined"
247
+
248
+ # Escape description for TypeScript
249
+ description = spec.get("description", "").replace("'", "\\'")
250
+
251
+ lines.extend(
252
+ [
253
+ f"export const {const_name}: MCPServer = {{",
254
+ f" id: '{server_id}',",
255
+ f" name: '{spec['name']}',",
256
+ f" description: '{description}',",
257
+ f" icon: {icon},",
258
+ f" emoji: {emoji},",
259
+ f" url: '',",
260
+ f" command: '{spec['command']}',",
261
+ f" args: {args_formatted},",
262
+ f" transport: '{spec.get('transport', 'stdio')}',",
263
+ f" enabled: {str(spec.get('enabled', True)).lower()},",
264
+ " isAvailable: false,",
265
+ " tools: [],",
266
+ f" requiredEnvVars: {envvars_formatted},",
267
+ "};",
268
+ "",
269
+ ]
270
+ )
271
+
272
+ # Generate library object
273
+ lines.extend(
274
+ [
275
+ "// " + "=" * 76,
276
+ "// MCP Server Library",
277
+ "// " + "=" * 76,
278
+ "",
279
+ "export const MCP_SERVER_LIBRARY: Record<string, MCPServer> = {",
280
+ ]
281
+ )
282
+
283
+ for spec in specs:
284
+ server_id = spec["id"]
285
+ const_name = f"{server_id.upper().replace('-', '_')}_MCP_SERVER"
286
+ # Quote keys with hyphens for valid JavaScript syntax
287
+ key = f"'{server_id}'" if "-" in server_id else server_id
288
+ lines.append(f" {key}: {const_name},")
289
+
290
+ lines.extend(
291
+ [
292
+ "};",
293
+ "",
294
+ ]
295
+ )
296
+
297
+ return "\n".join(lines)
298
+
299
+
300
+ def update_init_file(specs: list[dict[str, Any]], init_file: Path) -> None:
301
+ """Update the __init__.py file with correct imports based on generated specs."""
302
+ # Generate list of MCP server constant names
303
+ server_constants = []
304
+ for spec in specs:
305
+ server_id = spec["id"]
306
+ const_name = server_id.upper().replace("-", "_") + "_MCP_SERVER"
307
+ server_constants.append(const_name)
308
+
309
+ # Read the current __init__.py
310
+ init_content = init_file.read_text()
311
+
312
+ # Find the catalog_mcp_servers import section
313
+ import_start = init_content.find("from .catalog_mcp_servers import (")
314
+ if import_start == -1:
315
+ print(f"Warning: Could not find catalog_mcp_servers import in {init_file}")
316
+ return
317
+
318
+ # Find the end of the import statement
319
+ import_end = init_content.find(")", import_start)
320
+ if import_end == -1:
321
+ print(
322
+ f"Warning: Could not find end of catalog_mcp_servers import in {init_file}"
323
+ )
324
+ return
325
+
326
+ # Generate new import lines - all names sorted alphabetically (ruff/isort order)
327
+ all_names = sorted(
328
+ server_constants
329
+ + [
330
+ "MCP_SERVER_CATALOG",
331
+ "check_env_vars_available",
332
+ "get_catalog_server",
333
+ "list_catalog_servers",
334
+ ],
335
+ key=str.casefold,
336
+ )
337
+ new_imports = ["from .catalog_mcp_servers import ("]
338
+ for name in all_names:
339
+ new_imports.append(f" {name},")
340
+ new_imports.append(")")
341
+
342
+ # Replace the import section
343
+ new_content = (
344
+ init_content[:import_start]
345
+ + "\n".join(new_imports)
346
+ + init_content[import_end + 1 :]
347
+ )
348
+
349
+ # Update the __all__ list - find the catalog_mcp_servers.py exports section
350
+ all_start = new_content.find("# catalog_mcp_servers.py exports")
351
+ if all_start != -1:
352
+ # Find the end of this section (next closing bracket or end of __all__)
353
+ all_section_start = all_start
354
+ all_end = new_content.find("]", all_section_start)
355
+
356
+ # Generate new __all__ entries for MCP servers
357
+ all_entries = [
358
+ " # catalog_mcp_servers.py exports",
359
+ ' "MCP_SERVER_CATALOG",',
360
+ ' "check_env_vars_available",',
361
+ ' "get_catalog_server",',
362
+ ' "list_catalog_servers",',
363
+ ]
364
+ for const in sorted(server_constants):
365
+ all_entries.append(f' "{const}",')
366
+ all_entries.append("]")
367
+
368
+ # Replace the section
369
+ new_content = new_content[:all_section_start] + "\n".join(all_entries)
370
+
371
+ # Write updated content
372
+ init_file.write_text(new_content)
373
+ print(f"✓ Updated {init_file}")
374
+
375
+
376
+ def main():
377
+ """Main entry point."""
378
+ parser = argparse.ArgumentParser(
379
+ description="Generate Python and TypeScript code from YAML MCP server specifications"
380
+ )
381
+ parser.add_argument(
382
+ "--specs-dir",
383
+ type=Path,
384
+ required=True,
385
+ help="Directory containing YAML specification files",
386
+ )
387
+ parser.add_argument(
388
+ "--python-output",
389
+ type=Path,
390
+ required=True,
391
+ help="Output path for generated Python file",
392
+ )
393
+ parser.add_argument(
394
+ "--typescript-output",
395
+ type=Path,
396
+ required=True,
397
+ help="Output path for generated TypeScript file",
398
+ )
399
+
400
+ args = parser.parse_args()
401
+
402
+ # Validate specs directory
403
+ if not args.specs_dir.exists():
404
+ print(f"Error: Specs directory does not exist: {args.specs_dir}")
405
+ sys.exit(1)
406
+
407
+ # Load specifications
408
+ print(f"Loading MCP server specs from {args.specs_dir}...")
409
+ specs = load_mcp_specs(args.specs_dir)
410
+ print(f"Loaded {len(specs)} MCP server specifications")
411
+
412
+ # Generate Python code
413
+ print(f"Generating Python code...")
414
+ python_code = generate_python_code(specs)
415
+ args.python_output.parent.mkdir(parents=True, exist_ok=True)
416
+ args.python_output.write_text(python_code)
417
+ print(f"✓ Generated {args.python_output}")
418
+
419
+ # Generate TypeScript code
420
+ print(f"Generating TypeScript code...")
421
+ typescript_code = generate_typescript_code(specs)
422
+ args.typescript_output.parent.mkdir(parents=True, exist_ok=True)
423
+ args.typescript_output.write_text(typescript_code)
424
+ print(f"✓ Generated {args.typescript_output}")
425
+
426
+ # Update __init__.py with correct imports
427
+ init_file = args.python_output.parent / "__init__.py"
428
+ if init_file.exists():
429
+ print(f"Updating imports in __init__.py...")
430
+ update_init_file(specs, init_file)
431
+
432
+ print(f"\n✓ Successfully generated code from {len(specs)} MCP server specs")
433
+
434
+
435
+ if __name__ == "__main__":
436
+ main()