关于 agentsync
agentsync 是用于协调多个 AI Agent 在同一 Git 仓库协作的 MCP 服务。它在专用 Git 分支上记录文件与依赖声明,并通过 Git 推送检测竞争声明。
主要功能
- 01查看伙伴声明与过期任务
- 02按路径重叠检查并认领任务
- 03检查声明冲突与 Git 合并冲突
- 04更新状态、释放任务并查看历史
- 05创建仓库并邀请协作者
- 06完成工作并创建 GitHub PR
适用场景
- 01协调多个 Agent 并行修改仓库
- 02避免修改伙伴正在处理的文件
- 03合并工作前检查分支冲突
MCP 相关
它向 MCP 客户端提供协作工具,包括查看状态、认领任务、检查冲突、更新状态和查询历史。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx agentsync-mcpAGENTSYNC_REPOAbsolute path to the shared project git clone used for coordination.AGENTSYNC_AGENT_IDYour unique agent id, used to key your claims.AGENTSYNC_BRANCHThe dedicated coordination branch (default: agentsync).本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
9收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| permission | string | 否 | |
| github_username | string | 是 |
详细介绍
agentsync
一个 MCP 服务,可让两个(或更多)AI Agent 在同一个 git 仓库中协作,而不会互相干扰。每个 Agent 会在开始构建之前声明自己要做什么,查看伙伴认领的内容,并在工作合并时检测冲突——所有协调工作都通过仓库本身完成,无需锁定服务端,也不要求两个 Agent 同时在线。
工作原理(一段话)
协调状态存储在专用的 agentsync 分支上的单个 claims.json 文件中(与 main 隔离,因此不会污染代码历史,也不会受到 main 分支保护规则的阻碍)。每个 Agent 的认领信息会声明要做的工作、将要修改的文件、依赖项、分支和状态。重叠情况通过简单的集合交集判断。写入使用读-修改-写循环,并以 git push 执行比较并交换:如果推送被拒绝,服务端会重新获取最新认领信息并重新评估,因此在此 Agent 的认领信息提交之前,就能先观察到发生冲突的伙伴认领。所有 git 操作都在 .git/ 下的私有工作树中进行,因此不会影响 Agent 实际的代码分支。
架构设计原理请参阅 DESIGN.md,Agent 使用工具时遵循的操作指南请参阅 AGENTS.md。
安装
pip install -r requirements.txt # just `mcp`
对于任何需要与 GitHub 交互的操作——配置仓库(provision)、邀请协作者(add_collaborator)或创建 PR(finish)——还需要安装 GitHub CLI,并使用 repo 权限范围进行身份验证:
gh auth login # one-time; check with `gh auth status`
配置
双方协作者都要将此服务添加到各自的 MCP 客户端,并分别使用自己的 Agent ID 和本地克隆。请参阅 mcp.config.example.json:
{
"mcpServers": {
"agentsync": {
"command": "python3",
"args": ["/abs/path/to/agentsync_server.py"],
"env": {
"AGENTSYNC_BOARD_REPO": "/abs/path/to/the/clone/holding/the/board",
"AGENTSYNC_AGENT_ID": "jonny"
}
}
}
}
| 环境变量 | 必需 | 默认值 | 含义 |
|---|---|---|---|
AGENTSYNC_BOARD_REPO | 是* | — | 存放协调看板的克隆路径 |
AGENTSYNC_REPO | 否 | — | AGENTSYNC_BOARD_REPO 的旧别名 |
AGENTSYNC_AGENT_ID | 是 | — | 你的唯一 Agent ID |
AGENTSYNC_REMOTE | 否 | origin | git 远程名称 |
AGENTSYNC_BRANCH | 否 | agentsync | 协调分支名称 |
AGENTSYNC_PARTNER_GITHUB | 否 | — | 要邀请的伙伴 GitHub 用户(以逗号或空格分隔) |
AGENTSYNC_STALE_HOURS | 否 | 24 | 将进行中的认领标记为 stale 的时间阈值 |
AGENTSYNC_GIT_TIMEOUT | 否 | 25 | 任一 git/gh 调用失败前允许运行的秒数 |
首次针对明确指定的看板调用 survey() 或 claim() 时,会自动创建 agentsync 分支,无需手动设置。
看板的位置(看板寻址)
* 看板是共享的、长期存在的团队产物,不是你当前所在的某个仓库的属性。因此,看板地址会独立于会话,按以下顺序解析:
AGENTSYNC_BOARD_REPO— 显式指定的看板地址。它绝不会跟随 Xylem 会话指针(~/.xylem/active_project.json)。AGENTSYNC_REPO— 旧版显式固定地址;效果相同。- 当前仓库(会话指针指向的仓库,否则为当前工作目录的 Git 根目录)——但仅当该仓库确实包含协作分支时。检查会实际查找引用(本地分支 → 远程跟踪引用 →
ls-remote),因此此回退方式只会选择确实是看板的仓库。 - 否则,返回一个指明
AGENTSYNC_BOARD_REPO的ConfigError——绝不会静默选择一个没有看板的仓库。
survey() 会在 board: {repo, source} 下报告实际读取的看板,因此可以区分“团队目前没有动静”和“我查看的是错误的看板”。
为什么采用这个顺序。 以前,未固定地址的服务会盲目跟随会话指针。因此,每当会话切换项目,看板的身份也会改变;而在从未配置过的项目中,看板会直接消失——下游会将其报告为 "no coordination branch found",并视为正常情况。cambium 的 distill() 使用完全相同的解析逻辑,因此套件的两部分永远不会对看板的位置产生分歧。
从零开始(还没有仓库)
如果 GitHub 上还没有共享仓库,由一个人运行一次 provision()。将 AGENTSYNC_BOARD_REPO 指向你希望存放项目的文件夹(可以是空文件夹,也可以是尚未创建的文件夹),然后调用:
provision(repo="you/our-project", partner_github="their-username")
这会创建 GitHub 仓库(默认设为私有)、创建首次提交、初始化 agentsync 协作分支,并邀请你的伙伴成为可推送的协作者。此操作具有幂等性,可以安全地重复运行。然后将它返回的 clone_url 发给你的伙伴;对方接受邀请并克隆后,你们各自将 MCP 服务指向自己的克隆仓库,之后即可使用下面的常规协议。
工具
provision(repo="", partner_github="", private=True, description="") — 在共享仓库尚不存在时进行一次性引导。通过 gh 创建 GitHub 仓库、创建首次提交、初始化 agentsync 分支,并邀请伙伴成为可推送的协作者。具有幂等性。返回可交给伙伴的 clone_url。(需要已通过 repo 权限进行身份验证的 gh CLI。)
add_collaborator(github_username, permission="push") — 邀请一位或多位人员(以逗号或空格分隔)加入现有共享仓库,以便他们推送(pull|triage|push|maintain|admin)。如果仓库已存在,而你只想授予访问权限,请使用此工具——这是组建超过两人团队的方式。他们必须接受 GitHub 邀请,然后克隆仓库。(需要拥有该仓库管理员权限的 gh。)
survey() — 拉取最新状态,并报告每个其他 Agent 声明的任务、文件、依赖项、分支、状态和时间戳。支持任意数量的协作者。每位伙伴的条目都会标注 age_hours 和 stale 标志(任务进行中且超过 AGENTSYNC_STALE_HOURS 指定的时长,默认 24h),并提供顶层的 stale_claims 列表,让你能发现仍占用文件但已崩溃或离开的伙伴。规划前和完成后都应运行。
claim(task, touches, requires=None, branch="", force=False) — 认领一项工作。若 touches 涉及合作伙伴正在处理的文件(会妨碍对方),或 requires 涉及对方正在处理的文件(会让你基于不稳定的内容构建),则返回 status: "blocked" 并拒绝认领,同时准确列出重叠内容及相关人员。重叠检查会考虑路径:完全匹配、目录包含关系(src/api 与 src/api/routes.py)和 glob 模式(src/**、*.py)都会发生冲突,并且会先规范化路径(./auth.py == auth.py)。推送前会基于刚获取的最新状态检查重叠。传入 force=True 可强行认领(例如处理同一个大文件中的不同区域)。如果你的 Agent ID 已持有由另一个服务实例写入的进行中认领(即另一个 Agent 正以相同 ID 运行),claim() 会返回 blocked,并附带 shared_agent_id 原因,列出将被覆盖的任务、分支和文件,因为一个 ID 只能持有一项认领。为每个 Agent 分配独立 ID;在合法场景下,重启的服务重新认领自己的位置时,可用 force=True 覆盖,此时结果会包含一条 warning,列出刚刚失去保护的文件。
release(note="") — 放弃当前认领,但不标记为已完成,让合作伙伴可以接手这些文件。放弃任务或暂时离开时请使用此操作,否则崩溃或被放弃的认领会一直阻塞这些文件,直到有人手动进行 Git 操作。会立即推送。
check_conflicts(against_branch="") — 完成构建后,从两个层面比较你的分支与合作伙伴的分支:
claim_overlap— 已声明路径的交集(意图层面,考虑路径)。merge_conflict— 实际运行git merge-tree进行试合并(文本层面)。可发现认领时未预测到的冲突。
默认检查所有活跃合作伙伴认领中列出的分支;传入 against_branch 可检查某个特定分支。
update_status(status, note="") — 设置你自己的认领状态(planning | in-progress | done),并可选择留下一条备注给合作伙伴。会立即推送。状态设为 done 时,认领会自动附上 changed_files——你的分支相对默认分支的 diffstat——让合作伙伴依据实际数据而非手写摘要进行协调。该数据在看板仓库中计算;认领只记录不带仓库限定符的分支名称,因此,当你在专用看板仓库中协调时,其中同名分支也会产生看似干净、实则错误的文件列表。请先检查标签,再信任该列表。(若要放弃认领但不完成任务,请使用 release()。)
finish(note="", title="", draft=False) — 完成整个流程:将认领标记为 done,并且从你认领的分支向默认分支创建 GitHub 拉取请求。若未指定 PR 标题或正文,则使用认领中的任务或备注;如果已有尚未关闭的 PR,则返回其 URL。你的分支必须已推送。(需要 gh。)
history(limit=20) — 协调时间线,从 claims.json 的 Git 历史中读取(谁认领、完成或释放了什么,以及发生时间),按时间从新到旧排列。即使合作伙伴不在线,也能回答“我的合作伙伴最近在做什么?”
工作流程(你的 Agent 要执行的操作)
provision(...)— 仅在仓库尚不存在时执行一次(然后双方都克隆仓库)survey()— 合作伙伴在做什么(如果有)?- 规划一项不会与对方活跃工作重叠的任务
claim(...)— 如果受阻,缩小任务范围或等待- 在你的分支上构建
- 再次运行
survey()— 对方现在进展如何? check_conflicts()— 对方已合并的工作是否与我的工作冲突?- 协调(rebase/merge 或标记问题)→
update_status("done", ...)或运行finish(...)同时创建 PR
Agent 应运行的完整提示词位于 AGENTS.md。
两个以上的 Agent
这里没有任何限制要求只能有两个 Agent。claims.json 以 Agent ID 为键,claim()
会将你的计划与所有其他 Agent 进行检查,而比较并交换操作只会编辑你自己的键,因此三个、四个或更多 Agent 都能安全协作。组建团队:
-
邀请所有人:
add_collaborator("alice, bob, carol")(或在provision(partner_github=...)中列出他们)。 -
为每个 Agent 设置唯一的
AGENTSYNC_AGENT_ID——是每个Agent,而不是每个人。一人同时运行桌面会话、手机和远程 Agent 时,需要三个 ID,原因与三个人需要三个 ID 相同:一个 ID 只能持有一个认领。claim()会阻止操作,而不是覆盖你自己的 ID 下仍有效的认领;不过,为每个 Agent 分配唯一 ID 可以完全避免冲突。以前,这项保护机制依据每个进程的令牌来判定,因此能检测到重启的服务,却放过了并发会话——一台机器上的一个 agentsync 进程会为所有会话提供服务,因此两个会话共用同一个令牌,彼此静默覆盖。现在,它依据的是工作任务:如果你的 ID 下已有正在进行的认领,那么无论是哪个进程写入的,都会拒绝对不同任务的认领。重新认领同一任务仍不受限制,因此可以在单个工作单元中扩展
touches。release(expect_task=...)则处理相反的情况:如果要关闭的认领不是你认为自己持有的那个,就会拒绝操作。 -
少数 Agent 同时争用时,开销仍然很低;如果有大量 Agent 同时尝试认领,
claim()可能会返回retry_exhausted——只需调用survey()并重试即可。
测试
python3 test_agentsync.py # unit + protocol suite (real git repos)
python3 test_workflow.py # two-person lifecycle + real MCP stdio transport
test_agentsync.py(51 个用例,每项测试相互隔离)覆盖协议(共享文件上的认领与阻止、依赖进行中的工作、强制覆盖、已完成的认领不会造成阻止、状态验证)、路径感知的重叠检测(目录包含关系、glob、规范化、互不重叠的目录不会冲突)、冲突检测(文本冲突与可干净合并)、比较并交换保证(其他 Agent 的认领在操作过程中到达时,既能在我们的重试中保留,也能及时被观察到以阻止冲突)、活跃状态管理(release、stale 标记、防止并发会话的有效认领保护)、审查循环(history 时间线、done 差异统计捕获、finish 创建或复用 PR、推送必需保护)、错误路径,以及配置和 add_collaborator(单人和多人邀请、从环境变量读取合作方、跳过已有远程仓库、报告邀请失败、权限错误、没有远程仓库)。测试会使用 gh CLI 存根,不会触及真实的 GitHub 仓库。test_workflow.py(5 个用例)通过子进程运行完整的双人生命周期和真实的 MCP stdio 传输。每次推送时,CI 都会通过 GitHub Actions 运行这两组测试。
限制
- 基于文本,而非语义。
check_conflicts能捕获无法合并的文件;但无法发现“他们对 API 签名的更改会导致我的调用方出错”之类的问题。这类推理应由 Agent 负责(阅读双方的差异)——服务提供信号,而非判断。 - 双方都必须选择加入。 只有合作方的 Agent 也运行同一服务并遵循相同的认领协议时,这套机制才能完整发挥作用。否则,你的 Agent 只能退化为检查分支:它能看到已合入的内容,而看不到计划中的内容。
- 建议性锁定。 认领依靠约定防止冲突,而非强制执行;
force=True的存在正是因为有些重叠可以接受。
许可证
PolyForm Noncommercial License 1.0.0——可免费用于、修改并分享任何非商业用途。商业用途需要单独的许可证。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。