Skip to main content
Glama

MARL Cop & Thief - MCP を介したデュアル AI エージェント

2 つの自律 AI エージェント(CopThief)が MCP サーバー上で 自由な自然言語 で対話し、ゲーム理論的ミニマックス + 自己対戦 RL エンジンで手を決定し、Web コントロールパネル にライブ表示し、合意された JSON マッチレポート を Gmail API 経由でメール送信する、分散型・部分観測可能な 追跡ゲーム です。

University of Haifa · Orchestration of AI Agents (ex06) · Dr. Yoram Segal.
1 つのコマンドですべてを起動し、1 つのブラウザタブでマッチ全体を実行します。


Highlights

  • ワンコマンドノード - python -m cop_thief.app は両 MCP サーバー、パブリック Cloudflare トンネル、およびブラウザコントロールパネルをまとめて起動します(孤立トンネルなし、ポートのやりくり不要)。

  • Web コントロールパネル - ノードのライブステータス、コピー可能な公開 URL/トークン、対戦相手用の チャレンジフォーム、ワンクリックの ミラーセルフテスト、ライブな 5×5 ゲーム TV をすべて http://127.0.0.1:8800 で提供。

  • 本格的な戦略 - Conway の封鎖ゲーム(Cop = Devil の壁、§4.3)と 自己対戦 RL による重み学習を備えた Angel–Devil ミニマックス エンジン(ゼロ和マルコフゲーム、アルファベータ)。課題のベースラインであるテーブル型 Q をはるかに超えています。docs/STRATEGY.md を参照。

  • 分散型 & チート耐性 - 審判なし。両側が結果をハッシュ化(SHA-256)し、不一致があればスコアは 0/0 です。受信した散文は敵対的と見なされます。プロンプトインジェクション/強制は スクリーニングされ、証拠として記録され、結果を変更できません(降参アクションは存在しません)。

  • Single SDK boundary + API Gatekeeper - すべてのロジックは CopThiefSDK の背後にあり、すべての外部コール(LLM、Gmail)は DeepSeek→Anthropic フェールオーバを備えた FIFO バックプレッシャ付きゲートキーパーを経由します。

  • 品質ゲート - pytest カバレッジ 85 % 以上、ruff 違反ゼロ、1 ファイル 150 行以内、uv のみ。


Related MCP server: Police MCP Server

Quick start

uv sync                                   # install (uv is the ONLY package manager)
cp .env-example .env                      # fill in real values (see "Secrets")
uv run ruff check .                       # zero-violation lint gate
uv run pytest                             # full suite (>=85% coverage gate)
uv run python -m cop_thief.app            # launch the control panel + servers + tunnels

次に http://127.0.0.1:8800 を開きます。


Playing a match (control panel)

  1. uv run python -m cop_thief.app を実行 → パネルが開きます。Servers ●Tunnels ● が緑になるまで待ちます。

  2. ステータスカードには、2 つの公開 …/mcp/ URL とロール別トークン(コピー用ボタン)が表示されます。これらを対戦相手に送ってください。合わせて docs/INTER_GROUP_TREATY_SPEC.md も送ります。記入フォームは match_setup/ の(RULES.txtOUR_DETAILSOPPONENT_DETAILS)を使用します。

  3. 対戦相手の 2 つの …/mcp/ URL(トークンがあればそれも)を チャレンジフォーム に貼り付け、START CHALLENGE をクリックします。6 つのサブゲームがクロスホストで TV 上に表示され、レポートがメール送信されます。

  4. まだパートナーがいませんか? MIRROR SELF-TEST ⟳ をクリックします。自分のローカルホストエンドポイントとトークンが自動記入され、自分自身と対戦します(戦略テストに最適)。

A game = 6 sub-games(§4.1 に従う): Cop で 3 ゲーム(ホームレグ)と Thief で 3 ゲーム(アウェイレグ)をプレイし、Thief 先手、各 ≤ 25 手です。スコアリングは不変です: Cop が捕獲 → 20 / 5; Thief が生き残り → 5 / 10


Screenshots

