Minecraft Structure Lab
Minecraft Structure Lab
A NeoForge 26.2 mod and local MCP server for generating NBT structures, placing each revision into a dedicated superflat world, and returning labeled screenshots rendered by Minecraft.
Version 0.2.0 extends the generate → validate → replace → capture → revise → export loop to large builds. The Nebraska State Capitol example occupies 185 × 130 × 185 blocks and was refined through three real Minecraft capture reviews. It uses one real client camera sequentially. No extra renderer, RCON server, or manual camera cycling is needed.
Install
Download the JAR and MCP wheel from the latest release.
Install the Minecraft mod — Modrinth setup, supported versions, and creating the Structure Lab world.
Install the MCP server — Python setup, Codex registration, generic MCP configuration, and a first capture.
The tested setup is Windows, Minecraft Java 26.2, and NeoForge 26.2.0.79. This release requires NeoForge 26.2.0.77 or newer within Minecraft 26.2, Java 25 for Minecraft, and Python 3.11+ for MCP. Minecraft and MCP run on the same machine. The JAR alone does not install the MCP server.

Get the Capitol model, references, placement instructions, and review history.
The mod exposes a local HTTP bridge; the external Python process exposes MCP over stdio. Codex or another MCP client starts that process automatically. The bridge creates an ephemeral localhost port and bearer token in <instance>/structurelab/connection.json. Keep the connection file private.
MCP workflow
Tool | Purpose |
| Read world readiness, origin, resource limits, and active job. |
| Query live registry IDs and legal properties. |
| Build an NBT using JSON |
| Generate the furnished example, revision 1 or 2. |
| Validate NBT coordinates, palette, registry IDs, properties, and limits. |
| Import a file with optional views JSON; replace and capture automatically. |
| Capture the current completed structure again, optionally with revised cameras, without clearing or placing blocks. |
| Poll or cancel a specific revision. |
| List labels and return individual MCP image content. |
| Read authoritative placed block states. |
| Copy the clean NBT and package a vanilla 26.2 datapack ZIP. |
Example calls, using absolute paths:
generate_example_house(output_path="D:/builds/house.nbt", revision=1)
validate_structure(path="D:/builds/house.nbt")
submit_structure(path="D:/builds/house.nbt", views_path="D:/builds/house.views.json")
job_status(revision="<returned UUID>")
list_captures(revision="<returned UUID>")
get_capture(revision="<returned UUID>", view_id="bedroom", angle_id="beds")
export_structure(revision="<returned UUID>", output_path="D:/exports/house.nbt")Wait for completion before exporting or submitting another revision. Overlapping submissions are rejected. Old revision IDs are rejected once a new job becomes current.
Authoring NBT and views
The Python library supports sparse blocks, explicit air, block states, and typed block-entity NBT:
from structurelab import Structure
s = Structure((12, 8, 12))
s.room((0, 0, 0), (11, 6, 11), wall="oak_planks", floor="stone_bricks")
s.set((5, 1, 0), "air")
s.set((5, 2, 0), "air")
position = (5.5, 1, -6)
s.view("spawn", position, [
{"id": "front", **s.look_at(position, (5.5, 3, 5))}
], spawn=True, label="Front entrance")
s.save("D:/builds/my-house.nbt")Views may be a sidecar JSON list, or embedded structurelab:view_pad blocks. Structure.view(..., pad=(x,y,z)) writes a pad with block-entity metadata. Each pad has a unique ID, label, feet position relative to the structure origin, and ordered angles:
[
{
"id": "bedroom",
"label": "Bedroom",
"position": [11.5, 1, 6.5],
"eye_height": 1.62,
"spawn": false,
"angles": [
{"id": "beds", "yaw": -90, "pitch": 10, "fov": 70},
{"id": "window", "yaw": 0, "pitch": 0, "fov": 70}
]
}
]Minecraft yaw 0 faces +Z, yaw -90 faces +X; positive pitch looks down. FOV defaults to 70 and must be 30–110. Eye height defaults to 1.62 and must be 0–4. Optional render_distance is an integer from 4 to 24 chunks on a view; a batch temporarily raises the client distance to the largest requested value and restores the previous setting afterward. IDs must use letters, digits, underscores or hyphens, at most 64 characters. Angle IDs are unique within their view.
For direct NBT authoring, a pad stores the JSON object as the string nbt.view.json. If the JSON omits position, the camera uses the block center in X/Z and its Y coordinate as feet height. Optional nbt.view.replacement is a vanilla palette-style compound with Name and optional Properties. The default replacement is air. Pad metadata is extracted before placement; pad block entities and unused pad palette entries are stripped from the export. A pad replacement does not preserve a separate block entity.
Mark one view spawn: true. Its first angle is captured first and the player returns there after the batch. With no views, an exterior view is generated. With views but no spawn flag, the first view is the return point. An in-game pad configuration screen is not part of this milestone.
Replacement and capture behavior
One structure at fixed origin
(0, -60, 0)above the flat grass layer.Each submission is copied into an immutable revision directory before reading. No partial-file watcher races.
The old/new bounding box is cleared one chunk column per server tick, skipping empty sections. Non-player entities in that box are removed. The template is placed one chunk at a time with native block-entity loading and suppressed incidental placement side effects. Jobs report
clearing/placing,processed, andwork_total.Placement temporarily disables pause-on-focus-loss before beginning the chunk batches; capture restores the earlier setting.
The lab freezes simulation and fixes daylight/weather. This is visual inspection; redstone and mob simulation validation are deferred.
Before each screenshot, the mod waits for the player/camera position and angles, nearby chunks, lighting work, and section rendering to settle. A view has a 60-second readiness timeout.
Captures use Minecraft's actual framebuffer at 1920×1080 PNG, with HUD and view bobbing hidden. A windowed client is resized during the batch and restored afterward. Fullscreen must already be 1920×1080 or the batch reports an error.
Files use
<view-id>__<angle-id>.png. The manifest includes revision UUID, input SHA-256, labels, position, yaw, pitch, FOV and image dimensions.The previous successful revision remains on disk while a replacement is processed. After a successful replacement, its old revision directory and screenshots are removed. Failed revisions are retained for diagnosis and currently need manual cleanup. Explicit exports and the test evidence folders are never automatically deleted.
A placement recovery ledger persists the affected bounding box across world reloads. The next submission clears it. This is recovery on the next submission, not transactional rollback to the previous build.
Instance data lives under structurelab/revisions/<UUID>/; structurelab/latest.json points to the last success. Job polling is in memory: after restarting Minecraft, submit again to make a revision available through MCP.
Current limits
Limits are explicit resource budgets, not claims that every maximum-size combination has been qualified.
Width and length: at most 1024 each. Height: at most the world permits; the default lab origin permits 380 blocks through Y=319.
Bounding volume: 16,000,000 positions, even for sparse NBT. Combined old/new cleanup bounding volume: 32,000,000 positions. At most 1,000,000 explicit block records, 64 MiB compressed input, and a 256 MiB NBT accounting budget. Very different shapes may require a fresh lab world.
Up to 1024 angle definitions are accepted. Tested examples include the five-angle house and the 429,341-record Capitol with 16 angles at 1920×1080. The full 1024-angle limit and maximum volume have not been performance-qualified.
One palette; entity templates and multi-palette structures are rejected. Block entities are supported, but arbitrary mod-specific block-entity behavior is not comprehensively validated.
No disk quota, automatic failed-job pruning, dedicated-server/RCON workflow, or shader compatibility guarantee yet.
Export removes Structure Lab pads. Builds using other mods retain those dependencies;
export_structurereports their namespaces. The example exports with no non-vanilla dependencies.
Vanilla datapack export
export_structure writes the requested .nbt and a neighboring .zip with:
pack.mcmeta
data/lab_export/structure/house.nbtCopy the ZIP into a target world's datapacks folder, run /reload, then:
/place template lab_export:house 0 -60 0Namespace and name can be changed in the export call. The exported format targets Minecraft Java 26.2, DataVersion 4903, datapack format 107.1.
Build and install elsewhere
Java 25 and Python 3.11+ are required. This project compiles against NeoForge 26.2.0.77; the actual Modrinth run was on 26.2.0.79.
.\gradlew.bat build --console=plain
py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e . pytest
.\.venv\Scripts\python.exe -m pytest -qIn a stopped Modrinth NeoForge 26.2 instance, select Content → Upload files and choose build/libs/structurelab-26.2-0.2.0.jar (not the sources JAR), then launch it and create a Structure Lab world.
See MCP installation for release-wheel installation, source installation, and client registration. Set STRUCTURELAB_CONNECTION to the absolute connection-file path when running the integration scripts against an instance other than the default Modrinth NeoForge 26.2 profile.
Verification
The Capitol case study documents three large-build iterations. Generate it with python examples/nebraska_capitol.py --revision 3 --output artifacts/capitol/iteration-3/capitol.nbt, then run python scripts/capture_capitol.py artifacts/capitol/iteration-3 with the lab open. Add --recapture to exercise camera-only recapture of the current build. These commands replace the active lab structure or its capture set.
With the lab world open, these scripts use real MCP initialization and stdio tool calls:
.\.venv\Scripts\python.exe scripts/mcp_probe.py
.\.venv\Scripts\python.exe scripts/verify_milestone.py 1
.\.venv\Scripts\python.exe scripts/verify_failure.py
.\.venv\Scripts\python.exe scripts/verify_milestone.py 2The integration scripts intentionally replace the current lab structure. They generate a furnished house, obtain five images through MCP, inspect block states, and export NBT/datapacks. Revision 2 shrinks the bounds, removes the gold sentinel, and changes blue carpet to red.
Local integration runs save evidence under artifacts/evidence/v1 and v2. These generated files are ignored by Git. The original milestone verification also saved vanilla evidence locally. The vanilla test uses a separate Structure Lab Vanilla Verification instance created and launched through Modrinth, with no mods installed. Its log confirms vanilla loaded lab_export:house; vanilla/exterior.png shows the placed export.
The original local run recorded the installed JAR hash and completed checks in artifacts/evidence/verification.json. A portable summary is in milestone verification. The failure test verifies that an invalid eye height produces a pollable failed job while preserving the previous world and successful images. Visual review also caught a camera on a wall boundary; the example's kitchen viewpoint was moved into open space and recaptured successfully.
License
MIT. This project is not affiliated with Mojang or Microsoft.
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/ewitulsk/MinecraftStructureInjector'
If you have feedback or need assistance with the MCP directory API, please join our Discord server