Skip to content

Commit 2a6bec2

Browse files
Merge pull request #26 from MarcSkovMadsen/enhancement/list-projects
Add missing list_projects tool
2 parents 31c8853 + 0718a93 commit 2a6bec2

3 files changed

Lines changed: 58 additions & 14 deletions

File tree

src/holoviz_mcp/docs_mcp/data.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,39 @@ async def get_page(self, path: str, project: str, ctx: Context | None = None) ->
838838
raise ValueError(f"No page found for path '{path}' in project '{project}'.")
839839
return pages[0]
840840

841+
async def list_projects(self) -> list[str]:
842+
"""List all available projects with documentation in the index.
843+
844+
Returns
845+
-------
846+
list[str]: A list of project names that have documentation available.
847+
Names are returned in hyphenated format (e.g., "panel-material-ui").
848+
"""
849+
await self.ensure_indexed()
850+
851+
try:
852+
# Get all documents from the collection to extract unique project names
853+
results = self.collection.get()
854+
855+
if not results["metadatas"]:
856+
return []
857+
858+
# Extract unique project names
859+
projects = set()
860+
for metadata in results["metadatas"]:
861+
project = metadata.get("project")
862+
if project:
863+
# Convert underscored names to hyphenated format for consistency
864+
project_name = str(project).replace("_", "-")
865+
projects.add(project_name)
866+
867+
# Return sorted list
868+
return sorted(projects)
869+
870+
except Exception as e:
871+
logger.error(f"Failed to list projects: {e}")
872+
return []
873+
841874
async def _log_summary_table(self, ctx: Context | None = None):
842875
"""Log a summary table showing document counts by repository."""
843876
try:

src/holoviz_mcp/docs_mcp/server.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,20 +111,20 @@ async def get_reference_guide(component: str, project: str | None = None, conten
111111
return await indexer.search_get_reference_guide(component, project, content, ctx=ctx)
112112

113113

114-
# @mcp.tool
115-
# async def list_projects() -> list[str]:
116-
# """List all available HoloViz projects with documentation.
117-
118-
# This tool discovers all projects that have documentation available in the index,
119-
# including both core HoloViz libraries and any additional user-defined projects.
120-
121-
# Returns
122-
# -------
123-
# list[str]: A list of project names that have documentation available.
124-
# Names are returned in hyphenated format (e.g., "panel-material-ui").
125-
# """
126-
# indexer = get_indexer()
127-
# return await indexer.list_projects()
114+
@mcp.tool
115+
async def list_projects() -> list[str]:
116+
"""List all available projects with documentation.
117+
118+
This tool discovers all projects that have documentation available in the index,
119+
including both core HoloViz libraries and any additional user-defined projects.
120+
121+
Returns
122+
-------
123+
list[str]: A list of project names that have documentation available.
124+
Names are returned in hyphenated format (e.g., "panel-material-ui").
125+
"""
126+
indexer = get_indexer()
127+
return await indexer.list_projects()
128128

129129

130130
@mcp.tool

tests/docs_mcp/test_docs_mcp.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ async def test_update_index():
2929
assert result.data
3030

3131

32+
@pytest.mark.asyncio
33+
async def test_list_projects():
34+
"""Test that all projects are listed correctly."""
35+
client = Client(mcp)
36+
async with client:
37+
result = await client.call_tool("list_projects")
38+
39+
assert len(result.data) > 0
40+
assert "panel" in result.data
41+
42+
3243
@pytest.mark.asyncio
3344
async def test_pages_semantic_search():
3445
"""Test the pages tool with semantic search queries."""

0 commit comments

Comments
 (0)