browse_repo_recursive
List all files in a Git repository recursively to view the complete file structure and find specific file paths before reading content.
Instructions
List ALL files in a Git repository recursively — the full file tree.
USE THIS TOOL when the user asks 'what files are in this repo?', 'show me the whole repo structure', 'list all Python files', or needs to find correct file paths before reading. Much faster than calling browse_repo folder-by-folder.
Args: repo_name: Repository name (from list_repos). path: Starting folder path (default '/' for entire repo). branch: Branch name (default: repo's default branch). extension_filter: Filter by file extension, e.g. '.py', '.json', '.yaml'. Case-insensitive. Only files matching this extension are shown. project: Project name (default from config).
Returns a tree of ALL files and folders with full paths. Use read_repo_file(repo_name='...', path='...') to read any file.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| repo_name | Yes | ||
| path | No | / | |
| branch | No | ||
| extension_filter | No | ||
| project | No |
Implementation Reference
- mcp_server/tools/azdo_tools.py:325-412 (handler)Main implementation of browse_repo_recursive tool. This function recursively lists all files and folders in an Azure DevOps Git repository, supports optional extension filtering, and returns a formatted tree structure with file counts and paths.
def browse_repo_recursive( repo_name: str, path: str = "/", branch: str | None = None, extension_filter: str | None = None, project: str | None = None, ) -> str: """ List ALL files in a Git repository recursively — the full file tree. USE THIS TOOL when the user asks 'what files are in this repo?', 'show me the whole repo structure', 'list all Python files', or needs to find correct file paths before reading. Much faster than calling browse_repo folder-by-folder. Args: repo_name: Repository name (from list_repos). path: Starting folder path (default '/' for entire repo). branch: Branch name (default: repo's default branch). extension_filter: Filter by file extension, e.g. '.py', '.json', '.yaml'. Case-insensitive. Only files matching this extension are shown. project: Project name (default from config). Returns a tree of ALL files and folders with full paths. Use read_repo_file(repo_name='...', path='...') to read any file. """ url = f"{_project_url(project)}/_apis/git/repositories/{repo_name}/items" params: dict[str, str] = { "scopePath": path, "recursionLevel": "full", } if branch: params["versionDescriptor.version"] = branch params["versionDescriptor.versionType"] = "branch" data = _api_get(url, params=params) if isinstance(data, dict) and "error" in data: return data["error"] items = data.get("value", []) if isinstance(data, dict) else [] if not items: return f"No items found at path '{path}' in repo '{repo_name}'." # Separate folders and files folders = [] files = [] for item in items: item_path = item.get("path", "?") if item.get("isFolder", False): folders.append(item_path) else: files.append(item_path) # Apply extension filter if extension_filter: ext = extension_filter.lower() if extension_filter.startswith(".") else f".{extension_filter.lower()}" files = [f for f in files if f.lower().endswith(ext)] # Build tree output lines = [ f"\U0001f333 **{repo_name}** \u2014 full file tree from `{path}`", f" {len(folders)} folder(s), {len(files)} file(s)", "", ] if not files and not folders: lines.append("(empty)") return "\n".join(lines) # Group files by top-level folder for readability tree: dict[str, list[str]] = {} for f in sorted(files): # Get the directory part parts = f.rsplit("/", 1) folder = parts[0] if len(parts) > 1 and parts[0] else "/" tree.setdefault(folder, []).append(f) for folder in sorted(tree.keys()): lines.append(f"\U0001f4c1 **{folder}/**") for file_path in tree[folder]: file_name = file_path.rsplit("/", 1)[-1] lines.append(f" \U0001f4c4 {file_name} \u2192 `{file_path}`") lines.append("") lines.append(f"\U0001f4a1 Use `read_repo_file(repo_name='{repo_name}', path='<path>')` to read any file.") return "\n".join(lines) - mcp_server/main.py:222-222 (registration)Registration of browse_repo_recursive as an MCP tool using the mcp.tool() decorator, making it available to clients through the Model Context Protocol.
mcp.tool()(browse_repo_recursive) - mcp_server/main.py:154-163 (registration)Import statement that brings browse_repo_recursive from mcp_server.tools.azdo_tools into the main module, making it available for registration.
from mcp_server.tools.azdo_tools import ( # noqa: E402 list_repos, browse_repo, browse_repo_recursive, read_repo_file, get_current_sprint, get_sprint_work_items, get_work_item_details, get_backlog, ) - Function signature with type definitions that serves as the input schema: repo_name (str), path (str, default='/'), branch (str|None), extension_filter (str|None), project (str|None).
def browse_repo_recursive( repo_name: str, path: str = "/", branch: str | None = None, extension_filter: str | None = None, project: str | None = None, ) -> str: