Skip to main content
Glama

Breadcrumb MCP Server

by ScottHoang
resources.py6.74 kB
"""MCP resources for breadcrumb documents.""" from pathlib import Path from typing import Any from mcp.server import Server from mcp.types import Resource, TextResourceContents def register_resources(server: Server, breadcrumb_root: Path): """Register all breadcrumb resources.""" @server.list_resources() async def list_resources() -> list[Resource]: """List available resources.""" resources = [] projects_dir = breadcrumb_root / "projects" if not projects_dir.exists(): return resources # List all projects resources.append( Resource( uri="breadcrumb://projects", name="All Projects", mimeType="text/plain", description="List of all breadcrumb projects", ) ) # List resources for each project for project_dir in sorted(projects_dir.iterdir()): if not project_dir.is_dir() or project_dir.name.startswith("."): continue project_name = project_dir.name # Project index if (project_dir / "project-index.md").exists(): resources.append( Resource( uri=f"breadcrumb://project/{project_name}/index", name=f"{project_name} - Project Index", mimeType="text/markdown", description=f"Project index for {project_name}", ) ) # Sessions list sessions_dir = project_dir / "sessions" if sessions_dir.exists(): resources.append( Resource( uri=f"breadcrumb://project/{project_name}/sessions", name=f"{project_name} - Sessions", mimeType="text/plain", description=f"List of session logs for {project_name}", ) ) # Individual sessions for session_file in sorted(sessions_dir.glob("*.md")): resources.append( Resource( uri=f"breadcrumb://project/{project_name}/sessions/{session_file.name}", name=f"{project_name} - {session_file.stem}", mimeType="text/markdown", description=f"Session log: {session_file.stem}", ) ) # Components components_dir = project_dir / "components" if components_dir.exists(): for component_file in sorted(components_dir.glob("*.md")): resources.append( Resource( uri=f"breadcrumb://project/{project_name}/components/{component_file.name}", name=f"{project_name} - Component: {component_file.stem}", mimeType="text/markdown", description=f"Component documentation: {component_file.stem}", ) ) # ADRs adr_dir = project_dir / "adr" if adr_dir.exists(): for adr_file in sorted(adr_dir.glob("*.md")): resources.append( Resource( uri=f"breadcrumb://project/{project_name}/adr/{adr_file.name}", name=f"{project_name} - ADR: {adr_file.stem}", mimeType="text/markdown", description=f"Architectural Decision Record: {adr_file.stem}", ) ) # Patterns patterns_dir = project_dir / "patterns" if patterns_dir.exists(): for pattern_file in sorted(patterns_dir.glob("*.md")): resources.append( Resource( uri=f"breadcrumb://project/{project_name}/patterns/{pattern_file.name}", name=f"{project_name} - Pattern: {pattern_file.stem}", mimeType="text/markdown", description=f"Pattern documentation: {pattern_file.stem}", ) ) return resources @server.read_resource() async def read_resource(uri: str) -> str: """Read a resource by URI.""" if not uri.startswith("breadcrumb://"): raise ValueError(f"Invalid URI scheme: {uri}") path = uri.replace("breadcrumb://", "") parts = path.split("/") if path == "projects": # List all projects projects_dir = breadcrumb_root / "projects" if not projects_dir.exists(): return "No projects found" projects = [] for project_dir in sorted(projects_dir.iterdir()): if project_dir.is_dir() and not project_dir.name.startswith("."): projects.append(f"- {project_dir.name}") return "Projects:\n" + "\n".join(projects) elif parts[0] == "project" and len(parts) >= 2: project_name = parts[1] project_dir = breadcrumb_root / "projects" / project_name if not project_dir.exists(): raise ValueError(f"Project not found: {project_name}") if len(parts) == 3 and parts[2] == "index": # Read project index index_file = project_dir / "project-index.md" if not index_file.exists(): raise ValueError(f"Project index not found for: {project_name}") return index_file.read_text() elif len(parts) == 3 and parts[2] == "sessions": # List sessions sessions_dir = project_dir / "sessions" if not sessions_dir.exists(): return f"No sessions found for project: {project_name}" sessions = sorted(sessions_dir.glob("*.md")) return "Sessions:\n" + "\n".join(f"- {s.name}" for s in sessions) elif len(parts) == 4: # Read specific document doc_type = parts[2] # sessions, components, adr, patterns filename = parts[3] doc_file = project_dir / doc_type / filename if not doc_file.exists(): raise ValueError(f"Document not found: {uri}") return doc_file.read_text() raise ValueError(f"Invalid resource URI: {uri}")

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ScottHoang/breadcrumbs_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server