01 · ARCHITECTURE

HOW A REQUEST FLOWS

v3.x runs bots on Mineflayer + mineflayer-pathfinder against a real Java-edition server — full physics, A* pathfinding, containers, and crafting. Bedrock and Java humans play in the same world via Geyser/Floodgate; the bots join as ordinary Java clients underneath. Fleet coordination is process-local: it coordinates known OreMind reservations without pretending to lock humans, other processes, or Minecraft physics.

AI agent (Claude / OpenClaw / DaVinci) ──▸ MCP · Streamable HTTP · minecraft-mcp-http.js :3100 ──▸ minecraft-bot-mcp-server.js (bot core)
Mineflayer + mineflayer-pathfinder ──▸ PaperMC :25565 ◂── Geyser / Floodgate ◂── Bedrock + Java human clients
01A · RELEASE READINESS

THE PATH TO STABLE v3.2

v3.1 is the current supported runtime and its fleet contract is covered by unit, contract, and live-PaperMC checks. The remaining milestone is operational validation, not a speculative feature promise: run a real multiplayer playtest, validate the authenticated LAN path from a second machine, then feed those observations back into fleet coordination.

#42 / PLAYTESTFirst sustained session with real humans and bots in a persistent world. This is the biggest gap between CI-proven and actually used.
#43 / LANSecond-machine validation of the explicit authenticated LAN path; loopback-first defaults remain the safe baseline.
#44 / FEEDBACKTune waypoint ergonomics, corridor radius defaults, and automatic assignment selection from real usage data.
#45 / AUDITKeep re-checking the inherited moderate dependency chain on each Mineflayer or MCP SDK release; no unsupported downgrade.

The upstream roadmap and GitHub issues are the source of truth for status.

02 · HTTP SURFACE

ROUTES ON :3100

POST /mcp MCP Streamable HTTP endpoint — the 39 tools live here for any MCP-speaking client.
GET /health Process liveness + per-bot telemetry. A 200 does not mean the configured bot has joined.
GET /ready Deployment readiness. Returns 503 until the configured default bot has spawned; API-only mode is explicit.
GET /api/status Full status payload the dashboard polls every 2s (position, task, guard mode, chat log, last error).
GET /api/events Bearer-authenticated Server-Sent Events for bounded live chat replay. Use Last-Event-ID to resume; a reset event means reconcile from /api/status.
GET /dashboard Zero-dependency dashboard shell. Telemetry requires a short-lived browser session.
POST /api/session Exchanges a bearer token sent in the Authorization header for a short-lived HttpOnly dashboard cookie.

If MCP_AUTH_TOKEN is set, MCP and telemetry fail closed — send it as Authorization: Bearer <token>. Legacy query tokens are limited to GET telemetry compatibility and are rejected on /dashboard and POST /mcp. The dashboard instead uses POST /api/session. Unset, the process and Compose bind to loopback by default and reject non-loopback Host headers. Browser origins must be loopback or explicitly allowlisted. Every request body is capped at 1 MiB.

03 · REPOSITORY LAYOUT

WHAT'S IN THE REPO

minecraft-bot-mcp-server.js Current Mineflayer bot core — BotEntry, task-queue runner, all 39 tool handlers, reconnect loop.
fleet-coordinator.js Process-local fleet state: reservations, assignments, waypoints, conflict records, and sanitized snapshots.
fleet-planner.js Deterministic bounded corridor planner used by reserved movement and named-waypoint navigation.
minecraft-bot-mcp-server.bedrock.js Archived v2 bedrock-protocol core, kept for reference only — not installed/shipped. MCP_BOT_IMPL=bedrock is retired and refuses to start.
minecraft-mcp-http.js HTTP transport — wires Streamable HTTP, auto-reconnect, readiness, dashboard sessions, telemetry, and origin/host boundaries.
minecraft-chat-bridge.js Outbound Discord/Telegram delivery plus a generic inbound /relay API, via the official MCP client.
dashboard/index.html The zero-dep dashboard UI served at /dashboard.
scripts/deploy-java.sh Single-shot bare-metal installer: Java 21 + Paper + Geyser + systemd. Idempotent.
scripts/install-linux.sh / install-windows.ps1 Docker-based installers — accept host/port/auth-mode flags, generate a bearer token, and wait for the bot to actually join.
Dockerfile, docker-compose*.yml Container packaging — loopback-published by default, --full-stack bundles Paper+Geyser+Floodgate.
docs/ARCHITECTURE.md, docs/HTTP-API.md Deep-dive references: system design rationale, and the full HTTP request/response contract for every route.
CONTRIBUTING.md, docs/ROADMAP.md, docs/ISSUES.md Contributor onboarding, stable-v3.2 sequencing, and the GitHub-linked backlog that tracks the remaining validation work.
test/ node:test unit suite — queue runner, summary dispatcher, bridge dedup, lifecycle, HTTP/MCP transport.
.github/workflows/ci.yml GitHub Actions: lint + tests on Node 20 & 22, plus shellcheck on scripts.
04 · CONFIGURATION

