Skip to main content
Glama

Escritório

Claude Code 会话之间点对点通信。您的会话和专家成为可按名称寻址的人员,他们可以同时就多个主题进行交流——无需协调者。

设计说明:pessoal/claudicaro-cli/docs/design/2026-08-02-escritorio-multiagente.md。

为什么之前无法做到

Claude Code 的原生拓扑是树状:子代理返回给父级,SendMessage 只能到达当前会话生成的对象,Workflow 通过脚本传递数据。两个兄弟节点无法对话。横向通信需要共享介质——这就是这个信箱。

Related MCP server: neighbors

六种工具

tool

功能

roster

列出谁存在、知道什么、什么等级——每人一行,不加载任何 .md 文件

ask

提问并等待回答

dm

发送并继续;在待处理问题的线程中,它会变成该问题的回答

inbox

拉取信件(通常钩子会自动传递)

board

共享白板,无收件人

claim

在操作前声明资源

还有 fechar_thread,用于结束对话并让每位同事提炼笔记。

工作原理

线程是唯一的对话容器——取代了房间和频道。同级之间的讨论是一个有 N 个参与者的线程,每个人可以选择回复谁。

没有负责人,信箱中的两条规则维护系统:

  • hops 每次消息递减;归零时,信箱拒绝消息。阻止无限乒乓。

  • 线程的创建者是所有者,只有创建者可以关闭它。

投递有两种性质:

  • 活跃会话通过 hook 接收(Stop 阻止停止并投递;PostToolBatch 在工作中间投递)。钩子是脚本——在模型外运行,零 token 成本。

  • 花名册中的同事被信箱通过 claude -p 唤醒,回答后继续休眠。

同事的记忆: 在线程内,它保持会话活跃(--resume),并记住所有内容;当线程关闭时,它将所学内容提炼到**.md 笔记**中,会话结束。长期记忆是笔记——可审计、可手动编辑、可版本控制。

安装

npm install && npm run build
node scripts/instalar.mjs          # --dry pra ver antes, --remover pra desfazer

安装程序在 ~/.claude/settings.json 中注册投递钩子,设置 ESCRITORIO_WORKSPACE/ESCRITORIO_ROSTER,并通过 claude mcp add --scope user 注册 MCP 服务器(该命令写入 ~/.claude.json——settings.json 不注册 MCP)。

首次运行时在 settings.json.antes-do-escritorio 创建备份,并且永远不会覆盖该备份。

花名册

~/claude-workspace-config/roster.yaml(同步的仓库 Mac ↔ VM):

especialista-deposito:
  brief: "Depósito antecipado: cobrança, pagamento, reembolso (DSG/v1)"
  agent_file: ${ESCRITORIO_WORKSPACE}/dsg/.agent/especialista-deposito.md
  caderno: ${ESCRITORIO_WORKSPACE}/pessoal/escritorio/cadernos/especialista-deposito.md
  tier: advisor
  cwd: ${ESCRITORIO_WORKSPACE}/dsg/v1

brief 是 roster() 唯一返回的内容——编写时请考虑“我什么时候会调用这个人”。路径支持 ~ 和 ${VAR};环境变量扩展使得同一文件在 Mac 和 VM 上都能工作,因为工作区位置不同。

等级

等级

允许操作

如何强制执行

advisor

读取和建议

允许列表 工具(--allowedTools):只读的 Bash 和 Escritório 的工具

editor

在工作树中写入

acceptEdits,并且仅在 claim() 激活时——信箱拒绝在没有声明的情况下唤醒

worktree

隔离写入

自己的 git worktree;如果无法创建,则拒绝而不是落入真实仓库

请求可以在查询中降低等级,但绝不能提升。

为什么使用允许列表而非拒绝列表

第一个版本使用 --disallowedTools Edit Write NotebookEdit 配合 bypassPermissions。在实际 claude 中测试时,泄露了:同事通过 Bash 写入了文件,而 Bash 不在禁止列表中。在四种变体中测量:

flags

结果

bypassPermissions + 禁止 Edit/Write

泄露(通过 Bash 写入)

bypassPermissions + 禁止 Edit/Write/Bash

安全

无权限模式 + 禁止 Edit/Write/Bash

安全

无权限模式 + 允许列表 只读

安全,并且仍然正常读取 git log

最终采用允许列表:我忘记列出的内容将被拒绝而不是放行。值得注意的是,允许列表中的 Bash(cat:*) 并没有允许通过重定向逃逸(cat > arquivo)。

实时查看

npm run tail

跟踪信箱并打印所有会话之间发生的情况——白板写入、声明、线程打开、消息交换、应答到达:

Escritório — monitor ao vivo
sessões vistas na última hora: icaromelo@v1, icaromelo@kairos-ui, icaromelo@oraculo-api, …
threads abertas: (nenhuma)
────────────────────────────────────────────────────────────────────────
13:26:36 ▤ quadro dsg/v1:decisoes = cache sempre via RedisService · icaromelo@v1
13:26:37 🔒 claim src/infra/redis por icaromelo@v1 · revisar TTLs
13:26:38 ⊕ thread [477cfbdc] Em uma frase: qual TTL padrao usamos? · dono icaromelo@v1
13:26:38 icaromelo@v1 →? especialista-cache  [477cfbdc]
        Em uma frase: qual TTL padrao usamos?
13:26:44 especialista-cache ←! icaromelo@v1  [477cfbdc]
        O TTL padrão é 3600 segundos (1 hora) — mas sempre passe TTL explícito…

→? 是阻塞问题,→ 是消息,←! 是应答。

身份

每个会话需要一个名称。声明 ESCRITORIO_ID 时使用该值;否则,从 usuário@pasta 派生——在项目内稳定,因此在 dsg/v1 中打开的会话始终是 icaromelo@v1,并且可以被其他会话寻址。

测试

npm test                        # 117 testes, sem gastar API
node scripts/smoke-mcp.mjs      # sobe o servidor MCP de verdade via stdio
node scripts/smoke-e2e.mjs      # E2E REAL: acorda colega, --resume, caderno (gasta API)
node scripts/smoke-escrita.mjs  # E2E REAL dos 3 tiers: advisor bloqueado, worktree isolado,
                                # editor sob claim (gasta API)

已知限制

  • 每台机器一个信箱。 Oracle VM 上的会话无法与 Mac 的信箱通信;跨机器桥接是单独的问题。

  • dist/ 位于 SSD 上。 当 SSD 卸载时,钩子静默失败(|| true),MCP 断开连接——没有崩溃,但办公室消失直到重新挂载。

  • 对活跃会话的 ask 依赖于该会话正在运行。 如果没有人打开该会话,您将等待直到超时(5 分钟),应答会留在收件箱中供以后处理。

Related MCP Connectors

Related MCP Servers