ue5-gameplay-mcp
Enables playing and observing a running Unreal Engine 5 game through virtual gamepad, keyboard, and mouse input, plus screen capture, log streaming, and UMG UI inspection and control.
README
ue5-gameplay-mcp
実行中のUnreal Engine 5のゲームをプレイするMCPサーバーです。 仮想ゲームパッド、キーボード、マウスの入力を受け付け、スクリーンキャプチャ、ログ行、UMGステータスを出力します。
これはエンジンプラグインではなく、クライアントです。2つのプラグインがすでにエンジン内の処理を担い、それぞれ独自のポートを保持しています。 このサーバーはその両方にダイヤルインし、1つのツールインターフェースとして提供します。
| プラグイン | ポート | 提供機能 |
|---|---|---|
| RemoteConsole2 | 10101 | IInputDeviceによるゲームパッド/キーボード/マウスのインジェクション、コンソールコマンド、UMGのダンプ/クリック/フォーカス、ライブログストリーム、構造化されたゲームステート |
| RemoteCapturePlugin | 10102 | JPEG/PNGスクリーンキャプチャ(PIEおよびパッケージ化されたビルドで動作)ue5_gamecapture_mcp 付属 |
両プラグインには、このサーバーのために少量のC++コードが追加されました。 これらは独立性を保ち、独自のプロトコルを維持しています。追加部分は後方互換性があるため、古いクライアントでも再ビルドされたゲームと通信可能です:
FImageMeta.SourceSize— ゲームのバックバッファサイズ。構造体のサイズを24バイトに保つため、以前は予約語だった領域にパックされています。これにより、クライアントはダウンスケールされたキャプチャ上の特定の点をウィンドウのピクセルにマッピングし直すことができます。CMD_GET_GAME_STATE(520) およびIRemoteGameStateProvider— 詳細は後述します。
セットアップ
cd ue5_gameplay_mcp
uv sync
MCP Python SDK v2 (mcp.server.MCPServer) が必要です。
実行方法
まずゲームを起動します。 このプロジェクトでは、Gameターゲットがクックされていないプロジェクトでは即座に終了してしまうため、スタンドアロンゲームはエディタのバイナリから実行されます:
"C:/Program Files/Epic Games/UE_5.8/Engine/Binaries/Win64/UnrealEditor.exe" "<PATH>/MyProject.uproject" -game -windowed -resx=1280 -resy=720 -log -nosplash
次にサーバーを登録します。
プロジェクトルートにある.mcp.jsonがすでにこれを行っているため、Claude Codeは自動的にこれを認識します。
手動で行う場合と同等のコマンドは以下の通りです:
claude mcp add ue5-gameplay -- uv run --directory <PATH>/ue5_gameplay_mcp -m ue5_gameplay_mcp
サーバーは遅延接続(レイジーコネクト)を行うため、実際の起動順序は重要ではありません。 ゲームより先に起動した場合でも、最初のツール呼び出し時に接続が行われます。
オプション: --host, --console-port, --capture-port, --format, --quality, --max-size, --grid-step, --transport streamable-http --mcp-port 14102。
ツール
セッション — game_connect, game_status, game_reset_input
オブザベーション(観察) — game_observe, game_state, game_log, game_wait_for_log
アクション — game_pad, game_pad_sequence, game_key, game_mouse, game_console, game_time_scale
UMG — game_ui_dump, game_ui_click, game_ui_focus
APIの設計とその理由
エージェントのラウンドトリップには数秒かかりますが、ゲームは60Hzで動作します。フレーム単位でのアクションは非現実的であるため、以下のようになっています:
- すべてのアクションツールは
duration(継続時間)を受け取り、押す/押し続ける/離すという一連の動作をローカル環境で通信速度に合わせて実行します。1回のラウンドトリップは1フレームではなく、1つの意図(インテント)を伝達します。 - アクションツールはデフォルトで観察(Observe)を行います。
game_pad(ly=1.0, duration=0.5)は前進し、その結果のフレームを返します。これにより、行動と確認を別々に行う場合の半分のラウンドトリップで済みます。 game_pad_sequenceは、入力間の確認よりも入力のタイミングが重要な場合に、コンボ全体を1回の呼び出しにまとめます。game_time_scale(0.2)は、瞬間の精度が必要な場合にゲーム内時間を稼ぎます。hold=Trueは、エージェントが思考している間もキャラクターが動き続けるように、ターンの間も入力を適用したままにします。game_reset_inputでこれをクリアします。
ピクセルではなく数値
game_stateは、レベル、ワールドタイム、ポーズ/タイムダイレーション、プレイヤーポーンのトランスフォーム、速度、移動モード、カメラ、そして最も近いアクタの距離と正規化された画面位置を返します。
これはgame_mouseが受け取るのと同じ0~1の座標であるため、ステータスレポート内で見つけた対象に即座に狙いを定めることができます。
この処理コストは画像の処理コストのほんの一部であり、HUDの数値を読み違えることもありません。
game_observe(state=True)はこれを観察に組み込み、game_pad(..., state=True)はアクションに組み込むため、移動と確認は依然として1回のラウンドトリップで済みます。
実際のマップでは、最も近いアクタのほとんどが背景オブジェクトであるため、レポートにはclass_counts(半径内のすべてのオブジェクトの調査結果)も含まれます。これを一度読み取り、class_filter="Enemy"で絞り込みます。
ゲーム独自の数値の追加
組み込みのレポートにはゲーム側のコードは必要ありません。ヘルス、スコア、クエストフラグなど、そのプロジェクトのみが知る情報については、任意のアクタにIRemoteGameStateProvider(Plugins/RemoteConsole2/Source/RemoteConsole2/RemoteGameState.h)を実装し、JSONオブジェクトの文字列を返すようにします:
FString AMyGameMode::GetRemoteGameState_Implementation()
{
return FString::Printf( TEXT("{\"score\":%d,\"wave\":%d}"), Score, Wave );
}
これはBlueprintNativeEventであるため、Blueprintのみのプロジェクトでもオーバーライド可能です。
返された値はすべて、アクタ名をキーとしてcustomの下に格納されます。
プロバイダは距離フィルタに関係なく収集されるため、原点に配置されたスコアキーパーもレポートを送信します。
有効なJSONではないテキストは破棄されず、文字列としてそのままパススルーされるため、立ち上げ時の簡単なPrintfによるデバッグでも有用です。
メニューを操作する3つの方法(推奨順)
game_ui_dump+game_ui_click— 正確かつ高速ですが、UMG経由で登録されたウィジェットしか認識しません。カスタムのSlate UIを持つゲームでは何も返されませんが、ハングアップする代わりにツールがその旨を伝えます。- パッドナビゲーション —
game_pad(buttons=["DOWN"]),game_pad(buttons=["A"])。ほぼすべてのゲームで機能します。 - ルック&クリック —
game_observe(grid=True)は、ラベル付きの0~1の座標グリッドをオーバーレイ表示します。画像からターゲットを読み取り、同じ数値をgame_mouse(x=..., y=...)に渡します。解像度に依存せず、UIの構築方法に関係なく機能します。
規則(コンベンション)
- スティックはUEの仕様に従います:
ly=+1が前進です。(通信プロトコルではY軸が反転しますが、ここではそれを元に戻しているため、ツールAPIはゲーム独自の軸マッピングの意味と一致します)。 - マウス座標は左上を原点として0~1に正規化されており、ゲームの実際のバックバッファサイズを使用してピクセルに変換されます。キャプチャはリサイズ後の寸法を報告するため、このサイズは別途プローブされます。
game_observeは前回の観察以降の新しいログ行のみを返すため、長時間のセッションでも同じ出力が再送されることはありません。
既知の問題点・未完成な部分
- エディタバイナリでゲームをホストしている場合、コンソールコマンドはPythonを経由してルーティングされます。
FGameAccessAPI::ExecConsoleCommandはIConsoleCommandExecutorの実装[0]にディスパッチしますが、エディタのPythonプラグインがロードされている場合、そのスロットはCmdではなくPythonになります。そのため、単なるstat fpsがSyntaxErrorとして返されます。サーバーは初回使用時に一度プローブを行い、これを検出した場合はコマンドをunreal.SystemLibrary.execute_console_commandでラップします。パッケージ化されたビルドにはPythonエグゼキュータがないため、この回避策は不要です。game_console(via="cmd")でオーバーライド可能です。 - 画面のクリックは、キャプチャがゲームウィンドウ全体を満たしていることを前提としています。
-game -windowedの場合はこれが当てはまります。レターボックス化されたフルスクリーンモードの場合、報告されるソースサイズ内に黒帯が含まれることになり、マッピングがずれます。 game_stateは、呼び出されるたびにレベル内のすべてのアクタを走査します。 通常のマップの規模であれば問題ありませんが、ストリーミングされるオープンワールドではTActorIteratorの代わりに空間クエリが必要になるでしょう。
テスト
uv run test/smoke_test.py
ゲームと直接通信し、smoke_*.jpgを書き出します。これにより、キャプチャやグリッドのオーバーレイを目視で確認できます。
uv run test/mcp_client_test.py
標準入出力(stdio)経由でサーバーを実際のMCPクライアントとして起動し、エラーパスを含めてすべてのツールを実行・テストします。
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。