Skip to main content
Glama

list_repo_branches

Retrieve and display branch information for a specified repository, allowing users to view available branches with configurable limits for efficient repository exploration.

Instructions

list branches for a repository

Args: repo: repository identifier in 'owner/repo' format (e.g., 'zzstoatzz/tangled-mcp') limit: maximum number of branches to return (1-100)

Returns: list of branches

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
repoYesrepository identifier in 'owner/repo' format (e.g., 'zzstoatzz/tangled-mcp')
limitNomaximum number of branches to return

Implementation Reference

  • Handler function for the 'list_repo_branches' tool. Includes input schema via Annotated/Field, calls helpers, and returns typed result. Also serves as registration via @tangled_mcp.tool decorator.
    @tangled_mcp.tool
    def list_repo_branches(
        repo: Annotated[
            str,
            Field(
                description="repository identifier in 'owner/repo' format (e.g., 'zzstoatzz/tangled-mcp')"
            ),
        ],
        limit: Annotated[
            int, Field(ge=1, le=100, description="maximum number of branches to return")
        ] = 50,
    ) -> ListBranchesResult:
        """list branches for a repository
    
        Args:
            repo: repository identifier in 'owner/repo' format (e.g., 'zzstoatzz/tangled-mcp')
            limit: maximum number of branches to return (1-100)
    
        Returns:
            list of branches
        """
        # resolve owner/repo to (knot, did/repo)
        knot, repo_id = _tangled.resolve_repo_identifier(repo)
        response = _tangled.list_branches(knot, repo_id, limit, cursor=None)
    
        return ListBranchesResult.from_api_response(response)
  • Pydantic models defining the output schema: BranchInfo and ListBranchesResult, including a classmethod to parse from raw tangled API response.
    class BranchInfo(BaseModel):
        """branch information"""
    
        name: str
        sha: str
    
    
    class ListBranchesResult(BaseModel):
        """result of listing branches"""
    
        branches: list[BranchInfo]
    
        @classmethod
        def from_api_response(cls, response: dict[str, Any]) -> "ListBranchesResult":
            """construct from raw API response
    
            Args:
                response: raw response from tangled API with structure:
                    {
                        "branches": [
                            {"reference": {"name": "main", "hash": "abc123"}},
                            ...
                        ]
                    }
    
            Returns:
                ListBranchesResult with parsed branches
            """
            branches = []
            if "branches" in response:
                for branch_data in response["branches"]:
                    ref = branch_data.get("reference", {})
                    branches.append(
                        BranchInfo(
                            name=ref.get("name", ""),
                            sha=ref.get("hash", ""),
                        )
                    )
    
            return cls(branches=branches)
  • Core helper function that performs the actual API call to tangled's knot via XRPC to list repository branches.
    def list_branches(
        knot: str, repo: str, limit: int = 50, cursor: str | None = None
    ) -> dict[str, Any]:
        """list branches for a repository
    
        Args:
            knot: knot hostname (e.g., 'knot1.tangled.sh')
            repo: repository identifier in "did/repo" format (e.g., 'did:plc:.../repoName')
            limit: maximum number of branches to return
            cursor: pagination cursor
    
        Returns:
            dict containing branches and optional cursor
        """
        params = {"repo": repo, "limit": limit}
        if cursor:
            params["cursor"] = cursor
    
        return make_tangled_request("sh.tangled.repo.branches", params, knot=knot)
  • Helper function to resolve user-friendly 'owner/repo' identifier to the (knot, did/repo) format required for tangled XRPC calls.
    def resolve_repo_identifier(owner_slash_repo: str) -> tuple[str, str]:
        """resolve owner/repo format to (knot, did/repo) for tangled XRPC
    
        Args:
            owner_slash_repo: repository identifier in "owner/repo" or "@owner/repo" format
                             (e.g., "zzstoatzz.io/tangled-mcp" or "@zzstoatzz.io/tangled-mcp")
    
        Returns:
            tuple of (knot_url, repo_identifier) where:
            - knot_url: hostname of knot hosting the repo (e.g., "knot1.tangled.sh")
            - repo_identifier: "did/repo" format (e.g., "did:plc:.../tangled-mcp")
    
        Raises:
            ValueError: if format is invalid, handle cannot be resolved, or repo not found
        """
        if "/" not in owner_slash_repo:
            raise ValueError(
                f"invalid repo format: '{owner_slash_repo}'. expected 'owner/repo'"
            )
    
        owner, repo_name = owner_slash_repo.split("/", 1)
        client = _get_authenticated_client()
    
        # resolve owner (handle or DID) to DID
        if owner.startswith("did:"):
            owner_did = owner
        else:
            # strip @ prefix if present
            owner = owner.lstrip("@")
            # resolve handle to DID
            try:
                response = client.com.atproto.identity.resolve_handle(
                    params={"handle": owner}
                )
                owner_did = response.did
            except Exception as e:
                raise ValueError(f"failed to resolve handle '{owner}': {e}") from e
    
        # query owner's repo collection to find repo and get knot
        try:
            records = client.com.atproto.repo.list_records(
                models.ComAtprotoRepoListRecords.Params(
                    repo=owner_did,
                    collection="sh.tangled.repo",  # correct collection name
                    limit=100,
                )
            )
        except Exception as e:
            raise ValueError(f"failed to list repos for '{owner}': {e}") from e
    
        # find repo with matching name and extract knot
        for record in records.records:
            if (name := getattr(record.value, "name", None)) and name == repo_name:
                knot = getattr(record.value, "knot", None)
                if not knot:
                    raise ValueError(f"repo '{repo_name}' has no knot information")
                return (knot, f"{owner_did}/{repo_name}")
    
        raise ValueError(f"repo '{repo_name}' not found for owner '{owner}'")

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/zzstoatzz/tangled-mcp'

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