Tangled MCP Server
by zzstoatzz
README.md
# tangled-mcp
MCP server for [Tangled](https://tangled.org) - a git collaboration platform built on AT Protocol.
reads go through [bobbin](https://docs.tangled.org/bobbin.html), tangled's public XRPC API (`api.tangled.org`) — **no credentials needed**. writes (issues, comments, labels) are atproto records put directly on your PDS and require an app password.
> **note**: this repository is mirrored to [GitHub](https://github.com/zzstoatzz/tangled-mcp) for deployment via [FastMCP Cloud](https://fastmcp.cloud).
## hosted server
a hosted instance runs at **`https://nate-tangled-mcp.fastmcp.app/mcp`** — no install needed:
```bash
claude mcp add --transport http tangled https://nate-tangled-mcp.fastmcp.app/mcp
```
for write access, pass credentials per request via headers:
```bash
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.
## installation
```bash
git clone https://tangled.org/zzstoatzz/tangled-mcp
cd tangled-mcp
just setup
```
> [!IMPORTANT]
> requires [`uv`](https://docs.astral.sh/uv/) and [`just`](https://github.com/casey/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`:
```bash
TANGLED_HANDLE=your.handle
TANGLED_PASSWORD=your-app-password
```
## usage
<details>
<summary>MCP client installation instructions</summary>
### claude code
```bash
# 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`):
```json
{
"mcpServers": {
"tangled": {
"command": "uvx",
"args": ["tangled-mcp"],
"env": {
"TANGLED_HANDLE": "your.handle",
"TANGLED_PASSWORD": "your-app-password"
}
}
}
}
```
### codex cli
```bash
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`
</details>
### development usage
```bash
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. issues are identified by 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
- `get_issue(issue)`
- `list_pulls(repo, status, limit)` - filterable by open/closed/merged
- `get_pull(pull)` - single PR with live state (derived from PDS status records, no index lag)
- `list_pipelines(repo, limit)` - CI pipeline runs
### writes (require credentials)
- `create_pull(repo, title, patch | edits, target_branch, body)` - open a PR from `git format-patch` output, or from whole-file `edits` (no clone needed — the server synthesizes the patch)
- `create_issue(repo, title, body, labels)`
- `update_issue(issue, title, body)`
- `set_issue_state(issue, state)` - close/reopen
- `set_pull_state(pull, state)` - close/reopen a PR
- `comment_on_issue(issue, body)`
- `delete_issue(issue)`
## development
```bash
just test # run tests
just check # run pre-commit checks
```
see [docs/bobbin-api.md](docs/bobbin-api.md) for notes on tangled's public API.
---
mcp-name: io.github.zzstoatzz/tangled-mcp
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 issues