内容
# 塔楼 🗼
[](https://github.com/Rohanxmalik/Tower/actions/workflows/ci.yml)

[](LICENSE)
**用于编辑共享仓库的AI代理的空中交通管制。**
**[tower-mcp on npm](https://www.npmjs.com/package/tower-mcp)** · **[网站](https://rohanxmalik.github.io/Tower/)** · **[文档](./docs)** — 安装:`npx -y tower-mcp serve`
塔楼是一个[MCP](https://modelcontextprotocol.io)服务器,可以防止两个AI代理在同一代码上发生冲突。任何代理——Claude Code、Cursor、Codex、Gemini——都会注册它们即将进行的更改;塔楼会检测与其他活动代理的语义重叠,并在编辑发生之前发出警告,而不是在合并时。

```
⛔ 碰撞 — AuthService.verify
代理 "cursor-bob" 正在更改中(2秒前开始,预计 6 分钟,目的:替换 JWT)。
选项: [w] 等待 [d] 执行依赖任务 [b] 从他们的 WIP 分支 [f] 强制
```
> 上面的横幅是一个动画SVG。如果您更喜欢真实的终端录制GIF,请运行
> [`vhs`](https://github.com/charmbracelet/vhs):`vhs examples/two-agents-demo/demo.tape` → `docs/demo.gif`。
> 状态:**早期 / 公开开发中。** MVP 功能已端到端可用。有关完整的设计和路线图,请参见 [MVP-SPEC.md](./MVP-SPEC.md)。
## 为什么
内存、代理协议(MCP/A2A)和可观察性仪表板已经解决。未拥有的空白是**写入协调**——当团队在仓库中并行运行许多代理时,瓶颈成为碰撞和浪费的工作,只有在合并时才发现。塔楼是模型无关的层,位于 git 之上并使用 MCP;它不会替换两者。
## 看看它(5秒)
```bash
npm run demo
```
两个代理到达同一个符号;第二个在第一次按键之前被捕获。
将其转换为GIF:`vhs examples/two-agents-demo/demo.tape`。
## 快速入门
需要 **Node 22+** (使用内置的 `node:sqlite`,无需原生构建)。将塔楼添加到代理的MCP配置中:
```jsonc
// Claude Code — .mcp.json
{
"mcpServers": {
"tower": { "command": "npx", "args": ["-y", "tower-mcp", "serve"] },
},
}
```
或从终端驱动:
```bash
npx -y tower-mcp init # 写入.tower/policy.yaml + 打印MCP设置
npx -y tower-mcp serve # 通过stdio的MCP(或:serve --http --port 4319 --token <secret>)
```
<details><summary>从源代码(贡献者)</summary>
```bash
git clone https://github.com/Rohanxmalik/Tower && cd Tower
npm install && npm run build
node packages/cli/dist/index.js serve
```
</details>
然后添加到代理的规则文件:
> "在编辑任何文件之前,使用您将更改的文件和符号调用 `claim_intent`。
> 如果返回 `hard` 冲突,请停止并询问用户。"
完整设置 → [docs/quickstart.md](./docs/quickstart.md)。
## 9 种工具
| 工具 | 目的 |
| ---------------------------------- | ------------------------------------------------------------ |
| `claim_intent` | 注册意图 **和** 获取冲突(主要) |
| `check_collision` | 碰撞检查的预运行,无需持久化声明 |
| `heartbeat` | 保持声明活跃(否则自动过期) |
| `complete_claim` / `release_claim` | 在提交时释放声明 / 放弃 |
| `list_claims` | 实时声明状态 |
| `log_decision` / `get_decisions` | 共享架构决策内存 |
| `next_task` | 基于规则的排序器:一个安全的模块,可以现在启动 |
线路合约 → [docs/protocol.md](./docs/protocol.md)。
## 它是如何工作的
```
MCP 客户端(Claude Code / Cursor / Codex)
│ stdio · HTTP/SSE
▼
塔楼服务器 ── 碰撞引擎(tree-sitter 符号) · 排序器 · SQLite 存储
▲
塔楼 CLI:init · serve · status · watch · claim · guard · complete (+ git & PreToolUse hooks)
```
- **语义,不是文本:** 符号来自 tree-sitter AST(TS/JS/Python),因此 `AuthService.verify` 即使跨不同的 diff hunks 也会发生冲突。
- **模型无关:** 它是一个 MCP 服务器——每个主要代理今天都可以使用。
## 强制执行(不要依赖代理记住)
代理选择的调用工具不是安全网。 **Claude Code PreToolUse hook** 使其成为一个:编辑前,塔楼检查文件,如果另一个活动代理持有硬冲突声明,则编辑被 **阻止**,并将原因反馈给 Claude。
```bash
npm run build
cp .claude/settings.example.json .claude/settings.json # 然后重新加载Claude Code
```
在同一个仓库中打开两个代理会话 → 第二个在访问文件时被阻止,文件正在被第一个代理编辑。详细信息 + 范围 → [docs/enforcement.md](./docs/enforcement.md)。
## 团队模式(不同机器)
托管一个塔楼,并通过MCP-HTTP将每个代理指向它:
```bash
TOWER_TOKEN=your-secret docker compose up -d # http://<host>:4319/mcp
```
每个开发人员的 `.mcp.json` 使用 `"type": "http", "url": ".../mcp"` — 现在您的 Claude 告诉您的联合创始人 Claude “不要在提交 abc123 之前触摸 auth”。设置 → [docs/team.md](./docs/team.md)。
## 仓库布局
```
packages/shared 协议类型 + zod 模式(真实来源)
packages/server 碰撞引擎、排序器、SQLite 存储、MCP 服务器、传输
packages/cli `tower` 命令
hooks/ Claude Code PreToolUse 强制执行钩子
examples/ two-agents-demo, git-hooks
docs/ 快速入门、协议、强制执行、团队
Dockerfile 托管团队服务器
```
## 开发
```bash
npm install
npm test # vitest,80% 覆盖率门控
npm run build # tsc -b
```
## 路线图
- 预测冲突检测(基于您的合并历史的ML)——最终的护城河
- 自动解决/调和代理
- 跨仓库/组织范围的意图图 + API-合同破坏检测
- 企业:策略引擎、SSO、审计账本
- 跨供应商代理委托的A2A适配器
## 许可证
MIT