ue5-gameplay-mcp
ue5-gameplay-mcp
Es un servidor MCP para jugar a un juego de Unreal Engine 5 en ejecución. Acepta entradas de un gamepad virtual, un teclado y un ratón, y produce capturas de pantalla, líneas de registro y el estado de UMG.
No es un complemento del motor, sino un cliente. Dos complementos ya asumen el procesamiento interno del motor y cada uno mantine su propio puerto. Este servidor se conecta a ambos y los expone como una dica interfaz de herramientas.
Complemento | Puerto | Funcionalidad |
RemoteConsole2 | 10101 | Inyección de gamepad/teclado/ratón mediante |
RemoteCapturePlugin | 10102 | Captura de pantalla JPEG/PNG (funciona entre PIE y compilaciones empaquetadas) incluye |
Se añadió una pequeña cantidad de código C++ a ambos complementos para este servidor. Mantienen su independencia y cada uno conserva su propio protocolo. La ampliación tiene retrocompatibilidad, por lo que un cliente antiguo puede comunicarse igualmente con el juego recompilado:
FImageMeta.SourceSize— El tamaño del back buffer del juego. Está empaquetado en el espacio que antes estaba reservada, mientras se mantiene 24- byte del tamaño de the struct. Así, el cliente puede volver a asociar un punto concreto de la captura reducida al pixel de la ventana.CMD_GET_GAME_STATE(520) yIRemoteGameStateProvider— los detalles a continuación.
Preparación
cd ue5_gameplay_mcp
uv syncSe requiere MCP Python SDK v2 (mcp.server·MCPServer).
Related MCP server: VERA MCP Server
Manera de ejecutarlo
Primero inicia el juego.
Este proyecto, el juego independiente se ejecuta desde el binario del editor, porque el objetivo Game se cierra inmediatamente en los proyectos sinus cocinar:
"C:/Program Files/Epic Games/UE_5.8/Engine/Binaries/Win64/UnrealEditor.exe" "<PATH>/MyProject.uproject" -game -windowed -resx=1280 -resy=720 -log -nosplashLuego se registra el servidor. El . del project root ya hace eso, así que Claude Code recognizes auto-el. El comando equivalente en manual es el siguiente:
claude mcp add ue5-gameplay -- uv run --directory <PATH>/ue5_gameplay_mcp -m ue5_gameplay_mcpEl servidor realiza la conexión diferida (o lazy, / lazy connect), por lo que el orden real de encendido no es importante. Even if it starts before the game, the connection is made at the time of the first tool call.
Opciones: --host, --console-port, --capture-port, --format, --quality, --max-size, --grid-step, --transport streamable-http y --mcp-port 14102.
Tools
Sesiones — game_connect, game_status, game_reset_input
Observación (Observe) — game_observe, game_state, game_log, game_wait_for_log
Acciones — game_pad, game_pad_sequence, game_key, game_mouse, game_console, game_time_scale
Respuesta — game_ui_dump, game_ui_click, game_ui_focus
Diseño de la API y su motivo
MCP puede ir y venir por segundos para el agente, pero el juego funciona a 60 Hz. Dado que las acciones píxeles por frame no son reales, se diseñan así:
Todas las tools de acción reciven una
duration(duración) y realizan una secuencia de pulsar / mantener / soltar de forma local, acorde a la velocidad de comunicación. Una ida yy no significa un frame, sino una intención.Las acciones están por defecto puestas en observación (Observe).
game_pad(ly=1.0, duration=0.5)avanza y devuelve el frame resultante. Esto correcta la half-round trips compared to f carrying out a the action and its confirmation dependently.game_command_sequenceagrupa un combo completo into a sole chat, when the timing of at entries matters more than the confirmation between them.game_time_scale(0.2) can let you win in-game time when instantaneous precision does matter.hold=True** mantiene active la entrada incluso a lo largo del turno, asi que el personaje sigue movement while the agent is thinking. Se resuelve con Mogame_reset_input.
Números, no píxeles
game_state devuelve el nivel, el tiempo del mundo, la pausa/dilatación temporal, la transformación del personaje jugador (pawn), la velocidad, el modo de movement, la camera, y la distance to the "actor más cercano" junto to its posición de pantalla normalizada. Se trata de las mismas coordenadas de 0~1 que recibe name-accord game_mouse, therefore you can point instantly to a object found in the status report. Its processing cost is not only a fraction of the cost of procssing the image, it could also not misread HUD numbers.
game_observe(state=True) recomienda this in the observation report, dos game_button(..., state=True) en la acción; asi, movimiento y confirmation stilling give la misma ida and vuelta.
In real maps, almost all the nearby actors are background objects. The report also comes with class_counts (a census of all objects within radius). Own a single once and filter by "enemy" with class_filter="Enemy".
Adding the game's own numbers
La reportada incorporada no requiere damentos en el bloque del juego. Para información that only el project know - health, score, quest flags, etc., implementar IRemoteGameStateProvider in any actor (path: Plugins/RemoteConsole2/Source/RemoteConsole2/RemoteGameState.h) and make it return the string of a JSON object:
FString AMyGameMode::GetRemoteGameState_Implementation()
{
return FString::Printf( TEXT("{\"score\":%d,\"wave\":%d}"), Score, Wave );
}Dado que es BlueprintNativeEvent, se puede reescribir aun en un proyecto y solo Blueprints. Todos los valores son stored under custom, con el nombre del actor como clave. The providers eran gathered regardless of distance filter, so a scorekeeper placed at the origin of the also sends its report. The non-JSON text is not discarded; it is passed through “ad string, so a quickPrintf during setup is still useful.
Three ways to operate the menus (in order recommended)
game_ui_dump+game_ui_click. It’s accurate & fast, but only recognizes the widgets that have been registered through UMG. To a game with a custom Slate UI, returns nothing — but instead of hanging, the tool says so.Pad navigation —
game_pad(buttons=["DOWN"]),game_pad(buttons=["A"]). Works in (almost) every game.Mirada y clic —
game_observe(grid=True) superposes a 0-1 grid with labels. Read the target in the image and pass that helps same coordinates togame_mouse(x=..., y=...). It is resolution-independent and works no matter howUIbuilt it.
Norms
| "el esco" el mando sigue the UE spec: ly=+1 is advances. The transport protocol flips the Y axis, but here it unflips so the tool API matches the game’s own semantics axis mapping.
| The mouse coordinates are normalized 0..1 with origin at bottom-left, now converted right pixels with the actual back-buffer size of the game.
| The captures report the resized dimensions, for that reason the size in question is checked separately.
| game_observe only gives us new lines of the record, since previous observation, so the same lines are never remitted repeatedly in long session.
Known problems and outstanding areas
When hosting the game from a binary editor, the console commands are routed through Python.
FGameAccessAPI::ExecConsoleCommandservesIConsoleCommandExecutor[0]; but in case the Python plugin of the editor has loaded, the slot is a Python not. For this reason, a simplestat fpsgets returned asSyntaxError. First time the tool is used, the server a single probe within; if it detects that, it wraps the command inunreal.SystemLibrary.execute_console_command. It doesn’t exist a Python for a packaged build, so this workaround is not necessary. It can be overridden bygame_console(via="cmd").Click on screen head I, "screen assuming capture fills complete window". This is the case for
-game -windowed. In full-screen with letterbox, the reportedsource sizeincludes black band, and the mapping goes wrong.game_statetraverses every actor in the level every time it is called. This is fine on a normal map size, but on an open-world with streaming* need to invoke a spatial query instead ofTActorIterator.
Tests
uv run test/smoke_test.pyCommunicate Matter directly with the game and write smoke_*.jpg. This lets you visually check the capture and the grid overlay.
uv run test/mcp_client_test.pyServer instrument through standard input/output (stdio) as a real MCP client and run all tests, including the error paths.
Maintenance
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
- AlicenseBqualityAmaintenanceEnables AI assistants to control Unreal Engine via Remote Control API for game development automation, including asset management, actor control, level editing, animation, physics, visual effects, and cinematics creation through natural language.1336830MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI clients like Claude Code, Cursor, or VS Code to drive the Unreal Editor: execute Python, capture screenshots, tail logs, check status, and run VERA commands.13MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to interact with a running Roblox game client to execute Lua code, inspect scripts, spy on remotes, and more.143216MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to interact with Unreal Engine via Remote Control API for actor, asset, level, and editor operations.2215MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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