holoviz-mcp 0.0.1a0__py3-none-any.whl → 0.0.1a2__py3-none-any.whl
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.
Potentially problematic release.
This version of holoviz-mcp might be problematic. Click here for more details.
- holoviz_mcp/__init__.py +18 -0
- holoviz_mcp/apps/__init__.py +1 -0
- holoviz_mcp/apps/configuration_viewer.py +116 -0
- holoviz_mcp/apps/search.py +314 -0
- holoviz_mcp/config/__init__.py +31 -0
- holoviz_mcp/config/config.yaml +167 -0
- holoviz_mcp/config/loader.py +308 -0
- holoviz_mcp/config/models.py +216 -0
- holoviz_mcp/config/resources/best-practices/hvplot.md +62 -0
- holoviz_mcp/config/resources/best-practices/panel-material-ui.md +318 -0
- holoviz_mcp/config/resources/best-practices/panel.md +294 -0
- holoviz_mcp/config/schema.json +203 -0
- holoviz_mcp/docs_mcp/__init__.py +1 -0
- holoviz_mcp/docs_mcp/data.py +963 -0
- holoviz_mcp/docs_mcp/models.py +21 -0
- holoviz_mcp/docs_mcp/pages_design.md +407 -0
- holoviz_mcp/docs_mcp/server.py +220 -0
- holoviz_mcp/hvplot_mcp/__init__.py +1 -0
- holoviz_mcp/hvplot_mcp/server.py +152 -0
- holoviz_mcp/panel_mcp/__init__.py +17 -0
- holoviz_mcp/panel_mcp/data.py +316 -0
- holoviz_mcp/panel_mcp/models.py +124 -0
- holoviz_mcp/panel_mcp/server.py +650 -0
- holoviz_mcp/py.typed +0 -0
- holoviz_mcp/serve.py +34 -0
- holoviz_mcp/server.py +77 -0
- holoviz_mcp/shared/__init__.py +1 -0
- holoviz_mcp/shared/extract_tools.py +74 -0
- holoviz_mcp-0.0.1a2.dist-info/METADATA +641 -0
- holoviz_mcp-0.0.1a2.dist-info/RECORD +33 -0
- {holoviz_mcp-0.0.1a0.dist-info → holoviz_mcp-0.0.1a2.dist-info}/WHEEL +1 -2
- holoviz_mcp-0.0.1a2.dist-info/entry_points.txt +4 -0
- holoviz_mcp-0.0.1a2.dist-info/licenses/LICENSE.txt +30 -0
- holoviz_mcp-0.0.1a0.dist-info/METADATA +0 -6
- holoviz_mcp-0.0.1a0.dist-info/RECORD +0 -5
- holoviz_mcp-0.0.1a0.dist-info/top_level.txt +0 -1
- main.py +0 -6
holoviz_mcp/server.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""HoloViz MCP Server.
|
|
2
|
+
|
|
3
|
+
This MCP server provides comprehensive tools, resources and prompts for working with the HoloViz ecosystem,
|
|
4
|
+
including Panel and hvPlot following best practices.
|
|
5
|
+
|
|
6
|
+
The server is composed of multiple sub-servers that provide various functionalities:
|
|
7
|
+
|
|
8
|
+
- Documentation: Search and access HoloViz documentation as context
|
|
9
|
+
- hvPlot: Tools, resources and prompts for using hvPlot to develop quick, interactive plots in Python
|
|
10
|
+
- Panel: Tools, resources and prompts for using Panel Material UI
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import asyncio
|
|
14
|
+
import logging
|
|
15
|
+
import os
|
|
16
|
+
|
|
17
|
+
from fastmcp import FastMCP
|
|
18
|
+
|
|
19
|
+
from holoviz_mcp.config.loader import get_config
|
|
20
|
+
from holoviz_mcp.docs_mcp.server import mcp as docs_mcp
|
|
21
|
+
from holoviz_mcp.hvplot_mcp.server import mcp as hvplot_mcp
|
|
22
|
+
from holoviz_mcp.panel_mcp.server import mcp as panel_mcp
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
mcp: FastMCP = FastMCP(
|
|
27
|
+
name="holoviz",
|
|
28
|
+
instructions="""
|
|
29
|
+
[his MCP server provides comprehensive tools, resources and prompts for working with the HoloViz ecosystem following best practices.
|
|
30
|
+
|
|
31
|
+
HoloViz provides a set of core Python packages that make visualization easier, more accurate, and more powerful:
|
|
32
|
+
|
|
33
|
+
- [Panel](https://panel.holoviz.org): for making apps and dashboards for your plots from any supported plotting library.
|
|
34
|
+
- [hvPlot](https://hvplot.holoviz.org): to quickly generate interactive plots from your data.
|
|
35
|
+
- [HoloViews](https://holoviews.org): to help you make all of your data instantly visualizable.
|
|
36
|
+
- [GeoViews](https://geoviews.org): to extend HoloViews for geographic data.
|
|
37
|
+
- [Datashader](https://datashader.org): for rendering even the largest datasets.
|
|
38
|
+
- [Lumen](https://lumen.holoviz.org): to build data-driven dashboards from a simple YAML specification that's well suited to modern AI tools like LLMs.
|
|
39
|
+
- [Param](https://param.holoviz.org): to create declarative user-configurable objects.
|
|
40
|
+
- [Colorcet](https://colorcet.holoviz.org): for perceptually uniform colormaps.
|
|
41
|
+
|
|
42
|
+
The server is composed of multiple sub-servers that provide various functionalities:
|
|
43
|
+
|
|
44
|
+
- Documentation: Search and access HoloViz documentation and reference guides
|
|
45
|
+
- Panel: Tools, resources and prompts for using Panel and Panel Extension packages
|
|
46
|
+
- hvPlot: Tools, resources and prompts for using hvPlot to develop quick, interactive plots in Python
|
|
47
|
+
""",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
async def setup_composed_server() -> None:
|
|
52
|
+
"""Set up the composed server by importing all sub-servers with prefixes.
|
|
53
|
+
|
|
54
|
+
This uses static composition (import_server), which copies components
|
|
55
|
+
from sub-servers into the main server with appropriate prefixes.
|
|
56
|
+
"""
|
|
57
|
+
await mcp.import_server(docs_mcp, prefix="docs")
|
|
58
|
+
await mcp.import_server(hvplot_mcp, prefix="hvplot")
|
|
59
|
+
await mcp.import_server(panel_mcp, prefix="panel")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def main() -> None:
|
|
63
|
+
"""Set up and run the composed MCP server."""
|
|
64
|
+
pid = f"Process ID: {os.getpid()}"
|
|
65
|
+
print(pid) # noqa: T201
|
|
66
|
+
|
|
67
|
+
async def setup_and_run() -> None:
|
|
68
|
+
await setup_composed_server()
|
|
69
|
+
config = get_config()
|
|
70
|
+
await mcp.run_async(transport=config.server.transport)
|
|
71
|
+
|
|
72
|
+
asyncio.run(setup_and_run())
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
# Run the composed MCP server
|
|
77
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Shared features for the holoviz-mcp project."""
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Extract tools from the MCP server for documentation."""
|
|
3
|
+
|
|
4
|
+
import asyncio
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from holoviz_mcp.server import mcp
|
|
8
|
+
from holoviz_mcp.server import setup_composed_server
|
|
9
|
+
|
|
10
|
+
# Configure logging
|
|
11
|
+
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def extract_tools():
|
|
16
|
+
"""Extract available tools from the HoloViz MCP server and return as structured data."""
|
|
17
|
+
await setup_composed_server()
|
|
18
|
+
tools_dict = await mcp.get_tools()
|
|
19
|
+
|
|
20
|
+
# Group tools by category
|
|
21
|
+
docs_tools = []
|
|
22
|
+
panel_tools = []
|
|
23
|
+
utility_tools = []
|
|
24
|
+
|
|
25
|
+
for tool_name, tool_info in tools_dict.items():
|
|
26
|
+
tool_data = {"name": tool_name, "description": getattr(tool_info, "description", "No description available"), "parameters": []}
|
|
27
|
+
|
|
28
|
+
# Get input schema
|
|
29
|
+
input_schema = getattr(tool_info, "inputSchema", None)
|
|
30
|
+
if input_schema and hasattr(input_schema, "get") and "properties" in input_schema:
|
|
31
|
+
for param_name, param_info in input_schema["properties"].items():
|
|
32
|
+
required = param_name in input_schema.get("required", [])
|
|
33
|
+
param_type = param_info.get("type", "unknown")
|
|
34
|
+
desc = param_info.get("description", "No description")
|
|
35
|
+
tool_data["parameters"].append({"name": param_name, "type": param_type, "required": required, "description": desc})
|
|
36
|
+
|
|
37
|
+
# Categorize tools
|
|
38
|
+
if any(x in tool_name for x in ["docs", "get_best_practices", "get_reference_guide", "get_document", "update_docs"]) or (
|
|
39
|
+
tool_name == "search" and "component" not in str(tool_info)
|
|
40
|
+
):
|
|
41
|
+
docs_tools.append(tool_data)
|
|
42
|
+
elif any(x in tool_name for x in ["component", "packages"]) or "search" in tool_name:
|
|
43
|
+
panel_tools.append(tool_data)
|
|
44
|
+
else:
|
|
45
|
+
utility_tools.append(tool_data)
|
|
46
|
+
|
|
47
|
+
return {"panel_tools": panel_tools, "docs_tools": docs_tools, "utility_tools": utility_tools}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def main():
|
|
51
|
+
"""Extract and print available tools from the HoloViz MCP server."""
|
|
52
|
+
tools_data = await extract_tools()
|
|
53
|
+
logger.info("## 🛠️ Available Tools")
|
|
54
|
+
logger.info("")
|
|
55
|
+
|
|
56
|
+
def print_tools(tools_list, category_name):
|
|
57
|
+
if not tools_list:
|
|
58
|
+
return
|
|
59
|
+
logger.info("<details>")
|
|
60
|
+
logger.info(f"<summary><b>{category_name}</b></summary>")
|
|
61
|
+
logger.info("")
|
|
62
|
+
for tool_data in tools_list:
|
|
63
|
+
logger.info(f"- **{tool_data['name']}**: {tool_data['description']}")
|
|
64
|
+
logger.info("")
|
|
65
|
+
logger.info("</details>")
|
|
66
|
+
logger.info("")
|
|
67
|
+
|
|
68
|
+
print_tools(tools_data["panel_tools"], "Panel Components")
|
|
69
|
+
print_tools(tools_data["docs_tools"], "Documentation")
|
|
70
|
+
print_tools(tools_data["utility_tools"], "Utilities")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
asyncio.run(main())
|