hvmcp 0.1.0__tar.gz

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 (132) hide show
  1. hvmcp-0.1.0/.github/workflows/publish.yml +44 -0
  2. hvmcp-0.1.0/.gitignore +57 -0
  3. hvmcp-0.1.0/AGENTS.md +209 -0
  4. hvmcp-0.1.0/PKG-INFO +522 -0
  5. hvmcp-0.1.0/README.md +471 -0
  6. hvmcp-0.1.0/assets/holoviews.png +0 -0
  7. hvmcp-0.1.0/assets/hvplot.png +0 -0
  8. hvmcp-0.1.0/assets/panel.png +0 -0
  9. hvmcp-0.1.0/mcp_architecture.png +0 -0
  10. hvmcp-0.1.0/mrve.py +490 -0
  11. hvmcp-0.1.0/panel-live-server/.copier-answers.yml +16 -0
  12. hvmcp-0.1.0/panel-live-server/.gitattributes +1 -0
  13. hvmcp-0.1.0/panel-live-server/.github/CODEOWNERS +1 -0
  14. hvmcp-0.1.0/panel-live-server/.github/dependabot.yml +10 -0
  15. hvmcp-0.1.0/panel-live-server/.github/workflows/build.yml +45 -0
  16. hvmcp-0.1.0/panel-live-server/.github/workflows/ci.yml +122 -0
  17. hvmcp-0.1.0/panel-live-server/.github/workflows/docs.yml +55 -0
  18. hvmcp-0.1.0/panel-live-server/.github/workflows/update-lockfiles.yml +34 -0
  19. hvmcp-0.1.0/panel-live-server/.gitignore +383 -0
  20. hvmcp-0.1.0/panel-live-server/.pre-commit-config.yaml +51 -0
  21. hvmcp-0.1.0/panel-live-server/.prettierrc +7 -0
  22. hvmcp-0.1.0/panel-live-server/LICENSE.txt +30 -0
  23. hvmcp-0.1.0/panel-live-server/MANIFEST.in +1 -0
  24. hvmcp-0.1.0/panel-live-server/README.md +102 -0
  25. hvmcp-0.1.0/panel-live-server/docs/assets/gif/panel-live-server-showcase-mcp.gif +0 -0
  26. hvmcp-0.1.0/panel-live-server/docs/assets/gif/panel-live-server-showcase.gif +0 -0
  27. hvmcp-0.1.0/panel-live-server/docs/assets/logo.svg +157 -0
  28. hvmcp-0.1.0/panel-live-server/docs/assets/videos/panel-live-server-showcase-mcp-fast.mp4 +0 -0
  29. hvmcp-0.1.0/panel-live-server/docs/assets/videos/panel-live-server-showcase-mcp.mp4 +0 -0
  30. hvmcp-0.1.0/panel-live-server/docs/assets/videos/panel-live-server-showcase.mp4 +0 -0
  31. hvmcp-0.1.0/panel-live-server/docs/examples.md +262 -0
  32. hvmcp-0.1.0/panel-live-server/docs/explanation/architecture.md +203 -0
  33. hvmcp-0.1.0/panel-live-server/docs/how-to/configure-server.md +232 -0
  34. hvmcp-0.1.0/panel-live-server/docs/index.md +207 -0
  35. hvmcp-0.1.0/panel-live-server/docs/reference/panel_live_server.md +8 -0
  36. hvmcp-0.1.0/panel-live-server/docs/tutorials/getting-started.md +311 -0
  37. hvmcp-0.1.0/panel-live-server/docs/tutorials/installation.md +86 -0
  38. hvmcp-0.1.0/panel-live-server/docs/tutorials/mcp-server.md +217 -0
  39. hvmcp-0.1.0/panel-live-server/docs/tutorials/standalone-server.md +207 -0
  40. hvmcp-0.1.0/panel-live-server/pixi.lock +13526 -0
  41. hvmcp-0.1.0/panel-live-server/pixi.toml +66 -0
  42. hvmcp-0.1.0/panel-live-server/project/closed-issues.md +134 -0
  43. hvmcp-0.1.0/panel-live-server/project/open-issues.md +10 -0
  44. hvmcp-0.1.0/panel-live-server/pyproject.toml +187 -0
  45. hvmcp-0.1.0/panel-live-server/research/panel-viz-mcp.md +241 -0
  46. hvmcp-0.1.0/panel-live-server/src/panel_live_server/__init__.py +14 -0
  47. hvmcp-0.1.0/panel-live-server/src/panel_live_server/app.py +121 -0
  48. hvmcp-0.1.0/panel-live-server/src/panel_live_server/cli.py +280 -0
  49. hvmcp-0.1.0/panel-live-server/src/panel_live_server/client.py +109 -0
  50. hvmcp-0.1.0/panel-live-server/src/panel_live_server/config.py +86 -0
  51. hvmcp-0.1.0/panel-live-server/src/panel_live_server/database.py +602 -0
  52. hvmcp-0.1.0/panel-live-server/src/panel_live_server/endpoints.py +116 -0
  53. hvmcp-0.1.0/panel-live-server/src/panel_live_server/manager.py +364 -0
  54. hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/__init__.py +8 -0
  55. hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/add_page.py +200 -0
  56. hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/admin_page.py +155 -0
  57. hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/feed_page.py +204 -0
  58. hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/view_page.py +216 -0
  59. hvmcp-0.1.0/panel-live-server/src/panel_live_server/py.typed +0 -0
  60. hvmcp-0.1.0/panel-live-server/src/panel_live_server/server.py +648 -0
  61. hvmcp-0.1.0/panel-live-server/src/panel_live_server/templates/show.html +447 -0
  62. hvmcp-0.1.0/panel-live-server/src/panel_live_server/ui.py +17 -0
  63. hvmcp-0.1.0/panel-live-server/src/panel_live_server/utils.py +443 -0
  64. hvmcp-0.1.0/panel-live-server/src/panel_live_server/validation.py +303 -0
  65. hvmcp-0.1.0/panel-live-server/tests/__init__.py +0 -0
  66. hvmcp-0.1.0/panel-live-server/tests/conftest.py +24 -0
  67. hvmcp-0.1.0/panel-live-server/tests/test_app.py +37 -0
  68. hvmcp-0.1.0/panel-live-server/tests/test_cli.py +28 -0
  69. hvmcp-0.1.0/panel-live-server/tests/test_config.py +156 -0
  70. hvmcp-0.1.0/panel-live-server/tests/test_database.py +184 -0
  71. hvmcp-0.1.0/panel-live-server/tests/test_endpoints.py +154 -0
  72. hvmcp-0.1.0/panel-live-server/tests/test_integration.py +191 -0
  73. hvmcp-0.1.0/panel-live-server/tests/test_manager.py +167 -0
  74. hvmcp-0.1.0/panel-live-server/tests/test_server.py +454 -0
  75. hvmcp-0.1.0/panel-live-server/tests/test_utils.py +610 -0
  76. hvmcp-0.1.0/panel-live-server/tests/test_validation.py +227 -0
  77. hvmcp-0.1.0/panel-live-server/tests/test_view_page.py +134 -0
  78. hvmcp-0.1.0/panel-live-server/tests/ui/__init__.py +1 -0
  79. hvmcp-0.1.0/panel-live-server/tests/ui/test_ui.py +26 -0
  80. hvmcp-0.1.0/panel-live-server/uv.lock +4317 -0
  81. hvmcp-0.1.0/panel-live-server/zensical.toml +129 -0
  82. hvmcp-0.1.0/pixi.lock +7433 -0
  83. hvmcp-0.1.0/pixi.toml +45 -0
  84. hvmcp-0.1.0/pyproject.toml +99 -0
  85. hvmcp-0.1.0/smithery.yaml +24 -0
  86. hvmcp-0.1.0/src/holoviz_mcp_server/__init__.py +8 -0
  87. hvmcp-0.1.0/src/holoviz_mcp_server/chart_builders.py +418 -0
  88. hvmcp-0.1.0/src/holoviz_mcp_server/cli.py +144 -0
  89. hvmcp-0.1.0/src/holoviz_mcp_server/codegen/__init__.py +0 -0
  90. hvmcp-0.1.0/src/holoviz_mcp_server/codegen/codegen.py +149 -0
  91. hvmcp-0.1.0/src/holoviz_mcp_server/config.py +86 -0
  92. hvmcp-0.1.0/src/holoviz_mcp_server/display/__init__.py +1 -0
  93. hvmcp-0.1.0/src/holoviz_mcp_server/display/app.py +91 -0
  94. hvmcp-0.1.0/src/holoviz_mcp_server/display/client.py +52 -0
  95. hvmcp-0.1.0/src/holoviz_mcp_server/display/database.py +328 -0
  96. hvmcp-0.1.0/src/holoviz_mcp_server/display/endpoints.py +97 -0
  97. hvmcp-0.1.0/src/holoviz_mcp_server/display/manager.py +242 -0
  98. hvmcp-0.1.0/src/holoviz_mcp_server/display/pages/__init__.py +5 -0
  99. hvmcp-0.1.0/src/holoviz_mcp_server/display/pages/view_page.py +183 -0
  100. hvmcp-0.1.0/src/holoviz_mcp_server/introspection/__init__.py +1 -0
  101. hvmcp-0.1.0/src/holoviz_mcp_server/introspection/holoviews.py +59 -0
  102. hvmcp-0.1.0/src/holoviz_mcp_server/introspection/hvplot.py +59 -0
  103. hvmcp-0.1.0/src/holoviz_mcp_server/introspection/panel.py +123 -0
  104. hvmcp-0.1.0/src/holoviz_mcp_server/introspection/skills.py +110 -0
  105. hvmcp-0.1.0/src/holoviz_mcp_server/py.typed +0 -0
  106. hvmcp-0.1.0/src/holoviz_mcp_server/server/__init__.py +1 -0
  107. hvmcp-0.1.0/src/holoviz_mcp_server/server/compose.py +19 -0
  108. hvmcp-0.1.0/src/holoviz_mcp_server/server/guided_mcp.py +290 -0
  109. hvmcp-0.1.0/src/holoviz_mcp_server/server/holoviews_mcp.py +34 -0
  110. hvmcp-0.1.0/src/holoviz_mcp_server/server/hvplot_mcp.py +34 -0
  111. hvmcp-0.1.0/src/holoviz_mcp_server/server/main.py +1169 -0
  112. hvmcp-0.1.0/src/holoviz_mcp_server/server/panel_mcp.py +77 -0
  113. hvmcp-0.1.0/src/holoviz_mcp_server/skills/charting/SKILL.md +102 -0
  114. hvmcp-0.1.0/src/holoviz_mcp_server/skills/data/SKILL.md +124 -0
  115. hvmcp-0.1.0/src/holoviz_mcp_server/skills/holoviews/SKILL.md +158 -0
  116. hvmcp-0.1.0/src/holoviz_mcp_server/skills/hvplot/SKILL.md +100 -0
  117. hvmcp-0.1.0/src/holoviz_mcp_server/skills/panel/SKILL.md +211 -0
  118. hvmcp-0.1.0/src/holoviz_mcp_server/skills/param/SKILL.md +147 -0
  119. hvmcp-0.1.0/src/holoviz_mcp_server/templates/dashboard.html +379 -0
  120. hvmcp-0.1.0/src/holoviz_mcp_server/templates/multi.html +105 -0
  121. hvmcp-0.1.0/src/holoviz_mcp_server/templates/show.html +309 -0
  122. hvmcp-0.1.0/src/holoviz_mcp_server/templates/stream.html +107 -0
  123. hvmcp-0.1.0/src/holoviz_mcp_server/themes.py +39 -0
  124. hvmcp-0.1.0/src/holoviz_mcp_server/utils.py +217 -0
  125. hvmcp-0.1.0/src/holoviz_mcp_server/validation.py +225 -0
  126. hvmcp-0.1.0/tests/__init__.py +0 -0
  127. hvmcp-0.1.0/tests/conftest.py +12 -0
  128. hvmcp-0.1.0/tests/test_codegen.py +125 -0
  129. hvmcp-0.1.0/tests/test_config.py +73 -0
  130. hvmcp-0.1.0/tests/test_skills.py +55 -0
  131. hvmcp-0.1.0/tests/test_utils.py +81 -0
  132. hvmcp-0.1.0/tests/test_validation.py +95 -0
@@ -0,0 +1,44 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ with:
14
+ fetch-depth: 0
15
+
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.11"
19
+
20
+ - name: Install build tools
21
+ run: pip install build hatchling hatch-vcs
22
+
23
+ - name: Build package
24
+ run: python -m build
25
+
26
+ - uses: actions/upload-artifact@v4
27
+ with:
28
+ name: dist
29
+ path: dist/
30
+
31
+ publish:
32
+ needs: build
33
+ runs-on: ubuntu-latest
34
+ environment: pypi
35
+ permissions:
36
+ id-token: write
37
+ steps:
38
+ - uses: actions/download-artifact@v4
39
+ with:
40
+ name: dist
41
+ path: dist/
42
+
43
+ - name: Publish to PyPI
44
+ uses: pypa/gh-action-pypi-publish@release/v1
hvmcp-0.1.0/.gitignore ADDED
@@ -0,0 +1,57 @@
1
+ # Pixi environment
2
+ .pixi/
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *.pyo
8
+ *.pyd
9
+ *.so
10
+ *.egg
11
+ *.egg-info/
12
+ dist/
13
+ build/
14
+ .eggs/
15
+ *.whl
16
+
17
+ # Virtual environments
18
+ .venv/
19
+ venv/
20
+ env/
21
+
22
+ # Database
23
+ *.db
24
+ *.db-shm
25
+ *.db-wal
26
+
27
+ # Logs
28
+ *.log
29
+
30
+ # OS
31
+ .DS_Store
32
+ Thumbs.db
33
+
34
+ # IDE
35
+ .idea/
36
+ *.swp
37
+ *.swo
38
+
39
+ # MCP config (may contain API keys)
40
+ .vscode/mcp.json
41
+ .cursor/mcp.json
42
+
43
+ # Testing
44
+ .pytest_cache/
45
+ .coverage
46
+ htmlcov/
47
+ .mypy_cache/hores
48
+
49
+ # Claude Code
50
+ CLAUDE.md
51
+ .claude/
52
+ Gsoc_Idea.txt
53
+
54
+ # External context (personal/private files)
55
+ external context/
56
+
57
+ demo.txt
hvmcp-0.1.0/AGENTS.md ADDED
@@ -0,0 +1,209 @@
1
+ # AGENTS.md — HoloViz MCP Server
2
+
3
+ A guide for AI coding agents contributing to this project.
4
+
5
+ ---
6
+
7
+ ## Project Overview
8
+
9
+ **Name**: HoloViz MCP Server
10
+ **Purpose**: MCP server that lets AI agents create interactive HoloViz visualizations rendered as live UIs inside LLM chat
11
+ **Language**: Python 3.11+
12
+ **Build system**: Pixi (conda-based) + Hatchling (PEP 517)
13
+ **Framework**: FastMCP 3.0+ (server composition via `mount()`)
14
+ **Key deps**: Panel, HoloViews, hvPlot, Bokeh, Pydantic, psutil, ruff
15
+
16
+ ---
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ curl -fsSL https://pixi.sh/install.sh | bash
22
+ cd Panel-mcp-live
23
+ pixi install
24
+ pixi run postinstall
25
+ hvmcp --help
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Architecture
31
+
32
+ Three layers:
33
+
34
+ 1. **MCP Server** (`server/`) — FastMCP tools that AI agents call
35
+ 2. **Display Server** (`display/`) — Panel subprocess that renders and serves visualizations
36
+ 3. **MCP App Templates** (`templates/`) — HTML files that render as iframes in LLM chat
37
+
38
+ ### Module Structure
39
+
40
+ ```
41
+ src/holoviz_mcp_server/
42
+ ├── cli.py # Typer CLI: hvmcp serve / mcp / status
43
+ ├── config.py # Pydantic config + env var loading
44
+ ├── validation.py # 5-layer validation pipeline (ast, ruff, packages, extensions, runtime)
45
+ ├── utils.py # execute_in_module, find_extensions, validate_extension_availability
46
+
47
+ ├── server/ # MCP server layer
48
+ │ ├── main.py # Main FastMCP server + core tools
49
+ │ ├── compose.py # Mounts sub-servers with namespaces
50
+ │ ├── guided_mcp.py # viz.* sub-server (create, dashboard, stream, multi, annotate, export)
51
+ │ ├── panel_mcp.py # pn.* sub-server (list, get, params, search)
52
+ │ ├── hvplot_mcp.py # hvplot.* sub-server (list, get)
53
+ │ └── holoviews_mcp.py # hv.* sub-server (list, get)
54
+
55
+ ├── codegen/ # Code generators (structured config → Python code)
56
+ │ └── codegen.py # generate_viz_code, generate_dashboard_code, generate_stream_code, generate_multi_chart_code
57
+
58
+ ├── introspection/ # Pure Python discovery functions (no MCP dependency)
59
+ │ ├── panel.py # Panel component discovery (list_components, get_component, search_components)
60
+ │ ├── holoviews.py # HoloViews element discovery (list_elements, get_element)
61
+ │ ├── hvplot.py # hvPlot chart type discovery (list_plot_types, get_plot_type)
62
+ │ └── skills.py # Skill file loading (list_skills, get_skill)
63
+
64
+ ├── display/ # Panel subprocess system
65
+ │ ├── app.py # Panel server entry point (run as subprocess via python app.py)
66
+ │ ├── manager.py # PanelServerManager: start/stop/restart/health-check subprocess
67
+ │ ├── client.py # DisplayClient: HTTP client (POST /api/snippet, GET /api/health)
68
+ │ ├── database.py # SQLite + FTS5: stores all snippets permanently
69
+ │ ├── endpoints.py # Tornado REST handlers for /api/snippet and /api/health
70
+ │ └── pages/ # Panel web UI pages
71
+ │ ├── view_page.py # Renders a single visualization by ID
72
+ │ ├── feed_page.py # Live feed of all visualizations
73
+ │ ├── add_page.py # Manual snippet submission form
74
+ │ └── admin_page.py
75
+
76
+ ├── templates/ # MCP App HTML (iframes rendered inline in LLM chat)
77
+ │ ├── show.html # Chart viewer — BokehJS embed or iframe + click-to-insight
78
+ │ ├── stream.html # Live streaming viewer with play/pause
79
+ │ ├── dashboard.html # Dashboard with stats + filters
80
+ │ └── multi.html # Multi-chart grid with linked selections
81
+
82
+ └── skills/ # Agent skill guides (SKILL.md with YAML frontmatter)
83
+ ├── panel/SKILL.md
84
+ ├── hvplot/SKILL.md
85
+ ├── holoviews/SKILL.md
86
+ ├── param/SKILL.md
87
+ └── data/SKILL.md
88
+ ```
89
+
90
+ ### Server Composition
91
+
92
+ ```python
93
+ main_mcp.mount(guided_mcp, namespace="viz") # viz.create, viz.dashboard, viz.stream, viz.multi
94
+ main_mcp.mount(panel_mcp, namespace="pn") # pn.list, pn.get, pn.params, pn.search
95
+ main_mcp.mount(hvplot_mcp, namespace="hvplot") # hvplot.list, hvplot.get
96
+ main_mcp.mount(holoviews_mcp, namespace="hv") # hv.list, hv.get
97
+ ```
98
+
99
+ Core tools on main server: `show`, `stream`, `load_data`, `validate`, `handle_interaction`, `skill_list`, `skill_get`, `list_packages`.
100
+
101
+ ### Data Flow
102
+
103
+ ```
104
+ LLM calls show(code)
105
+ → 5-layer validation (syntax → security → packages → extensions → runtime)
106
+ → DisplayClient POSTs to Panel subprocess /api/snippet
107
+ → Panel executes code, stores in SQLite
108
+ → Returns URL or Bokeh JSON spec
109
+ → MCP App HTML renders chart (BokehJS embed or iframe)
110
+ → User clicks chart → postMessage("bokeh-tap")
111
+ → HTML calls app.callServerTool("handle_interaction", ...)
112
+ → Server returns insight → displayed in iframe
113
+ ```
114
+
115
+ ### Two Rendering Paths in show()
116
+
117
+ | Condition | Path | How |
118
+ |-----------|------|-----|
119
+ | `method="jupyter"` + pure HoloViews/hvPlot | Client-side BokehJS | Serialized to `json_item`, rendered by BokehJS in template |
120
+ | `method="panel"` or Panel widgets | Server-side iframe | Panel subprocess URL embedded in `<iframe>` |
121
+
122
+ ### Validation Pipeline (validation.py)
123
+
124
+ 1. **Syntax** — `ast.parse(code)` → `ast_check()`
125
+ 2. **Security** — blocked imports (subprocess, socket, ctypes, pickle, etc.) + ruff security rules → `ruff_check()`
126
+ 3. **Packages** — `importlib.util.find_spec()` for every import → `check_packages()`
127
+ 4. **Extensions** — detect Panel extensions requiring `pn.extension()` → `validate_extension_availability()`
128
+ 5. **Runtime** — execute in isolated `types.ModuleType` namespace → `validate_code()`
129
+
130
+ ---
131
+
132
+ ## Configuration
133
+
134
+ Environment variables (prefix `HOLOVIZ_MCP_SERVER_`):
135
+
136
+ | Variable | Default | Description |
137
+ |----------|---------|-------------|
138
+ | `PORT` | 5077 | Panel server port |
139
+ | `HOST` | 127.0.0.1 | Panel server host |
140
+ | `MAX_RESTARTS` | 3 | Max subprocess restart attempts |
141
+ | `DB_PATH` | `~/.holoviz-mcp-server/snippets/snippets.db` | SQLite path |
142
+ | `EXTERNAL_URL` | *(auto)* | Public URL override |
143
+ | `SKILLS_DIR` | *(builtin)* | Custom skills directory |
144
+
145
+ Auto-detects JupyterHub (`JUPYTERHUB_SERVICE_PREFIX`) and Codespaces (`CODESPACE_NAME`).
146
+
147
+ ---
148
+
149
+ ## CLI Commands
150
+
151
+ ```bash
152
+ hvmcp serve # Start Panel display server standalone
153
+ hvmcp mcp # Start MCP server (stdio) — also auto-starts Panel subprocess
154
+ hvmcp status # Check display server health
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Development Workflow
160
+
161
+ ```bash
162
+ pixi run test # pytest tests/ -v
163
+ pixi run test-coverage # pytest with --cov
164
+ pixi run lint # ruff check + format --check
165
+ pixi run format # ruff format + check --fix
166
+ pixi run postinstall # pip install -e . + fastmcp (run after structural changes)
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Code Style
172
+
173
+ - **Type hints**: Required on all new code (Python 3.11+ syntax: `X | Y`, `list[X]`)
174
+ - **Line length**: 120 characters
175
+ - **Imports**: Single-line, alphabetical (enforced by ruff isort)
176
+ - **Linter**: ruff (replaces black + isort + flake8)
177
+ - No docstrings, comments, or type annotations on code you didn't change
178
+
179
+ ---
180
+
181
+ ## Adding a New Tool
182
+
183
+ 1. Choose the right sub-server (or `server/main.py` for core tools)
184
+ 2. Add `@mcp.tool()` decorated async function
185
+ 3. For guided tools: add codegen function in `codegen/codegen.py` first, then call from `server/guided_mcp.py`
186
+ 4. Add tests in `tests/`
187
+
188
+ ## Adding a New Skill
189
+
190
+ 1. Create `skills/<name>/SKILL.md` with YAML frontmatter (`name`, `description`)
191
+ 2. Auto-discovered at runtime — no code changes needed
192
+
193
+ ---
194
+
195
+ ## Key Dependencies
196
+
197
+ | Package | Role |
198
+ |---------|------|
199
+ | `fastmcp>=3.0` | MCP server framework + tool/resource decorators |
200
+ | `panel` | Display server + web UI framework |
201
+ | `holoviews` | Declarative visualization layer |
202
+ | `hvplot` | High-level plotting API |
203
+ | `bokeh` | Rendering backend + JS interactivity |
204
+ | `pandas` | DataFrame support |
205
+ | `pydantic>=2.0` | Config models |
206
+ | `psutil` | Cross-platform process management |
207
+ | `requests` | HTTP client (MCP → Panel subprocess) |
208
+ | `typer` | CLI framework |
209
+ | `ruff` | Code validation + formatting |