mc-snap
Declarative Minecraft server management. Write one YAML file pinning the Minecraft version, loader, mods, Java runtime, and configs; mc-snap resolves and downloads everything, manages the server process, and produces a shareable bundle so anyone can reproduce the exact same server with one command.
Think "docker-compose for Minecraft servers".
Status
Working: Vanilla and Fabric loaders, Modrinth and direct-URL mod providers, install / start / stop / status / logs / console / pack / unpack / validate / doctor / check / updatable / search / update / revert, system Java discovery with Adoptium Temurin auto-download fallback, content-addressed jar cache, RCON-based lifecycle, source bundles, snapshot-based version updates.
Tracks the Minecraft 26.x series; default scaffold pins 26.1.2 + Java 26. Tested on Linux with system Java 26. Windows process management and the hardlink-based cache are implemented but not CI-tested.
Install
From crates.io:
Or from source:
# binary lives at target/release/mc-snap
Or use the helper script, which runs cargo install into either your user or system prefix:
Requires a system java (any version) for the doctor probe. Minecraft 26.x needs Java 26 at runtime; if your system Java is older, mc-snap auto-downloads Temurin 26 into ~/.local/share/mc-snap/jdks/.
Quickstart
&&
# elsewhere:
Example mc-snap.yml
schema: 1
eula: true
server:
name: grimwald
description: the grimwald smp
minecraft: 26.1.2
loader:
type: fabric
runtime:
java: 26
memory: 4G
flags:
- -XX:+UseG1GC
mods:
- id: fabric-api
provider: modrinth
version: latest
- url: https://github.com/owner/repo/releases/download/v1.0/mymod.jar
provider: url
sha256: abc123...
config:
server.properties:
motd: "Welcome to Grimwald"
max-players: 20
Commands
| Command | Purpose |
|---|---|
mc-snap init [--non-interactive] |
Interactive scaffold of a new mc-snap.yml; --non-interactive writes the default template without prompts |
mc-snap validate |
Schema check, no network |
mc-snap doctor |
Report discovered Java installs and cache paths |
mc-snap install |
Resolve, download, materialize .mc-snap/server/, write lockfile |
mc-snap start [--detach] |
Start the server (foreground by default) |
mc-snap stop |
Graceful stop via RCON |
mc-snap restart |
stop then start --detach |
mc-snap status |
Running/stopped + player count (via RCON) |
mc-snap logs [-f] |
Tail logs/latest.log |
mc-snap console [cmd...] |
One-shot RCON command, or interactive shell |
mc-snap pack -o out.zip |
Bundle mc-snap.yml + mc-snap.lock + configs/ |
mc-snap unpack <bundle.zip> |
Extract a bundle into the current directory |
mc-snap check --to <ver> |
Per-mod compatibility report against a target Minecraft version; no filesystem changes |
mc-snap updatable [--to <ver>] |
With --to: yes/no for that version. Without: the newest Minecraft version every mod supports |
mc-snap search |
List newer mod versions available for the current Minecraft version |
mc-snap update --to <ver> [--skip-missing] [--loader <ver>] |
Snapshot, then update mc-snap.yml + lockfile to a new Minecraft version. Resolves mods against the new version first; prompts if any are missing, or use --skip-missing to drop them automatically |
mc-snap revert [<id>] / --list |
Restore the most recent snapshot (or named one); --list shows all snapshots |
Layout
The tool keeps a clean split between user-owned and tool-owned files:
my-server/
├── mc-snap.yml # you edit; commit this
├── mc-snap.lock # generated; commit this
├── configs/ # external config files; commit these
└── .mc-snap/ # generated; gitignore this
├── server/ # actual Minecraft server root
├── snapshots/ # pre-update snapshots of yml + lock + configs (for `revert`)
├── state.json # last-applied lockfile hash
├── pid # present when running (pid + start-token, for reuse detection)
├── rcon.secret # auto-generated RCON password (0600 on Unix)
└── .lock # advisory lock held by mutating commands
.gitignore should include /.mc-snap/ (the init command appends this automatically).
Global cache shared across servers: ~/.local/share/mc-snap/{cache,jdks}/ on Linux, ~/Library/Application Support/mc-snap/ on macOS, %APPDATA%\mc-snap\mc-snap\data on Windows.
RCON
install auto-generates a 256-bit RCON password in .mc-snap/rcon.secret (mode 0600 on Unix) and writes enable-rcon=true, rcon.password=<secret>, and rcon.ip=127.0.0.1 into server.properties. stop, status, and console all use this. RCON is plaintext, so we always bind it to loopback - the rcon.ip override in your yml is overwritten on every install for that reason.
Development
See DESIGN.md for architecture, trait extension points, and implementation notes.