Skip to main content
Glama

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

TableJSON Schema
NameRequiredDescriptionDefault
repo_nameYes
pathNo/
branchNo
extension_filterNo
projectNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • 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)
  • 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)
  • 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:
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: it's a read-only operation (implied by 'List'), returns a tree structure ('Returns a tree of ALL files and folders with full paths'), and mentions performance characteristics ('Much faster'). However, it doesn't cover potential limitations like rate limits, authentication needs, or error conditions, which would be helpful for a tool with no annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose, followed by usage guidelines, parameter details, and return information. Every sentence adds value: the first sentence defines the tool, the usage section provides practical guidance, the Args section explains parameters, and the final sentences describe output and related tools. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (5 parameters, 0% schema coverage, no annotations, but has output schema), the description is remarkably complete. It covers purpose, usage guidelines, parameter semantics, output format ('Returns a tree of ALL files and folders with full paths'), and even references a related tool ('Use read_repo_file... to read any file'). The presence of an output schema means the description doesn't need to detail return values, and it focuses appropriately on what's not covered elsewhere.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description fully compensates by providing detailed parameter explanations in the 'Args:' section. It clarifies the purpose of each parameter (e.g., 'repo_name: Repository name (from list_repos)', 'extension_filter: Filter by file extension... Only files matching this extension are shown'), adds default values, and provides usage context beyond what the bare schema offers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('List ALL files in a Git repository recursively') and distinguishes it from siblings by mentioning 'Much faster than calling browse_repo folder-by-folder.' It explicitly differentiates from the 'browse_repo' sibling tool, which appears to be a non-recursive alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidelines with a dedicated 'USE THIS TOOL when' section that lists specific user queries ('what files are in this repo?', 'show me the whole repo structure', 'list all Python files') and explains when to use it ('needs to find correct file paths before reading'). It also contrasts with the sibling 'browse_repo' tool by stating it's 'Much faster than calling browse_repo folder-by-folder.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

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/SrujanReddyKallu2024/MCP'

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