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.
- hvmcp-0.1.0/.github/workflows/publish.yml +44 -0
- hvmcp-0.1.0/.gitignore +57 -0
- hvmcp-0.1.0/AGENTS.md +209 -0
- hvmcp-0.1.0/PKG-INFO +522 -0
- hvmcp-0.1.0/README.md +471 -0
- hvmcp-0.1.0/assets/holoviews.png +0 -0
- hvmcp-0.1.0/assets/hvplot.png +0 -0
- hvmcp-0.1.0/assets/panel.png +0 -0
- hvmcp-0.1.0/mcp_architecture.png +0 -0
- hvmcp-0.1.0/mrve.py +490 -0
- hvmcp-0.1.0/panel-live-server/.copier-answers.yml +16 -0
- hvmcp-0.1.0/panel-live-server/.gitattributes +1 -0
- hvmcp-0.1.0/panel-live-server/.github/CODEOWNERS +1 -0
- hvmcp-0.1.0/panel-live-server/.github/dependabot.yml +10 -0
- hvmcp-0.1.0/panel-live-server/.github/workflows/build.yml +45 -0
- hvmcp-0.1.0/panel-live-server/.github/workflows/ci.yml +122 -0
- hvmcp-0.1.0/panel-live-server/.github/workflows/docs.yml +55 -0
- hvmcp-0.1.0/panel-live-server/.github/workflows/update-lockfiles.yml +34 -0
- hvmcp-0.1.0/panel-live-server/.gitignore +383 -0
- hvmcp-0.1.0/panel-live-server/.pre-commit-config.yaml +51 -0
- hvmcp-0.1.0/panel-live-server/.prettierrc +7 -0
- hvmcp-0.1.0/panel-live-server/LICENSE.txt +30 -0
- hvmcp-0.1.0/panel-live-server/MANIFEST.in +1 -0
- hvmcp-0.1.0/panel-live-server/README.md +102 -0
- hvmcp-0.1.0/panel-live-server/docs/assets/gif/panel-live-server-showcase-mcp.gif +0 -0
- hvmcp-0.1.0/panel-live-server/docs/assets/gif/panel-live-server-showcase.gif +0 -0
- hvmcp-0.1.0/panel-live-server/docs/assets/logo.svg +157 -0
- hvmcp-0.1.0/panel-live-server/docs/assets/videos/panel-live-server-showcase-mcp-fast.mp4 +0 -0
- hvmcp-0.1.0/panel-live-server/docs/assets/videos/panel-live-server-showcase-mcp.mp4 +0 -0
- hvmcp-0.1.0/panel-live-server/docs/assets/videos/panel-live-server-showcase.mp4 +0 -0
- hvmcp-0.1.0/panel-live-server/docs/examples.md +262 -0
- hvmcp-0.1.0/panel-live-server/docs/explanation/architecture.md +203 -0
- hvmcp-0.1.0/panel-live-server/docs/how-to/configure-server.md +232 -0
- hvmcp-0.1.0/panel-live-server/docs/index.md +207 -0
- hvmcp-0.1.0/panel-live-server/docs/reference/panel_live_server.md +8 -0
- hvmcp-0.1.0/panel-live-server/docs/tutorials/getting-started.md +311 -0
- hvmcp-0.1.0/panel-live-server/docs/tutorials/installation.md +86 -0
- hvmcp-0.1.0/panel-live-server/docs/tutorials/mcp-server.md +217 -0
- hvmcp-0.1.0/panel-live-server/docs/tutorials/standalone-server.md +207 -0
- hvmcp-0.1.0/panel-live-server/pixi.lock +13526 -0
- hvmcp-0.1.0/panel-live-server/pixi.toml +66 -0
- hvmcp-0.1.0/panel-live-server/project/closed-issues.md +134 -0
- hvmcp-0.1.0/panel-live-server/project/open-issues.md +10 -0
- hvmcp-0.1.0/panel-live-server/pyproject.toml +187 -0
- hvmcp-0.1.0/panel-live-server/research/panel-viz-mcp.md +241 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/__init__.py +14 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/app.py +121 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/cli.py +280 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/client.py +109 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/config.py +86 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/database.py +602 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/endpoints.py +116 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/manager.py +364 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/__init__.py +8 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/add_page.py +200 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/admin_page.py +155 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/feed_page.py +204 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/pages/view_page.py +216 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/py.typed +0 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/server.py +648 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/templates/show.html +447 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/ui.py +17 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/utils.py +443 -0
- hvmcp-0.1.0/panel-live-server/src/panel_live_server/validation.py +303 -0
- hvmcp-0.1.0/panel-live-server/tests/__init__.py +0 -0
- hvmcp-0.1.0/panel-live-server/tests/conftest.py +24 -0
- hvmcp-0.1.0/panel-live-server/tests/test_app.py +37 -0
- hvmcp-0.1.0/panel-live-server/tests/test_cli.py +28 -0
- hvmcp-0.1.0/panel-live-server/tests/test_config.py +156 -0
- hvmcp-0.1.0/panel-live-server/tests/test_database.py +184 -0
- hvmcp-0.1.0/panel-live-server/tests/test_endpoints.py +154 -0
- hvmcp-0.1.0/panel-live-server/tests/test_integration.py +191 -0
- hvmcp-0.1.0/panel-live-server/tests/test_manager.py +167 -0
- hvmcp-0.1.0/panel-live-server/tests/test_server.py +454 -0
- hvmcp-0.1.0/panel-live-server/tests/test_utils.py +610 -0
- hvmcp-0.1.0/panel-live-server/tests/test_validation.py +227 -0
- hvmcp-0.1.0/panel-live-server/tests/test_view_page.py +134 -0
- hvmcp-0.1.0/panel-live-server/tests/ui/__init__.py +1 -0
- hvmcp-0.1.0/panel-live-server/tests/ui/test_ui.py +26 -0
- hvmcp-0.1.0/panel-live-server/uv.lock +4317 -0
- hvmcp-0.1.0/panel-live-server/zensical.toml +129 -0
- hvmcp-0.1.0/pixi.lock +7433 -0
- hvmcp-0.1.0/pixi.toml +45 -0
- hvmcp-0.1.0/pyproject.toml +99 -0
- hvmcp-0.1.0/smithery.yaml +24 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/__init__.py +8 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/chart_builders.py +418 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/cli.py +144 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/codegen/__init__.py +0 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/codegen/codegen.py +149 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/config.py +86 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/display/__init__.py +1 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/display/app.py +91 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/display/client.py +52 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/display/database.py +328 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/display/endpoints.py +97 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/display/manager.py +242 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/display/pages/__init__.py +5 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/display/pages/view_page.py +183 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/introspection/__init__.py +1 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/introspection/holoviews.py +59 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/introspection/hvplot.py +59 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/introspection/panel.py +123 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/introspection/skills.py +110 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/py.typed +0 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/server/__init__.py +1 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/server/compose.py +19 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/server/guided_mcp.py +290 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/server/holoviews_mcp.py +34 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/server/hvplot_mcp.py +34 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/server/main.py +1169 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/server/panel_mcp.py +77 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/skills/charting/SKILL.md +102 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/skills/data/SKILL.md +124 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/skills/holoviews/SKILL.md +158 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/skills/hvplot/SKILL.md +100 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/skills/panel/SKILL.md +211 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/skills/param/SKILL.md +147 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/templates/dashboard.html +379 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/templates/multi.html +105 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/templates/show.html +309 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/templates/stream.html +107 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/themes.py +39 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/utils.py +217 -0
- hvmcp-0.1.0/src/holoviz_mcp_server/validation.py +225 -0
- hvmcp-0.1.0/tests/__init__.py +0 -0
- hvmcp-0.1.0/tests/conftest.py +12 -0
- hvmcp-0.1.0/tests/test_codegen.py +125 -0
- hvmcp-0.1.0/tests/test_config.py +73 -0
- hvmcp-0.1.0/tests/test_skills.py +55 -0
- hvmcp-0.1.0/tests/test_utils.py +81 -0
- 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 |
|