docs/minecraft.md

Minecraft

Clankie can join an owner-configured Java server as his own offline player, chat, follow a player, navigate, dig, place blocks, craft inventory recipes and build a sequence of placements. His play mind observes, chooses, acts, verifies and remembers continuously by default; the service-owned MCP motor handles physics, navigation and immediate falling/drowning/combat reflexes.

In-game chat and the active Discord room reach the same mind. Its journal retains working notes, objectives, action evidence and per-call token/spend usage. It re-observes before acting, caps decision preemption, backs off repeated failures and quiet worlds, and leaves its own bot on idle/budget/failure stop. No activity or words are scripted. Defaults and model selection live in minecraft.play; clankie minecraft configure play and /minecraft expose them.

One driver operates the existing conversation-owned play lease. Use clankie minecraft driver owner before direct actions, driver mind to resume autonomous play, or driver worker fleet:FLEET:pane:SEAT to hand off to a chosen native worker. The worker discovers clankie_minecraft_* through fleet tools and uses clankie_call; raw motor, joins, configuration and administration remain outside that handoff. Driver changes cancel prior work and require settlement. The owner can take back control through the same command.

Owner-configured external profiles support offline protocol login. His own Paper server supports premium-verifying hybrid authentication; a Microsoft account for Clankie remains unnecessary. This does not prove a live friend session or Discord call. The local manual conformance script verifies the motor independently through Paper RCON; ordinary CI never starts a world.

Host Clankie's own server

Ask Clankie to set up a Minecraft server for you in Discord. Choose this computer, an existing AWS instance, or a server you already own; tell him who will play and which room should receive the invite. An owner/admin approves setup and friend enrollment. On this computer, Clankie supplies the playit claim link for browser approval and completes it without anyone opening a terminal. AWS needs the provisioning described below; choosing it does not create an instance. Friends request enrollment under their own Discord identities, then join through the premium or one-time-code path below.

Hosting stays off by default: ask to play, then let the empty-server and maximum-uptime controls stop it. Local play uses the computer's electricity and network. AWS estimates must use the selected instance's current regional rate: a played hour plus 15 empty minutes is 1.25 instance-hours, before boot time, public IPv4/transfer/CPU-credit charges and ongoing EBS/snapshot storage. The roughly $10/month alert is not a hard cap. No live hourly cost is established here.

The Minecraft integration owns a pinned Paper 1.21.4 build 232 server, Java process, private RCON, world backups and playit agent. Clankie's service owns Discord authority, username bindings, auditing, destination policy and the one play lease. The integration's hosting port separates the local Mac provider from the optional AWS EC2 provider. Neither starts a server during catalog or status reads.

The operator CLI/TUI is the manual path:

clankie minecraft host configure
clankie minecraft host start
clankie minecraft host status
clankie minecraft host admin '{"operation":"list"}'
clankie minecraft host admin '{"operation":"gamerule","rule":"keepInventory","value":true}'
clankie minecraft host backup
clankie minecraft host stop

Java 21 must be installed. The manager discovers an explicit Java path, JAVA_HOME, Homebrew's Java 21 or java on PATH. Artifacts are downloaded only for requested setup/start and verified against pinned checksums. James approved the local server EULA on 2026-10-04. Server settings and world data live under Clankie's data directory, in minecraft-host/; the standalone integration accepts --data-dir. Broker credentials stay in the canonical credential store. Never copy its private server.properties, plugin databases or console logs into chat.

host configure JSON changes integration-owned settings while stopped. Available fields are gamePort, rconPort, java (an absolute Java 21 path), memoryMiB, backupIntervalMs, backupRetention, idleTimeoutMs and maxUptimeMs. Defaults are game/RCON 25684/25685, 1024 MiB, daily backups retained for seven runs, 15 minutes empty-server timeout and 6 hours maximum requested-run uptime. Idle timeout cannot exceed 15 minutes. Empty-server shutdown saves and backs up before stopping; the uptime limit also applies while players are present. Crash restarts use backoff and retain the original run deadline. An idle/watchdog stop also stops the tunnel. A bot still connected counts as a player; maximum uptime prevents it keeping the server alive indefinitely.

AWS hosting and cost controls

AWS hosting manages one pre-provisioned EC2 instance through Systems Manager (SSM). Provisioning is an operator task; gameplay tools cannot create instances, change IAM or increase spending limits. The controller needs AWS CLI v2 and the Session Manager plugin. The product uses its own scoped broker credential, never the operator's administrative SSO profile. SSH and public RCON are unnecessary. Preserve an existing volume with a snapshot before modifying an existing server; an x86 instance cannot be resized directly to an ARM/Graviton instance type.

