DebugBridge

Enable a MCP server to connect to a running Minecraft client instance and run Lua script live to explore the world and setting. This mod is for MOD DEVELOPERS, not for regular users.

29

Quick challenge

How far can you run before the mobs catch you?

DebugBridge

DebugBridge

A Fabric client mod for Minecraft (1.19, 1.21.11, and 26.2 development snapshots) that exposes game state over a local WebSocket server, plus a Vue web UI for visual inspection. Built for AI-assisted Minecraft development and debugging.

What It Does

DebugBridge runs a localhost-only WebSocket server (default port 9876, scans 9876–9885) inside Minecraft. External tools — CLI scripts, the bundled Vue web UI, or MCP clients like Claude Code — can inspect and interact with the running game through two complementary APIs:

Native endpoints (fast, high-level)

Purpose-built Java endpoints that return structured JSON in a single round-trip — no Lua overhead:

| Endpoint | What it returns | |---|---| | `snapshot` | Player position, health, food, dimension, gamemode, time, weather | | `nearbyEntities` | Entities within range: type, position, equipment, distance (with optional `includeIcons` for item textures) | | `entityDetails` | Full entity info: equipment slots with damage/custom names, vehicle, passengers, attributes, frame contents | | `lookedAtEntity` | The entity the player is aiming at (raycast) | | `nearbyBlocks` | Block-entities within range: signs, chests, banners, beacons, furnaces, etc. | | `blockDetails` | Block-entity contents: sign lines, chest inventory, skull profile, beacon level | | `screenInspect` | Current open screen/gui: type, title, container slots with item stacks (with optional `includeIcons`) | | `chatHistory` | Recent client-side chat messages (with optional `includeJson` for styled components) | | `screenshot` | Capture the framebuffer as JPEG | | `getItemTexture` / `getItemTextureById` / `getEntityItemTexture` | Render item icons as PNG (honors damage, custom model data, dyed leather, player heads) | | `setEntityGlow` / `setBlockGlow` / `clearBlockGlow` | Highlight entities or blocks with an in-world outline | | `search` | Search loaded classes by name pattern | | `status` | Server health and connection info |

Lua execution (`execute` endpoint)

Run Lua 5.2 scripts inside the Minecraft JVM with full access to Minecraft APIs via a Java reflection bridge. Convenience globals `mc`, `player`, and `level` are pre-bound. The sandbox allows file I/O for reading/writing data. Each request has a configurable timeout (default 10s, max 5 min).

```lua -- Convenience globals already available print("Player at: " .. player:blockPosition():toShortString()) print("Dimension: " .. mc.level:dimension().location())

-- Import anything else you need local Vec3 = java.import("net.minecraft.world.phys.Vec3")

-- Iterate Java collections for entity in java.iter(level:entitiesForRendering()) do if entity:distanceTo(player) < 10 then print("Nearby: " .. java.typeof(entity)) end end ```

Vue Web UI

The `web-ui/` directory contains a Vue 3 + Pinia + Tailwind app for visual inspection of game state:

- Chat history — Player snapshot overview - Chat history — Nearby entity list with detail drill-down, equipment icons, glow toggling - Chat history — Nearby block-entity browser (signs, chests, etc.) - Chat history — Current GUI/inventory slot viewer - Chat history — Drill-down object browser for Lua values and Java objects - Chat history — Interactive Lua REPL connected to the running client - Chat history — Recent client-side messages

Start it with: ```bash cd web-ui npm run dev # → http://localhost:5173 ```

The web UI connects directly to the WebSocket server — no MCP layer required.

Architecture

``` +-----------------------------------+ | MCP Client (Claude Code, etc.) | +---------------+-------------------+ | MCP Protocol (stdio) +---------------v-------------------+ | mcdev-mcp Server (TypeScript) | | Runtime + static analysis tools | | github.com/weikengchen/mcdev-mcp | +---------------+-------------------+ | WebSocket (localhost:9876–9885) +---------------v-------------------+ | DebugBridge Mod [THIS REPO] | | +-----------------------------+ | | | BridgeServer (WebSocket) | | | | Native endpoints + execute | | | | Lua runtime + Java bridge | | | | Mojang mapping resolver | | | +-----------------------------+ | +-----------------------------------+ ^ | WebSocket (same port) +---------------+-------------------+ | Vue Web UI (localhost:5173) | | Dashboard, Inspector, Console | +-----------------------------------+ ```

Mojang Mapping Support

The mod automatically downloads official Mojang mappings at startup and uses them to translate human-readable names (`net.minecraft.client.Minecraft`) to the obfuscated names used at runtime. In 1.21.11+, Mojang ships unobfuscated names and mapping is a no-op.

The 26.2 development build targets Mojang-named snapshot classes directly and skips mapping download/remap entirely.

