HTTP API
The Kraft server serves its board, and the JSON API behind it, on one port
(127.0.0.1:8765 by default). The kraft command and the MCP server are
clients of that API.
Stable routes
Only two routes are meant for other programs, and only these keep their shape between minor releases. See Versioning and stability.
| Route | Use |
|---|---|
POST /api/triggers | File a work item from a webhook or script. See Inbound triggers. |
GET /api/health | Check that the server is up. Answers status (ok or degraded), the reasons it is degraded, and which instance this is (run_dir, pid, bind, port). Needs no login. |
Every other route under /api/, and the /api/ws/events WebSocket, exists
for the board and can change in any release. For those, prefer the kraft
command with --json, which is stable.
POST /api/work-items, the board's create route, files the item paused unless
the body sets autostart: true, like kraft item create without
--autostart. A body with no chain_template gets the repo's
default_chain_template. Every repo path you send must be absolute: the
server would read a relative one against its own directory, not yours.
POST /api/repos, POST /api/work-items and POST /api/triggers refuse it
with a 422, and PATCH or DELETE /api/repos?path= answer 404.
The schema
FastAPI generates a schema of every route:
| Path | What it serves |
|---|---|
/openapi.json | The OpenAPI schema, as JSON. |
/docs | Swagger UI for that schema. |
/redoc | ReDoc for that schema. |
curl -s http://127.0.0.1:8765/openapi.json | jq '.paths | keys'
These three paths need no login. Open /docs or /redoc in a browser to read
the API there. Both pages load their scripts from a public CDN, so on a machine
without internet access, load /openapi.json into your own OpenAPI viewer.
Who may call
| Caller | What it needs |
|---|---|
| A process on the same machine, while Kraft is bound to loopback | Nothing. |
| Anyone, once Kraft is bound off loopback | A browser session from the login page, or the MCP bearer token in $KRAFT_HOME/run/mcp-token, sent as Authorization: Bearer <token>. |
| A trigger sender, once Kraft is bound off loopback | For POST /api/triggers only, the trigger token in $KRAFT_HOME/run/trigger-token, sent the same way. |
| A remote caller while no password is set | Nothing works. Kraft answers 403. |
A request without valid credentials gets 401. A browser request whose Host
is not an allowed name, or a cross-site write, gets 403. The MCP bearer token is
a full-access credential. See Security for the whole
model, and Remote access to set a password.