UE5 Unreal Python を使った MCP のテスト

UE5 5.8 には MCP サーバー機能が搭載されましたが、もともと Unreal Engine には python コードをリモート実行する機能も備わっています。こちらでも似たようなことが可能で、5.8 よりも前のバージョンでも動きます。ただしサンドボックス化されていないため、もし AI エージェントから呼び出す場合は注意が必要となります。

Python Remote Execution の有効化

  1. もし有効になっていなかったらプラグインマネージャーから「Python Editor Script Plugin」を有効化して Editor を起動し直します
    • 大抵デフォルトで有効になっています
  2. メニューの “Edit” → “Project Settings…”
  3. 左側のカテゴリから「Python」を選択して、「Python Remote Execution」の中にある ” Enable Remote Execution? ” にチェックを入れます
  4. Editor を一旦閉じて起動し直します

MCP サーバー化スクリプトを作ってみる

python の remote 呼び出しを mcp 化します。ファイル名は “ue5-python-mcp.py” とします。

import os
import sys
import time

from mcp.server.fastmcp import FastMCP

ue5_root= os.environ.get('UE5_ENGINE_ROOT', 'C:/Program Files/Epic Games/UE_5.8')
sys.path.append( os.path.join( ue5_root, 'Engine/Plugins/Experimental/PythonScriptPlugin/Content/Python' ) )
from remote_execution import RemoteExecution

mcp= FastMCP('ue5-python', json_response=True)

#------------------------------------------------------------------------------

logger= None
def print_err( *msg ):
    if True:
        print( *msg, file=sys.stderr )
    else:
        global logger
        if not logger:
            logger= open( 'log.txt', 'w' )
        logger.write( ' '.join([ str(m) for m in msg]) + '\n' )
        logger.flush()


class UEInterface:
    def __init__( self ):
        self.remote_exec= None

    def find_node( self, nodes, machine ):
        for node in nodes:
            if machine == '*':
                return  node.get('node_id')
            pc= node.get('machine')
            if pc == machine:
                return  node.get('node_id')
        print_err( 'Error: UE5 node %s not found' % machine )
        return  None

    def connect( self ):
        if not self.remote_exec:
            self.remote_exec= RemoteExecution()
            self.remote_exec.start()
            time.sleep( 1 )
            hostname= os.environ.get('COMPUTERNAME',os.environ.get('HOST',os.environ.get('HOSTNAME','*')))
            node_id= self.find_node( self.remote_exec.remote_nodes, hostname )
            if node_id:
                self.remote_exec.open_command_connection( node_id )

    def disconnect( self ):
        if self.remote_exec:
            self.remote_exec.stop()
            self.remote_exec= None

    def script_wrapper( self, script ):
        out_str= 'try:\n'
        for line in script.split('\n'):
            out_str+= ' ' + line + '\n'
        out_str+= '\nexcept Exception as e:\n print("Error:",str(e))\n'
        return  out_str

    def exec( self, script ):
        wrapped= self.script_wrapper( script )
        result= self.remote_exec.run_command( wrapped )
        return  result

    def is_valid( self ):
        return  self.remote_exec

ueinterface= None

def get_api():
    global ueinterface
    if not ueinterface:
        ueinterface= UEInterface()
        ueinterface.connect()
    return  ueinterface

#------------------------------------------------------------------------------

@mcp.tool()
def run_ue5python( script:str ) -> str:
    """
    UE5 の remote_execution 機能を使って python script を実行します。
    UE5 の python api を呼び出すことが出来ます。

    Args:
        script     実行するpythonスクリプト
    """
    api= get_api()
    if not api.is_valid():
        return  'Error: Unable to connect to UE5'
    result= api.exec( script )
    success= result.get('success',False)
    output= result.get('output')
    return  str( { 'success': success, 'output': str(output) } )

#------------------------------------------------------------------------------

if __name__=='__main__':
    mcp.run(transport='stdio')

スクリプトをそのまま実行すると、エラー発生時にうまく動かなくなる場合があります。例外が出た場合、Editor のコンソール上では赤文字でエラーメッセージが表示されているのですが、戻り値として LLM には何も返っていないからです。原因がわからないとエラー時に無駄な試行錯誤を繰り返してしまうので、mcp に渡されたスクリプトコードをあらかじめ “try:” ~ “except” で囲んでエラーを返すようにしています。

AI クライアントアプリ側の MCP 設定例

使用するツールにあわせて設定してください。以下は uv を使う場合の mcp.json の設定例です。環境変数 UE5_ENGINE_ROOT にエンジンのパスを設定します。

  "mcpServers": {
    "ue5": {
      "command": "uv",
      "args": [
        "run",
        "--with",
        "mcp",
        "ue5-python-mcp.py"
      ],
      "env": {
        "UE5_ENGINE_ROOT": "C:/Program Files/Epic Games/UE_5.8"
      }
    }
  }

または直接 PYTHONPATH に UE5 の remote_execution.py が置いてあるパスを設定しても構いません。

  "mcpServers": {
    "ue5": {
      "command": "uv",
      "args": [
        "run",
        "--with",
        "mcp",
        "ue5-python-mcp.py"
      ],
      "env": {
        "PYTHONPATH": "C:/Program Files/Epic Games/UE_5.8/Engine/Plugins/Experimental/PythonScriptPlugin/Content/Python"
      }
    }
  }

uv を使わない場合は “pip3 install mcp” で mcp モジュールをあらかじめ追加しておいてください。

  "mcpServers": {
    "ue5": {
      "command": "python",
      "args": [
        "ue5-python-mcp.py"
      ],
      "env": {
        "UE5_ENGINE_ROOT": "C:/Program Files/Epic Games/UE_5.8"
      }
    }
  }

実行前の注意点

これはあくまで検証用で、サンドボックス化が行われていないので注意してください。このツールを使うと mcp 経由で任意の python コードが実行可能となります。ファイルアクセスやコマンド実行、ネットワークアクセス等が行われる可能性があるため、使用する場合は必ず安全対策を行ってください。以下はその例です。

  • ローカルアカウントを使ったまっさらな PC を用意して、そこで UE5 を起動する
  • 自動承認を行わず、呼び出されるスクリプトが問題ないか毎回確認してから手動承認する

使ってみる

先に UE5 Editor を起動してから、AI 側のクライアントアプリを起動します。例えば Claude Code のような mcp に対応したコーディングツールを使うことができます。Python の unreal モジュールの命令を AI 経由で実行できます。アセットの編集やレベルへの配置などもエージェントに任せることが可能です。

この方法を使うと 5.8 よりも古い UE5 でエージェントを使用することができます。ただ色々と機能制限はあります。UE5 5.8 の標準の MCP サーバーの方ができることが多く機能が豊富なので、やはり本格的に使う場合はそちらを使った方が良いかと思います。

関連ページ