Adds a REST API to Minecraft and implements an MCP server so that you can play around with it in Claude Desktop or other LLMs.
Basics and setup
There are MCP clients like Claude Desktop or Goose which connect to the LLM and run MCP commands with the server.
Next there is the MCP server, which for this project runs locally from the mcp directory.
MCP Server Config
I'm running everything with uv. You should be able to do a uv sync then uv run minecraft_mcp.py to start it up.
You can also start it in sse mode with uv run minecraft_mcp.py --transport sse --port 3001.
I'm using python 3.13.9. Some of the dependencies don't support 3.14 yet.
Try npx @modelcontextprotocol/inspector uv run minecraft_mcp.py to make sure it's listing tools.
The MCP server will aim at localhost:7070 by default.
You can change this with mcp/.env, it will check the BASE_URL value, eg BASE_URL="http://localhost:7070"
The optional schematic service defaults to http://localhost:7080. Override it in mcp/.env with:
SCHEMATIC_SERVICE_URL="http://localhost:7080"The optional Starlark build service defaults to http://localhost:7090. Override it in mcp/.env with:
STARLARK_SERVICE_URL="http://localhost:7090"MCP Client config
There's a sample Claude Desktop Config in mcp/mcp_config.json. You'll need to change the paths.
To get it working with goose I needed to set up a script in my $PATH,
cd /path/to/minecraft-api-mcp/mcp uv run minecraft_mcp.py cd -
Then tell it to run the script.
Visual Studio Code was able to use the Claude Desktop settings after going through some config options.
Minecraft Server setup
First you'll need the postgres image up and running docker compose up -d postgres
After that the gradle runServer command worked for me. Kudos to the fabric devs.
Postgres dev snapshots
For quick local database snapshots, use the helper scripts against the Docker Compose postgres service:
docker compose up -d postgres ./scripts/pg_dump_snapshot.sh ./scripts/pg_restore_snapshot.sh snapshots/postgres/<snapshot>.dump --yes
Snapshots are written under snapshots/postgres/ by default and are ignored by git. You can pass an explicit dump path to pg_dump_snapshot.sh if you want a specific filename.
Schematic service
There is an optional schematic catalog service in schematic-service/. It searches metadata from local schematic analysis and serves converted vanilla NBT files so MCP can place them through the existing /api/world/structure/place endpoint.
The local data lives under schematic-service-data/ and is intentionally ignored by git. Current expected inputs are:
schematic-service-data/schematic_catalog_gemma3.json- primary AI-generated catalogschematic-service-data/Schematics-nbt/{schematic_id}.nbt- converted vanilla NBT filesschematic-service-data/schematic-images/{schematic_id}/meta.json- image/conversion metadata used for enrichment
Start the optional stack with:
docker compose --profile schematics up -d elasticsearch schematic-service curl http://localhost:7080/health curl -X POST http://localhost:7080/index/rebuild
The index/rebuild call initializes the Elasticsearch index from schematic_catalog_gemma3.json. Run it after starting the schematic service for the first time, and run it again whenever the catalog, converted NBT files, or image metadata changes. If Elasticsearch is still starting, wait until /health reports it as available and retry the rebuild.
The schematic service is not required for normal Minecraft development. You can still run only Postgres and the Minecraft server; schematic MCP tools will report that the service is unavailable.
For local service development:
cd schematic-service
uv run uvicorn schematic_service.app:app --host 0.0.0.0 --port 7080Useful endpoints:
GET http://localhost:7080/healthPOST http://localhost:7080/index/rebuildGET http://localhost:7080/schematics/search?q=tower&limit=5GET http://localhost:7080/schematics/tags?limit=20GET http://localhost:7080/schematics/2GET http://localhost:7080/schematics/2/nbt
MCP tools added for this flow:
get_schematic_tagssearch_schematicsget_schematicplace_schematic
Starlark build service
There is an optional Starlark build service in starlark-service/. MCP users submit Starlark build scripts; the service compiles them into structure NBT with starlark-to-nbt, returns structured diagnostics on failure (so the LLM can edit and resubmit), caches successful builds by content hash, and serves the NBT so MCP can place it through the existing /api/world/structure/place endpoint.
The starlark-to-nbt tool is vendored as a git submodule at starlark-service/starlark-to-nbt. After cloning this repo (or pulling this change), run:
git submodule update --init
Start the service with:
docker compose --profile starlark up -d starlark-service curl http://localhost:7090/health
The artifact cache lives under starlark-service-data/ (git-ignored). Builds run in a killable subprocess with a wall-clock timeout, memory rlimit, and volume/output-size caps; load() in submitted scripts is confined to the vendored lib/ component library.
For local service development:
cd starlark-service uv sync uv run starlark-service # or: uv run uvicorn starlark_service.app:app --host 0.0.0.0 --port 7090 uv run pytest # service tests
Useful endpoints:
GET http://localhost:7090/healthPOST http://localhost:7090/build—{"source": "...", "entry": "build", "props": {}, "root_size": [w, h, l]}GET http://localhost:7090/artifacts/{artifact_id}and.../nbtGET http://localhost:7090/docs/catalog— the script API referenceGET http://localhost:7090/examplesandGET http://localhost:7090/examples/{name}
MCP tools added for this flow:
build_starlark_structure— compile source; success returns an artifact id, failure returns diagnostics to fix and resubmitplace_starlark_structure— place a built artifact (applies the artifact'sy_offsetautomatically)get_starlark_docs,list_starlark_examples,get_starlark_example
Rail planning debug loop
For a manual end-to-end rail planning regression check, run:
uv run python skills/minecraft-http-gateway/scripts/rail_debug_e2e.py \ --start-x 0 --start-y 64 --start-z 0 \ --end-x 200 --end-y 64 --end-z 200
The harness will:
- start
docker compose up -d postgresunless--skip-postgresis passed - start
./gradlew runServerunless--reuse-serveris passed - wait for
http://localhost:7070/api/test - create a build, run
plan-rail, poll until the planning job completes, then audit the build - exit non-zero if planning fails or audit reports any errors
It writes diagnostics to logs/rail-debug/<timestamp>/summary.json and server.log.