# LLM がツールを直接呼び出す（MCP）

> tools/war3_mcp.py は MCP サーバーです。Claude Code、Claude Desktop、または MCP に対応した任意のクライアントに登録すれば、LLM がコードを書かずに、局面を見る、コマンドを出す、画面上でプレイヤーに話しかける、カードを出してプレイヤーに尋ねる、スクリーンショットで画面を見る、といったことを直接行えます。

出典: https://war3ai.com/ja/docs/mcp/

`tools/war3_mcp.py` は **MCP サーバー**（stdio）です。Claude Code、Claude Desktop、ローカルモデル用の Agent フレームワーク —— MCP に対応した任意のクライアントに登録すれば、LLM がコードを書かずに**直接**、局面を見る、コマンドを出す、ゲーム画面上でプレイヤーに話しかける、プレイヤーに尋ねる、スクリーンショットで画面を見る、といったことができます。

Bot を書く、アドバイザーを務める、ユニットにしゃべらせる、に続くもう 1 つの接続方法です：**LLM 自身がツールの使い手になります**。

## 登録する

```bash
claude mcp add war3 -- python <リポジトリ>\tools\war3_mcp.py --inst 9      # Claude Code。<リポジトリ> は自分の openwar3 フォルダに置き換える
```

他のクライアントでは、次の形式で設定を書きます。

```json
{"mcpServers": {"war3": {"command": "python", "args": ["<リポジトリ>\\tools\\war3_mcp.py", "--inst", "9"]}}}
```

ゲームに接続するのは最初にツールが呼ばれたときなので、ゲームは後から起動しても構いません。ゲームを閉じて起動し直した場合も、次の呼び出しで自動的に再接続します。`--role` を付けると、LLM にできることを制限できます。

| ロール | 使えるもの |
|---|---|
| `dev`（デフォルト） | すべてのツール。`war3_jass` を含む |
| `player --player N` | N 番プレイヤーのユニットだけを指揮でき、その視界内のものだけが見えます（フェアモード）。JASS はなし |
| `observer` | 読み取り専用。画面への描画も、ユニットにしゃべらせることもできない。下したコマンドはランタイムがそのまま拒否 |

`player` ロールの制限は[ゲートウェイ](https://war3ai.com/ja/docs/gateway/)と同じです：ゲームの終了、速度変更、一時停止は使えず、他プレイヤーの手の内が見える API も使えません。プレイヤー番号を取るクエリは自分の分しか照会できません。

いくつかの上限：1 つのツール結果は最大 20 万文字で、超えた分は切り詰められ、範囲の絞り方が示されます。`war3_ask_player` の待ち時間は最大 120 秒です。スクリーンショットの `scale` は 0.1 から 1 の間です。

## ツール

| ツール | 内容 |
|---|---|
| `war3_overview` | 局面の要約：時刻、資源、人口、自軍の兵種ごとの数、ヒーロー（HP、マナ、レベル、クールダウン）、見えている敵の兵種、生産。**最初にこれを呼ぶ** |
| `war3_units` | ユニット一覧（`owner` は me / enemy / creep / all、`types` で絞り込み）。コマンドを出すときは `addr` を使う |
| `war3_events` | 前回の呼び出し以降に起きたこと：死亡、レベルアップ、スキル使用、生産完了、チャット、プレイヤーがボタンをクリック……（デフォルトでは大量に流れる数種類を除外） |
| `war3_call` | 任意の公開 API を呼ぶ（`move`、`attack_move`、`train`、`build`、`cast`、`learn`、`ui.button`、`canvas.text`……）。ユニットは `{"unit": addr}` で指定 |
| `war3_api` | API を調べる：キーワードで名前と説明を検索 |
| `war3_toast` / `war3_say` | 画面上部に 1 行のテキスト / ユニットの頭上にひと言 |
| `war3_ask_player` | 画面中央にプレイヤー向けの選択カードを数枚出し、クリックを待って、どれが選ばれたかを返す（ゲームを一時停止できる） |
| `war3_screenshot` | ゲーム画面のスクリーンショット（PNG。ウィンドウが隠れていても撮れて、フォーカスも奪わない） |
| `war3_jass` | JASS を実行（dev 専用。ワールドを変更できるのはシングルプレイのみ） |

こんな使い方ができます：

- **一緒に遊ぶ / コーチ**：`war3_overview` で局面を見て、`war3_toast` で画面にアドバイスを出す。
- **プレイしながらプレイヤーに尋ねる**：`war3_ask_player` でカードを 3 枚出し、プレイヤーが選んだとおりに進める。
- **実況**：`war3_events` で何が起きたかを読み、`war3_say` でユニット自身にしゃべらせる。
- **1 つの部隊を直接指揮する**：`player` ロール + `war3_call` で、自分のユニットだけを動かす。
- **画面を見て UI を調整する**：`war3_screenshot` で 1 枚撮り、自分で描いたボタンの配置が正しいかを確認する。

## 会話はたとえばこんな感じ

```text
あなた：今の局面を見て、それから画面で聞いて：次は拡張、兵の量産、ティアアップのどれにする？

→ war3_overview      {}
← 局面の要約：ゲーム時間、ゴールド 500、人口 10/12、自軍 htow 1 · hpea 5 · Hpal 1、敵は見えず、生産中のものなし
→ war3_ask_player    {"question": "次はどうする？", "options": ["兵の量産", "拡張", "ティアアップ"], "pause": true}
← {"picked": 1, "option": "拡張"}

モデル：拡張を選びましたね。まず war3_units で手の空いている農民を探し、最寄りの金鉱がどこかを確認します……
```

## 実測

2026-09-25：

- 自作の MCP クライアントを実際の試合につないで 7/7：ハンドシェイク → ツール一覧（10 個）→ `war3_overview`（`htow` 1、`hpea` 5）→ `war3_units` → `war3_toast` → `war3_screenshot`（PNG 約 20 万バイト）→ `war3_ask_player`（カード 3 枚。2 枚目のクリックをシミュレート → `{"picked": 1, "option": "拡張"}`）。
- Claude Code 2.1 に実際に登録：Claude Code が自分でサーバーを起動してハンドシェイクし、ステータスは `connected`。10 個のツールがすべて `mcp__war3__*` としてツール一覧に現れました。

## 実装

- 改行区切りの JSON-RPC 2.0（`initialize` / `tools/list` / `tools/call` / `ping`）。プロトコルバージョンは 2025-06-18 で、2025-03-26 と 2024-11-05 にも対応します。
- ツールのエラーは MCP の規約どおり結果の中に入れ（`isError: true`）、接続は切りません。
- [ゲートウェイ](https://war3ai.com/ja/docs/gateway/) と、同じロールのホワイトリスト、ユニット引数の形式、「局面の要約」を共有しています。
- ログは stderr に出し、stdout にはプロトコルだけを流します。
