Featuredmcbot 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.
Author
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.
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.
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.
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.
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.