The control panel - ノードのステータス(Servers/Tunnels/Game)、共有可能な …/mcp/ URL とトークン(コピー用ボタン付き)、対戦相手チャレンジフォーム、ライブゲーム。ここではミラーセルフテストが実行中です。[INTENT: BARRIER] 行(Cop が隣接セルに壁を作りその場に留まる、§4.3)、緑色の B バリア、! による捕獲に注目。

Control panel

Live board - Cop C(青)と Thief T(赤)がいる 5×5 グリッド。隣に通信傍受フィードがあり、自然言語の [INTENT: MOVE] 送信と HOME LEG / Sub-game セパレータが表示されています。

Live board

Leg transition - サブゲーム 4/6 で AWAY LEG(こちらが Thief をプレイ)に入るランナー。ボード上には B バリアと ! による捕獲が残っています。

Away leg and barrier

ノードを起動すると、共有可能なエンドポイントがターミナルに出力されます(1 プロセス: servers + tunnels + panel):

Control panel  >  http://127.0.0.1:8800   (open in a browser)
╔══════════════════════════════════════════════════════════════════╗
║ LIVE PUBLIC MATRIX (Team Alpha)                                   ║
╠══════════════════════════════════════════════════════════════════╣
║ COP   (:8001)  https://acting-tomorrow-yard-raid.trycloudflare.com/mcp/   ║
║ THIEF (:8002)  https://dial-mean-courses-tramadol.trycloudflare.com/mcp/  ║
╚══════════════════════════════════════════════════════════════════╝
Tunnels live and written to config/setup.json. Share these /mcp/ URLs. Ctrl+C to stop.

Architecture

Layer

Module

Responsibility

Domain

domain/

不変の DecPomdpGameStateGrid、ジオメトリ、NL 移動言語([INTENT: …])。

Strategy

domain/strategy/

minimax(アルファベータ)、evaluation/features(Angel–Devil)、selfplay(RL)、Q テーブルベースライン。

SDK

sdk/

CopThiefSDK 単一エントリポイント;MatchCoordinator の終端/罠捕獲死ロジック;warfare/injection ス クリーニング。

Gatekeeper

infra/gatekeeper/

すべての LLM/Gmail コールに対する FIFO チョークポイント;DeepSeek→Anthropic フェールオーバ;トークンテレメトリー。

Servers

servers/

Cop & Thief FastMCP サーバー;トークン認証;request_move ツール → StrategyResolver

Transport

infra/network/

ストリーム可能な HTTP /mcp ホスト、RemoteMoveClient、Cloudflare スイッチボード。

Orchestration

orchestrator/

ChallengeRunner(クロスホスト、レグごと)、reconcile(相互合意 / 0-0)、シリーズ。

UI

ui/

コントロールパネルバックエンド(server.py)、NodeState、ブロードキャスト SSE バス、static/panel.html

Reporting

reporting/

Gmail OAuth レポータ(件名と本文にグループ名)、追記のみの監査ログ、安全ガード。

Entry points

Command

What it does

python -m cop_thief.app

コントロールパネル: servers + tunnels + web UI(メインのもの)。

python -m cop_thief.challenge

対話型ターミナルによるクロスホストチャレンジ(対戦相手の URL を入力)。

python -m cop_thief.serve

Servers + tunnels のみ(UI なし)。

python -m cop_thief.infra.network.dual_mcp_host

2 つの MCP サーバーのみ(:8001/:8002 /mcp)。

python -m cop_thief.diagnostic_runner

オフライン、ゼロコストの追跡プローブ(モック LLM)。


Strategy in one paragraph

request_move には、ゼロ和マルコフゲーム(Cop が最大化、Thief が最小化、最適敵対仮定)に対する深さ制限付き アルファベータ・ミニマックス で応答します。進捗に応じた終端スコア(±WIN ∓ turns)により、ポリシーは捕獲/生存を迫るため、引き分けは構造的に回避されます。Cop のアクション集合には 隣接セルへの壁作成(Conway の "Devil" ムーブ、§4.3)が含まれます。評価関数の containment 特徴量は、Thief のフラッドフィル逃出領域であり、プランナーは適法な追い込んで罠に嵌める手筋を自ら発見します。線形評価の重みは 自己対戦 TDselfplay.train_weights)で調整可能です。3 つのバリアント・プロファイル(aggressive / balanced / defensive)が要求される 3 エージェントのロースターを編成します。完全な設計: docs/STRATEGY.md


