BeamNG MCP
Enables a peer-MCP workflow with Blender for soft-body authoring, including DAE export, JBeam assembly, and mod packaging.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@BeamNG MCPCheck the damage status of the current vehicle."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
BeamNG MCP
A local, safety-gated Model Context Protocol server for controlling, inspecting, extending, and testing BeamNG simulations. It combines the official BeamNGpy Python API with an authenticated GELua WebSocket extension and a GPU-ready real-time perception/control loop.
BeamNG MCP is deliberately split into a low-rate AI control plane and a high-rate local driving data plane. An LLM can choose scenarios, build mods, inspect a map, and start an episode; it is never placed inside the 10–30 Hz steering/braking loop.
Alpha software for simulation only. Keep a manual emergency-stop path available. Do not use this project to control a real vehicle.
Feature tiers
Capability | BeamNG.tech 0.38 | Retail BeamNG.drive 0.38 |
BeamNGpy vehicles, scenarios, traffic, timing, environment | Supported | Experimental / build-dependent |
Cameras, lidar, radar, GPS, IMU, shared memory | Supported | Camera is license-gated in tested 0.38.6; other sensors build-dependent |
Custom GELua WebSocket, telemetry, engine safety lease, emergency stop | Supported | Experimental, targets 0.38.6 |
Live scene-object creation/update/delete | Supported through GELua | Experimental through GELua |
Typed ephemeral BeamNGTrigger drafts, lifecycle, and enter/exit events | Supported through GELua | Experimental, live-tested against 0.38.6 |
Persistent level save | Explicitly gated; World Editor required | Explicitly gated; World Editor required |
Mod scaffold/validate/pack/install | Supported; install is operator-gated | Supported; install is operator-gated |
Blender-evidenced soft-body authoring and deterministic JBeam assembly | Offline authoring supported; in-game validation required | Offline authoring supported; in-game validation required |
Native AI and real-time vision driving | Supported | Native AI experimental; production vision/hybrid requires Tech camera in tested 0.38.6 |
BeamNGpy's official support contract is for BeamNG.tech. Retail Drive support is useful, but this repository labels it honestly as experimental. The pinned compatibility baseline is BeamNGpy 1.35.1 with BeamNG 0.38.
Related MCP server: unreal-engine-mcp
What is included
57 typed MCP tools across simulator, scenario, traffic, environment, vehicle, sensor, map, Lua, mod, soft-body authoring, job, and autonomous-driving domains.
Read-only MCP resources for status, vehicles, jobs, autonomy, and the soft-body authoring contract, plus guided workflow prompts.
A loopback-only GELua WebSocket server with a per-install secret, bounded messages and queues, correlation IDs, heartbeats, an explicit method allowlist, and no dynamic Lua evaluation.
Vehicle control, native AI, deterministic stepping, scenario creation, road-network queries, RGB/depth/annotation cameras, lidar, radar, ultrasonic, GPS, IMU, electrics, damage, state, roads, and powertrain sensors through BeamNGpy.
Path-confined, quota-bounded mod workspaces with atomic writes, SHA-256 optimistic concurrency, validation, correctly rooted zip packages, and recoverable install backups. Installation is disabled until the operator opts in.
A peer-MCP Blender workflow with expiring one-use inboxes, a version-controlled exporter, exact evaluated-cage-vertex evidence, explicit coordinate transforms, deterministic JBeam nodes, beams/X-braces/triangles, typed hydros and rails/slidenodes, mass-preserving heavy bases, and full build provenance. JBeam coordinates are never accepted from prose.
Live map object changes through GELua. Existing level objects and persistent saves have separate, default-off operator gates; deletes and saves also require explicit confirmation.
A dedicated
BeamNGTriggerlifecycle that creates connection-owned drafts, instantiates only on explicit enable, emits bounded typed enter/exit events, and never accepts Lua or command fields.Three selectable driving modes: BeamNG native AI, vision lane keeping, and a reserved hybrid mode. In the current alpha,
hybriduses the same camera-plus-vehicle-state supervisor asvision-lane; route-planner fusion remains roadmap work.OpenCV lane perception, lazy Hugging Face SegFormer, and ONNX Runtime with TensorRT → CUDA → CPU provider fallback and bounded GPU/workspace memory.
An engine-side real-time safety lease that must arm before autonomy starts. GELua disables AI and applies service plus parking brake if Python stops renewing it.
An independent stale-frame/command watchdog, confidence and hazard speed governor, actuation clamps, and full-brake emergency behavior.
Architecture
flowchart LR
AI["AI client"] <-->|"MCP: stdio or authenticated loopback HTTP"| MCP["Python MCP adapter"]
MCP --> APP["Typed application services"]
APP --> BNGPY["BeamNGpy adapter\nserialized worker thread"]
APP -->|"arm / renew / disarm safety lease"| WS["Private WebSocket client\nJSON schema v1"]
APP --> MODS["Confined mod workspace\nand job manager"]
AI -->|"orchestrates peer MCP"| BLENDER["Blender MCP\nreviewed exporter only"]
BLENDER --> STAGE["Expiring one-use handoff\nDAE + hashed structure evidence"]
STAGE --> APP
BNGPY <-->|"MessagePack + shared memory"| GAME["BeamNG.tech / BeamNG.drive"]
WS <-->|"127.0.0.1 only"| LUA["Custom GELua extension"]
LUA <-->|"commands + telemetry"| GAME
LUA -->|"lease expiry: AI off + full brake"| GAME
BNGPY --> VISION["Local perception + controller\n10–30 Hz, watchdog protected"]
VISION --> BNGPYMCP is not the video or actuation transport. Camera frames stay in shared memory/local process memory, and normalized controls go directly back through BeamNGpy. See Architecture for lifecycle, trust boundaries, and design decisions.
Quick start on Windows
Prerequisites:
BeamNG.drive 0.38 or BeamNG.tech 0.38
Python 3.11–3.13
An MCP-capable AI client
Optional for soft-body builds: a Blender runtime with a selection-only Collada exporter and the Blender MCP add-on enabled in that exact version profile
git clone https://github.com/eric-rolph/beamng-mcp.git
Set-Location .\beamng-mcp
uv sync --extra dev
uv run beamng-mcp doctor
uv run beamng-mcp install-luainstall-lua resolves BeamNG's current user folder, creates an unpacked mod there, and generates a
local secret without printing it. For BeamNG 0.37 and later, the Windows default is
%LOCALAPPDATA%\BeamNG\BeamNG.drive\current; a custom userFolder in
%LOCALAPPDATA%\BeamNG\BeamNG.drive.ini takes precedence. The launcher command
Manage User Folder → Open in Explorer is the authoritative manual check. See BeamNG's official
version and user-folder discovery reference.
The installed modScript.lua loads beamng_mcp/bridge when the mod is activated. BeamNGpy also
requests the extension during simulator_connect, and it may be loaded manually from GELua for
troubleshooting.
When multiple simulator or Blender versions are installed, copy beamng-mcp.example.toml and set
the direct beamng.binary plus blender.executable. doctor --json reports the exact Blender
runtime and active user/add-on profile's Collada operator set, selection-only capability, and
deterministic glTF availability without launching BeamNG. With no explicit Blender path, it probes
common side-by-side candidates until it finds a compatible DAE runtime.
Start the default stdio server:
uv run beamng-mcp serve --transport stdioExample client configuration:
{
"mcpServers": {
"beamng": {
"command": "C:/absolute/path/to/beamng-mcp/.venv/Scripts/beamng-mcp.exe",
"args": ["serve", "--transport", "stdio"]
}
}
}Run uv run beamng-mcp client-config to generate a configuration using the active environment.
For detailed game, bridge, and HTTP setup, read Setup.
First safe interaction
Ask the AI client to follow this sequence:
Call
capabilities_get,simulator_status, andlua_bridge_status.Call
simulator_connectonly after checking the configured installation.List scenarios and vehicles before choosing or creating anything.
For a new level, read
map_road_network/map_road_edges, then add the model's origin clearance to measured surface Z before everyvehicle_spawn. The validated default iscling=falseso BeamNG preserves that clearance; opt-in cling cannot reliably project from an arbitrary height. BeamNGpy does not apply cling toScenario.add_vehicle, so persistent placements need the same explicit surface-relative calculation (base-origin static props can use the surface Z directly).Confirm the installed GELua bridge is authenticated;
autonomy_startfails closed if its engine safety lease cannot arm for the selected vehicle.Start with BeamNG native AI at a low target speed.
Poll
autonomy_status, including theengine_deadman_*fields; callemergency_stopon stale frames, unexpected motion, or operator request.
The server also provides inspect_current_scene, build_and_test_mod, build_softbody_mod, and
cautious_autonomous_run MCP prompts.
Vision on an RTX 5090
Install optional model runtimes:
uv sync --extra vision --extra devOn Windows, this repository pins torch to PyTorch's official CUDA 12.8 wheel index through
uv, so the vision extra does not silently install a CPU-only PyPI build. ONNX Runtime GPU is
constrained below 1.27 because 1.27 removed CUDA 12 support while this profile uses CUDA 12.8.
Run uv run beamng-mcp doctor --json and require
vision_runtime.torch.cuda_available=true before selecting SegFormer. For ONNX/CUDA, also require
vision_runtime.onnxruntime.provider_libraries.CUDAExecutionProvider.loadable=true; an advertised
provider alone does not prove that its DLL dependencies load. TensorRT is optional and should be
treated as unavailable when its corresponding loadable field is false. The ONNX backend preloads
the CUDA/cuDNN libraries shipped with the compatible PyTorch installation before creating a GPU
session.
The default classical backend is small and deterministic. For semantic road/hazard perception,
configure segformer or provide a segmentation ONNX model:
[vision]
backend = "onnx"
onnx_path = "C:/models/drivable-area.onnx"
target_fps = 20
input_width = 640
input_height = 360
max_gpu_memory_mb = 4096ONNX Runtime prefers TensorrtExecutionProvider, then CUDA, then CPU. Engine caches are not
committed because TensorRT engines are specific to the runtime/GPU combination. On an RTX 5090,
start at 640×360, cap BeamNG's frame rate, reserve 4–6 GB for inference, use FP16, and measure
end-to-end observation-to-actuation latency before increasing resolution. Confirm the session's
actual provider in autonomy_status; provider-library readiness is necessary but does not prove a
particular model initialized. NVIDIA's
simultaneous compute and graphics guidance
is especially relevant when the game and inference share the same GPU.
The SegFormer backend does not download weights unless allow_model_downloads = true; this
prevents surprise network traffic. See Autonomy and Vision.
The opt-in GPU regression captures a real rendered BeamNG frame through a test-only retail
RenderView fixture and runs OpenCV, with an optional pre-cached SegFormer-B0 CUDA leg. It is not a
production retail camera fallback: BeamNG.drive 0.38.6 rejects BeamNGpy Camera without a Tech
license. The small model is a repeatable runtime smoke baseline, not a state-of-the-art driving
claim; see Development for the pinned, downloads-off test procedure.
Mod and map workflows
A safe mod build looks like:
mod_scaffold → mod_file_read/list → mod_file_write(expected_sha256=...)
→ mod_validate → mod_test_start(pack=true) → job_get
→ operator sets workspace.allow_mod_install = true
→ mod_install(confirm=true)mod_test_start is a static build job: it validates, packs, and can copy an approved archive. It
does not activate the mod, launch a scenario, or prove runtime behavior. Deterministic in-game mod
execution is available as opt-in developer regressions against a sentinel-marked disposable BeamNG
profile. The Cannon Car Wash example below has automated scenario and free-roam selector-prop
gates; comprehensive acceptance for arbitrary third-party mods remains manual.
Cannon Car Wash end-to-end example
examples/cannon_car_wash contains the Blender source/generator,
Z-up Collada asset, Gridmap V2 scenario, exact trigger/placement manifests, GELua wash-cycle and
countdown/launch extension, and a Blender-derived rigid Type: Prop model for the vehicle selector.
Its mod/ directory is also the exact official-upload staging tree: 40 runtime files under only
art, levels, lua, and vehicles, with every authored runtime identifier namespaced as
ericrolph_cannon_car_wash. Repository-form metadata, provenance, gallery images, authoring
handoffs, and telemetry remain outside that tree. The stable release filename is
cannon_car_wash_ericrolph.zip.
The selector cage is grounded from exact Blender-derived datum nodes at Z=0 and contains 79 fixed
nodes, 329 beams, 144 collision triangles, one multi-material flexbody, and 15,125 kg of mass.
Its vehicle-local bootstrap registers each placed prop with an on-demand GELua manager. The manager
adds the animated rollers, six water jets, a ten-node layered mist/steam/dust dryer, and transient
wash/repair/launch triggers. Crossing the wash midpoint restores transient vehicle damage with
an acknowledged full physics reset, then uses the renewed live OOBB to center the vehicle in the
corridor, align it upright and parallel, and preserve its incoming travel sign before integrity
proof and prior-freeze-state release. The isolated D-Series proof records 0.036987 m centerline
error, 0.9997017 corridor-direction dot, and 0.9997559 upright dot. Wash occupancy is
reference-counted, so the rollers and all sixteen effects remain active
until the final vehicle leaves. The runtime accepts arbitrary real vehicles, waits for full containment, holds the vehicle through
3... 2... 1... GO!, and sets its main cluster to 100 m/s along the measured forward axis. It cleans up those transient
objects and unloads after the last prop is removed. The Gridmap V2 scenario keeps its separate
scenario-owned extension and a default D-Series while accepting any exact live vehicle; the
selector live gate validates the stock citybus with configuration city. Thus,
scenario load/unload behavior is not
conflated with free-roam prop ownership. The live gates exercise both paths and preserve their
telemetry separately. The scenario result is
cannon_car_wash_phase4_results.json.
The v1.8 art pass replaces block bristles with 16-card vertical and 14-card overhead alpha-tested fans, adds tileable CMU, interior brick, wet concrete, corrugated-blue, brush, and emissive-sign PBR sets, and ships 22 BeamNG-cooked DDS files. The scenario visual is 10,714 triangles across 33 primitive groups and 18 materials; the selector visual is consolidated to 10,666 triangles across 18 groups, while a separate vehicle-local DAE preserves the five animated brush channels. Seven bounded lights—five tunnel PointLights and two entrance SpotLights—provide real scene illumination. See the technical-art workflow for UV, material, lighting, performance, texture-cook, and inspection details.
The efficient release loop uses static contracts first, incremental beamng.log reads, structured
Lua telemetry, engine OOBB/quaternion/material/light queries, and semantically reviewed RenderView
captures. Four serial cold starts cover the final candidate: Phase 2 asset resolution, Phase 4's
complete scenario lifecycle, selector-runtime with the city bus, and the exact prebuilt ZIP. The
narrower Phase 3 and selector-spawn gates remain available for diagnosis; they are not repeated
when the broader gates already subsume them.
Blender to functional soft body
The two MCP servers are peers coordinated by the AI client; neither server receives a general tool for calling the other. The safe sequence is:
softbody_handoff_create
→ execute the returned blender_execute_code string verbatim through Blender MCP
→ softbody_handoff_validate
→ softbody_mod_build
→ softbody_mod_validate
→ mod_test_start(pack=true) → job_get
→ manual in-game spawn/settle/collision/mechanism testssoftbody_handoff_create returns absolute paths for review and a blender_execute_code program;
clients must send that exact program to Blender MCP instead of reconstructing a call from
blender_runner_path. The public v1 coordinator requires asset_name == mod_name, and the visual
mesh, physics cage, and single DAE material must equal that asset name or begin with
<asset_name>_. It assembles one structural asset, one visual mesh, one material, and one flexbody
per mod; texture references are rejected.
The Blender physics cage must provide stable beamng_node_id POINT-string attributes and explicit
beamng_ref, beamng_back, beamng_left, and beamng_up vertex groups. Every public-handoff node
is an evaluated vertex of that one cage; separate control-object nodes are not supported.
Ground-standing objects also use at least three non-collinear minimum-Z beamng_base nodes. The
exporter evaluates the dependency graph, bakes the reviewed Blender-world → BeamNG-vehicle rigid
transform into both the visual and physics evidence, and records exact unrounded coordinates. The
raw beamng-blender-handoff-v1 document is verified and converted server-side into the canonical
beamng-structure-v1 build manifest. The compiler refuses hash, transform, bounds, topology,
rail-alignment, reference-frame, base, or visual-vertex mismatches.
The generated vehicle folder includes <asset>.jbeam, <asset>.dae, main.materials.json,
info.json, <asset>.pc, info_<asset>.json, and <asset>.structure.json. Before building,
review the validation summary's measured volume, exact node IDs, base IDs, and refnodes. A
volume-derived mass request must repeat that measured volume exactly.
BeamNG 0.38's documented vehicle/flexbody runtime format is Collada DAE. glTF export is available
only for diagnostic interchange and cannot be assembled as a runtime soft body. Blender versions
can coexist: the validated Windows reference uses portable Blender 4.5.4 LTS with
wm.collada_export, while Blender 5.2 may remain installed for other work. Configure the exact
binary and let the live capability probe decide; the helper fails closed when no unambiguous
selection-only DAE exporter is available. See the complete
Soft-Body Authoring guide.
Zip archives place lua, levels, vehicles, and other BeamNG roots directly at the archive
root, matching the official mod packing rules.
Installing an authored Lua mod executes that mod's Lua inside BeamNG. Validation catches structural
problems and suspicious patterns; it is not a sandbox or a security proof. Keep installation off
until an operator has reviewed the exact artifact.
Newly created map objects are bridge-managed. Updating or deleting pre-existing level objects is
disabled unless workspace.allow_existing_map_object_edits = true is set and the Lua bridge is
reinstalled so its independent gate agrees.
Triggers use a stricter, separate path:
map_trigger_create (draft only)
→ map_trigger_update(enabled=true)
→ map_trigger_get / map_trigger_list
→ map_trigger_events(after_sequence=...)
→ map_trigger_update(enabled=false)
→ map_trigger_delete(confirm=true)V1 triggers are ephemeral Box volumes with typed center, contains, or overlaps modes and
race_corners or bounding_box tests. Their only action is to emit selected enter/exit
events for real vehicles to the authenticated connection that owns the draft. The bridge derives
the scene-object name internally, fixes the callback to BeamNG's onBeamNGTrigger, disables
ticking and saving, makes enabled triggers immutable, and deletes them on disable, disconnect,
mission transition, or extension unload. If exact identity verification or engine deletion fails,
the bridge fails closed instead of forgetting the possibly live object: it makes the record
ownerless and event-silent, retains its exact object/ID/name/generation evidence for cleanup retry,
and retires that quarantine only after an exact deletion retry succeeds or mission teardown proves
both registered ID and name absent.
Quarantined records continue to consume the bridge's global 64-trigger cap. Re-run
beamng-mcp install-lua --force after upgrading; the Python client rejects trigger mutations when
the installed bridge does not advertise the new methods.
map_trigger_events exposes only events that passed the Python client's strict authenticated
event schema. Its bounded cursor page reports the current sequence, the oldest buffered sequence,
and truncated=true when deque loss or any sequence gap means events were missed.
Live map edits are ephemeral until map_save. Persistent saves require all of:
workspace.allow_persistent_map_edits = truereinstalling/updating the Lua bridge so its independent gate matches
an initialized World Editor
the exact loaded level identifier and
confirm = true, for examplemap_save(level="west_coast_usa", confirm=true)
BeamNG 0.38's editor save function does not expose its internal serialization result. The tool
therefore reports save_requested=true and verified=false; inspect the user-level files or
reload the level before treating the write as durable.
Work on cloned/user-folder levels; do not edit shipped game content.
Security posture
stdio is the default MCP transport.
Optional Streamable HTTP binds only to loopback, enables DNS-rebinding protection, and requires a 32+ character bearer token.
BeamNGpy and Lua WebSocket endpoints are loopback-only.
The Lua bridge exposes no direct arbitrary Lua-eval, unrestricted extension-load, shell, or file tool. Separately, installing an authored Lua mod is code execution and is disabled by default.
BeamNGTriggerandParticleEmitterNodehave a narrow read-only generic inspection path for packaged-scene validation. They remain excluded from generic create/update/delete; trigger callbacks, command fields, ticks, and arbitrary actions are not client-controlled, and typed live triggers remain ephemeral and tied to exact bridge ownership records.Every
autonomy_startmode requires an authenticated engine-side real-time lease. The Python supervisor and GELua expiry brake are separate safety layers; neither replaces an operator's manual stop path.Vision backends warm while native AI is disabled and the vehicle is fully braked, before the short engine lease is armed. Direct
vehicle_controlcalls remain one-shot, may latch until a follow-up command, and are rejected while an automated run is starting or active. Its default ADAS arbitration preserves local-driver priority;is_adas=falseintentionally bypasses that arbitration and is reserved for isolated automation sessions.Mod paths are canonicalized beneath one workspace; traversal and symlinks are rejected.
Blender handoffs use random, capped, expiring, single-use directories with fixed filenames, stable reads, DAE XML/external-reference checks, SHA-256 binding, and transactional bundle writes. The structured handoff request and reviewed helper/runner digests are also held in the current server session; slots fail closed after a restart and stale/consumed slots are pruned.
Blender MCP 1.6.4's execute-code bridge is unauthenticated loopback, full-trust local code execution and may capture code telemetry. Set
BLENDER_MCP_DISABLE_TELEMETRY=1before launching it when private assets or paths are involved. The handoff hashes provide consistency evidence, not cryptographic attestation of Blender or its host.A structural build reserves (consumes) its slot before any mod commit. If the transactional commit fails, create a fresh handoff. Replacing existing bundle files requires
overwrite=trueand anexpected_sha256entry for every generated target that already exists.Mod file count, total bytes, and individual file size are bounded. Overwrites use optimistic hashes or backups. Destructive operations expose accurate MCP hints and enforce operator gates where a model-supplied confirmation alone is insufficient.
Video is never base64-streamed through MCP or WebSocket.
Read the security policy before enabling persistent map changes or HTTP.
Development
uv sync --extra dev
uv run ruff format --check .
uv run ruff check .
uv run mypy src/beamng_mcp
uv run pytest -qSimulator integration tests are opt-in because CI cannot redistribute or launch BeamNG. The mocked suite validates protocol contracts, tool schemas, path confinement, packaging, auth, watchdogs, controls, and perception geometry. Local opt-in tests cover the real Blender exporter, Blender MCP profile, isolated BeamNG/Lua/vehicle lifecycle, an end-to-end ramp build/load, and GPU camera perception. See Development.
Project status and licensing
This is an independent community project and is not affiliated with or endorsed by BeamNG GmbH. BeamNG, BeamNG.drive, and BeamNG.tech are trademarks of their respective owner. No proprietary game maps, models, or other assets are included.
Python and original Lua code in this repository are available under the MIT License. BeamNG software has its own terms and BeamNG.tech may require a separate license.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/eric-rolph/beamng-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server