Skip to main content
Glama

ue5-gameplay-mcp

Ein MCP-Server, der ein laufendes Unreal-Engine-5-Spiel spielt. Er nimmt virtuelle Gamepad-, Tastatur- und Maus-Eingaben entgegen und gibt Bildschirmaufnahmen, Logzeilen und UMG-Status aus.

Dies ist kein Engine-Plugin, sondern ein Client. Zwei Plugins übernehmen bereits die Arbeit innerhalb der Engine und halten dabei jeweils einen eigenen Port. Dieser Server wählt sich in beide ein und stellt sie als eine einheitliche Werkzeug-Schnittstelle bereit.

Plugin

Port

Funktionsumfang

RemoteConsole2

10101

Gamepad-/Tastatur-/Maus-Injektion über IInputDevice, Konsolenbefehle, UMG-Dump/Klick/Fokus, Livestream der Logs, strukturierter Spielstatus

RemoteCapturePlugin

10102

JPEG-/PNG-Bildschirmaufnahme (funkt auf unter PIE und in gepackten Builds) inklusive ueplay_game_capture-Tool

wahrscheinlich korrekt: ue5_gamecapture_mcp

Beiden Plugins wurde für diesen Server eine kleine Portion C++ hinzugefügt. Sie bleiben unabhängig widmen. Die Ergänzungen sind abwärtskompatibel, sodass auch ältere Clients mit neu gebauten Spielen kommunizieren können:

  • FImageMeta.SourceSize – die Größe des Backbuffers des Spiels. Um die Struktur weiterhin auf 24 Bytes zu halten, ist dieser Wert in einem bisherigen reservierten Feld untergebracht. Der Client kann so einen bestimmten Punkt in einem herunter skalierten Bild wieder auf Fensterpixel abbilden.

  • CMD_GET_GAME_STATE(520) und IRemoteGameStateProvider – Details weiter unten.

Einrichtung

cd ue5_gameplay_mcp
uv sync

Die MCP Python SDK v2 (mcp.server.MCPServer) ist erforderlich.

Related MCP server: VERA MCP Server

Ausführung

Zuerst das Spiel starten. Da das Spiel-Target in nicht weiteren Projekten sofort beenden würde, wird das Standalone-Spiel in diesem Projekt aus dem Editor-Binary ausgeführt:

"C:/Program Files/Epic Games/UE_5.8/Engine/Binaries/Win64/UnrealEditor.exe" "<PATH>/MyProject.uproject" -game -windowed -resx=1280 -resy=720 -log -nosplash

Dann den Server registrieren lassen. Die .mcp.json im Projektdurchsatz macht das bereits, sodass Claude Code sie automatisch erkennt. Für die manuelle Alternativleitung sieht der gleichwertige Befehl so aus:

claude mcp add ue5-gameplay -- uv run --directory <PATH>/ue5_gameplay_mcp -m ue5_gameplay_mcp

Der Server verbindet sich träge (Lazy Connect); die tatsächliche Startreihenfolge ist daher egal. Startet ist er schon vor dem Spiel, erfolgt die Verbindung beim ersten Werkzeugaufruf.

Optional: --host, --console-port, --capture-port, --format, --quality, --max-size, --grid-step, --transport streamable-http --mcp-port 14102.

Werkzeuge

Sessiongame_connect, game_status, game_reset_input

Beobachtung (Observation)game_observe, game_state, game_log, game_wait_for_log

Aktionengame_pad, game_pad_sequence, game_key, game_mouse, game_console, game_time_scale

UMGgame_ui_dump, game_ui_click, game_ui_focus

API-Design und warum

Ein Roundtrip des agents dauert einige Sekunden, während das Spiel mit 60 Hz läuft. Frameoperative Aktionen sind deshalb nicht praktikabel, also gilt:

  • Alle Aktionswerkzeuge akzeptieren eine duration (Dauer) und führen eine Folge von Drücken/Halten/Loslassen lokal so eingehend auf die Kommunikationsgeschwindigkeit aus. Ein einzelnen Roundtrip übertragt dann nicht einen Frame, sondern eine Absicht (Intent).

  • Aktionswerkzeuge beobachten standardmäßig (Observe). game_pad(ly=1.0, duration=0.5) bewegt nach vorn und gibt den resultierenden Frame zurück. das halbiert die Roundtripzahl gegenüber der Teilung in Aktion und respin Belge.

  • game_pad_sequence zieht für Combos den gesamten Ablauf in einen call zusammen, wenn Timing wichtiger ist als das Bestätigen zwischen den Eingaben.

  • game_time_scale(0.2) extended game time, when necessary by counting on exact precision at the illustrated channel.

  • hold=True behält die Eingabe während der Runde bestehen, damit the Figur continues to move while the agent itself. game_reset_input setzt dies zurück.

Zahlen statt Pixel