Formal model - Dec-POMDP

この追跡は Decentralized, Partially-Observable Markov Decision Process としてモデル化され、タプル ⟨ n, S, {Aᵢ}, P, R, {Ωᵢ}, O, γ ⟩(ex06 §11)で表されます。

Symbol

Meaning

In this project

n

agents

2 - Cop と Thief(独立、共有メモリなし)。

S

state space

DecPomdpGameState: cop_posthief_pos ∈ 5×5 グリッド、barriers ⊆ G の集合(≤ 5)、cop_barriers_leftturn_counterturn_role。結合位置空間は (R·C)² = 625 で制限されます。バリアを含めると到達可能空間はより大きいが有限です。

Aᵢ

per-agent actions

Cop: 8 方向の King ムーブ(Chebyshev ≤ 1)∪ 隣接する空きセルにバリアを置く(その場に留まる) ∪ HOLD。Thief: 8 方向の King ムーブ ∪ HOLD。「Stay」は退化したムーブです。

P

transition

決定論的 なボード状態マシン(apply_action): 各ターンに 1 回の変異。非合法ムーブ(ボード外 / バリア上 / King でない)は拒否されます。バリアのターンでは指定した隣接セルに壁を作り Cop はその場に留まります。

R

reward

不変の表 1: 捕獲 → Cop +20 / Thief +5; 回避 → Cop +5 / Thief +10。プランナーは進捗に応じた終端値(±WIN ∓ turns)を用いるため、プレイは厳密に決定的です(引き分けなし)。

Ωᵢ

observation space

エージェントごとの 主観的 ビュー: 視野半径内なら対戦相手の正確な座標を iff で得るが、それ以外は定性的な遮蔽 セクタ(例: THIEF_IN_NORTHWEST_QUADRANT)。

O

observation function

get_subjective_observation(role, radius) - マンハッタン距離が vision.radius(デフォルト 2)以下のとき対戦相手を明らかにし、それ以外は象限のみ。両ロールで対称(fog-of-war)。

γ

discount

自己対戦 TD / Q ベースラインでは rl.gamma = 0.9。ミニマックスのレイヤは代わりに進捗に応じた終端スコアを用いて捕獲/生存を迫ります。

部分観測可能性は現実のものです。各エージェントは、ボードに対する 信念(直前の観測 + 解析された対戦相手の散文)から決定し、グローバルな真実値からは決して決定しません。

Orchestration challenges (the hard part)

ex06 §14 によれば、この課題の 価値はオーケストレーション であり、勝利ではありません。難しい問題とその解決方法:

  • 自由な自然言語、事前定義されたプロトコルなし。 エージェントは散文で対話します。薄い決定的コントラクトを重ねます - 各メッセージは、正確に1つの標識 [INTENT: MOVE|BARRIER|HOLD] で始まり、その後に方角語が続きます - これにより、本体は自由なNLのままでも手は機械的に解決可能です。これにより、独立に構築された2つのエンジンを、共有コードベースなしでロックステップに保ちます。

  • 言語的曖昧さと信頼できない入力。 受信した散文は決定的に解析されます(最長一致の方角語、フレーバーテキストが偽装できないようにブラケットのみのインテント)。非構造化された相手テキストに対してはオプションのLLM解析を使用します; 信頼度が低い場合は → 安全な探索的フォールバック(クラッシュせず、キャプチャを偽造しない)。すべてのフィールドは敵対的として扱われます - 例えば非数値の variant は強制的に変換され、信頼されません。

  • 相互理解の確保。 両ピアは決定的な手言語を共有し(LLM不要のエンコード/パース)、ゲームはバイト再現可能です。最後に両サイドは標準 sub_games をハッシュします(SHA-256、K3); 不一致があれば ⇒ 両者とも 0/0 - 合意は前提ではなく強制されます。

  • 信頼性のないネットワーク上での活性。 ホスト間の手は再接続によるリトライを行います; 継続的な停止またはフローズンしたピア(手ごとの20秒タイムアウト)は、そのサブゲームを棄権し、シリーズは常に全6戦を完了し、レポートはそれでもメール送信されます - 停止した相手は決してマッチを止められません。