Checkout provisioning helpers live in integrations/minecraft-mcp/scripts/aws/. They require explicit account/instance identifiers and verify the target before changes; deployment finishes with EC2 stopped. Cold Paper startup can take several minutes on a small instance; the AWS guest permits up to eight minutes of Java startup while retaining its independent boot and uptime limits.

Select the provider while the existing host is stopped. The operator supplies the account and instance identifiers from provisioning; these are not model inputs or credentials:

clankie minecraft host configure '{"backend":{"kind":"aws-ec2","accountId":"YOUR_ACCOUNT_ID","instanceId":"YOUR_INSTANCE_ID","region":"us-east-1"}}'
clankie minecraft host configure '{"backend":{"kind":"local"}}'

Clankie's bot reaches the guest's loopback Paper port through a scoped SSM port forward, preserving the bot's source restriction and the ordinary shared play lease. Friend invitations use the public address. Host control uses a bounded custom SSM document; secret-bearing replies are encrypted to the requesting adapter rather than recorded as plaintext in SSM command history.

The instance stays stopped until someone requests play. Its public IP/DNS may change on every start; use the current ready-state invite, not a saved address. No Elastic IP or playit tunnel is required. Public TCP ingress must preserve the real client address through a trusted guest proxy; Paper and RCON remain bound to loopback. The proxy opens only after authentication readiness and closes before server transitions. Do not expose Paper's PROXY-enabled listener directly to the internet: a client could forge its source address.

Cost protection has separate failure boundaries:

  • A guest watcher checks actual player occupancy and saves, backs up and shuts down after 15 empty minutes. It runs independently of Clankie's service; a failed backup must not prevent shutdown.
  • A maximum-uptime limit bounds even occupied or unhealthy runs. A guest deadline survives controller failure; the service also checks the requested run. The supplied systemd timer powers off at six hours after boot regardless of a longer configured application timeout.
  • A CloudWatch low-CPU alarm provides an additional EC2 stop action. CPU is only a heuristic: low CPU does not prove there are no players, and busy idle software can avoid its threshold.
  • A Minecraft-tagged monthly budget alerts the operator around $10. A budget alert is not a hard spending cap. Stopped instances still incur EBS and snapshot storage charges, and active instances may incur public IPv4, transfer and CPU-credit charges. Activate the resource tag for cost allocation before relying on the filtered budget; resource tags alone do not enable billing allocation. See AWS cost allocation tags.

A stopped Paper process is not proof that EC2 stopped. Verify the instance state through EC2 after every manual test, including failed starts and guardrail probes. Live acceptance must separately establish the guest idle stop with the controller absent, the uptime deadline, the CloudWatch stop action, budget configuration, a premium human join and the bot join. Unit tests and an installed alarm alone cannot establish those outcomes. Resource IDs, private account details and live cost measurements belong in the operator's private provisioning record.

Public tunnel and invites

Clankie can start a claim and send the owner its browser approval link. The manual equivalent provisions the pinned playit agent and begins a claim:

clankie minecraft host tunnel claim
clankie minecraft host tunnel status  # Repeat while preparing; pending includes the URL.
# Approve that URL in your browser; the integration completes it automatically.
clankie minecraft host tunnel status

Claim returns quickly with preparing; its background build survives the request. Status reports its phase and the approval URL when ready. The integration calls playit every three seconds, exchanges browser approval, and stores the permanent agent key in the broker even after the CLI exits. complete also reads status. Expired/rejected claims need a new claim. On macOS, playit has no official binary asset for the selected version: setup compiles pinned 0.17.1 source with its locked Cargo dependencies, so Cargo is required. Future starts use the verified cached executable. No router forwarding is needed. Public address and genuine remote connectivity remain unverified until an account claim and remote join.

Claim completion authenticates the agent; it does not confirm tunnel allocation. Start launches the pinned agent before requesting its first tunnel, allowing playit to register its supported version and configuration. Initial registration may take a short time. A persistent playit-agent-version-too-old means playit has not accepted that agent version; playit-api-invalid-request reports an integration/API compatibility failure. Neither code proves that a paid plan is required. clankie minecraft host status reports a safe tunnel.error code when startup fails. playit-email-verification-required means the owner must verify their playit account email, then retry clankie minecraft host start. Failed allocation is reconciled on the next start against the agent's tunnel list. A confirmed rejection permits another create attempt; an uncertain result can adopt a matching tunnel but remains playit-tunnel-allocation-pending while none is visible. Do not delete its allocation marker to force a retry.

