AuthGate
Process-wide authorization gate for MCP tool calls that exercise authority above the player — execute_code (arbitrary Kotlin/JVM = root, on any lane) and run_command target=server (runs at op level 4 in the local server, above the world's cheat setting). Complements McpServer's transport auth (loopback bind + bearer token + Origin check) with a world/server authority check, derived from the live session:
dedicated server → always allowed (the operator owns the box and set the token/launch flags; there is no world to grief that they don't already control);
client + local authoritative server (single-player / opened-to-LAN) → only if the world has cheats enabled (
allowCommands);client on a remote server → only if the local player is OP permission level >= 3;
client with no world loaded → allowed (nothing to grief; arbitrary-Kotlin/JVM access is fenced by token + loopback, same as the dedicated-server case).
run_command target=client grants nothing above the player and never consults this gate — see McpServer.runCommand.
The decision is produced on the game thread (the client tick via ClientAuthProbe, or once at init on a dedicated server) and read from the HTTP handler and the lane threads — hence a volatile, and one, since authorization is a single process-wide fact.
Revokes reach already-running work two ways: McpServer and Lane.pump read allowed themselves, and publish pushes to the two that cannot — the parallel lane and installed patches.
No client types here: this object links on a dedicated server, and the verifier force-loads any class a verified method references — so touching net.minecraft.client.Minecraft et al. would NoClassDefFoundError there. Every client-typed read lives in ClientAuthProbe, which is never linked on a dedicated server.
Types
Properties
Fail-closed until the first publish — the client heartbeat, or init on a dedicated server.
The current decision — a SINGLE volatile read, so Decision.allowed and Decision.reason are coherent (no torn read where a caller sees allowed==false but a stale/flipped reason).
DENY_PROBE_FAILED's common cause, named separately so the reason points at the mapping subsystem rather than at the player's permissions.
The probe reached no session-derived answer. Distinct from DENY_INIT: that one means "not determined YET" and clears on its own, this one means "could not be determined" and may not.