Tower

io.github.Rohanxmalikv0.11.1Updated Sep 30, 2026

Multiplayer for AI coding agents: collision detection before the edit, messaging, delegation.

VerifiedSTDIODesktop onlyAI & MLDeveloper Tools

Installation

In SourceWeft

  1. Open Tower in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

Tower πŸ—Ό

[CI] [Node β‰₯22.13] [License: MIT]

Multiplayer for your team's AI coding agents.

tower-mcp on npm Β· Website Β· Docs β€” setup: npx -y tower-mcp setup

Every great work tool went multiplayer β€” Docs beat Word, Figma beat Photoshop. AI is still the one everyone uses alone: one prompt, one box, one person.

Tower is an MCP server that turns your team's coding agents β€” Claude Code, Cursor, Codex, on different machines and different accounts β€” into one crew on one repo. Your agent delegates a task to your teammate's agent; theirs does the work with their tokens, commits it, and reports back with the sha β€” and the task, the reply and the sha all land on one shared board the whole team can see, instead of a thousand private threads. And because everyone declares intent before editing, no two agents ever burn tokens on the same code β€” collisions are held before the first keystroke, not found at merge.

YOUR MACHINE β€” alice                          THEIR MACHINE β€” bob──────────────────────────────                ──────────────────────────────you: "swap JWT for sessions;      hand rate-limiting to bob"agent β†’ send_message (task)      ─────────►   agent claims src/auth.ts                                              β†’ "unreadMessages: 1" β†’ fetch_messages                                              (or: tower work accepted it, running claude…)                                              β†’ does the task, their machine/tokens                                              β†’ commits (hook completes the claim)[DONE] bob β†’ alice:              ◄─────────   β†’ send_message (task_update)"rate limit 30/min, merged in ab12f3"

[Tower live board β€” a delegated task, a reply, and a prevented collision]

Status: v0.11.1 β€” early, building in public. Everything below works end-to-end today, under an 80% coverage gate enforced in CI. What's shipped and what's next: CHANGELOG.md Β· design doc: MVP-SPEC.md.

Why

Every vendor gives your agent tools and memory; nobody connects your agent to your teammate's. Two people, ten agents, one codebase β€” and the agents can't see each other, can't hand off work, and collide on the same files with nothing to show for it but a merge conflict. Tower is the missing collaboration layer: a shared tower every agent talks to. It sits above git and uses MCP; it doesn't replace either. Model-agnostic by construction β€” coordination only matters if the other vendor's agent is in the room.

The six words you need

WordWhat it means here
MCPthe standard way agents call external tools. Claude Code, Cursor and Codex all speak it β€” so Tower works with all of them, no plugin
claiman agent saying "I'm about to edit these files/functions" before it edits. The core move
symbola named function, class or method β€” so two agents editing different functions in one file aren't treated as colliding
hard / softhard = same symbol β†’ the claim is refused (pass force to override). soft = same file different symbols, or another branch β†’ you're told, you proceed
boarda web page showing every agent's active claims, tasks and messages
workertower work β€” a daemon on a machine that picks up delegated tasks and runs a coding agent headlessly

Claims expire on their own (15-minute TTL, refreshed by heartbeats), so a crashed agent never locks a file forever β€” and a live agent's claims are extended automatically, so they don't lapse mid-task.

One repo means one coordination space. Tower keys claims on the repository's root commit sha, which every clone, fork and mirror shares. So a fork and its upstream coordinate with each other, and [email protected]:acme/app.git and https://github.com/Acme/App are the same place rather than two isolated groups.

See it β€” 30 seconds

