Craftless is automation infrastructure for real Minecraft Java clients, headless or visible. It runs or attaches to real clients, loads a small in-client driver, discovers the live runtime capability graph, and exposes generated local APIs for agents, tools, tests, and CI.
The product shape is intentionally thin: stable lifecycle control outside the client, generated per-client OpenAPI inside the live runtime, and adaptive consumers that discover before they invoke. Craftless should feel like Browserless-style infrastructure for Minecraft Java, not a hand-written gameplay SDK.
| Area | Current state |
|---|---|
| Runtime | Kotlin/JVM under com.minekube.craftless |
| Tooling | Pinned with mise; Bun only through mise exec -- bun |
| HTTP | Ktor Server and Ktor Client |
| CLI | Released craftless binary with install script and packaged driver-mod discovery |
| Distribution | CLI tar/zip, runtime Docker image, and reusable GitHub Action |
| API | Stable supervisor OpenAPI plus generated per-client OpenAPI |
| Gameplay surface | Runtime capability graph projection, not a static catalog |
| Events | SSE streams plus JSON-RPC-style HTTP control/query calls |
| Current Fabric lane | Verified for the compiled lane |
| Latest and older lanes | Latest/current 26.2 and representative older 1.20.6 packaged lanes are verified through create, attach, connect, generated OpenAPI, projections, SSE, JSON-RPC query/subscription, JSON-RPC invocation, and adaptive CLI invocation |
| Final gameplay evidence | Historical public API/CLI survival evidence exists; final completion still requires a refreshed run after usability and release gates close |
| Completion | Still active; see docs/project-completion-checklist.md |
Install the released CLI on Linux or macOS:
curl -fsSL https://raw.githubusercontent.com/minekube/craftless/main/install.sh | sh
craftless server start --port 8080 --workspace .craftlessInstall a specific release:
CRAFTLESS_VERSION=v0.1.2 \
CRAFTLESS_INSTALL_DIR="$HOME/.local/bin" \
sh -c "$(curl -fsSL https://raw.githubusercontent.com/minekube/craftless/main/install.sh)"The installer writes the launcher symlink to $HOME/.local/bin by default.
Set CRAFTLESS_INSTALL_DIR to use another directory.
The installed CLI distribution carries
mods/craftless-driver-fabric.jar, the representative older
mods/fabric-1.20.6/craftless-driver-fabric.jar, and the latest/current
mods/fabric-26.2/craftless-driver-fabric-official.jar lane. craftless server start auto-discovers the packaged driver manifest unless
CRAFTLESS_FABRIC_DRIVER_MOD is set explicitly, so daemon-managed Fabric
clients do not need extra driver-mod configuration.
Check the CLI:
craftless --helpThe CLI has a small stable core for daemon lifecycle, client lifecycle, cache, runtime, discovery, output, and generic invocation. Gameplay commands and help come from each live client's generated OpenAPI document.
Run the runtime image:
docker run --rm -p 8080:8080 \
-v "$PWD/.craftless:/var/lib/craftless" \
ghcr.io/minekube/craftless:latestThe image contains the packaged Craftless CLI/runtime and required OS libraries. Minecraft artifacts are downloaded into the workspace at runtime; client/server artifacts are resolved into the mounted workspace and are not baked into the image.
Use Craftless from another workflow:
jobs:
minecraft:
runs-on: ubuntu-latest
steps:
- uses: minekube/craftless/.github/actions/setup-craftless@v0.1.2
id: craftless
with:
start: "true"
workspace: .craftless
- run: curl -fsSL "${{ steps.craftless.outputs.api-url }}/openapi.json"The action installs the released CLI distribution and can optionally start
craftless server start for the job. Fabric driver-mod discovery follows the
same installed-distribution path as the install script.
Craftless keeps the API layers separate:
- Supervisor API: stable lifecycle, workspaces, clients, cache preparation, Java runtime resolution, files, events, and per-client spec discovery.
- Live generated API: one
GET /clients/{id}/openapi.jsondocument per running client, reflecting that client's version, loader, driver runtime, installed mods, registries, server features, permissions, screens, inventory, entities, resources, actions, schemas, availability, and fingerprints. - Runtime capability graph: internal graph of discovered resources, operations, handles, schemas, availability, events, fingerprints, and source evidence.
- Fabric discovery and projection: client-thread probes inspect the real Minecraft runtime and project Craftless-owned graph nodes.
- Generic invocation:
POST /clients/{id}:rundispatches graph-projected operations through private client-thread adapters. - Live streams: Server-Sent Events carry lifecycle, runtime, capability, and gameplay observations; JSON-RPC-style HTTP calls handle invoke, subscribe, unsubscribe, and query control.
- Adaptive consumers: the CLI, agent skills, exported tools, and future generated clients fetch live specs instead of shipping gameplay catalogs.
The HMC bridge code is lifecycle/launch evidence only and is not a gameplay adapter. It is not the product path for chat, movement, inventory, world, entity, screen, or building behavior. Gameplay breadth belongs in the Fabric runtime capability graph and generated per-client OpenAPI.
Start the supervisor:
craftless server start --port 8080 --workspace .craftlessSet the API URL:
CRAFTLESS=http://127.0.0.1:8080Create a daemon-managed client session:
curl -sS "$CRAFTLESS/clients" \
-H 'content-type: application/json' \
-d '{
"id": "alice",
"version": "latest-release",
"loader": "FABRIC",
"profile": { "kind": "OFFLINE", "name": "Alice" }
}'Connect it to a server:
curl -sS "$CRAFTLESS/clients/alice:connect" \
-H 'content-type: application/json' \
-d '{"host":"localhost","port":25565}'Discover the live contract before invoking actions:
curl -sS "$CRAFTLESS/clients/alice/openapi.json"
curl -sS "$CRAFTLESS/clients/alice/actions"
curl -sS "$CRAFTLESS/clients/alice/resources"Invoke an action only after the generated live API advertises it:
curl -sS "$CRAFTLESS/clients/alice:run" \
-H 'content-type: application/json' \
-d '{"action":"player.chat","args":{"message":"hello from Craftless"}}'Stream live events:
curl -N "$CRAFTLESS/clients/alice/events:stream"Use the adaptive CLI against the same generated metadata:
craftless clients alice actions --api "$CRAFTLESS"
craftless clients alice resources --api "$CRAFTLESS"
craftless clients alice run player.chat --api "$CRAFTLESS" --arg message="hello from Craftless"
craftless clients alice actions --help --api "$CRAFTLESS"
craftless clients alice player chat --help --api "$CRAFTLESS"Generated aliases such as craftless clients alice player chat are derived
from the live OpenAPI document. They are not source-maintained gameplay
commands.
Agents should behave like external Craftless users:
- Fetch the supervisor spec with
GET /openapi.json. - Create or select a client.
- Fetch
GET /clients/{id}/openapi.json. - Treat
x-craftless-actions,x-craftless-resources, route metadata, schemas, availability, and fingerprints in that document as the authority. - Use
/clients/{id}/actionsand/clients/{id}/resourcesas projection evidence, not as an independent catalog. - Subscribe to
GET /clients/{id}/events:streambefore state-changing work. - Invoke only advertised actions through
POST /clients/{id}:run, generated alias routes, or the adaptive CLI.
The repo-local skill
.agents/skills/craftless-public-gameplay-agent/SKILL.md captures this
workflow for agents. Final gameplay evidence must include the connected
OpenAPI document, action/resource projections, SSE or JSONL event capture,
public action log, and public inventory/world/entity observations. Do not use
server-provisioned inventory, driver internals, Fabric internals, or
hard-coded scenario actions as product proof.
Craftless can prepare repeatable launch/cache state before running clients:
craftless cache prepare \
--mc latest-release \
--loader fabric \
--workspace .craftlessCache preparation resolves Minecraft metadata, the selected client jar,
libraries, asset objects, native libraries, Fabric loader metadata, Java
runtime requirements, launch arguments, classpath handles, logging metadata,
asset indexes, and file layout inside a Craftless-owned workspace.
Use latest-release or latest-snapshot for moving Mojang aliases, or a
concrete Minecraft version id when a run must be pinned.
Java selection is a product runtime concern, separate from repository build tooling. Craftless can evaluate configured, managed, mise, and system runtime providers against Minecraft version requirements.
Verified surfaces:
- stable supervisor OpenAPI at
GET /openapi.json; - generated per-client OpenAPI at
GET /clients/{id}/openapi.json; - graph-projected actions, resources, handles, schemas, availability, fingerprints, generated aliases, and event metadata;
- generic action invocation through
POST /clients/{id}:run; - SSE event streams plus JSON-RPC-style HTTP control/query calls;
- adaptive CLI discovery, generated help, generated aliases, action invocation, event watching, tools export, and OpenAPI cache revalidation;
- cache preparation for Minecraft/Fabric metadata, libraries, assets, natives, Java runtime files, launch arguments, classpaths, logging, and instance file layout;
- release workflow, install script, Docker runtime image, packaged CLI distribution with the Fabric driver mod, and reusable GitHub Action;
- packaged latest/current
26.2and representative older1.20.6product lanes with generated OpenAPI/projection/SSE/JSON-RPC/CLI invocation evidence; - bridge lifecycle-only behavior after removal of bridge-owned gameplay descriptors and helpers.
Historical final gameplay evidence uses generated public APIs only. The
external public-agent path fetched generated OpenAPI/actions/resources,
consumed SSE evidence, collected materials, crafted and equipped a
Wooden Sword, found Cows through entity.query, killed a Cow through
entity.attack, and observed Raw Beef, Leather, and the Cow with
alive:false. That run completed without server-provisioned inventory or
static survival macro evidence. Final completion still requires a refreshed
public API/CLI gameplay run after external-user usability and final local
release gates close.
Still open before the broader project can be called complete:
- broaden Fabric discovery/projection across more Minecraft versions, mods, registries, screens, world/entity/inventory resources, permissions, and installed runtime affordances;
- turn future gameplay breadth into generic discovery/projection instead of transitional bootstrap bindings;
- strengthen navigation/pathfinding and building evidence through generated public API/CLI/SSE only;
- keep the verified latest/current and representative older lanes current while adding additional Fabric client lanes only when cache preparation, Java/runtime selection, loader/API resolution, launch metadata, compatibility matrix, packaged driver manifests, attach evidence, and generated API/CLI smoke evidence prove them;
- close the active external-user usability gate with fresh install, Docker, adaptive CLI, GitHub Action, agent-skill, and docs evidence before final release and gameplay gates.
Craftless is not considered complete until the active checklist proves every remaining generic-discovery, multi-version, transport, CLI, docs, and gameplay gate with current Codex-verifiable evidence.
| Area | Craftless | Mineflayer | Baritone | Prism Launcher |
|---|---|---|---|---|
| Runs the real Minecraft Java client | Yes | No, protocol bot | Yes | Yes |
| Local OpenAPI control plane | Yes | No | No | No |
| Live per-client generated API | Yes | No | No | No |
| Runtime discovery from version/mod/server state | Core design | Protocol data oriented | In-client pathing state | Launcher/profile state |
| External agent and CI usage | Primary use case | Script/library use | Mod/API use | Launch management |
| Pathfinding maturity | Growing | Mature bot movement ecosystem | Mature pathfinding | Not a pathfinder |
| Public gameplay surface | Generated Craftless actions/resources | Library API | Java/mod commands/API | None |
| Best fit | Real-client automation infrastructure | Fast protocol bot scripts | In-game navigation/pathing | Client installation and launch UX |
Craftless is not trying to replace Mineflayer, Baritone, or Prism Launcher. The goal is a Browserless-style runtime for real Minecraft clients where agents can discover the live API and operate through stable local contracts.
The source of truth is:
Next work focuses on:
- closing CL-05 with fresh install, Docker runtime, adaptive CLI, GitHub Action, README, and agent skill evidence;
- running final local release gates after CL-05 closes;
- replaying final honest survival gameplay through public OpenAPI/CLI/SSE only;
- keeping future gameplay breadth generated from discovery/projection rather than descriptor/binding catalog growth.
Use pinned tools through mise:
mise install
mise run lint
mise run architecture-check
mise run ciFocused commands:
mise exec -- gradle test
mise exec -- bun test playwright
mise run package-cli
mise run ci-craftless-smokeci-craftless-smoke runs the packaged CLI distribution, starts
craftless server start, and probes the live supervisor API.
Docs-only edits must at least pass:
git diff --checkOpt-in real Minecraft checks can download artifacts and launch server/client processes:
CRAFTLESS_LOCAL_SERVER_SMOKE=1 mise exec -- gradle :testkit:localMinecraftServerSmoke
CRAFTLESS_FABRIC_CLIENT_SMOKE=1 mise exec -- gradle :driver-fabric:fabricClientSmoke
CRAFTLESS_FINAL_GAMEPLAY=1 mise exec -- gradle :driver-fabric:fabricFinalGameplayThe final gameplay task is a completion gate, not a normal CI check.
Historical specs, plans, and evidence live under docs/superpowers/.
