agentsync について
agentsyncは、同じGitリポジトリで作業する複数のAIエージェントを調整するMCPサーバーです。専用ブランチに対象ファイルや依存関係を記録し、Gitのプッシュで競合する申告を検出します。
主な機能
- 01相手の申告と停滞中の作業を確認
- 02パスの重複を判定してタスクを申告
- 03申告上の競合とGitのマージ競合を確認
- 04状態更新、作業解放、履歴確認
- 05リポジトリ作成と共同作業者の招待
- 06作業を完了してGitHub PRを作成
活用シーン
- 01複数エージェントによる並行変更の調整
- 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
2つ以上の AI エージェントが、互いの作業を妨げることなく同じ git リポジトリで協力できる MCP サーバーです。各エージェントは作業を始める前に何を構築するのかを宣言し、パートナーが申告した内容を確認して、作業が取り込まれた際に競合を検出します。すべてリポジトリ自体を通じて調整されるため、ロックサーバーは不要で、両方のエージェントが同時にオンラインである必要もありません。
仕組み(1段落)
調整状態は、専用の agentsync ブランチ上に置かれた単一の claims.json です(main から分離されているため、コード履歴に混入せず、main のブランチ保護によって妨げられることもありません)。各エージェントの申告には、作業内容、変更するファイル、必要とするもの、ブランチ、ステータスが記載されます。重複は単純な集合の積集合で判定されます。書き込みには、git push を比較交換として使う読み取り・変更・書き込みループを使用します。push が拒否された場合、サーバーは最新の申告を再取得して再評価するため、このエージェントの申告がコミットされる前に、競合するパートナーの申告が認識されます。すべての git 操作は .git/ 配下のプライベートな worktree で行われるため、エージェントが実際に使用するコードブランチが影響を受けることはありません。
アーキテクチャの設計理由については DESIGN.md を、エージェントがツールを操作する際に従う手順については AGENTS.md を参照してください。
インストール
pip install -r requirements.txt # just `mcp`
GitHub と連携する操作(リポジトリのプロビジョニング(provision)、コラボレーターの招待(add_collaborator)、PR の作成(finish))には、repo スコープで認証済みの GitHub CLI も必要です。
gh auth login # one-time; check with `gh auth status`
設定
両方のコラボレーターが、それぞれ固有のエージェント ID とローカルクローンを使って、MCP クライアントにサーバーを追加します。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 | はい | — | 一意のエージェント ID |
AGENTSYNC_REMOTE | いいえ | origin | git リモート名 |
AGENTSYNC_BRANCH | いいえ | agentsync | 調整ブランチ名 |
AGENTSYNC_PARTNER_GITHUB | いいえ | — | 招待するパートナーの GitHub ユーザー(カンマまたはスペース区切り) |
AGENTSYNC_STALE_HOURS | いいえ | 24 | 進行中の申告に stale のフラグを付けるまでの経過時間 |
AGENTSYNC_GIT_TIMEOUT | いいえ | 25 | 1 回の git/gh 呼び出しが失敗として扱われるまでの秒数 |
明示的に指定されたボードに対する最初の survey() または claim() 呼び出し時に、agentsync ブランチが自動的に作成されます。手動でのセットアップは不要です。
ボードの保存場所(ボードのアドレス指定)
* ボードは共有され、長期間維持されるチームの成果物であり、作業中のリポジトリに属するものではありません。そのため、アドレスはセッションとは独立して、次の順序で解決されます。
AGENTSYNC_BOARD_REPO— 明示的に指定するボードのアドレスです。Xylem のセッションポインター(~/.xylem/active_project.json)には一切追従しません。AGENTSYNC_REPO— レガシーな明示指定です。同じ効果があります。- 現在のリポジトリ(セッションポインター、それがなければ cwd の git ルート)— ただし、そのリポジトリに調整ブランチが実際に存在する場合に限ります。実際に参照を検索して確認するため(ローカルのヘッド → リモート追跡参照 →
ls-remote)、このフォールバックで選ばれるのは、実際にボードであるリポジトリに限られます。 - それ以外の場合は、
AGENTSYNC_BOARD_REPOを示すConfigErrorが発生します。ボードのないリポジトリが黙って選択されることはありません。
survey() は、実際に読み取ったボードを board: {repo, source} として報告するため、「チームに動きがない」のか「別のボードを見ている」のかを判別できます。
この順序にする理由。 以前は、明示指定のないサーバーがセッションポインターに無条件で追従していました。そのため、セッションのプロジェクトが変わるたびにボードのアドレスも変わり、プロビジョニングされたことのないプロジェクトではボード自体が見つからず、下流では "no coordination branch found" と報告され、それが正常な状態として扱われていました。cambium の distill() もまったく同じ方法で解決するため、スイートの両方の部分でボードの場所が食い違うことはありません。
何もない状態から始める(リポジトリがまだない場合)
共有リポジトリが GitHub 上にまだ存在しない場合は、1 人が provision() を 1 回実行します。AGENTSYNC_BOARD_REPO にプロジェクト用のフォルダーを指定し(空でも、まだ作成されていなくてもかまいません)、次を呼び出します。
provision(repo="you/our-project", partner_github="their-username")
これにより GitHub リポジトリ(デフォルトではプライベート)が作成され、最初のコミットが行われ、agentsync 調整ブランチが作成され、パートナーがプッシュ権限を持つコラボレーターとして招待されます。冪等なので、安全に再実行できます。返される clone_url をパートナーに送ってください。パートナーが招待を受け入れてクローンしたら、2 人ともそれぞれのクローンを MCP サーバーに指定し、以降は通常のプロトコルに従います。
ツール
provision(repo="", partner_github="", private=True, description="") —
共有リポジトリがまだ存在しない場合に、一度だけ行う初期設定です。gh を使って GitHub リポジトリを作成し、最初のコミットを行い、agentsync ブランチを作成して、パートナーをプッシュ権限を持つコラボレーターとして招待します。冪等です。パートナーに渡す clone_url を返します。(repo スコープで認証済みの gh CLI が必要です。)
add_collaborator(github_username, permission="push") — 既存の共有リポジトリに、プッシュできるよう1 人以上(カンマまたはスペース区切り)を招待します(pull|triage|push|maintain|admin)。リポジトリがすでに存在し、アクセス権を付与したい場合に使います。2 人を超えるチームを作る方法です。招待された人は GitHub の招待を受け入れてから、クローンする必要があります。(リポジトリの管理者権限を持つ gh が必要です。)
survey() — 最新の状態を取得し、ほかのエージェントが申告した内容(タスク、ファイル、依存関係、ブランチ、ステータス、タイムスタンプ)を報告します。コラボレーターが何人いても使えます。各パートナーの情報には age_hours と stale フラグ(作業中のまま AGENTSYNC_STALE_HOURS(デフォルトは 24 時間)を超過した場合)が付加され、さらに最上位に stale_claims リストが表示されます。そのため、クラッシュしたり作業を中断したりして、ファイルを確保したままのパートナーを見つけられます。計画の前と、作業完了後に実行してください。
claim(task, touches, requires=None, branch="", force=False) — 作業単位を確保します。touches がパートナーの作業中のファイルと重なる場合(作業を妨げてしまいます)、または requires がパートナーの進行中のファイルと重なる場合(不安定な状態を基盤にすることになります)、status: "blocked" を返して拒否し、重複する内容と相手を正確に示します。重複の判定はパスを考慮します。完全一致、ディレクトリの包含関係(src/api と src/api/routes.py)、グロブ(src/**、*.py)はすべて衝突し、パスは最初に正規化されます(./auth.py == auth.py)。重複は、プッシュの直前に取得した最新の状態を対象に確認されます。強制的に確保する場合(例:同じ大きなファイルの別々の領域を編集する場合)は、force=True を指定します。エージェント ID がすでに別のサーバーインスタンスによって書き込まれた進行中の claim を保持している場合(同じ ID で別のエージェントが稼働中の場合)、claim() は blocked と shared_agent_id の理由を返し、消去されるタスク、ブランチ、ファイルを示します。1 つの ID が保持できる claim は 1 つだけです。エージェントごとに異なる ID を割り当ててください。正当なケースとして、再起動したサーバーが自分の枠を再確保する場合は force=True で上書きできます。その場合、結果には保護を失ったファイルを列挙する warning が含まれます。
release(note="") — 現在の claim を完了扱いにせずに放棄し、パートナーがファイルを引き継げるようにします。タスクを中断するときや作業を離れるときに使ってください。そうしないと、クラッシュまたは放棄された claim によって、そのファイルは手動で Git を操作するまでブロックされます。即座にプッシュされます。
check_conflicts(against_branch="") — 作業後に、2 つのレベルで自分のブランチとパートナーのブランチを比較します。
claim_overlap— 宣言されたパスの交差(意図を反映し、パスを考慮)。merge_conflict— 実際のgit merge-treeによるマージのドライラン(テキストベース)。claim では予測できなかった衝突を検出します。
デフォルトでは、アクティブなピア claim に記載されたすべてのブランチを対象にします。特定のブランチを確認するには against_branch を指定します。
update_status(status, note="") — 自分の claim のステータス(planning | in-progress | done)を設定し、任意でパートナー向けのメモを残します。即座にプッシュされます。done にすると、デフォルトブランチとの自分のブランチの diffstat に基づく changed_files が claim に自動で注釈として追加されるため、パートナーは手書きの要約だけでなく実際のデータをもとに調整できます。これはボードリポジトリで計算されます。また、claim に記録されるブランチはリポジトリを示す情報のない名前だけです。そのため、専用のボードリポジトリで調整している場合、同じ名前のブランチがそこにあると差分は問題なく計算されますが、ファイル一覧は誤っているのに確実であるかのように見えます。一覧を信用する前にラベルを確認してください。(完了せずに claim を放棄するには、release() を使います。)
finish(note="", title="", draft=False) — 一連の作業を締めくくります。自分の claim をdoneにし、確保したブランチからデフォルトブランチへの GitHub プルリクエストを作成します。PR のタイトル/本文には、claim のタスク/メモを代用します。すでに PR が開いている場合は、その URL を返します。ブランチはプッシュ済みである必要があります。(gh が必要です。)
history(limit=20) — claims.json の Git 履歴から読み取った調整のタイムラインです(誰が、いつ、何を確保、完了、または解放したか)。最新のものから順に表示します。相手がオフラインでも「パートナーはこれまで何をしていたのか?」を確認できます。
ワークフロー(エージェントが行うこと)
provision(...)— リポジトリがまだ存在しない場合に限り、一度だけ実行します(その後、両者がクローンします)survey()— パートナーが作業中かどうか、作業中なら何をしているかを確認します- パートナーの進行中の作業と重ならない作業範囲を計画します
claim(...)— ブロックされた場合は、作業範囲を狭めるか、待機します- 自分のブランチで作業します
survey()を再実行し、相手の状況を確認しますcheck_conflicts()— 相手が取り込んだ変更は、自分の変更と衝突するか確認します- 調整(rebase/merge または問題の報告)を行い、
update_status("done", ...)を実行するか、finish(...)で PR も作成します
エージェントが実行する完全なプロンプトは AGENTS.md にあります。
2つを超えるエージェント
ここでは2つに限定されません。claims.json はエージェント ID をキーとしており、claim() はすべての相手エージェントに対して計画を確認します。また、比較交換で編集するのは常に自分のキーだけです。そのため、3つ、4つ、あるいはそれ以上のエージェントでも安全に連携できます。チームを運用するには、次のようにします。
-
全員を招待します:
add_collaborator("alice, bob, carol")(またはprovision(partner_github=...)に列挙します)。 -
すべてのエージェントに一意の
AGENTSYNC_AGENT_IDを割り当てます。一意にするのは人ごとではなく、すべてのエージェントです。1人がデスクトップセッション、スマートフォン、リモートエージェントを実行する場合、3人で実行する場合と同じ理由で、3つの ID が必要です。1つの ID が保持できる claim は1つだけだからです。claim()は、自分の ID で有効な claim を上書きせずに処理をブロックしますが、エージェントごとに一意の ID を使えば、衝突そのものを避けられます。このガードは以前、プロセスごとのトークンをキーにしていたため、再起動したサーバーは検出できても、同時実行中のセッションは通過させていました。1台のマシンでは1つの agentsync プロセスがすべてのセッションにサービスを提供するため、2つのセッションが同じトークンを共有し、互いの claim を気づかれないまま上書きしていました。現在は作業をキーにしています。自分の ID でタスクを実行中に別のタスクを claim しようとすると、どのプロセスが書き込んだかにかかわらず拒否されます。同じタスクの再 claim は引き続き許可されるため、ユニットの途中で
touchesを広げられます。反対方向の操作にはrelease(expect_task=...)が対応し、自分が保持していると思っているものとは異なる claim を閉じることを拒否します。 -
少数のエージェントであれば、競合が発生しても負荷は軽微です。多数のエージェントが同時に claim すると、
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ケース)では、プロトコル(共有ファイルに対する claim/ブロック、WIP への依存、強制上書き、完了済み claim はブロックしないこと、ステータスの検証)、パスを考慮した重複検出(ディレクトリの包含、glob、正規化、互いに異なるディレクトリはクリーンであること)、競合検出(テキスト上の競合とクリーンなマージ)、比較交換の保証(処理中に相手の claim が登録されても、こちらの再試行後にその claim が保持され、衝突をブロックするのに間に合うよう検出されること)、生存性(release、stale フラグの設定、同時セッションに対する有効な claim のガード)、レビューのループ(history のタイムライン、done の diffstat の取得、finish による PR の作成または再利用、push 必須のガード)、エラー経路、プロビジョニングと add_collaborator(単独および複数の招待、環境変数からのパートナー取得、既存リモートのスキップ、招待失敗の報告、不正な権限、リモートなし)を検証します。実際の GitHub リポジトリにアクセスしないよう、gh CLI はスタブ化されています。test_workflow.py(5ケース)では、2人でのライフサイクル全体と、サブプロセスとして実行する実際の MCP stdio トランスポートをテストします。CI では、GitHub Actions を通じて、プッシュごとに両方のテストを実行します。
制限事項
- 意味的な判定ではなく、テキスト上の判定です。
check_conflictsはマージできないファイルを検出しますが、「相手の API シグネチャの変更によって自分の呼び出し側が壊れる」といったことは検出しません。そうした判断はエージェントの役割です(両方の diff を読みます)。サーバーはそのためのシグナルを提供しますが、判断自体は行いません。 - 双方が参加する必要があります。 パートナー側のエージェントも同じサーバーを実行し、同じ claim プロトコルに従う場合に限り、すべての機能が動作します。そうでない場合、こちら側はブランチの確認にとどまり、予定されている変更ではなく、反映済みの変更を確認します。
- アドバイザリロックです。 claim は慣例によって衝突を防ぐものであり、強制するものではありません。一部の重複は問題ないため、
force=Trueが用意されています。
ライセンス
PolyForm Noncommercial License 1.0.0 — 非商用目的であれば、無償で使用、変更、共有できます。商用利用には別途ライセンスが必要です。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。