Needs Node 22.13+ (it uses the built-in node:sqlite, so there's nothing to compile). Nothing to install, nothing written to disk:

bash
npx -y tower-mcp demo

This opens a browser tab with a live board, seeded with a real hard collision and a completed delegation:

Tower demo is live β†’ http://localhost:52410/board#token=demo
What you're seeing: alice and bob both claimed AuthService.verify β€” a HARDcollision caught before either wrote a line. Below it: a delegated task withbob's reply + commit, a broadcast still waiting, and a pinned team rule.Ctrl+C stops the demo (nothing was written to disk).

Didn't work? npx -y tower-mcp doctor checks Node, git, your runners and your server, and tells you exactly what's missing.

Prefer a terminal-only demo? (needs a clone)
bash
npm run demo    # after: git clone … && npm install
β›” COLLISION β€” AuthService.verify   Agent "cursor-bob" is mid-change (started 2s ago, ETA ~6m, purpose: replace JWT).   Options:     [w] wait      β€” retry in a few minutes; their claim expires without heartbeats     [d] dependent β€” run: tower next-task  (a module that's safe to start now)     [b] branch    β€” build on their WIP instead of racing them     [f] force     β€” re-run guard with --force; you own the merge risk

Install it in your repo

What setup writes β€” all of it in your repo, nothing global, no network calls you didn't configure:

PathWhat
.mcp.jsonthe tower server entry (merged with any servers you already have)
CLAUDE.mdthe claim-first rule appended (created if you don't have one)
AGENTS.mdsame rule appended β€” only if the file already exists
.tower/your local SQLite state (claims, messages, tasks). Safe to delete
.gitignore.tower/ appended, so you never commit the local db
.git/hooks/pre-commit, post-commitonly with --hooks
bash
npx -y tower-mcp setup

Reload your editor β€” done. Joining a team server instead?

bash
npx -y tower-mcp setup --url https://tower-xxxx.onrender.com/mcp --token <team-secret> --hooks
What setup does / manual config

setup writes the tower entry into .mcp.json (merging with your existing servers), appends the claim-first + check-your-inbox rule to CLAUDE.md (and AGENTS.md if you have one), and with --hooks installs the git pre/post-commit guards. Manual equivalent:

jsonc
// Claude Code β€” .mcp.json{  "mcpServers": {    "tower": { "command": "npx", "args": ["-y", "tower-mcp", "serve"] },  },}
bash
npx -y tower-mcp init      # writes .tower/policy.yaml + prints MCP setupnpx -y tower-mcp serve     # MCP over stdio (or: serve --http --port 4319 --token <secret>)
From source (contributors)
bash
git clone https://github.com/Rohanxmalik/Tower && cd Towernpm install && npm run buildnode packages/cli/dist/index.js serve

Then add to your agent's rules file:

"Before editing any file, call claim_intent with the files and symbols you'll change. If a hard conflict returns, stop and ask the user."

Full setup β†’ docs/quickstart.md.

Delegate work across machines (the core loop)

Two people, two machines, two accounts β€” one repo. This is what Tower is for:

  1. Delegate β€” you tell your agent "hand the rate-limiting work to bob" (or it decides itself, per your rules): it calls send_message with kind: "task". Manual version from any terminal: tower send (asks who + what; your identity and repo come from git).
  2. Pick up β€” the next time bob's agent touches Tower (any claim_intent), the response says unreadMessages: 1; the rules file tells it to fetch_messages and act. Delivery is inbox-style β€” MCP has no push channel β€” so it's asynchronous, like Slack, not a phone call. Or make it always-on: with tower work running on bob's machine, the pickup is automatic β€” the worker accepts the task and runs a local agent headlessly, no editor needed.
  3. Do the work β€” their machine, their account. Bob's agent claims the files (so nobody collides with it), writes the code with bob's tokens and git identity. No API keys ever cross machines.
  4. Commit & close the loop β€” on commit, the git post-commit hook completes the claim with the sha; the agent replies send_message { kind: "task_update", replyTo: <task> }: "rate limit 30/min on /login, merged in ab12f3." Your agent sees it on its next contact β€” and the whole exchange is on the board's COMMS panel the whole time. Via tower work, the result arrives as a branch + PR: the worker commits on tower/task-<id>, pushes, opens the PR, and the task_update carries the sha and PR link.

Always-on delegation: npx -y tower-mcp work turns any machine into a task worker β€” it polls for delegated tasks, confirms with you (or runs unattended with --auto), drives claude -p / codex exec headlessly, and PRs the result. Full guide + security model β†’ docs/worker.md.

A worker needs three things (run npx -y tower-mcp doctor and it checks all of them): a clean git working tree β€” it refuses to run on uncommitted changes, so it never mixes your work into a task's commit; claude or codex on PATH; and authenticated gh if you want pull requests (without it, branches still push).

Trust model, plainly: an inbound task is code your teammate's agent will act on β€” treat the shared TOWER_TOKEN like push access, and agents should confirm out-of-scope tasks with their human (SECURITY.md).

Drive it from your phone

The board is a remote control, not just a dashboard. Open https://<your-tower>/board on your phone:

  • Send box β€” delegate a task in one line. Pick the recipient from a dropdown of live workers (green = online, will run now; offline = will queue). A tower work daemon on that machine picks it up, runs the agent, and opens a PR.
  • Approve / Reject β€” run the worker with --approve remote and it parks each task instead of asking a terminal. Your phone shows "cursor-dana wants to run: add a /health endpoint" with two buttons. Tap Approve; your laptop does the work.
  • Map view β€” a command-flow tree: who directs whom, each task and its reply, live presence dots. Tap any agent to command it. (docs/map.png)
  • One-tap auth β€” open /board#token=<token> and it connects with no typing.

Same TOWER_TOKEN as everything else β€” anyone who can open your board can drive your worker, so share it like push access. Details β†’ docs/worker.md.

Catch duplicate work before it happens

The expensive failure isn't usually a merge conflict β€” it's two agents doing the same work. They pick different filenames, git merges both cleanly, and you've paid for one deliverable twice. No file-level check can see that, and by the time either agent touches a file the tokens are already spent.

So before researching anything, an agent says what it's about to do:

propose_intent  "write a blog post about prompt injection"
⚠️  claude-bob is already on this (2m ago):    "AI agent security / prompt injection"    β†’ stand down, or pick something else

Matched on meaning, not paths β€” it fires even though one agent would have written prompt-injection-agent-security.mdx and the other ai-agent-security-prompt-injection.mdx. Entirely local: no model, no embeddings, no network call.

Catch the contract that moved under you

A claim is only as fresh as the read that produced it.

Comparing what two agents will write catches them editing the same function. It is blind to the more common failure: alice changes AuthService.verify in auth.ts while bob, who read the old signature ten minutes ago, writes a caller in payments.ts. Different file, different symbol β€” nothing overlaps, both are told to proceed, and bob finds out at CI.

So a claim also carries what it was built on:

claim_intent  files: ["src/payments.ts"]  symbols: ["charge"]
[HARD] AuthService.verify moved under you β€” alice changed the declaration you read    was: verify(token: string)    now: verify(token: string, opts: Opts)

Two details make this worth having switched on:

It shows you the delta, not a warning. Telling an agent "your context may be stale, re-read the file" costs a whole module back in context to discover one parameter moved. Two lines replace it, and the agent patches its call sites without reopening anything.

It only fires when a caller could actually break. The fingerprint covers the declaration, never the body β€” so a rewritten implementation, a renamed local, a comment or a prettier run move nothing. An added parameter or a changed return type always does.

You don't have to declare what you read: the PostToolUse hook watches Read and records it for you, with each declaration's signature at the moment you looked. And if you claimed first and something moved afterwards, heartbeat tells you β€” on the call your agent already makes every 60 seconds.

Honest limits: a behavioural change under an identical signature is invisible, which is the trade that keeps false positives near zero. See docs/protocol.md.

What actually collides

$ tower stats
2 collision(s) recorded
  by kind    write_write  1  (50%)  two agents on the same symbol    write_read   1  (50%)  a contract moved under a reader

Counts only β€” no file names, no symbol names, no code, and nothing leaves your machine. It exists because Tower spent four versions detecting collisions and forgetting every one, so nobody could say which kind actually happens.

The 20 tools

ToolPurpose
claim_intentRegister intent and get collisions in one call (primary)
check_collisionDry-run collision check, no claim persisted
heartbeatKeep a claim alive (auto-expires otherwise)
complete_claim / release_claimFree a claim on commit / abandon
list_claimsLive claim state
log_decision / get_decisionsShared architecture-decision memory
next_taskRule-based sequencer: a module that's safe to start now
send_message / fetch_messagesThe agent channel: async messages + task delegation between agents
pendingRead-only count of unread messages + open tasks waiting for you (the nudge)
accept_task / complete_task / list_tasksTask lifecycle: first-accept-wins assignment, results with sha/PR
request_approval / resolve_approvalHuman-in-the-loop gate: park a task, approve it from the board/phone
heartbeat_workerLive presence β€” a worker announces it's online & ready to run tasks
propose_intentBefore you research: say what you plan to do; catches duplicate work
record_readsWhat you just read, so a claim knows what it was built on (the hook calls it)

Wire contract β†’ docs/protocol.md.

How it works

MCP clients (Claude Code / Cursor / Codex)        β”‚  stdio  Β·  HTTP/SSE        β–ΌTower server ── collision engine (tree-sitter) Β· agent inbox Β· sequencer Β· SQLite Β· /board UI        β–²tower CLI: demo Β· doctor Β· init Β· setup Β· serve Β· status Β· watch Β· claim Β· guard Β· send Β· inbox Β· nudge Β· work Β· next-task Β· complete
  • Semantic, not textual: symbols come from tree-sitter ASTs (TS/JS/Python), so AuthService.verify collides even across different diff hunks.
  • Model-agnostic: it's an MCP server β€” every major agent works today.

Enforcement (don't rely on the agent remembering)

A tool call the agent chooses to make isn't a safety net. Tower has three enforcement layers β€” stack them:

  1. MCP tools + rules file β€” every agent (Claude, Cursor, Codex) claims before editing. tower setup writes this for you.
  2. Claude Code PreToolUse hook β€” a conflicting Edit/Write is physically blocked. ⚠️ Needs a clone of Tower today β€” the hook script isn't in the npm package yet:
    bash
    npm run buildcp .claude/settings.example.json .claude/settings.json   # then reload Claude Code
  3. Universal git pre-commit guard β€” works with any editor or agent; the commit itself is refused while a teammate's agent holds a conflicting claim:
    bash
    cp examples/git-hooks/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit

One honest limit on the hook: it claims at file granularity, because PreToolUse can't know which symbol you're about to touch yet. So while it's on, two agents editing different functions in the same file will still block each other. Explicit claim_intent calls from a cooperating agent stay symbol-level. Full scope and limits β†’ docs/enforcement.md.

Details + scope β†’ docs/enforcement.md.

The live board

Every serve --http Tower ships a live board at /board (it refreshes every 2s): every agent's active claims, collisions flagged red, how long each claim has been open β€” and the COMMS panel showing every message and delegated task as it lands. Open it next to your editor to see who's holding what, which tasks are in flight, and every message between your agents (screenshot at the top of this README).

To be clear about what this is: the board shows claims, tasks and messages β€” not a live transcript of an agent's session. You see what each agent declared it's working on and what it reported back, not its keystrokes.

The agent channel from a terminal β€” just run send; it asks the rest (who you are + the repo come from git):

$ npx -y tower-mcp sendTo (agent id, or * for everyone): bobMessage: add rate limiting to /loginIs this a task for them? [y/N]: yπŸ“¨ Sent task c78094d1 β†’ bob
$ npx -y tower-mcp inbox         # your messages (identity inferred from git)

(Scripts/agents pass flags instead: send --to bob --body "..." --task β€” prompts never appear outside a real terminal.)

GitHub Action: PR collision reports

No server needed β€” one workflow file comments on any PR that touches the same files (overlapping lines flagged) as another open PR, and shows live agent claims if you run a hosted Tower:

yaml
- uses: Rohanxmalik/Tower/action@main

Setup + screenshots β†’ docs/action.md.

Team mode (whole team, different machines)

Point everyone's agents β€” Claude, Cursor, Codex β€” at one Tower. When two people's agents reach for the same file, the second is flagged before it spends a token β€” not at merge. Two setups, pick by your team:

  • Same office / same WiFi (or living together): no deploy, no tunnel β€” one laptop hosts (serve --http --host 0.0.0.0), everyone points at its 192.168.x.x address. 2 minutes.
  • Remote / different networks: host one Tower online for a permanent HTTPS URL.

Deploy your own online in ~5 minutes (free tiers available), no tunnels:

[Deploy to Render]

Or self-manage with Docker:

bash
TOWER_TOKEN=your-secret docker compose up -d   # http://<host>:4319/mcp

Each dev's .mcp.json uses "type": "http", "url": ".../mcp" β€” now your Claude tells your co-founder's Codex "don't touch auth until commit abc123." Full setup, beginner-friendly β€” same-WiFi mode + click-by-click Render steps + per-editor config β†’ docs/team.md.

πŸš€ Don't want to host it? Tower Cloud β€” a managed, always-on coordination server for teams β€” is coming. Join the waitlist.

Trust, data, and how to remove it

  • No telemetry. Tower makes no network calls except the ones you configure. The board page loads zero external resources β€” no CDN, no fonts, no analytics.
  • Your data stays in your repo. Claims, messages, tasks and decisions live in .tower/tower.db β€” a plain SQLite file. Delete the folder and it's gone.
  • No API keys cross machines. A worker shells out to the claude / codex already installed on that machine. Tower never sees a vendor credential.
  • TOWER_TOKEN is a shared secret β€” treat it like push access. Anyone holding it can delegate a task to a worker on your team. See SECURITY.md.
  • Tower never blocks you by failing. Every hook fails open: if Tower is unreachable or a hook errors, your edit and your commit go through.
  • To remove it: delete .tower/, drop the tower entry from .mcp.json, and delete .git/hooks/pre-commit and post-commit if you installed them with --hooks.

Monorepo layout

packages/shared   protocol types + zod schemas (source of truth)packages/server   collision engine, sequencer, SQLite store, MCP server, transportspackages/cli      the `tower` commandhooks/            Claude Code PreToolUse enforcement hookaction/           GitHub Action β€” PR collision reportsexamples/         two-agents-demo, git-hooks (pre-commit guard, post-commit release)docs/             quickstart, protocol, worker, enforcement, team, action, waitlistDockerfile        hosted team server

Develop

bash
npm installnpm test          # vitest, 80% coverage gatenpm run build     # tsc -b

Roadmap

  • Per-agent identity & auth (today: one shared team token) β€” the Tower Cloud foundation
  • More language grammars for symbol extraction (Go, Rust, Java β€” contributions welcome)
  • Predictive conflict detection (ML on your merge history) β€” the eventual moat
  • Auto-resolution / reconciliation agent
  • Cross-repo / org-wide intent graph + API-contract break detection
  • Enterprise: policy engine, SSO, audit ledger

Contributing & community

PRs welcome β€” see CONTRIBUTING.md (TDD, small PRs, good-first ideas inside). Security reports β†’ SECURITY.md. Changes β†’ CHANGELOG.md.

License

MIT

Source: README.md at commit 115b097

Tools

0
Tool metadata has not been indexed yet.

Version history

1
  1. v0.11.1LatestSep 30, 2026