可視化と決定的な証拠(§11)

  • GUI - 上記のスクリーンショットは、ライブの5×5ボード、[INTENT: …] 通信傍受フィード、バリア(B)、キャプチャー(!)、およびレグ遷移を示しています。

  • クラウド MCP 通信 - 上記のブートブロックは、ライブの公開 Cloudflare /mcp/ URLを出力し、パネルの通信フィードはクラウドサーバーと交換される実際の [INTENT:] 送信をストリームします; 各手番も data/game_audit.jsonl に追記され、改ざん防止付きのゲーム別アーカイブ(data/archive/、レポート内のバンドル SHA-256)に封入されます。

  • 学習 - 戦略の重みは自己対戦TDselfplay.train_weights)で調整されます; 比較用にテーブル型Q学習ベースラインも保持されます。設計+カーブ: docs/STRATEGY.md

セキュリティと公正なプレー

  • トークン - すべての MCP ツール呼び出しには、ロールごとの失効可能なベアラートークンが必要です; 帯域外で交換され、ローテーションで失効できます。サーバーはフェイルクローズドです。

  • インジェクション対策 - 受信送信は信頼されません; インジェクション/強制/成りすまし/偽造は検査され、data/game_audit.jsonlhostile:true とフラグされ、レポートで計上され、エンジン決定の結果には一切影響を与えません。相手との条約(§F)に明文化されています。

  • 相互合意 - 両サードは標準 sub_games をハッシュします; 不一致があれば ⇒ 0/0both_lose)。

  • レポーティング - OAuth2 Desktop 経由の Gmail API(スコープ gmail.modify、パスワードなし); グーループ名は件名とJSONボデーの両方に含まれます; 安全ガードはデフオルトで使い捨て用受信トレーを使用します。


トークン予算とコスト

すべての外部呼び出しは API GatekeeperTokenTracker によってメータリングされ、ライブな使用量を data/token_usage.json にストリームします(原子書き込み; K3合意ハッシュから除外されるため、コストが結果に影響することはありません)。すべての数値は設定駆動です(config/setup.json → token_budget / economics)。

プロバイダー(ロール)

入力 $/100万トークン

出力 $/100万トークン

DeepSeek deepseek-chat(プライマリ)

0.15

0.60

Anthropic claude-3-5-sonnet(フェールオーバーのみ)

3.00

15.00

予算項目

実際の支出(全ランの合計)

≈ $0.01

ライフサクル予算

200,000入力 + 50,000出力トークン

→ 予測ライフサクルコスト(プライマリ)

~$0.06

1ターンあたりの推定(入力120 / 出力40)

~$0.00004

ハード上限(80%で警告)

$0.50(警告 $0.40)

強制

上限に達した課金対象のLLM呼び出しに対して API GatekeeperBudgetExceeded を返す - クラッシュしない

実際には、プロジエクト全体の LLM コストは約 $0.01 です。 手はローカルなミニマックスエージンから来ており、 手言語は決定的な [INTENT: …] エンコード/パースです - プレーやレポート送信に LLM は不要です (Gmail API であり、LLM ではありません)。小さな予算 + DeepSeek 優先のフェールオーバーは、オプショナル の LLM 支援自然言語パースのためのガードレールです; 上限は**$0.50**に設定されており、十分な余裕があります。

シークレットと設定

  • .env-example.env にコピーして記入します: DEEPSEEK_API_KEYANTHROPIC_API_KEYCOP_MCP_TOKENTHIEF_MCP_TOKENGMAIL_CREDENTIALS_PATH。依存ゼロのオートローグーが起動時に .env を注入します - export/source は不要です; 既存のシェル export が常に優先されます。

  • 調整可能な項目はすべてバージョン管理された config/*. json にあります(ハードコーデングなし)。シークレット(.envcredentials.jsontoken.json)は git に無視され、ソース管理に入ることはありません。

ドキュメンテーション

PRD · PLAN · TODO · STRATEY · RULES_AND_AGREEMENTS · INTER_GROUP_TREATY_SPEC

ライセンス

MIT.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/najikay/mcp-marl-pursuit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server