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