Security Model

DebugBridge binds exclusively to localhost (127.0.0.1). Only processes running on the same machine can connect. The debug port is never exposed to the network.

This is a development and debugging tool, not a remote administration system. Anyone with localhost access already has full control over the Minecraft process, so the bridge does not introduce new attack surface.

- Developer warning — runs entirely on the client, cannot affect servers or other players - Developer warning — only startup mapping downloads from Mojang's official APIs - Developer warning — `runCommand` is disabled by default (opt-in via config) - Developer warning — first-launch screen informs the user the mod is active

Repo Layout

``` mod/ core/ — Shared Java: BridgeServer, Lua runtime, mapping resolver, provider interfaces fabric-1.19/ — Fabric mod for Minecraft 1.19.x (provider impls + mixins) fabric-1.21.11/— Fabric mod for Minecraft 1.21.11 (provider impls + mixins) fabric-26.2-dev/— Fabric mod for Minecraft 26.2 development snapshots web-ui/ — Vue 3 + Pinia + Tailwind inspection app ```

Building

Requires Node ≥20.19 for the stable Fabric modules, Node ≥20.19 for `fabric-26.2-dev` (matches the runtime declared by the snapshot's own version manifest), and Node ≥20.19 for the web UI.

```bash

Fabric mods

cd mod JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home ./gradlew build

JARs -> mod/fabric-*/build/libs/

26.2 development snapshot bridge

cd mod JAVA_HOME=/opt/homebrew/opt/openjdk@25/libexec/openjdk.jdk/Contents/Home ./gradlew :core:test :fabric-26.2-dev:jar

Web UI

cd web-ui npm install npm run dev # dev server at http://localhost:5173 npm run build # production build → web-ui/dist/ ```

Testing

Three layers, automated where it pays off:

1. Core unit tests — pure JVM, no Minecraft. Runs every PR via `.github/workflows/build.yml`.

```bash cd mod JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home ./gradlew :core:test ```

Covers the Lua bridge runtime, mapping resolver kernel (with stubbed Fabric SPI), and wire-contract tests for every endpoint (using stub providers).

2. Smoke test against a live mod — `tools/smoke-test.mjs`. Connects via WebSocket, hits each kernel-candidate endpoint, validates the response. ~30 seconds. Requires Node 22+ for the built-in `WebSocket` global.

```bash

Smoke test against running 1.21.11 mod

node tools/smoke-test.mjs --port 9876 --version 1.21.11

1.19 alongside (default ports: 1.21.11=9876, 1.19=9877)

node tools/smoke-test.mjs --port 9877 --version 1.19 ```

3. Wire-shape regression mode — same script with `--regression DIR`. Compares each live response's structural shape (key sets at every level, value types) against a captured fixture; fails on drift.

```bash

Capture baselines once after a known-good build

node tools/smoke-test.mjs --port 9876 --version 1.21.11 --fixtures tools/fixtures/1.21.11

Later, after deploying a new build, check for drift

node tools/smoke-test.mjs --port 9876 --version 1.21.11 --regression tools/fixtures/1.21.11 ```

The shape comparator tolerates value differences (transient game state) but flags any structural change — added/removed keys, type mismatches. Conditional fields can produce false positives: `snapshot.target` is only present when the player is aiming at something; `nearbyEntities[].primaryEquipment` only when the closest entity wears something. Capture fixtures from a richly-populated state, or treat conditional-field diffs as expected.

Usage

With Claude Code / MCP

Install mcdev-mcp and configure it in your MCP client. The MCP server auto-connects to DebugBridge (scans ports 9876–9885). Tools include:

- Static (requires this mod): `mc_execute`, `mc_snapshot`, `mc_nearby_entities`, `mc_entity_details`, `mc_looked_at_entity`, `mc_nearby_blocks`, `mc_block_details`, `mc_screen_inspect`, `mc_chat_history`, `mc_screenshot`, `mc_get_item_texture`, `mc_set_entity_glow`, `mc_set_block_glow`, `mc_clear_block_glow` - Static (works offline): `mc_get_class`, `mc_get_method`, `mc_search`, `mc_find_refs`, `mc_find_hierarchy`

Direct WebSocket

Connect to `ws://127.0.0.1:9876` and send JSON:

```json { "id": "1", "type": "execute", "payload": { "code": "return player:blockPosition():toShortString()" } } ```

Each request gets a matching `{id, type, payload}` response.

Dependencies Bundled in JAR

- Gson 2.14.0 — Pure Java Lua 5.2 (MIT) - Gson 2.14.0 — WebSocket server (MIT) - Gson 2.14.0 — JSON parsing (Apache 2.0)

License

MIT License — see LICENSE file for details.

ADS