BOT CORE + TRANSPORT

MINECRAFT_HOST Java server host. Default 127.0.0.1.
MINECRAFT_PORT Java server port. Default 25565.
MINECRAFT_AUTH offline for Floodgate/cracked servers (default), microsoft for online-mode Java.
MINECRAFT_VERSION Auto-detected; pin it if Mineflayer mis-detects (e.g. 1.21.4).
MINECRAFT_PROFILES_FOLDER Docker-only: persists Microsoft device-flow auth tokens across rebuilds.
MCP_PORT HTTP transport port. Default 3100.
MCP_HOST Direct-process bind address. Default 127.0.0.1; Compose overrides the in-container listener to 0.0.0.0.
MCP_BIND_ADDRESS Docker-only: host interface the published port binds to. Default 127.0.0.1 — loopback-first.
MCP_AUTH_TOKEN Bearer token; the installers generate one automatically. Gates every route when set, fail-closed.
MCP_DEFAULT_BOT Auto-connected on boot with capped backoff retry. Default MCPTestBot; empty string disables it.
MCP_BOT_IMPL mineflayer — the only supported runtime. MCP_BOT_IMPL=bedrock is retired and refuses to start; any other value is treated as a Node require path.
MCP_MAX_BOTS Cap on concurrently connected bots. Default 4.
MCP_MAX_SESSIONS Cap on concurrent MCP client sessions. Default 32.
MCP_MAX_EVENT_CLIENTS Cap on concurrent /api/events streams. Default 32; slow consumers are disconnected rather than accumulating an unbounded socket queue.
MCP_EVENT_BUFFER_SIZE Newest chat events retained for Last-Event-ID replay. Default 256; an older cursor receives an explicit reset.
MCP_EVENT_HEARTBEAT_MS SSE heartbeat interval. Default 15000.
MCP_SESSION_IDLE_MS Idle session eviction timeout. Default 1800000 (30 min).
MCP_BROWSER_SESSION_TTL_MS Dashboard HttpOnly session lifetime. Default 300000 (5 min).
MCP_ALLOWED_ORIGINS Comma-separated browser origins trusted when the service sits behind a reverse proxy.
MCP_MAX_QUEUE_LENGTH Per-bot queued-step backlog cap. Default 256; overflowing submissions are rejected atomically.
MCP_MAX_CHAT_MESSAGE_LENGTH Max length accepted by minecraft_chat / minecraft_emote. Default 512.
MCP_MAX_SCRIPT_STEPS Max steps accepted by minecraft_run_script. Default 128.
MCP_MAX_WAIT_MS Max duration for a script's wait step. Default 60000.
MCP_FLEET_STATE_FILE Optional path for persisted fleet metadata. When configured, assignments, waypoints, and recent conflicts are written atomically; active work is restored as interrupted rather than replayed.

CHAT BRIDGE

A bidirectional relay between Minecraft chat and Discord/Telegram. Inbound: POST a message to the bridge's /relay route and it calls minecraft_chat as its own bot username. Outbound: the bridge consumes the bearer-authenticated /api/events stream by default, resumes with Last-Event-ID, and falls back to /api/status polling only after a disconnect or reset.

MCP_SERVER host:port of the MCP HTTP server. Default 127.0.0.1:3100.
BRIDGE_PORT Inbound POST /relay listener. Default 3101.
BRIDGE_AUTH_TOKEN Bearer credential for POST /relay. Defaults to MCP_AUTH_TOKEN.
BRIDGE_ALLOW_UNAUTHENTICATED Explicit opt-in required to enable relay without a token. Default 0.
BRIDGE_ALLOWED_ORIGINS Comma-separated allowlist for browser callers of the relay.
BRIDGE_BOT_USERNAME Bot name used when relaying into Minecraft. Default ChatBridge.
DISCORD_WEBHOOK_URL Enables Discord output.
TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID Enables Telegram output.
OUTBOUND_USE_STREAM Use /api/events SSE for Minecraft → Discord/Telegram delivery. Default 1; set 0 for polling-only compatibility.
OUTBOUND_POLL_MS Recovery-poll interval while the stream is unavailable or resets. Default 3000; 0 disables outbound.
OUTBOUND_EVENT_QUEUE_SIZE Maximum parsed events awaiting external delivery. Default 256; reaching the cap closes the stream so normal replay/reconciliation can recover.
OUTBOUND_IGNORE Comma-separated usernames never forwarded outbound (echo-loop protection). The bridge's own username is always excluded.
MAX_CHAT_MESSAGE_LENGTH Max relayed message length before the bridge rejects it. Default 512.
MCP_JOIN_TIMEOUT_MS How long the bridge waits for its bot to spawn. Default 35000.
MCP_REQUEST_TIMEOUT_MS Timeout on MCP tool calls the bridge makes. Default 15000.
BRIDGE_HTTP_TIMEOUT_MS Timeout on the bridge's own inbound HTTP handling. Default 10000.

