mcbotFeatured

mcbot

2026In DevelopmentApplications

Overview

mcbot is a self-hostable Minecraft automation platform built around a single Rust workspace. The same supervisor and worker crates run three ways: as a headless daemon on a VPS, as a hosted daemon in Kubernetes, and inside a Tauri 2 desktop app that is a daemon with a window attached, so enrollment, the hub link and the key schedule have exactly one implementation. Daemons always dial out to the hub and hold the stream open, because real daemons live behind home NAT and on firewalls I do not control. The Minecraft protocol stack is written from scratch, with no third-party protocol crate: varints, framing, compression, encryption, NBT, packets, chunk and registry decoding, and movement a server will accept, with the protocol version threaded through as a parameter rather than a compile flag. The hub is a TanStack Start app over Postgres with a separate realtime process carrying socket.io for browsers and a raw websocket server for daemons on one port, plus a public HTTP API a Discord bot uses to act on behalf of a user. No Minecraft or Microsoft password exists anywhere in the system: users authenticate with Microsoft directly and what is stored is a sealed, rotating OAuth refresh token they can revoke without my cooperation. The project is still in development and the hosted hub is not public yet; it will live at mcbot.nick22985.com.

RustTauriTanStack StartMinecraftWebSocketsPostgreSQLCryptography

My Role

Author

Key Features

Desktop client (Tauri 2 + React) that runs bots locally with a GUI
Headless daemon for a VPS, home server, or hosted Kubernetes
Web hub for creating bots, assigning them to daemons, and watching them live
Microsoft device-code and PKCE sign-in, so no Minecraft password is ever typed into the app
Per-bot credential posture: attended, always-on self-hosted, or always-on hosted
Config-driven bot behaviours (anti-AFK, chat responder, low-health alerts) validated against typed parameter descriptors
Live console and telemetry streaming with a bounded scrollback buffer
Enrollment codes that are single-use, owner-bound, short-lived, and hashed at rest
Public HTTP API for acting on behalf of a user, used by a companion Discord bot
Local bring-up with Docker Compose, including a pinned vanilla Minecraft server to round-trip packets against

Challenges Solved

Writing the Minecraft protocol from scratch, with the protocol version threaded through the stack as a parameter so multiple game versions share one implementation
Designing a multi-tenant trust model where a daemon I host runs many owners' bots while a daemon a user runs is assigned nothing but their own, enforced hub-side at assignment time
Sealing credentials so how much can be decrypted is the user's choice per bot: attended, always-on self-hosted, or always-on hosted, with one key schedule behind all three
Keeping the hub from ever dialling a daemon, since daemons run behind home NAT and on VPS firewalls outside my control
Making high-volume bot telemetry droppable rather than fatal, with batching, sequence numbers, drop counts and per-bot flow levels raised only while somebody is watching
Sharing chunk storage between bots standing in the same place without leaking one owner's world view into another's
Shipping the same codebase to Windows, macOS, X11, Wayland and Linux with no display server at all

Technical Details

The Minecraft stack is mine

No azalea, no valence, no third-party NBT crate. crates/mc-proto implements varints, framing, compression, encryption, NBT and packets; mc-world holds chunks, palettes and registries; mc-physics produces movement a server will accept; mc exposes an edition-agnostic session facade. Packet bodies are hand-written Rust types, while packet ids and registry data are generated per version from Mojang's own report, so a new game version is a table rather than a fork.

The dependency graph is the architecture

A dedicated arch crate encodes the whole crate graph as tests and fails the build on any edge not in it. Two edges are security boundaries rather than tidiness: the supervisor daemon links no protocol code, so the process holding every owner's ciphertext is never the one parsing bytes from arbitrary third-party servers, and a worker cannot reach the hub, so a process holding one owner's data key can never act as the daemon for everybody. Credential crypto is confined to one vault crate.

Tenancy and the key schedule

Every daemon holds a hub-issued token carrying a tenancy claim: Shared for daemons I run, SingleOwner for daemons a user runs. Assignment is enforced in the hub, never delegated to the daemon, and nothing in the wire protocol lets a daemon name an owner. Credentials are sealed under the user's own password; the daemon-wrapped key is what makes always-on possible, and whether it is persisted is the only difference between the three postures. Every query touching a bot-scoped table carries an owner predicate in the SQL, with a test enforcing the shape.

Telemetry with flow control

Bot telemetry is the high-volume path and the only droppable one. Batches carry sequence numbers and their own drop count, a daemon stops sending after a fixed number of unacknowledged batches, and the hub tells each daemon how much it wants per bot: off, summary, or full. Full is turned on when a browser subscribes to a bot and off when the last subscriber leaves, and chat lines land in a bounded Redis ring buffer rather than being persisted by default.

One codebase, every platform

Platform-conditional code lives in a single platform module per crate and nowhere else, enforced by a test that rejects stray cfg attributes, so the surface written three times stays small enough to actually write three times. Nothing outside the desktop crate may link a GUI toolkit, which is what lets the supervisor run on a headless box with no display server, session bus, or windowing library present.

Tech Stack

Frontend

React 19TanStack StartTauri 2Tailwind CSS

Backend

RustTokioBun realtime processbetter-authsocket.io + raw WebSockets

Database

PostgreSQLRedisSQLiteDrizzle ORM

Tools & Services

DockerKubernetesCaddypm2argon2 / ChaCha20-Poly1305 / X25519