Ask Clankie for an invite in the Discord room where you want it. He posts the public Minecraft address/version there, with the two login paths below. The public tunnel carries only the game port, uses mandatory PROXY V2 forwarding, and never exposes RCON. A missing claim, unsafe tunnel configuration or failed auth readiness refuses a usable invite. Tunnel status confirms its supervised agent/configuration; it does not by itself prove end-to-end connectivity.

Friends and authentication

Premium friends ask Clankie to whitelist their usual Minecraft name and join with their normal Java launcher. Premium classification is checked against Mojang and persisted in FastLogin before admission; those names require real Mojang session authentication, including during a lookup outage. Approved enrollment also prepares and verifies the premium name's AuthMe account before whitelist admission. Premium friends receive no login code and do not self-register. An AuthMe registration prompt for an approved premium name is a server provisioning failure to resolve through the approved enrollment flow. Startup repairs missing AuthMe accounts for previously approved premium names already in this server's whitelist, without enrolling or whitelisting new names. FastLogin keeps premiumUuid: false to preserve the world's existing player identity; Mojang session verification still authenticates premium players. Managed AuthMe keeps settings.useAsyncTasks: true for FastLogin's asynchronous automatic login hook, while player self-registration stays disabled.

Nonpremium friends ask in Discord using their Minecraft name. Clankie records the authenticated requester, and a designated owner/admin approves that recorded request. He DMs a random one-time code; enter /login <code> after joining. The code expires after five minutes and rotates after authenticated login. For later joins, request a fresh code in Discord; an owner/admin approves the renewal request. In-game self-registration and IP/session remembered login are disabled. A failed or uncertain DM never exposes the code publicly or silently reissues it; disabled DMs need resolving first.

Username ownership is case-insensitively bound to the Discord requester. In-game names/chat cannot authorize hosting actions. An already approved Discord-bound friend may request an on-demand start; this standing play permission grants no other administration. Server administration requires Clankie's configured Discord owner or an individually designated machine operator; a trusted guild/channel grant alone is insufficient. Commands cover whitelist, kick/ban/pardon, typed gamerules, time/weather/gamemode, say/tell and player list. There is no player op or arbitrary RCON command tool. All core requests are audited in minecraft-host/admin-audit.jsonl without secrets.

Clankie automatically gets the reserved clankie-hosted approved profile when the server is ready. His account is ClankieLocal26, because Clankie is a registered premium name. His bot joins through loopback, supplies a trusted local PROXY header and logs in internally from the broker. Public forwarded sources cannot log in as that account, even with its password. AuthMe rejects a restricted source after a brief unauthenticated spawn; its movement/chat and inventory restrictions stay enabled. His ordinary game-chat tools never carry the login password. Playing still requires the existing shared play lease.

The pinned plugin stack is FastLogin, ProtocolLib 5.4.0, AuthMe 5.6.0 and ViaVersion 5.12.0. Supported Java clients are 1.21.4–1.21.11 and 26.1–26.3 (including the supported patch versions listed in status). Invites state that list; the server, bot and viewer remain on 1.21.4. Older clients need additional translation and are not advertised. Plugin startup or provisioning failures keep auth readiness false. FastLogin's lookup-error defaults alone are insufficient; the persisted premium marker, disabled in-game registration and mandatory original-IP forwarding are part of the hosted boundary. Local tests established these paths; a premium human join, actual public source-IP forwarding and Discord code delivery still need live acceptance. Local subsystem tests do not prove those external paths.

Join a server you already own

Ask Clankie to add an approved profile using its address, port, Java version and a non-premium bot username. Public destinations require explicit approval; Clankie cannot use an online-mode-only server without a premium account. Existing external profiles support offline protocol login, with no external AuthMe password flow. Keep a plain offline server private: a whitelist alone does not prevent impersonating a whitelisted name.

For the same easy hybrid login as Clankie's hosted world, use the managed local or AWS backend. Its first start installs the pinned plugins and generates the whitelist, premium-verification, restricted bot login and proxy configuration; follow the hosting and friend enrollment steps above. Merely installing AuthMe, FastLogin and ProtocolLib on another server does not connect Discord codes or Clankie's broker login. Back up an existing world before an owner-approved migration; automatic world import and arbitrary external hybrid-server onboarding are not implemented.

Configure and join

Run these from the source checkout or an installed release containing the motor:

clankie minecraft configure local 127.0.0.1 --port 25565 --version 1.21.4 --username Clankie
clankie minecraft join local
clankie minecraft status
clankie minecraft chat Hello from Clankie
clankie minecraft follow FriendName 2
clankie minecraft cancel
clankie minecraft leave

/minecraft offers the same commands in the console. --conversation ID binds CLI operations to an existing conversation; the console uses its selected conversation. Configure settings with the CLI or operator API, rather than editing the settings file. configure without arguments shows profiles and allowlists; configure remove PROFILE removes a profile.

Profiles hold an id/name, host/port, Java version, username and explicit offline auth. Model tools see only profile ids/names. DNS and Minecraft SRV targets are resolved and checked before connection; the motor dials the checked literal address. Loopback and private network addresses are allowed. Public targets require configure allow-public HOST [PORT] for the resolved target or its literal address; configure revoke-public HOST [PORT] removes that grant. An SRV redirect to a public target needs approval for that target and port.

Actions and ownership

goto X Y Z [TOLERANCE], dig X Y Z, place X Y Z ITEM, craft ITEM COUNT, follow PLAYER [DISTANCE], and chat TEXT return an action handle promptly. action JSON accepts the domain action shape, including build with placements. Use action-status ACTION to inspect settlement and evidence. Crafting is currently limited to recipes available without a crafting table.

cancel [ACTION] clears navigation and controls and stops active digging. pause stops current work and retains the session; resume admits fresh actions. An already-sent placement or craft can remain uncertain after cancellation. Completion and verified effects are separate: only fresh server packets can verify a block or inventory postcondition. Optimistic Mineflayer cache updates and local completion text do not prove success. Unknown evidence stays unknown.

Minecraft holds the same play lease as Pokémon, from before join through a confirmed disconnect of the exact bot session/generation. Other conversations receive a busy response. Restart, connection loss or a timeout alone never release the lease. clankie body recover play attempts exact reconciliation; an unmatched or missing motor cannot establish that the old bot disconnected. Raw MCP, worker and fleet calls cannot bypass the service-owned Minecraft tools. World chat and signs are untrusted observations and grant no machine authority.

Watch

The motor serves prismarine-viewer's browser client on loopback and screenshots it with headless Chromium. Chrome is an external dependency, as for browsing; no native canvas or GL addon is needed. Set CLANKIE_MINECRAFT_CHROMIUM to an executable path when Chrome is installed elsewhere. Frames are PNGs at 320×180, bounded to 256 KiB. The service publishes them through the existing brokered Activity producer, with session checks and no overlapping capture requests. Disconnect closes the producer so the viewer cannot retain a stale live frame. Capture checks the motor every 500 ms only while the service owns a Minecraft stay, including unresolved recovery. Configured destinations alone never cause periodic MCP status calls; a new join resumes capture within the next 500 ms tick.

In an admitted Discord voice channel, /clankie watch surface:Minecraft selects the Minecraft Activity. It uses DISCORD_ACTIVITY_APPLICATION_ID_MINECRAFT when set, otherwise the existing DISCORD_ACTIVITY_APPLICATION_ID_GBA. The producer credential and usual Activity setup are still required. Frame dimensions set the viewer's aspect ratio. This wiring requires a separate live Discord check; local PNG inspection alone does not establish continuous viewing in a call. The current 1.21.4 renderer is rough; inspected local frames include missing textures. It is suitable for the first automated view, pending live validation and visual refinement.

API and manual proof

Operator-authenticated GET /v1/minecraft reads status; POST /v1/minecraft dispatches the typed command (join, act, cancel, leave, etc.). GET/PUT /v1/minecraft/configuration reads or replaces the offline settings. Use x-clankie-conversation-id for an existing conversation; omitted selects the default console conversation. Endpoints never accept account credentials.

The owned adapter's README records the pinned upstream provenance, dependencies and manual RCON conformance command. ADR 0219 explains the body, evidence and viewing boundaries.

pnpm --filter @clankie/clankie minecraft:smoke --output DIRECTORY runs an isolated service and the real HTTP/CLI flow against the loopback Paper fixture in ~/dev/minecraft-spike, with a second scripted player and RCON evidence. It saves a report and three captured frames without changing owner settings or restarting the running service. --routes-only exercises the production Minecraft routes without the rest of the app's import graph; the report labels that narrower scope. Both modes are manual checks, outside CI and evals.