Discord posts can't ping @everyone/@here/roles. Telegram text is HTML-escaped. TLS verification is on for both.

05 · DEVELOPMENT & TESTING

RUNNING THE TEST SUITE

git clone https://github.com/christopherdeck/oremind.git
cd oremind
npm install
npm run lint    # node --check on every source JS file
npm test        # ~180 tests; environment-specific checks may skip

CI runs the same lint + test matrix on Node 20 and 22, plus shellcheck + bash -n on scripts/*.sh. Coverage includes queue bounds and cancellation, readiness and telemetry contracts, dashboard sessions, origin/host protections, chat-bridge relay behavior, reconnects, documentation consistency, fleet reservations, waypoint conflicts, movement corridors, and bot lifecycle. A small number of environment-specific installer scenarios may skip when their host conditions are unavailable.

06 · OPERATIONS

LOGS & ROLLBACK

sudo journalctl -u paper-server -f          # the Java server
sudo journalctl -u minecraft-bot-mcp -f     # the MCP + bot core
sudo journalctl -u minecraft-chat-bridge -f # the bridge (if installed)

The archived v2 Bedrock core is no longer installed or runnable by flipping an env var — the supported v3 runtime refuses to start with MCP_BOT_IMPL=bedrock. Real rollback now means deploying an older release of this repo from before the v3 pivot, not reconfiguring your current install; treat it as a last resort, reinstalling that release's own dependencies rather than switching a variable in place.

For fleet durability, set MCP_FLEET_STATE_FILE to a service-owned path. OreMind writes a schema-versioned metadata snapshot through a temporary file and atomic rename; active assignments are intentionally restored as interrupted so uncertain Minecraft mutations are not replayed after restart.

scripts/deploy-java.sh only overwrites the main unit file, never drop-ins — re-running it to update in place is safe.

07 · VERSION HISTORY

WHY IT LOOKS LIKE THIS

v3.1 — Fleet coordination + runtime hardening (current)
The public surface is now 39 MCP tools, adding minecraft_fleet_status, minecraft_fleet_assign, plus named waypoint registration, removal, and default-reserved navigation. Gather/build queues reserve known mutations and can auto-assign to the least-busy eligible bot, one-shot movement can reserve bounded corridors, and conflicts are reported explicitly. Runtime hardening also added session and bot caps, stricter script/wait/chat-length limits, immediate-abort waits, loopback-first deployment, generated bearer tokens, dashboard HttpOnly sessions, optional persisted fleet metadata, and a bounded bearer-authenticated /api/events stream for chat replay and bridge recovery.
2026-07 maintenance — safer upgrades, clearer contribution path
The upstream repository now pins a patched Hono server adapter without a breaking downgrade, keeps high/critical production advisories cleared, and documents the contributor workflow plus GitHub issues as the canonical backlog. The public runtime contract remains v3.1: 39 tools, bounded SSE chat events, safe fleet metadata recovery, and loopback-first deployment.
v3.0–3.1 — Pivot to Mineflayer / Java
bedrock-protocol is a raw-packet library — reimplementing Mineflayer-grade physics, pathfinding, containers and crafting on top of it was an unending fight. v3 swapped the bot core for Mineflayer + mineflayer-pathfinder against a Java server; Bedrock clients still play via Geyser, so human UX was unchanged and the MCP tool surface stayed identical to v2. v3.1 added the gather/build composite tools, Docker packaging, and one-command installers.
v2.x — Last-mile Bedrock packet fixes
Fixed up to actually join and act on modern (1.20+) server-authoritative Bedrock: rebuilt player_auth_input against current minecraft-data, removed client-side move_player, replaced use_item with inventory_transaction, and loaded the block palette from Bedrock's blockStates.json. Still limited by bedrock-protocol's level of abstraction.
v1 / pre-history
Initial Bedrock implementation, plus a targetDx-not-defined fix in faceBlock and minecraft_move.