minecraft-bedrock-mcp-server
v0.3.0
Published
Model Context Protocol server that bridges MCP clients to a Minecraft Bedrock Dedicated Server.
Maintainers
Readme
Minecraft Bedrock MCP Server
A Model Context Protocol (MCP) server that bridges MCP clients — Claude and other AI agents — to a Minecraft Bedrock Dedicated Server (BDS). It exposes the Bedrock Script API as MCP tools, so an agent can read and manipulate a live world programmatically.
⚠️ Built on an experimental API
This project depends on Mojang's Bedrock Script API, including the beta modules
@minecraft/server-net and @minecraft/server-admin. The Script API is an evolving surface that
Mojang revises between Minecraft versions, and a Bedrock update can change, deprecate, or remove
APIs this project depends on — beta modules can be discontinued outright with no stable
replacement. Pin your BDS to a known-good version, do not auto-update it, and keep the BDS, the
behavior pack, and this server upgraded together. Treat the whole stack as experimental.
The three repositories
This system is split across three repositories:
| Repository | Role |
| ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| minecraft-bedrock-mcp-server (this repo) | The MCP server. Speaks MCP to clients and bridges commands to the world. |
| minecraft-bedrock-mcp-behavior-pack | The BDS behavior pack. Runs inside the world and executes commands via the Script API. |
| minecraft-bedrock-claude-plugin | A Claude Code plugin — skills that guide this setup and agents that build in the world. |
The first two repositories are required. This README is the end-to-end guide — it covers standing up the whole stack. The behavior pack repository documents the pack itself in more depth. The Claude plugin is optional but recommended: it turns the tutorial below into a guided, step-by-step experience and adds a builder agent for designing and constructing things in the world.
How it works
The server runs on the same host as BDS and exposes two authenticated HTTP surfaces:
MCP clients (Claude Desktop, Cursor, ...)
| MCP over Streamable HTTP + bearer token
minecraft-bedrock-mcp-server <-- this repository
| HTTP long-poll + bearer token
Bedrock Bridge behavior pack <-- separate repository
| @minecraft/server Script API
the Minecraft world- The
/mcpsurface speaks the MCP Streamable HTTP transport to clients. - The
/bridgesurface is long-polled by the companion behavior pack running inside the world.
An MCP tool call enqueues a command; the behavior pack polls for it, executes it through the Script API, and posts the result back. The server correlates that result to the waiting tool call and returns it to the client.
End-to-end setup tutorial
This walkthrough takes you from nothing to an AI agent building in your world. It has eight steps:
- Set up a Bedrock Dedicated Server
- Create a compatible world
- Transfer the world to the server
- Install the behavior pack
- Install and configure the MCP server
- Configure the behavior pack
- Start everything
- Connect Claude Desktop
Assumption: this tutorial assumes the Bedrock Dedicated Server and the MCP server run on the same Ubuntu (Linux) host. The commands below are written for Ubuntu. BDS also ships for Windows; if you run it there, adapt the paths and shell commands accordingly — the configuration values are identical.
Prefer a guided setup? The
minecraft-bedrock-claude-pluginturns these eight steps into an interactive walkthrough inside Claude Code — itsminecraft-mcp-setupagent runs the whole sequence with you, on Linux or Windows. The manual tutorial below remains the canonical reference.
Prerequisites
- An Ubuntu host (a VM, a spare machine, or a cloud instance) for the server.
- Node.js 20 or newer on that host.
- A copy of Minecraft: Bedrock Edition on a PC or device — used once to create the world.
- About 20 minutes.
Step 1 — Set up a Bedrock Dedicated Server
Download the Linux Bedrock Dedicated Server from the official page: https://www.minecraft.net/en-us/download/server/bedrock. Accept the EULA and privacy policy prompts on that page to reveal the download link.
Unzip it on the Ubuntu host:
sudo mkdir -p /opt/bedrock-server sudo unzip bedrock-server-*.zip -d /opt/bedrock-server sudo chown -R "$USER" /opt/bedrock-server cd /opt/bedrock-serverDo a first test run so BDS generates its default files, then stop it with
Ctrl+C:LD_LIBRARY_PATH=. ./bedrock_serverIf it complains about a missing library, install the basics:
sudo apt-get update && sudo apt-get install -y libcurl4 unzip.Edit
server.properties. The settings that matter for this project:| Setting | Value | Why | | -------------- | ------------------------ | ------------------------------------------------------- | |
level-name| your world folder name | Selects which world underworlds/to load. | |allow-cheats|true| Required formc_run_commandand command-backed tools. | |gamemode|creative| Recommended so agents can place and break freely. |Leave the rest at their defaults for now. You will set
level-namein Step 3.
Step 7 covers running BDS as a systemd service. For more detail (firewall rules, backups),
search "Bedrock Dedicated Server" in the Minecraft help center at https://help.minecraft.net.
Step 2 — Create a compatible world
The behavior pack needs a world created with the Beta APIs experiment enabled. That toggle can only be set when the world is created in the Minecraft client — the dedicated server cannot turn it on. So create the world on your PC/device first, then move it to the server.
In Minecraft: Bedrock Edition, choose Create New World and set:
| Setting | Value | Why |
| ---------------------------- | -------- | ------------------------------------------------------------------ |
| Game Mode | Creative | Agents place/break blocks and spawn entities freely. |
| Cheats (Activate Cheats) | On | Enables commands; pairs with allow-cheats on the server. |
| Experiments → Beta APIs | On | Required. @minecraft/server-net / -admin are beta modules. |
Then play the world once for a few seconds so it is fully written to disk, and exit.
Step 3 — Transfer the world to the server
In Minecraft, on the worlds list, open the world's settings (the pencil icon) and choose Export World. This produces a
.mcworldfile — which is just a ZIP archive.Copy that file to the Ubuntu host (e.g. with
scp) and unzip it into a folder underworlds/:cd /opt/bedrock-server/worlds mkdir "mcp-world" unzip ~/exported-world.mcworld -d "mcp-world"Set
level-name=mcp-worldin/opt/bedrock-server/server.propertiesso BDS loads it.
The world's absolute path is now /opt/bedrock-server/worlds/mcp-world — you will need it shortly.
Step 4 — Install the behavior pack
Get the pack from the behavior pack repository — download
bedrock-bridge.mcpackfrom its Releases, or clone andnpm run buildit. The pack is the folder holdingmanifest.json,scripts/main.js, andpack_icon.png.Place the pack folder inside the world:
mkdir -p "/opt/bedrock-server/worlds/mcp-world/behavior_packs" cp -r bedrock-bridge "/opt/bedrock-server/worlds/mcp-world/behavior_packs/"Activate it for the world by creating (or editing)
/opt/bedrock-server/worlds/mcp-world/world_behavior_packs.json:[{ "pack_id": "fa013817-66f2-4a5f-a724-1347f912bd40", "version": [0, 3, 0] }]
The pack's absolute path is now
/opt/bedrock-server/worlds/mcp-world/behavior_packs/bedrock-bridge.
Step 5 — Install and configure the MCP server
Install this server on the same host:
npm install -g minecraft-bedrock-mcp-serverGenerate two long random secrets — one for MCP clients, one for the behavior pack:
openssl rand -hex 32 # use for BRIDGE_CLIENT_TOKEN
openssl rand -hex 32 # use for BRIDGE_AGENT_TOKENCreate a .env file (copy .env.example as a starting point):
BRIDGE_CLIENT_TOKEN=<first secret>
BRIDGE_AGENT_TOKEN=<second secret>
BRIDGE_WORLD_PATH=/opt/bedrock-server/worlds/mcp-world
BRIDGE_BEHAVIOR_PACK_PATH=/opt/bedrock-server/worlds/mcp-world/behavior_packs/bedrock-bridge
BRIDGE_HOST=0.0.0.0
BRIDGE_PORT=8765See the configuration reference for every variable.
Step 6 — Configure the behavior pack
The pack reads its configuration from the BDS scripting config directory. Create
/opt/bedrock-server/config/default/ and add three files (the behavior pack repository ships
copy-ready versions under its config/default/):
permissions.json — lets the pack load its Script API modules:
{
"allowed_modules": ["@minecraft/server", "@minecraft/server-net", "@minecraft/server-admin"]
}variables.json — where the bridge listens (the MCP server's /bridge surface):
{ "bridge_url": "http://localhost:8765" }secrets.json — the bridge token. The value is the full Authorization header — the word
Bearer, a space, then the BRIDGE_AGENT_TOKEN from your .env:
{ "bridge_agent_token": "Bearer <the BRIDGE_AGENT_TOKEN second secret>" }The
Bearerprefix must be part of the stored secret — the pack receives an opaque handle it cannot read or concatenate, so the scheme prefix has to travel inside the secret itself.
Step 7 — Start everything
You can start the two processes by hand, or — recommended — install them as systemd services so
they survive logout, restart on crash, and start at boot.
Option A — run in the foreground
Start the MCP server, then the Bedrock server, in two terminals:
# Terminal 1 — the MCP server
minecraft-bedrock-mcp-server # reads .env from the working directory
# Terminal 2 — the Bedrock Dedicated Server
cd /opt/bedrock-server && LD_LIBRARY_PATH=. ./bedrock_serverOption B — run as systemd services (recommended)
This is how the two processes are run in a typical long-lived deployment.
Create a dedicated unprivileged user to own and run both processes, and hand it the files:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin minecraft sudo chown -R minecraft:minecraft /opt/bedrock-serverMove the MCP server's
.env(from Step 5) somewhere the service can read it, and lock it down — it holds both bearer tokens:sudo mkdir -p /etc/minecraft-bedrock-mcp sudo cp .env /etc/minecraft-bedrock-mcp/.env sudo chown -R minecraft:minecraft /etc/minecraft-bedrock-mcp sudo chmod 600 /etc/minecraft-bedrock-mcp/.envCreate
/etc/systemd/system/bedrock-server.service:[Unit] Description=Minecraft Bedrock Dedicated Server After=network.target [Service] Type=simple User=minecraft Group=minecraft WorkingDirectory=/opt/bedrock-server Environment=LD_LIBRARY_PATH=/opt/bedrock-server ExecStart=/opt/bedrock-server/bedrock_server Restart=on-failure RestartSec=10 StandardInput=null StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.targetCreate
/etc/systemd/system/mc-mcp-server.service:[Unit] Description=Minecraft Bedrock MCP server After=network.target bedrock-server.service [Service] Type=simple User=minecraft Group=minecraft EnvironmentFile=/etc/minecraft-bedrock-mcp/.env ExecStart=/usr/bin/minecraft-bedrock-mcp-server Restart=on-failure RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.targetExecStartpoints at the global install from Step 5. Runcommand -v minecraft-bedrock-mcp-serverto confirm its path on your host and adjust the line if it differs.Enable and start both — the MCP server first, so the bridge is listening when the world loads:
sudo systemctl daemon-reload sudo systemctl enable --now mc-mcp-server bedrock-serverCheck status and follow the logs:
systemctl status mc-mcp-server bedrock-server journalctl -u mc-mcp-server -f
Confirm the handshake
When the world loads, the behavior pack handshakes with the bridge. The MCP server logs the
successful handshake, and BDS logs that the bedrock-bridge pack's script started. If the
handshake fails, the most common causes are a token mismatch between secrets.json and .env, or
a wrong bridge_url.
Quick liveness check:
curl http://localhost:8765/healthzStep 8 — Connect Claude Desktop
The MCP server speaks the Streamable HTTP transport. Claude Desktop connects to it through the
mcp-remote adapter, which bridges a local stdio
server entry to a remote HTTP endpoint and attaches the bearer token.
Edit Claude Desktop's config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add a minecraft-bedrock entry under mcpServers:
{
"mcpServers": {
"minecraft-bedrock": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://YOUR-SERVER-HOST:8765/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer <the BRIDGE_CLIENT_TOKEN first secret>"
}
}
}
}Replace YOUR-SERVER-HOST with the host running the MCP server (localhost if it is the same
machine as Claude Desktop). The token is passed via the AUTH_HEADER env var so its space is not
mangled by argument parsing.
Restart Claude Desktop fully. The mc_* tools appear under the tools (🔌) menu once it
reconnects. If your Claude Desktop version supports custom connectors natively, you can
instead add the http://YOUR-SERVER-HOST:8765/mcp URL directly in Settings → Connectors with
the Authorization: Bearer <token> header — that skips mcp-remote entirely.
Sample prompts
With at least one player in the world (the agent acts relative to players and the world origin), try prompts like these in Claude Desktop:
Building
"Build a 9×9×5 hollow stone-brick house at around x=100, z=100 on the surface, with a door, a couple of glass windows, and torches inside. Find a flat spot first."
"Clear a 20×20 area to bedrock-flat grass, then lay out a small village square — a fountain in the middle, paths to four corners, and a lamp post at each corner."
"Save the structure I just built as
starter-houseso I can paste copies of it elsewhere."
Interacting with the world
"What's the time and weather right now? Set it to clear and to midday."
"List the players online and tell me what each is holding and standing on."
"Spawn a ring of twelve armor stands around the nearest player, then give that player a netherite pickaxe."
Reacting to events
"Subscribe to block-break events, then tell me what gets broken over the next minute."
"Strike lightning wherever a player places a redstone block — keep watching until I say stop."
Start small and concrete. The agent works through the tool surface below; vague prompts ("make it cooler") give it nothing to aim at.
Reference
Install
npm install -g minecraft-bedrock-mcp-serverRun it directly without installing:
npx minecraft-bedrock-mcp-serverOr with Docker. Each v* tag publishes a multi-arch image (linux/amd64,
linux/arm64) to the GitHub Container Registry — pull and run it directly:
docker run --env-file .env -p 8765:8765 ghcr.io/chapmanjw/minecraft-bedrock-mcp-server:latestPin to a specific version (e.g. :0.3.0) for reproducible deployments. To build the
image from source instead:
docker build -t minecraft-bedrock-mcp-server .
docker run --env-file .env -p 8765:8765 minecraft-bedrock-mcp-serverConfiguration reference
All configuration is through environment variables, validated at startup — the server exits with a clear message if a required variable is missing. Copy .env.example and adjust.
| Variable | Default | Description |
| ------------------------------------ | ------------ | --------------------------------------------- |
| BRIDGE_CLIENT_TOKEN | (required) | Bearer token for MCP clients |
| BRIDGE_AGENT_TOKEN | (required) | Bearer token for the behavior pack |
| BRIDGE_WORLD_PATH | (required) | Absolute path to the active world folder |
| BRIDGE_BEHAVIOR_PACK_PATH | (required) | Absolute path to the behavior pack folder |
| BRIDGE_HOST | 0.0.0.0 | Bind address |
| BRIDGE_PORT | 8765 | Listen port |
| BRIDGE_TLS_CERT / BRIDGE_TLS_KEY | (none) | TLS cert/key paths — set both, or neither |
| BRIDGE_TRUST_PROXY | false | Trust X-Forwarded-* (enable behind a proxy) |
| BRIDGE_LOG_LEVEL | info | Log level |
| BRIDGE_POLL_TIMEOUT_MS | 30000 | Bridge long-poll hold time |
| BRIDGE_COMMAND_TIMEOUT_MS | 15000 | How long a tool call awaits a result |
| BRIDGE_RATE_LIMIT_RPM | 60 | Per-token request rate on /mcp |
| BRIDGE_MAX_BODY_BYTES | 16777216 | Maximum request body size |
| BRIDGE_QUEUE_MAX | 256 | Maximum outstanding commands |
| BRIDGE_METRICS_ENABLED | false | Expose the Prometheus /metrics endpoint |
| BRIDGE_CORS_ORIGINS | (none) | Comma-separated allowed CORS origins |
Endpoints
| Route | Auth | Purpose |
| ------------------------ | ------------ | ------------------------------------ |
| POST/GET/DELETE /mcp | client token | MCP Streamable HTTP transport |
| GET /bridge/poll | agent token | Behavior-pack long-poll for commands |
| POST /bridge/result | agent token | Behavior-pack command results |
| POST /bridge/event | agent token | Behavior-pack world events |
| POST /bridge/handshake | agent token | Behavior-pack version negotiation |
| GET /healthz | none | Liveness probe |
| GET /metrics | client token | Prometheus metrics (when enabled) |
TLS
The bridge carries bearer tokens and world data. Use TLS outside a fully trusted network.
Direct TLS with mkcert (private LAN)
mkcert issues a certificate trusted by your LAN machines:
mkcert -install
mkcert bedrock-host.lan 192.168.1.50Point the server at the generated files:
BRIDGE_TLS_CERT=./bedrock-host.lan+1.pem
BRIDGE_TLS_KEY=./bedrock-host.lan+1-key.pemWhen both are set, the server listens HTTPS only. When neither is set, it listens HTTP and logs a prominent warning at startup.
TLS at a reverse proxy
Alternatively, terminate TLS upstream — Caddy with its internal CA, or Traefik — and run this
server on plain HTTP bound to localhost. Set BRIDGE_TRUST_PROXY=true so client IP addresses
are logged correctly.
Tool surface
78 tools across 13 domains, consistently named mc_<domain>_<action>:
| Domain | Examples |
| --------------- | ----------------------------------------------------------------- |
| World | mc_world_get_info, mc_world_set_time, mc_world_set_weather |
| Blocks | mc_block_get, mc_block_fill, mc_block_clone |
| Structures | mc_structure_create_from_blocks, mc_structure_place |
| Structure files | mc_structure_file_read, mc_structure_file_write |
| Entities | mc_entity_spawn, mc_entity_teleport, mc_entity_apply_effect |
| Players | mc_player_list, mc_player_give_item, mc_player_set_gamemode |
| Inventory | mc_inventory_get, mc_inventory_set_slot |
| Scoreboard | mc_scoreboard_set_score, mc_scoreboard_add_objective |
| Properties | mc_property_get, mc_property_set |
| Effects | mc_explosion_create, mc_lightning_strike |
| Events | mc_event_subscribe, mc_event_poll |
| Server | mc_server_save_world, mc_server_get_status |
| Escape hatch | mc_run_command |
Stability and versioning
This server is a stable foundation for separately built skills and plugins. Its public contract, governed by semantic versioning, is:
- tool names,
- tool input schemas,
- tool output (the
resultfield of the response envelope), - stable error codes,
- the bridge protocol envelopes.
Internal structure — the HTTP framework, module layout, logging format — is not part of the contract and may change at any time. The bridge protocol is versioned independently; its major version is negotiated at handshake.
Note that this contract is the server's contract. The underlying Bedrock Script API is not stable (see the warning at the top): a Bedrock update can still break behavior even when this server's contract is unchanged.
Security
- Two separate bearer tokens isolate MCP clients from the behavior pack; tokens are compared in constant time.
- Every route except
/healthzrequires a token. - Per-token rate limiting on
/mcp; per-command throttling protects the BDS script watchdog. - The command queue is in memory and is not persisted — commands do not survive a restart.
See SECURITY.md to report a vulnerability.
Development
npm install
npm run typecheck
npm run lint
npm test
npm run buildLicense
MIT — see LICENSE.