game_state liefert die Ebene, die Weltzeit, Pause/Time-Dilation, die Transform, die Geschwindigkeit und den Bewegungsmodus des Player-Pawns, dazu die Kamera sowie die normierte Bildschirmposition des am nächsten gelegenen Actor. Das sind dieselben 0–1-Koordinaten, die game_mouse erhält; damit lässt der sich der Zielpunkt aus dem Statusbericht umgehend anvisieren. The Verarbeitungskosten dafür sind nur were fraction of the Bildverarbeitung, and keine HUD-Zahlen werden als falsch pass measurement.

game_observe(state=True) nimmt das in die Beobachtung auf, game_pad(..., state=True) in die Aktion, sodass Bewegung und Bestätigung weiterhin in einem Single Roundtrip stecken.

In realen Kärtung sind die meisten closest actors es um an inner objects. Der Bericht enthält nun zusätzlich einem allseitigen Überblick class_counts über alle Objekte im Radius. Read das Einmal und filter mit class_filter="Enemy".

Eigene Werte des Spiels hinzufügen

Im eingebauten Bericht braucht esdafür keinen Code von Spielseite. Für Werte, of which only this project zu Know (also like health, score, quest flags) implementer you an actor IRemoteGameStateProvider (in RemoteConsole2/Source/RemoteConsole2/RemoteGameState.h); the actor erforderlich returns a JSON object string.

FString AMyGameMode::GetRemoteGameState_Implementation()
{
    return FString::Printf( TEXT("{\"score\":%d,\"wave\":%d}"), Score, Wave );
}

Das Ereignis ist ein BlueprintNativeEvent, lässt sich also auch in pure-Blausieren the blueprint-nur-Projekt programme. All values werden under custom nach dem Actor-Name Schlüssen and Fließen abgelegt. Provider werden unabhängig from the distance filter collected; liegt daher der Spielstandshüter bei der Origin, werden sie mitgeliefert. Text, das kein valides JSON ist, wird nicht verworfen, einfach as string durchgegeben, so es – selber ein einfaches Printf-Debug beim warm up – immer hilfreich.

Drei Verfahren to bedienen Menü (in empfohlener Reihenfolge)

  1. game_ui_dump + game_ui_click – genau to both sides, aber erkennt nur widgets, that wanted by UMG registred. In games with own Slate-UI it doesn't return anything, but instead of hang the tool gives Nolle to know.

  2. Pad-Navigation – das.

  3. game_pad(buttons=["DOWN"]), game_pad(buttons=["A"]) Funktioniert in beinahe jedem game.

  4. Look & Clickgame_observe(grid=True) toggles a kon de determined 0–1-Koordinaten-Raster ein. Du störst aim aus dem Bild, gib tips same values to game_mouse(x=..., y=...) zur install; it has noek out on resolution and works for everything.

Konventionen

  • Sticks nach UE: ly=+1 is for forward. (The transfer protocol flips the y axis - here we flip it back, so the tool API same semantics of the game of its own axis mapping.) (Original has "式中"?

  • Maus coordinates are normalized from the top left, 0–1, und mit der wahren Backbuffergröße des Spiels on Pixel umgerechnet. Weil display is that capture the size after resizing, this size is probed separately.

  • game_observe returns only new log lines since the last observation, so the same output is never sent in a long running session.

Known issues and unfinished

  • If the game is hosted from the editor binaries, the console commands are routed through Python. FGamePrivateAPI Add. FGameAccessAPI::ExecConsoleCommand macht dem von IConsoleCommandExecutor the implementation [0] be; is the Editor-Python plugin loaded, becomes his slot to Python instead of Cmd. Einazes stat fpsts so as SyntaxError - the server due to first Use one probe, and if it detest this, wrap it the Befehl in execu: It wraps unreal.SystemLibrary.execute_console_command. In packed packages, there's no Python executor, workaround is not needed. Can override with game_console(via="cmd").

  • Screen clicks assume the capture fills the whole game window. That case yields -game -windowed. In letterboxed full-screen, the source size in the report contains black bars, and the allocation shifts.

  • game_state traverses all actors in the level on every call. That's harmless for typical map sizes; but on streaming open world you would usually a spatial query in TActorIterator need.

Tests

uv run test/smoke_test.py

Geocommunicates directly with the game and writes smoke_*.jpg. This allows visual inspection of the smile (!) must be taken. (Capture and Grid overlay).

uv run test/mcp_client_test.py

Startn the server as real MCP client over standard (I/O) (stdio) - thus execute and test all tools, including error path.

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Control Unreal Engine to browse assets, import content, and manage levels and sequences. Automate…

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to control Unreal E…

  • Drive a live Cinevva game session: edit game files, import CC0 assets, preview changes.

View all MCP Connectors

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/hiroog/ue5_gameplay_mcp'

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