Skip to main content
Glama

tangled-mcp

MCP server for Tangled - a git collaboration platform built on AT Protocol.

reads go through bobbin, tangled's public index (api.tangled.org), and the knot that hosts each repository — no credentials needed. writes (issues, comments, states) go to the repository's knot with a service-auth token your PDS mints, and require an app password.

note: pushes to main deploy the hosted server through tangled CI, which uploads the source to Prefect Horizon (scripts/horizon_deploy.py). the GitHub mirror only publishes releases to PyPI and the MCP registry on v* tags.

hosted server

a hosted instance runs at https://nate-tangled-mcp.fastmcp.app/mcp — no install needed:

claude mcp add --transport http tangled https://nate-tangled-mcp.fastmcp.app/mcp

for write access, pass credentials per request via headers:

claude mcp add --transport http tangled https://nate-tangled-mcp.fastmcp.app/mcp \
  --header "x-tangled-handle: your.handle" \
  --header "x-tangled-password: your-app-password"

your PDS is auto-discovered from your handle — self-hosted PDS works with no extra config.

Related MCP server: mcp-git

installation

git clone https://tangled.org/zzstoatzz/tangled-mcp
cd tangled-mcp
just setup
IMPORTANT

requiresuv and just

configuration

credentials are optional — only write tools need them. hosted/multi-tenant deployments can send them per request via x-tangled-handle / x-tangled-password headers, which take precedence over env. for local use, create .env:

TANGLED_HANDLE=your.handle
TANGLED_PASSWORD=your-app-password

usage

claude code

# read-only (no credentials)
claude mcp add tangled -- uvx tangled-mcp

# with write access
claude mcp add tangled \
  -e TANGLED_HANDLE=your.handle \
  -e TANGLED_PASSWORD=your-app-password \
  -- uvx tangled-mcp

cursor

add to your cursor settings (~/.cursor/mcp.json or .cursor/mcp.json):

{
  "mcpServers": {
    "tangled": {
      "command": "uvx",
      "args": ["tangled-mcp"],
      "env": {
        "TANGLED_HANDLE": "your.handle",
        "TANGLED_PASSWORD": "your-app-password"
      }
    }
  }
}

codex cli

codex mcp add tangled \
  --env TANGLED_HANDLE=your.handle \
  --env TANGLED_PASSWORD=your-app-password \
  -- uvx tangled-mcp

other clients

for clients that support MCP server configuration, use:

  • command: uvx

  • args: ["tangled-mcp"]

  • environment variables (optional, for writes): TANGLED_HANDLE, TANGLED_PASSWORD

development usage

uv run tangled-mcp

tools

repositories are owner/repo (e.g. zzstoatzz.io/tangled-mcp); handles (with or without @) and DIDs both work for the owner, and a bare repo DID works too. issues and pulls are tickets: pass owner/repo#<number> or the ticket at-uri.

discovery (no auth)

  • search(query, limit) - full-text search across repos, issues, and strings

  • list_repos(owner, limit) - list a user's repositories

  • get_repo(repo) - metadata: knot, default branch, languages, labels

  • get_record(uri) - fetch the full record behind any at-uri (strings/pastes, comments, ...)

git (no auth)

  • list_branches(repo, limit) / list_tags(repo, limit)

  • list_files(repo, path, ref) - browse the tree

  • read_file(repo, path, ref) - file contents

  • commit_log(repo, ref, limit) - recent commits

  • compare(repo, rev1, rev2) - diff two revisions

issues & pulls (no auth)

  • list_issues(repo, state, limit) - filterable by open/closed/completed

  • get_issue(issue)

  • list_pulls(repo, status, limit) - filterable by open/closed/completed (merged)

  • get_pull(pull) - a PR's ticket and its latest patch round; cid names the round

  • get_pull_patch(pull, expected_cid) - the latest round as format-patch text

  • get_pull_file(pull, path) - one file as the latest round leaves it

  • list_pipelines(repo, limit) - CI pipeline runs, from the repo's spindle

pulls opened before tangled's org.tangled migration have no patch records; their rounds are read from the author's legacy sh.tangled.repo.pull record, matched by author, target repo, and title.

writes (require credentials)

  • create_issue(repo, title, body, labels)

  • update_issue(issue, title, body)

  • set_issue_state(issue, state) - close/complete/reopen

  • set_pull_state(pull, state) - close/reopen a PR

  • comment_on_issue(issue, body) / comment_on_pull(pull, body, expected_cid)

  • delete_issue(issue)

  • create_pull(repo, title, edits, target_branch, body) - commits whole-file edits on a new branch in the repo, pushes it, and opens the pull (needs push access: owner or collaborator)

  • update_pull(pull, edits, note) - commits onto the pull's branch and submits the next round

development

just test   # run tests
just check  # run pre-commit checks

see docs/bobbin-api.md for where each read and write goes.


mcp-name: io.github.zzstoatzz/tangled-mcp

Available Tools

7 tools
create_repo_issueA

create an issue on a repository

Args: repo: repository identifier in 'owner/repo' format title: issue title body: optional issue body/description labels: optional list of label names to apply

Returns: CreateIssueResult with url (clickable link) and issue_id

Inputs: repo (required), title (required), body, labels. Returns: result of creating an issue

delete_repo_issueB

delete an issue from a repository

Args: repo: repository identifier in 'owner/repo' format issue_id: issue number to delete

Returns: DeleteIssueResult with issue_id of deleted issue

Inputs: repo (required), issue_id (required). Returns: result of deleting an issue

list_repo_branchesB

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

Inputs: repo (required), limit. Returns: result of listing branches

list_repo_issuesA

list issues for a repository

Args: repo: repository identifier in 'owner/repo' format limit: maximum number of issues to return (1-100)

Returns: ListIssuesResult with list of issues

Inputs: repo (required), limit. Returns: result of listing issues

list_repo_labelsA

list available labels for a repository

Args: repo: repository identifier in 'owner/repo' format

Returns: list of available label names for the repository

Inputs: repo (required). Returns: result

list_repo_pullsA

list pull requests created by the authenticated user for a repository

note: only returns PRs that the authenticated user created (tangled stores PRs in the creator's repo, so we can only see our own PRs).

Args: repo: repository identifier in 'owner/repo' format limit: maximum number of pulls to return (1-100)

Returns: ListPullsResult with list of pull requests

Inputs: repo (required), limit. Returns: result of listing pull requests

update_repo_issueA

update an existing issue on a repository

Args: repo: repository identifier in 'owner/repo' format issue_id: issue number to update title: optional new title (if None, keeps existing) body: optional new body (if None, keeps existing) labels: optional list of label names to SET (replaces existing)

Returns: UpdateIssueResult with url (clickable link) and issue_id

Inputs: repo (required), issue_id (required), title, body, +1 more. Returns: result of updating an issue

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool targets a distinct resource and action: issues (create, delete, update, list), branches (list), labels (list), and pull requests (list). No overlapping purposes.

    Naming Consistency5/5

    All tools follow a consistent verb_repo_noun pattern (e.g., create_repo_issue, list_repo_branches), with snake_case throughout.

    Tool Count5/5

    7 tools is well-scoped for a repository management server, covering core operations without being overwhelming or sparse.

    Completeness3/5

    Issues have full CRUD, but branches and labels only have list operations, and pull requests are limited to listing only the authenticated user's PRs. Notable gaps exist for create/update/delete on other resources.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers