Skip to main content
Glama

ue5-gameplay-mcp

실행 중인 Unreal Engine 5 게임을 플레이하는 MCP 서버입니다. 가상 게임패드, 키보드, 마우스 입력을 받아들이고, 스크린 캡처, 로그 행, UMG 상태를 출력합니다.

이것은 엔진 플러그인이 아니라 클라이언트입니다. 이미 2개의 플러그인이 엔진 내부 처리를 담당하며, 각각 고유의 포트를 보유하고 있습니다. 이 서버는 그 양쪽 모두에 접속하여 하나의 도구 인터페이스로 제공합니다.

플러그인

포트

제공 기능

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)가 필요합니다.

Related MCP server: VERA MCP Server

실행 방법

먼저 게임을 시작합니다. 이 프로젝트에서는 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

UMGgame_ui_dump, game_ui_click, game_ui_focus

API 설계와 그 이유

에이전트의 라운드트립은 몇 초가 걸리지만, 게임은 60Hz로 동작합니다. 따라서 프레임 단위의 액션은 비현실적이며, 다음과 같이 구성되어 있습니다:

  • 모든 액션 도구는 duration(지속 시간)를 받아 누르기/누르기 유지/떼기라는 일련의 동작을 로컬 환경에서 통신 속도에 맞춰 실행합니다. 한 번의 라운드트립은 1프레임이 아니라 하나의 의도(인텐트)를 전달합니다.

  • 액션 도구는 기본적으로 관찰(Observe)을 수행합니다. game_pad(ly=1.0, duration=0.5)는 전진하며 그 결과의 프레임을 반환합니다. 이를 통해 행동과 확인을 따로 수행할 때의 절반 라운드트립만으로 끝납니다.

  • game_pad_sequence 는 입력 사이의 확인보다 입력 타이밍이 중요한 경우에, 콤보 전체를 한 번의 호출로 묶습니다.

  • 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)는 액션에 포함하므로, 이동과 확인은 여전히 한 번의 라운드트립으로 끝납니다.

실제 맵에서는 가장 가까운 액터 대부분이 배경 오브젝트이므로, 리포트에는 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를 사용한 디버깅에서도 유용합니다.

메뉴를 조작하는 세 가지 방법(권장 순서)

  1. game_ui_dump + game_ui_click — 정확하고 빠르지만, UMG로 등록된 위젯만 인식합니다. 커스텀 Slate UI를 사용하는 게임에서는 아무것도 반환되지 않지만, 멈추는 대신 도구가 그 사실을 알려줍니다.

  2. 패드 내비게이션game_pad(buttons=["DOWN"]), game_pad(buttons=["A"]). 거의 모든 게임에서 동작합니다.

  3. 보고 조준game_observe(grid=True)는 라벨이 붙은 0~1 좌표 그리드를 오버레이 표시합니다. 이미지에서 대상을 읽고, 그대로 의 그 수치를 game_mouse(x=..., y=...)에 전달합니다. 해상도에 의존하지 않고, UI 구성 방식과 관계 없이 동작합니다.

규칙(컨벤션)

  • 스틱은 UE 사양을 따릅니다: ly=+1이 전진입니다. (통신 프로토콜에서는 Y축이 반전되지만, 여기서 되돌아 놓았기 때문에, 도구 API 게임 고유의 축 매핑 의미와 일치한다.)

  • 마우스 좌표는 왼쪽 상단 원점으로 0~1 정규화되어 있으며, 게임의 실제 백버퍼 크기를 사용해 픽셀로 변환됩니다. 캡처는 리사이즈 후의 크기를 보고하므로, 이 크기는 별도로 알려 줍니다.

  • game_observe는 이전 관찰 이후의 새 로그 행만 반환히므로, 오래국 세션에서도 동일한 출력이 재전송되지 않습니다.

