read_docs
Retrieve documentation content from specified paths, supporting .md, .mdx, and .mdoc formats, to access detailed references, functions, and explanations within the Tenzir MCP Server environment.
Instructions
Get documentation for a given path from the docs folder.
Args: path: The path to the documentation file (e.g., "reference/functions/abs", "reference/operators/read_json", or "explanations/index") Supports .md, .mdx, and .mdoc file formats.
Returns: The content of the documentation file
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Implementation Reference
- The core handler function for the MCP tool 'docs_read', which reads and returns Tenzir documentation content for a given path. Includes input schema validation via Annotated Field.@mcp.tool( name="docs_read", tags={"documentation"}, annotations={ "title": "Read documentation", "readOnlyHint": True, "idempotentHint": True, "openWorldHint": False, }, ) async def docs_read( path: Annotated[ str, Field( description="Documentation path without extension (e.g., 'reference/operators/select', " "'reference/functions/abs', 'tutorials/map-data-to-ocsf')" ), ], ) -> ToolResult: """Read documentation content from the embedded Tenzir documentation. Use this tool to: - Read operator documentation BEFORE using any TQL operator - Read function documentation BEFORE using any TQL function - Study tutorials and guides for learning workflows """ try: clean_path = path.strip("/") for ext in [".md", ".mdx", ".mdoc"]: if clean_path.endswith(ext): clean_path = clean_path[: -len(ext)] break docs = TenzirDocs() possible_paths = [ f"src/content/docs/{clean_path}.md", f"src/content/docs/{clean_path}.mdx", f"src/content/docs/{clean_path}.mdoc", f"src/content/docs/{clean_path}/index.mdx", ] for try_path in possible_paths: if docs.exists(try_path): requested_path = path.strip() or "/" normalized_path = clean_path or "index" resolved_content = docs.read_file(try_path) metadata_header = "\n".join( [ f"**Requested Path**: `{requested_path}`", f"**Normalized Path**: `{normalized_path}`", f"**Resolved File**: `{try_path}`", ] ) content = f"{metadata_header}\n\n---\n\n{resolved_content}" return ToolResult( content=content, # Markdown text for display structured_content={ "path": normalized_path, "resolved_path": try_path, "content": resolved_content, # Same content for structured access }, ) error_msg = f"Documentation file not found for path '{path}'. Please check the path and try again." return ToolResult( content=error_msg, structured_content={ "error": error_msg, "path": clean_path or path, }, ) except Exception as e: logger.error(f"Failed to get docs markdown for path {path}: {e}") error_msg = f"Error retrieving documentation: {e}" return ToolResult( content=error_msg, structured_content={"error": error_msg, "path": path}, )
- src/tenzir_mcp/server.py:16-32 (registration)Creation of the FastMCP instance 'mcp' and import of tool packages, including 'tenzir_mcp.tools.documentation' which registers the docs_read tool via its @mcp.tool decorator.mcp = FastMCP( name="Tenzir MCP Server", instructions=load_system_prompt(), ) # Import tool packages so FastMCP registers their tools on startup. _TOOL_PACKAGES = ( "tenzir_mcp.tools.coding", "tenzir_mcp.tools.documentation", "tenzir_mcp.tools.execution", "tenzir_mcp.tools.ocsf", "tenzir_mcp.tools.packaging", ) for _module_name in _TOOL_PACKAGES: import_module(_module_name)
- src/tenzir_mcp/docs.py:46-137 (helper)TenzirDocs class used by the docs_read tool to access bundled documentation files, providing read_file() and exists() methods essential for tool logic.class TenzirDocs: """Access to bundled Tenzir documentation.""" def __init__(self) -> None: self._docs_root: Path | None = None self._metadata: DocsMetadata | None = None @property def docs_root(self) -> Path: """Get the root directory of the bundled docs.""" if self._docs_root is None: # First try fallback for development import tenzir_mcp pkg_root = Path(tenzir_mcp.__file__).parent potential_docs_path = pkg_root / "data" / "docs" if potential_docs_path.exists(): self._docs_root = potential_docs_path else: try: # Try to find docs in package data docs_pkg = files("tenzir_mcp.data.docs") if hasattr(docs_pkg, "_path"): # For editable installs or direct path access self._docs_root = docs_pkg._path else: # For wheel installs, we need to extract to a temp location # This is a simplified approach - in practice you might want # to cache this in a temp directory raise NotImplementedError( "Wheel-based docs access not yet implemented" ) except (ModuleNotFoundError, FileNotFoundError): raise FileNotFoundError( f"Documentation not found at {potential_docs_path}. " "Run 'make update-docs' or rebuild the package." ) from None if not self._docs_root.exists(): raise FileNotFoundError( f"Documentation not found at {self._docs_root}. " "Run 'make update-docs' or rebuild the package." ) return self._docs_root @property def metadata(self) -> DocsMetadata: """Get metadata about the bundled documentation.""" if self._metadata is None: metadata_file = self.docs_root / ".metadata.json" if metadata_file.exists(): with metadata_file.open("r", encoding="utf-8") as f: metadata_dict = json.load(f) self._metadata = DocsMetadata(metadata_dict) else: # Default metadata if file doesn't exist self._metadata = DocsMetadata({}) return self._metadata def list_files(self, pattern: str = "**/*") -> list[Path]: """List all files in the docs matching the given pattern.""" docs_root = self.docs_root return [p for p in docs_root.glob(pattern) if p.is_file()] def read_file(self, relative_path: str | Path) -> str: """Read a documentation file by its relative path.""" file_path = self.docs_root / relative_path if not file_path.exists(): raise FileNotFoundError(f"Documentation file not found: {relative_path}") with file_path.open("r", encoding="utf-8") as f: return f.read() def find_files(self, name_pattern: str) -> list[Path]: """Find files by name pattern (e.g., '*.md', 'index.*').""" return [p for p in self.docs_root.rglob(name_pattern) if p.is_file()] def get_file_path(self, relative_path: str | Path) -> Path: """Get the absolute path to a documentation file.""" file_path = self.docs_root / relative_path if not file_path.exists(): raise FileNotFoundError(f"Documentation file not found: {relative_path}") return file_path def exists(self, relative_path: str | Path) -> bool: """Check if a documentation file exists.""" return (self.docs_root / relative_path).exists()
- src/tenzir_mcp/tools/documentation/__init__.py:1-9 (registration)Package __init__.py that imports docs_read, triggering the @mcp.tool decorator to register the tool with the MCP server."""Documentation tools for searching and reading Tenzir docs.""" from .docs_read import docs_read from .docs_search import docs_search __all__ = [ "docs_read", "docs_search", ]