Schedule or webhook work
Set up a trigger that files a paused work item for you, from a cron schedule or from a webhook, and check that the item arrived. The fields and the HTTP contract are in Inbound triggers.
Before you start
- A repo connected with
kraft repo connect. - A running Kraft server.
Schedule a work item
- Add a
schedules:entry to$KRAFT_HOME/config/intake.yaml:config/intake.yamlschedules: - cron: "0 9 * * 1,2,3,4,5" # 9:00 UTC on weekdays repo: /path/to/repo chain: default title: "Weekday dependency check" description: "Filed by the 09:00 UTC weekday schedule" - Make the server read the file:
kraft admin reloadreloaded <N> template(s) and policy.yaml and intake.yaml
A file Kraft refused to read is named on arefused:line below it, and the running one is kept.
If you add the schedule in Settings › Auto-intake (Add schedule) instead of editing the file, you need no reload.
Kraft evaluates the schedule in UTC. The next matching minute files the item.
File a work item from a webhook
Post to /api/triggers from anything that can fire a webhook, such as CI or a
script. The body takes title, repo, and optionally chain and description.
Call it from the same machine
While Kraft is bound to 127.0.0.1 (the default), a call from the same machine
needs no login. Address Kraft as 127.0.0.1, localhost, or [::1]:
curl -s -X POST http://127.0.0.1:8765/api/triggers \
-H 'Content-Type: application/json' \
-d '{"title": "Dependency check", "repo": "/path/to/repo", "chain": "default"}'
Kraft answers 201 with the new work item as JSON, filed paused. Cut to the
fields that matter, the body reads:
{"id": "<work-item-id>", "title": "Dependency check", "status": "paused", "...": "..."}
Call it from another machine
After a non-loopback bind, every call needs the trigger token from
$KRAFT_HOME/run/trigger-token, including one from the same machine. Use the
address you reach Kraft at, and see Remote access
for how to bind:
curl -s -X POST https://<your-tunnel-hostname>/api/triggers \
-H "Authorization: Bearer $(cat ~/.kraft/run/trigger-token)" \
-H 'Content-Type: application/json' \
-d '{"title": "Dependency check", "repo": "/path/to/repo"}'
The trigger token is accepted only by POST /api/triggers, so it is the one to
store as a CI secret or give a webhook sender. Do not use run/mcp-token there:
it is a full-admin credential. See
Rotate the token for how to rotate either.
If you get 403 or 401
| Your call | What happens |
|---|---|
From the same machine, Kraft bound to loopback, addressed as 127.0.0.1, localhost or [::1] | It works with no credential. |
| Through a tunnel or reverse proxy, Kraft bound to loopback | 403 (unexpected Host), whatever the credential. |
| Kraft bound beyond loopback, with no trigger token | 401, even from the same machine. |
For a webhook that arrives through a tunnel or reverse proxy, follow
Put a proxy in front of Kraft.
Who may call lists every cause of a 403.
Check it worked
- For a schedule, wait for the next matching UTC minute, or test it right away:
set
cron: "* * * * *", reload, and do the checks below. Then restore the real expression and reload again, or the schedule files an item every minute. - List the paused items and look for the new one:
kraft view list --status=pausedID STATUS GATE NODE TITLE <work-item-id> paused - - Weekday dependency check
The item shows under Not started on the board, and itsSTATUSreadspaused. - Start it when you are ready: click its row on the board, then Start in the
side panel, or run
kraft item resume ID.
If nothing appears, check the server log for a skipped-trigger warning. It names the unconnected repo or the unknown chain.
Next steps
- Inbound triggers: the fields and status codes.
- Remote access: reach the server from another machine.
- intake.yaml: the rest of
intake.yaml.
Add a security review or a gate reviewer
Add the shipped security-review and gate-review skills to a chain of your own, since no shipped chain uses them.
Switch a task to another harness
Run some or all of a chain's agent tasks on Codex, Cursor, OpenCode, Gemini, Antigravity or Amp instead of Claude Code, and what changes when you do.