Tangled MCP Server
Summary: Tangled MCP Server lets you browse and search Tangled repositories, issues, and pull requests, and—when authenticated—perform write operations on issues, comments, states, and PRs.
Browse repositories, branches, tags, files, commits, diffs, and metadata.
Search repos/issues/strings and fetch AT Protocol records behind URIs.
List/read issues, pulls, labels, CI pipelines, PR patches, and PR files.
Create, update, delete, close, complete, or reopen issues; set labels.
Comment on issues/pulls and close/reopen pull requests.
Create/update pull requests by committing whole-file edits and opening/updating PRs, if you have push access.
Use read tools without credentials; writes require a Tangled handle and app password via env vars or request headers.
Run locally via uvx or use the hosted HTTP MCP endpoint.
Provides tools for interacting with git repositories through the Tangled platform, enabling repository and branch management, issue creation and listing capabilities.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Tangled MCP Server list branches for zzstoatzz/tangled-mcp"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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
maindeploy 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 onv*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/mcpfor 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 setupconfiguration
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-passwordusage
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-mcpcursor
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-mcpother clients
for clients that support MCP server configuration, use:
command:
uvxargs:
["tangled-mcp"]environment variables (optional, for writes):
TANGLED_HANDLE,TANGLED_PASSWORD
development usage
uv run tangled-mcptools
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 stringslist_repos(owner, limit)- list a user's repositoriesget_repo(repo)- metadata: knot, default branch, languages, labelsget_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 treeread_file(repo, path, ref)- file contentscommit_log(repo, ref, limit)- recent commitscompare(repo, rev1, rev2)- diff two revisions
issues & pulls (no auth)
list_issues(repo, state, limit)- filterable by open/closed/completedget_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;cidnames the roundget_pull_patch(pull, expected_cid)- the latest round as format-patch textget_pull_file(pull, path)- one file as the latest round leaves itlist_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/reopenset_pull_state(pull, state)- close/reopen a PRcomment_on_issue(issue, body)/comment_on_pull(pull, body, expected_cid)delete_issue(issue)create_pull(repo, title, edits, target_branch, body)- commits whole-fileeditson 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 checkssee docs/bobbin-api.md for where each read and write goes.
mcp-name: io.github.zzstoatzz/tangled-mcp
Available Tools
7 toolscreate_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
Scored across 7 tools
Each tool targets a distinct resource and action: issues (create, delete, update, list), branches (list), labels (list), and pull requests (list). No overlapping purposes.
All tools follow a consistent verb_repo_noun pattern (e.g., create_repo_issue, list_repo_branches), with snake_case throughout.
7 tools is well-scoped for a repository management server, covering core operations without being overwhelming or sparse.
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
Related MCP Connectors
Plain-English git for agents: 22 tools to branch, commit, push and tag. Free tier.
Git-backed platform for skills, tools, and context for AI agents
Read and write KukGit repositories, files, issues and pull requests from an AI assistant.
Operate GitHub from your AI assistant: repos, PRs, issues, Actions. Previews and read-only mode.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to interact with local Git repositories for operations like status, commits, branching, and diffs, plus GitHub API integration for managing pull requests when authenticated.-
- AlicenseBqualityDmaintenanceEnables Git repository interaction and automation via LLMs, providing tools to read, search, and manipulate Git repositories.15147 npm1MIT
- AlicenseNot gradedqualityDmaintenanceEnables GitLab repository management, including branches, merge requests, issues, pipelines, and more through natural language.MIT
- FlicenseNot gradedqualityDmaintenanceEnables querying today's GitHub commits, performing local git operations (status, diff, add, commit, push), and creating GitHub issues through natural language.-