The Unreal MCP Web Client is a layered system that bridges browser and AI clients to the Unreal Engine 5.8 MCP server. It consists of a FastAPI proxy (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/davidbuenov/dbv-mcp-server/llms.txt
Use this file to discover all available pages before exploring further.
server.py) for HTTP clients, a stdio bridge (bridge.py) for Claude Desktop, a three-tier tool cache keyed by MD5 hash, and a 20-iteration Gemini agent loop — all backed by a local Playwright-crawled knowledge base of ~15,000 Unreal Engine documentation pages.
Stack Overview
The Unreal MCP Web Client is composed of several discrete layers, each chosen to solve a specific constraint. The table below maps each layer to its technology and purpose.| Layer | Technology | Purpose |
|---|---|---|
| Frontend Core | HTML5, JavaScript (ES6+) | Single-page application with no build step — instant load and native browser debugging |
| Styles | Vanilla CSS3 (HSL tokens, glassmorphism dark theme) | Full control of animations and custom visual design with zero heavy dependencies |
| Proxy Server | Python FastAPI + Uvicorn + HTTPX | Async-first: reads Unreal SSE streams in the background without blocking other requests; injects CORS headers automatically |
| Stream Reader | Fetch Streams API | Native async text/event-stream reading without external libraries |
| AI Agent | Google Gemini API (generateContent) | Multi-turn tool calling against Unreal MCP toolsets, up to 20 iterations with intelligent wrap-up |
| Bridge CLI | bridge.py (stdio-to-HTTP-SSE) | Allows Claude Desktop and any standard MCP stdio client to consume Unreal tools as if they were native |
| Knowledge Base | dbv-unreal-python-api skill | Two tools under one skill: dbv_python_unreal_api (~11,600 UE 5.8 Python API class pages) and dbv_unreal_dev_guide (~3,600 official UE 5.8 conceptual guide pages) |
| Guide Crawler | Playwright + Chromium headless | Epic’s documentation portal is protected by Cloudflare Bot Management — urllib/curl receive 403. The crawler opens a real browser context per page to obtain a valid trust session for every request |
System Diagram
The following diagram shows the complete request path from a browser or Claude Desktop client through the proxy layers to the Unreal Engine MCP server.server.py is the path for the browser-based SPA and any HTTP client. It runs on port 5000 and proxies to http://localhost:8000/mcp.
bridge.py is the path for Claude Desktop and other MCP stdio clients. It reads JSON-RPC 2.0 messages from stdin, forwards them over HTTP to the same Unreal MCP endpoint, and writes responses to stdout. Log messages are written to stderr so they never pollute the JSON-RPC channel.
Both paths share the same flattening and namespace-translation logic described in the sections below.
Tool Cache Architecture
Because building the full toolset list requires onelist_toolsets call plus one describe_toolset call per toolset (potentially 10+ concurrent network round-trips to Unreal), the proxies implement a three-tier cache:
list_toolsets response text. If Unreal’s registered toolsets change (e.g. you recompile a plugin), the hash changes and the cache is automatically invalidated and rebuilt on the next request.
Cache is stored at
.mcp_tools_cache.json in the project root. Delete this file manually if you need to force a full rebuild without restarting the server.Concurrent rebuild in server.py
server.py uses asyncio.gather to describe all toolsets in parallel, which reduces rebuild time dramatically when many toolsets are registered:
Sequential rebuild in bridge.py
bridge.py is a synchronous script running outside an event loop, so it describes toolsets one at a time. The disk cache means this overhead is paid only once per session.
Gemini Agent Loop
The web client’s chat tab runs an autonomous agent loop (runAgentLoop in src/js/app.js) with the following rules:
- Maximum 20 iterations — accommodates complex multi-tool workflows (spawn actor → set material → position → verify).
- All flattened Unreal toolsets are exposed as Gemini function declarations on every turn.
- JSON Schema conversion — Gemini’s
FunctionDeclarationformat does not support several JSON Schema fields. TheconvertSchemaToGemini()function strips them recursively before sending:additionalPropertiesdefault$schematitle
- Toolset name normalization — Gemini function names cannot contain dots. All dots in toolset-qualified names are replaced with underscores (e.g.
SceneTools.add_to_scene_from_class→SceneTools_add_to_scene_from_class). - Final summary call — if the loop reaches 20 iterations while tool calls are still pending, a final Gemini request is made with no tools exposed, so the model can summarize results and return a coherent answer to the user.
Argument Formats (Critical)
Unreal’s Python toolsets use specific JSON object shapes for certain argument types. Passing a plain string where an object is expected silently fails or produces aninvalid argument error from Unreal.
UObject / UClass References
Unreal Python tools expect arefPath wrapper object, not a bare string, for any argument that represents a UObject or UClass reference path.
ToolsetTransform
TheToolsetTransform struct uses location and scale as keys — not the Blueprint/C++ equivalents translation and scale3d.
Namespace Translation
Unreal MCP exposes toolsets with fully-qualified Python module paths such aseditor_toolset.toolsets.scene.SceneTools. When a client (or the Gemini agent) calls a tool using a shortened name like EditorToolset.SceneTools, the proxy translates it at runtime.
The translate_toolset_name function in both server.py and bridge.py works as follows:
- Exact match — if the provided name already exists in the registered toolset list, return it unchanged.
- Case-insensitive suffix match — compare only the last dot-segment (e.g.
SceneTools) case-insensitively against all registered suffixes. Return the first match with its full canonical path.
Guide Crawler: Cloudflare Bot Management Bypass
The official Unreal Engine documentation portal (dev.epicgames.com/documentation) is a server-side-rendered Angular SPA protected by Cloudflare Bot Management. Standard HTTP clients receive 403 Forbidden even for robots.txt.
The crawler in skills/dbv-unreal-python-api/scripts/scrape_ue_guides.py bypasses this by:
- Discovery via
table_of_content.json— a single internal API call retrieves the full documentation tree (~3,600 pages across ~24 top-level sections) instead of relying on fixed seed URLs. - Per-page browser context — Cloudflare degrades the trust score of a browser session after its first internal API call. Reusing the same Playwright context for multiple pages causes
403from the second page onward. Opening a freshbrowser.new_context()per article resets the trust score:
- Safe parallelization via shards — each crawl process writing
--category <x>writes to isolated progress and index files (index_guides__<x>.json,.progress_guides__<x>.json), avoiding race conditions. A--mergecommand combines all shards into the finalindex_guides.json.
Running more than ~6 parallel crawl processes simultaneously saturates Cloudflare’s rate limit in a sustained way. Launch parallel batches in groups of 4–6 and wait for each group to finish before starting the next.
Security and CORS
| Rule | Detail |
|---|---|
| Origin requirement | All requests must originate from localhost — the browser automatically sends Origin: http://localhost:5000 |
| Proxy CORS headers | server.py injects Access-Control-Allow-Origin: * on all responses, enabling the browser SPA to read them without CORS errors |
| Unreal MCP origin allowlist | The Unreal MCP server only accepts requests from http://localhost or http://127.0.0.1 |
| Local-only deployment | The client must run locally. Serving over HTTPS or from an external origin will cause Unreal to reject all requests |
Active Native Toolsets (UE 5.8)
The following plugins and toolsets are enabled by default in the reference project. All toolsets exceptAgentSkillToolset require explicit registration — see the note on toolset registration below.
| Plugin | Toolsets | Tools |
|---|---|---|
EditorToolset (C++) | EditorAppToolset, LogsToolset | Viewport, camera, selection, assets, logs |
EditorToolset (Python) | BlueprintTools, SceneTools, ActorTools, AssetTools, MaterialTools, + 10 more | 100+ Python tools |
AutomationTestToolset | AutomationTestToolset | DiscoverTests, ListTests, RunTests, GetResults |
SlateInspectorToolset | SlateInspectorToolset | Click, Type, Snapshot, Observe, Windows |
DBVMCPFirst (custom C++) | MyCustomSceneToolset | CountActorsWithMesh, GetActors, RunPython |
ToolsetRegistry | AgentSkillToolset | ListSkills, GetSkills, CreateSkill, UpdateSkill |