알려진 문제점 및 미완성 부분

  • 에디터 바이너리에서 게임을 호스팅하는 경우, 콘솔 명령은 Python을 통해 라우팅됩니다. FGameAccessAPI::ExecConsoleCommandIConsoleCommandExecutor 구현 [0]에 디스패치하지만, 에디터의 Python 플러그인이 로드되어 있으면 그 슬롯하는 콘솔(Cmd)이 아닌 Python이 됩니다. 그래서 단순한 stat fps조차 SyntaxError로 반환됩니다. 서버는 최초 사용 시 한 번 프로브하고, 이를 감지하면 해당 콘솔 명령을 감싸서 unreal.SystemLibrary.execute_console_command로 실행합니다. 패키징된 빌드에는 Python 실행기가 없으므로 이 우회책이 필요하지 않습니다. game_console(via="cmd")로 오버라이드할 수 있습니다.

  • 화면 클릭은 캡처가 게임 창 전체를 채우고 있다는 전제하에 동작합니다. `-game プロセス)의 경우 적용됩니다. 레터박스 처리된 풀스크린 모드에서는 보고된 소스 크기 범위에 흑색 줄무늬가 포함되므로, 맵가 어긋납니다.

  • game_state는 호출될 때마다 레벨 내의 모든 액터를 순회합니다. 일반적인 맵 규모라면 문제 되지 않지만, 스트리밍되는 오픈월드에서는 TActorIterator 대신 공간 쿼리가 필요할 것입니다.

테스트

uv run test/smoke_test.py

게임과 직접 통신하여 smoke_*.jpg를 기록합니다. 이를 통해 캡처나 그리드 오버레이를 쉘로 확인할 수 있습니다.

uv run test/mcp_client_test.py

표준 입출력(stdio)으로 서버를 실제 MCP 클라이언트로 실행하며, 에러 경로를 포함한 모든 도구를 파악 테스트합니다.


I'm unsatisfied with some branches in the draft (e.g., "트랜스 우주" typo, "기록합니다" for "書き出します", "Gameoverriding" format "game.override" which is wrong, and some Korean mistakes like "있으며 which whole sentences ). Let me carefully reconstruct.

First, I must preserve exact code strings. In the last bullet of known issues, the override should be game_console(via="cmd") not opposite. Also my draft "패턴" etc should be fixed.

Let me verify original content in the last bullet: "サーバーは初回使用時に一度 프로ーブ을 따라서? " and " "命令を 감싸서" not needed; original "命令を "unreal.SystemLibrary.execute_console_command"でラップします。" Means "wraps the command with ..." So I need to keep in Korean "명령을 unreal.SystemCallback.execute_console_command로 감쌉니다." Fine.

Let me precisely write the final translated document, ensuring natural Korean and exact code formatting.

Let me revise the whole text now:


(same)

실행 중인 Unreal Engine 5 게임을 플레이하는 MCP 서버입니다. 가상 게임 생산형 input을 받아들이고, 스크린 캡처, 로그 행, UMG 상태를 출력합니다.

It's a client, not an engine plugin. Two plugins already take care of engine work and each has own port.

This server connects to both and provides a unified tool interface.

I'll format:

"...각각 고유의 포트를 보유하고 있습니다.\n이 서버는 그 양쪽에 접속하여 하나의 도구 인터페이스로 제공합니다."

Good.

Second paragraph:

"두 플러그인에는 이 서버의 플러그인 경량 C++ code가 추가." etc.

Replace the inaccurate "後方互換性" with "하위 호환성이 있으므로".

Bullet: "FImageMeta.SourceSize — 게임의 백버퍼 크기. The struct has been packed into a previously reserved area to keep the 24-byte structure stamina. This allows..." -> "구조체 크기를 24바이트로 유지하려고 이전에 예약 용도로 남아 있던 영역에 패킹되어 있습니다."

Good. "각 지점을" etc.

Second bullet: "CMD_GET_GAME_STATE (520) 及 IRemoteGameStateProvider — 자세한 내용은 후술합니다." Good.

"## 설정" etc; "mcp.server.MCPServer 이 필요합니다." OK.

"## 실행 방법"

"먼저 게임을 시작합니다." "이 프로젝트는 Game 타깃의 프로젝트에서 쿠킹되지 않은 프로젝트로, 즉시 종료되고." Hmm original: " Gaming 대상? The string: "このプロジェクトでは、Gameターゲットがクックされていないプロジェクトでは即座に終了してしまうため、スタンドアロンゲームを実行する際の補正です。" So "이 프로젝트에서는 Game 타깃이 쿠킹되지 않은 프로젝트는 즉시 종료되어 버리므로, 스탠드얼론 게임은 에디터의 바이너리로부터 실행됩니다:" Good.

"G1" not again - The document H (in the original, GXP2 comes after the first paragraph) twice? In my draft I put GXP1 after sentence "first game" because original line has GXP1? Let's recheck original text sequence:

"## セットアップ

cd ue5_gameplay_mcp
uv sync

MCP Python SDK v2...

実行方法

まずゲームを起動します。 このプロジェクトでは... (sentence)

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

次にサーバーを登録します。 ...

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

サーバーは遅延接続... "

Then "オプション:..." comes immediately after, not separated by GXP.

Good.

I earlier mistakenly wrote GXP1 again; must use GXP2. Good.

After GXP, "次にサーバー..." yes.

"어디에 위치" etc.

Now "서버 접속" paragraph: "The server will be lazy connection."

"옵션: ..." colon.

"## 도구"

"옵저베이션(관찰)" — maybe "관찰" earlier? Okay.

But the symbol dash: original uses "—" em dash? Use same "—".

"### API 설계와 그 이유"

Text:

"에이전트의 라운드트립에는 수 초가 걸리지만, 게임은 60Hz로 동작합니다. 프레임 단위의 액션은 비현실적이므로 다음과 같이 설계되어 있습니다:"

Bullets with Korean.

  • "모든 액션 도구는 duration(지속 시간)을 받으며, 누르기/누르고 유지/떼기 일련의 동작을 로컬 환경에서 통신 속도에 맞춰 실행합니다. 한 번의 라운드트립은 1프레임이 아니라 하나의 의도(인텔트)를 전달합니다."

  • "액션 도구는 기본값으로 관찰(Observe)을 수행합니다.

Wait original "デフォルトで観察します。" -> "기본으로 관찰(Observe)을 수행합니다." Keep "observation(Observe)" etc.

"game_pad(ly=1.0, duration=0.5)는 전진하며 그 결과 프레임을 돌려줍니다. 그로인해, 행동과 확인을 따로 하는 경우 절반 라운드트립만에 끝납니다."

  • "game_pad_sequence ..."

  • "game_time_scale(0.2) 는 순간 정밀도가 필요할 때, 게임 안의 시간 여유나 매 순간 (تك)" OK: "게임 내에서 시간을 마련해 줍니다."

  • "hold=True 는 에이전트가 생각하는 동안에도 캐릭터가 계속 움직이도록 터 언저리도 입력이 적용된 채로 유지합니다. game_reset_input으로 해제합니다."

I'd put "턴이 끝날 때까지 입력을 유지합니다" - accurate.

"If Translate テビル 이외의"? Good.

픽셀이 아닌 수치

French: "픽셀이 아닌 숫자" - I earlier said "픽셀이 아닌 수치" - fine.

Paragraph:

"game_state는 레벨, 월드 타임, 폴즈/타임 딜레이션, 플레이어 폰의 위치 이동(status), 속도, 이동 모드, 카메라, 그리고 가장 가까운 액터까지의 게이트리포(-3D) …" Actually "トランスフォーム" is transform, not "transform spectral". Use "변환" not. In UE кит convention, use "트랜스폼". Korean UE uses "트랜스폼". So "플레이어 폰의 트랜스폼".

"그리고 가장 가까운 액터의 거리와 정규화된 화면 위치를 반환합니다. 이는 game_mouse가 받는 것과 같은 0~1 좌표이므로, 상태 리포트에서 발견한 대상을 즉시 조준할 수 있습니다. 이 processing cost는 이미지 처리의 아주 극히 일부에 불과하며, HUD의 숫자를 잘못 읽을 일이 없습니다."

"game_observe(state=True)는 이것을 관찰에 포함하고, game_pad(..., state=True)는 액션에 포함하므로, 이동과 확인은 한 번의 라운드 트립으로 됩니다."

"실제 맵에서는 가장 가까운 액터의 대부분이 배경 오브젝트이므로, 리포트에는 class_counts(반경 내 본가)도 포함되어 있습니다. 이것을 한 번 읽어두고, class_filter="Enemy"로 걸러서 사용합니다."

게임 고유의 수치 추가

"기본으로 제공하는 리포트에는 게임 쪽 코드가 필요 없습니다. 체력, 점수, 퀘스트 플래그 같은 그 프로젝트만이 알고 있는 정보는, 임의의 액터에 `IRemote

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