Four more audits, on the same footing as the first four: nothing is started, nothing is loaded, and
every rule still names the source its underlying fact was read from.
world reads level.dat as NBT with a reader written for this project, so it never constructs
anything a world file asked for. It reports a folder that has chunk data and no level.dat, a
level.dat that stops mid-tag, a zero-byte region file, a datapack the server silently ignores, and
the finding nothing on a running server gives you: two worlds of one server last saved by different
game versions, with the conversion still ahead of whichever one nobody has entered.
crash parses crash-reports/crash-*.txt. It names the outermost frame that belongs to neither the
server, the JDK nor Netty, and it recovers the report's own JVM Flags: line — so the flags of a
machine you will never see can be audited from a file somebody emailed you. Reports are read as a set,
because one description written twice half an hour apart is a restart loop, and no single file says so.
perms reads ops.json, whitelist.json, banned-players.json, banned-ips.json and the
permissions file bukkit.yml actually points at. Operators are reported as dangerous only when nothing
verifies identity, so a backend server behind a proxy that forwards it stays silent. A permissions file
that is not valid YAML is a critical finding, because the server logs one warning and then ignores
every node in it.
diff compares two server directories: values that differ, keys present on one side only, the
plugin set, plugin versions, and jars that claim the same version and are not the same bytes. Ports,
addresses, seeds and secrets are skipped, and no finding says which server is the right one.
The MCP surface grows to nine tools with audit_worlds, read_crash_reports, audit_access_lists
and diff_servers. scan runs all eight audits over one directory.
Also in this release: stack frames written with a module or class-loader prefix (java.base/...) now
parse, SnakeYAML's multi-line parse errors are folded into a single line, and rules -o writes UTF-8
so docs/rules.md no longer depends on the console encoding of whoever generated it.
87 rules across eight audits. Requires Java 21 or newer; the jar is self-contained.
java -jar serverdoctor-0.2.0.jar scan /srv/mc --host-memory 8G
java -jar serverdoctor-0.2.0.jar crash crash-2026-08-24_11.04.12-server.txt
java -jar serverdoctor-0.2.0.jar diff /srv/staging /srv/production