"""Standards MCP server. Serves the hand-authored `standards` bundle (the application blueprint plus the library registry) and adds a discovery tool so an agent can find the right internal library — and its MCP endpoint — before writing any infrastructure. Resources: doc://index, doc://nav, doc://modules/{module} (from the base server) registry://libraries (the structured catalog) Tools: ping (from the base server) find_library (capability -> matching libraries + MCP endpoints) """ from __future__ import annotations import json from pathlib import Path from typing import Any from config import MCPBundle from mcp_server import MCPServer class StandardsMCPServer(MCPServer): """MCP server for the `standards` bundle with a library-discovery tool. Attributes: mcp_root (Path): Directory containing the generated bundle (index.json, nav.json, modules/, and the machine-readable libraries.json). """ def __init__(self, bundle: MCPBundle) -> None: super().__init__(bundle) self._register_standards() def _catalog(self) -> dict[str, Any]: """Load the machine-readable library registry.""" path = Path(self.mcp_root) / "libraries.json" if not path.exists(): return { "error": "not_found", "path": str(path), "libraries": [], } return json.loads(path.read_bytes()) def _register_standards(self) -> None: @self.app.resource("registry://libraries") def libraries() -> dict[str, Any]: return self._catalog() @self.app.tool() def find_library(capability: str) -> list[dict[str, Any]]: """Find internal libraries matching a capability keyword. Use this before writing infrastructure: it returns the library to use, its import name, what it replaces, and its MCP endpoint. Args: capability (str): A keyword such as "database", "pdf", "auth", "pipeline", "openapi", or "email". Returns: list[dict[str, Any]]: Matching library entries (empty when nothing matches). """ needle = (capability or "").strip().lower() if not needle: return self._catalog().get("libraries", []) matches: list[dict[str, Any]] = [] for lib in self._catalog().get("libraries", []): haystack = " ".join( [ str(lib.get("name", "")), str(lib.get("import", "")), str(lib.get("purpose", "")), str(lib.get("use_instead_of", "")), " ".join(lib.get("capabilities", [])), ] ).lower() if needle in haystack: matches.append(lib) return matches