# Create recipes

> Define a recipe with YAML and a companion script, map inputs to command arguments, collect declared outputs, and distinguish generation from verified execution.

Source: https://kaitoi.io/docs/cli/create-recipes/
Section: Kaitoi CLI / Local services and recipes
Written for: Developers packaging a local tool for Runtime.
Prerequisites: Kaitoi Runtime installed; A local script and knowledge of its dependencies and input/output contract
Last reviewed: 2026-10-24

---

A recipe describes how Runtime installs and runs a tool and collects its
outputs. Schema v1 prefers YAML plus a companion Python `script_file`. Inline
`script` is legacy. The examples below match CLI **0.9.0** and can be saved as
two neighboring files.

## Start with a small explicit contract

Save this as `recipe.yaml`:

```yaml
schema_version: v1
name: hello-text
version: 1.0.0
description: Write a short message to a text file.
script_file: run.py
inputs:
  message:
    type: string
    default: Hello
    arg: --message
outputs:
  - name: text
    type: file
    path: outputs/result.txt
backends:
  local:
    gpu: false
```

Save its companion as `run.py`:

```python
import argparse
from pathlib import Path

parser = argparse.ArgumentParser()
parser.add_argument("--message", required=True)
args = parser.parse_args()
Path("outputs").mkdir(exist_ok=True)
Path("outputs/result.txt").write_text(args.message, encoding="utf-8")
```

Then validate, inspect, and run your authored recipe:

```bash
kaitoi runtime validate ./recipe.yaml
kaitoi runtime info ./recipe.yaml
kaitoi runtime run ./recipe.yaml --message "Hello from Runtime"
```

Validation checks the schema. Execution is the step that tests the actual
script, dependency environment, and output behavior.

## Map values all the way through


The message input maps to --message, which the script parses from argv. The
script runs in the package repository with empty stdin and writes
outputs/result.txt. Runtime collects that declared path into the text output.
There is no implicit JSON stdin or output-directory environment variable.

The same Hello string travels from message, through --message, into the file contents. The output name text identifies collected file paths, rather than replacing the text inside the file.

*Figure: A declared input reaches the script only through its argument mapping; outputs come from declared paths.*

Only inputs with an `arg` mapping become command arguments. A true boolean
includes its mapped flag; false omits it. The process runs with the package
repository as its working directory and empty stdin. Design the script for that
contract rather than expecting implicit JSON input.

Input types include string, integer, float, boolean, file, and enum. Enums need
choices. Fields can define defaults, requirements, bounds, argument mappings,
and remote availability. Avoid names that collide with Runtime's own CLI flags.

Outputs require `name`, `type`, and `path`. Paths or globs resolve inside the
working directory. File matches return path lists; directory output returns
the first matching path. An unmatched string output captures stdout. Missing
unmatched files are omitted. A JSON or base64 type declaration does not make
the local collector automatically parse or encode the content. Declared output
locations are cleaned before a run; keep source and valuable data elsewhere.

## Make installation repeatable

Recipes can specify source `repo`, `ref` (default `main`), `requirements`, models,
environment values, and backends. Pin source revisions and dependency versions
when repeatability matters. Inspect downloads, hardware needs, and script
behavior before installation. A recipe's code can call paid services even when
Runtime itself executes locally.

For HTTP callers, `remote: false` inputs are owner-only: supplying them remotely
fails, while omitting them can use defaults. File inputs must come through
Runtime upload. Path-like string inputs are rejected, and model/checkpoint/weight
selectors need explicit remote access unless bounded by enum choices. See the
[Runtime API](/docs/cli/runtime-api/) for that different input boundary.

## Generate a draft, then verify its behavior

`kaitoi runtime generate URL -o recipe.yaml` uses Anthropic directly with your
provider key/configuration. It supports `--api-key`, `--model`, and `--run-after`;
prefer protected credential configuration over exposing keys in shell history.
It writes YAML and script, and executes only when `--run-after` is requested.

Dashboard generation uses Kaitoi login and managed model usage billed to your
Kaitoi account. Its generate-and-verify loop installs and checks imports and
`--help`; that does not establish a successful full inference run. In either
route, review the generated code and perform a bounded real test before using
the recipe with important inputs.
