browse_vault_structure
Explore and navigate Obsidian vault directories to view folder structures, optionally including files and recursively listing nested contents for comprehensive organization.
Instructions
Browse vault directory structure.
Args:
path: Path to browse from (defaults to vault root)
include_files: Include files in listing (default: False, folders only)
recursive: List nested contents recursively
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| include_files | No | ||
| path | No | ||
| recursive | No |
Implementation Reference
- src/obsidian_mcp/server.py:127-175 (handler)The primary MCP tool handler for 'browse_vault_structure', decorated with @mcp.tool(). Cleans input path, delegates to client.browse_vault(), separates directories and files, and returns a structured dictionary response with success/error handling.@mcp.tool( annotations={ "title": "Browse Obsidian Vault Structure", "readOnlyHint": True, "openWorldHint": False } ) async def browse_vault_structure(path: str = "", include_files: bool = False, recursive: bool = False) -> Dict[str, Any]: """ Browse vault directory structure. Args: path: Path to browse from (defaults to vault root) include_files: Include files in listing (default: False, folders only) recursive: List nested contents recursively """ try: # Remove leading/trailing quotes and whitespace clean_path = path.strip().strip('"\'') items = await client.browse_vault(clean_path, include_files, recursive) directories = [item for item in items if item.endswith('/')] files = [item for item in items if not item.endswith('/')] return { "success": True, "path": clean_path, "include_files": include_files, "recursive": recursive, "directories": directories, "files": files if include_files else [], "total_directories": len(directories), "total_files": len(files) if include_files else 0, "total_items": len(items) } except Exception as e: return { "success": False, "error": f"Failed to browse vault structure for path '{path}': {str(e)}", "path": path, "include_files": include_files, "recursive": recursive, "directories": [], "files": [], "total_directories": 0, "total_files": 0, "total_items": 0 }
- src/obsidian_mcp/client.py:62-97 (helper)Supporting helper method in ObsidianClient that implements the vault browsing logic, handling both shallow (non-recursive) and deep recursive traversal using list_directory(), with file inclusion filter and max_depth safety limit.async def browse_vault(self, base_path: str = "", include_files: bool = False, recursive: bool = False, max_depth: int = 10) -> List[str]: """Browse vault structure with flexible filtering options.""" if not recursive: all_items = await self.list_directory(base_path) if not include_files: # Filter to only show directories (items ending with '/') return [item for item in all_items if item.endswith('/')] return all_items all_items = [] async def _recursive_list(current_path: str, depth: int): if depth > max_depth: return try: items = await self.list_directory(current_path) for item in items: if current_path: full_path = f"{current_path}/{item}" else: full_path = item # Apply file filtering if include_files or item.endswith('/'): all_items.append(full_path) # If it's a directory, recurse into it if item.endswith('/'): await _recursive_list(full_path.rstrip('/'), depth + 1) except Exception: # Skip directories we can't access pass await _recursive_list(base_path, 0) return all_items
- src/obsidian_mcp/client.py:42-52 (helper)Low-level helper in ObsidianClient to list contents of a vault directory/path via Obsidian API endpoint.async def list_directory(self, path: str = "") -> List[str]: if path: # Just URL encode the path and try it directly encoded_path = quote(path, safe='/') endpoint = f"/vault/{encoded_path}/" else: endpoint = "/vault/" result = await self._request("GET", endpoint) return result.get("files", [])