Build a kit
Build your own worker kit.
A kit is one job written down once: the instructions, the apps and the exact access each one gets, and when it runs. Describe the job to the AI assistant you already use and it writes, checks and publishes the kit for you, or take the same six steps yourself over the API or the wk CLI.
Three ways in
Pick the one you already work in.
Every route ends in the same validators and the same directory, so a kit built one way is managed any other way.
- With your AI assistant
claude mcp add --transport http workerkit https://mcp.workerkit.ai/workers - Over the API
curl "https://api.workerkit.ai/api/directory/mcp/authoring/guide?section=index" - From the terminal
wk kit publish --file kit.json --private
- With your AI assistant Claude, ChatGPT, Cursor or any MCP client builds the kit from a plain-words request, then validates it, publishes it private and test-runs it. No code, no JSON by hand.
- Over the API The same six steps as plain HTTPS requests, for a platform or a script of your own. The guide and the vocabulary need no key.
- From the terminal The open-source wk CLI validates before every publish and speaks JSON for scripts and agents, from the guide to a running worker.
The anatomy
What a kit carries.
A kit is copied at install into a brand-new worker, and never linked to it afterwards.
| Part | What it holds | On the installed worker |
|---|---|---|
| The listing | Name, the one-sentence job, a short description and 1 to 8 categories. | The kit page and the directory card. Name and job sentence are the only searched fields. |
| The instructions | How the job is done, the start and end commands, when the worker is relevant, and up to 20 reference resources it fetches on demand. | The worker's instructions, rendered once at install. |
| The access | Each app, the exact operations and fields it grants, or an open app slot the installer fills. | The worker's permissions. Only the stance travels, never your own rules or accounts. |
| The cadence | Schedules, inbound webhook triggers and usage windows. | Schedules and triggers on the new worker, in its own time zone. |
| Memory setup | Up to 10 questions asked at install. | The first rules and facts in its memory. |
| Quality criteria | Optional content.evaluationSpec: public deterministic checks and model judgments reviewed with the creator. | Criteria copy at install; all three quality/learning gates start off. Review criteria, test on a previous run, and activate from Continuous Learning on the installed worker. |
- Language. Instructions an agent works through: research, writing, investigation, tool use. The default.
- Decision. A typed judgment on every item, with no agent loop: triage, sorting, scoring, labelling, filtering.
- Hybrid. A classification picks a bounded batch, and one language agent acts on it in the same run.
- Action. Selected app tools and no model: a caller invokes one exact operation per call.
The words are defined at worker kit and private kit. Decision and Action workers also have a shortcut that skips the kit file: see decision workers and Action workers.
Six steps
The same six steps on every surface.
- 01
Pick the kind and the one job.
Language, decision, hybrid or Action, decided from the job before anything is written. A second, unrelated job is a second kit.
- 02
Read the guide and the live vocabulary.
The authoring guide, the app-by-app tool explorer and the permission vocabulary are public and need no account. Copy every key from the vocabulary: there is no "all" shorthand, and an unknown key is a rejection.
- 03
Write the kit as one JSON document.
The listing, the instructions, the apps with the exact operations each one grants, the schedule, and a plain line on why each app is there. No real person, mailbox, channel or file: the installer supplies those.
- 04
Validate it.
The dry run judges the exact body you will publish against every gate at once and returns the permission manifest that would ship. Repeat until it answers canPublish.
- 05
Publish it private, install it, run it.
A private kit installs only on your own account. Installing creates the worker, deploying puts it on the managed runtime, and one run shows whether the instructions and the access hold.
- 06
Keep improving it privately.
Public publishing and promotion are temporarily paused. Replace it with visibility private to keep testing and improving it within your account.
Private first is the rule, not a suggestion: a private kit is also how a worker is built from scratch, because every permission an agent asks for passes the same review a directory listing does.
One complete kit
What the file looks like.
A language kit that writes a standup digest, read-only. The same body is the MCP arguments, the API request and the CLI file.
- kit.json
{ "name": "Standup Digest", "jobSentence": "Turns yesterday's task-board movement into one standup digest before the daily.", "description": "The standup nobody has to prepare.\n\n- Reads yesterday's task-board movement\n- Writes what shipped, what is moving and what is stuck\n- Runs every morning at 8:00, unattended\n- Read-only: never creates, edits or comments on a task", "categorySlugs": [ "summarization", "reporting", "engineering" ], "visibility": "private", "content": { "instructionContent": "You are [worker-name], a standup digest reporter. Each morning, turn yesterday's board movement into one short digest the team can read in the first minute of the daily.\n\nRuns are unattended: the morning schedule starts you and nobody is at a keyboard. Never ask a question and wait.\n\n## Workflow: Morning standup digest\n1. Collect the items that changed status, were completed, or passed their due date since the last run. Group them by board.\n2. For each item that is stuck, read its comments for the reason and for who can unblock it.\n\n## Output\n- Shipped: what finished, each with its owner.\n- Moving: the most significant items in progress, one line each.\n- Stuck: each blocked item, what it blocks, and who can unblock it.\nKeep the whole digest under 300 words.\n\n## Rules\n- Read-only: never create, edit or comment on a task.\n- Report only what the boards show, and name the board for every claim.\n- Blocker: if no task board is connected there is no digest. Report that and stop.", "whenToUse": "Runs unattended each morning to write the standup digest from yesterday's board activity. Not for a weekly stakeholder report, and not for triaging new work.", "endCommand": "Close with the Stuck section restated, one line each. That is the part the standup exists for.", "endCommandDescription": "Call after the digest is written, to restate the blocked items so they are the last thing the reader sees.", "apps": [ { "code": "tasks", "operations": [ "view_boards", "view_items", "view_comments" ], "visibleFields": [ "name", "status", "assignee", "due_date", "priority", "labels", "description", "comments" ], "providers": [ "MONDAY", "ASANA", "JIRA_CLOUD", "LINEAR", "CLICKUP", "NOTION" ] } ], "schedules": [ { "title": "Morning standup digest", "scheduleType": "DailyAtTime", "timeOfDayMinutesUtc": 480, "daysOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "isEnabled": true } ] }, "appDescriptions": [ { "code": "tasks", "description": "Reads yesterday's board movement, and the comments behind a blocked task. Read-only: it never creates, edits or comments on a task." } ] }
timeOfDayMinutesUtc is a minute of the installed worker's own day despite its name: 480 is 8:00 AM wherever the installer lives.
Add publisherName to the account's first publish only. The guide's example section carries a longer kit with a reference resource and an open app slot, and a decision kit beside it.
For agents
The skill file.
The procedure, the rules a publish enforces and the checks to run before one, written for an agent to keep: https://workerkit.ai/build/SKILL.md.
- Claude Code, for yourself (use .claude/skills/ inside a repository to share it with the team)
mkdir -p ~/.claude/skills/workerkit-kit-authoring curl -fsSL https://workerkit.ai/build/SKILL.md -o ~/.claude/skills/workerkit-kit-authoring/SKILL.md
On claude.ai, upload a ZIP containing workerkit-kit-authoring/SKILL.md under Customize, then Skills. An assistant that keeps no skills can read https://workerkit.ai/build/SKILL.md at the start of any session that builds a kit: one request, always current.
Already tuned one
Publish a worker you already have.
A worker you have already tuned becomes a kit in one call: publish with its sourceWorkerId instead of content. Its instructions, permissions, schedules and triggers become the kit. Rule values never travel, only that rules exist, so nothing of your own accounts reaches an installer.
The worker's id is the last part of its page address, workerkit.ai/workers/<workerId>, and every worker list returns it. Publish private first, as with any kit. A worker installed from a protected kit cannot be published: its text belongs to that kit's publisher.
- The body, on any surface
{ "name": "Invoice Follow-Up", "jobSentence": "Chases overdue invoices with a polite reminder and logs every reply.", "categorySlugs": [ "follow-ups", "finance" ], "sourceWorkerId": "<workerId>", "visibility": "private" }
Ask your assistant to "publish my worker as a private kit", send the body to the API, or save it as kit.json for the CLI.
The bar
What every publish enforces.
Each one is a rejection with the reason named, never a silent change to your kit.
| Rule | What happens |
|---|---|
| Keys come from the vocabulary | Every operation, field, provider and category is checked against the live vocabulary under that app. An unknown key is rejected, never ignored. |
| apps or appCodes, never both | appCodes grants each app at its safe default; apps names the exact operations, which is the better choice. An open app slot (categorySlots) composes with either, and an app offered in a slot is never also pinned. |
| Labels must resolve | [worker-name], [required: Field name] and the app labels such as [collaboration-app] resolve at install. A near miss like [chat-app] or [required Company] is a rejection. |
| No outside addresses or secrets | The scanner blocks text that sends data to a URL or a mailto address, and embedded secrets. A public publish also runs an external scan, and it fails closed. |
| Nothing real about anyone | No real person, mailbox, board, channel, file or customer. A value the worker cannot work without becomes an install-form field with a [required: ...] label. |
| One model type | A language kit carries instructions, a decision kit a routing table, a hybrid kit both, and an Action kit selected app tools with nothing a model would read. |
| A reviewed acceptance standard | Use content.evaluationSpec for what counts as good work; read the live schema for supported checks. Missing evidence is unknown, not a pass. Criteria are public even on protected kits: exclude private examples, channel IDs and secrets. Kit updates do not overwrite installed worker criteria. |
| Worker slots are type-correct | Each alias unique and 1 to 20 lowercase characters, operations only from the slot's model type, and an Action slot naming 1 to 8 tools from action_worker_options. A worker UUID or key in a kit is rejected: the installer binds the worker. |
| A publisher name, once | The account's first publish carries publisherName, 3 to 80 characters and unique. Later publishes ignore it; rename through the publisher profile. |
| Caps | 1 to 8 categories, instructions up to 100,000 characters (aim under about 5,000 words), up to 25 schedules, 10 worker slots, 100 public kits per account. Private kits are unlimited. |
After it ships
Edit, unlist and delete, on any surface.
| Task | MCP tool | API | CLI |
|---|---|---|---|
| Your kits, with their moderation state | my_kits_list | GET /api/manage/kits/mine | wk kit mine |
| Edit in place: texts, permissions, categories | kit_update | PATCH /api/manage/kits/{slug} | wk kit update <slug> |
| Replace wholesale, or promote private to public | kit_replace | PUT /api/manage/kits/{slug} | wk kit replace <slug> |
| The security-scan report | kit_scan_get | GET /api/manage/kits/{slug}/scan | wk kit scan <slug> |
| Take it off the directory, reversibly | kit_unpublish, kit_relist | POST /api/manage/kits/{slug}/unpublish, /relist | wk kit unpublish <slug>, wk kit relist <slug> |
| Keep it for your account only | kit_make_private | POST /api/manage/kits/{slug}/make-private | wk kit make-private <slug> |
| Delete it for good | kit_delete | DELETE /api/manage/kits/{slug} | wk kit delete <slug> |
| Your publisher profile | publisher_get_mine, publisher_set | GET or PUT /api/manage/kits/publisher | wk publisher me, wk publisher set |
A kit is copied at install, never linked: editing, unlisting or deleting a listing leaves every worker already installed from it untouched. The slug of a public kit never changes, so its page, installs and stars stay with it through every edit.
Publishing for others, or for clients? For Publishers covers the page a public kit earns and the three ways a kit ships.