| `description` | String | ✅ | A detailed description of what the recipe does |
| `instructions` | String | ✅* | Template instructions that can include parameter substitutions |
| `prompt` | String| ✅* | A template prompt that can include parameter substitutions. Required in [headless](/docs/tutorials/headless-goose) (non-interactive) mode. |
| `title` | String | ✅ | A short title describing the recipe |
| [`activities`](#activities) | Array | - | List of example prompts that can include parameter substitutions. Activities appear as clickable bubbles in goose Desktop. |
| [`extensions`](#extensions) | Array | - | List of extension configurations |
| [`parameters`](#parameters) | Array | - | List of parameter definitions for dynamic recipes |
The `activities` field defines an optional message and clickable activity bubbles (buttons) that appears when a recipe is opened in goose Desktop.
:::info Desktop only
Activities are a Desktop-only feature. When recipes with activities are run via the CLI or as a scheduled job, the `activities` field is ignored and has no effect on recipe execution.
1.**Message Activity**: Displays the markdown-formatted activity text in an info box above the activity bubbles. For example:
```
activities:
- "message: **Welcome!** Here's what I can help with:\n\n• 📊 Data analysis\n• 🔍 Code review\n• 📝 Documentation\n\nSelect an option below to begin."
```
Only include one `message:` prefixed activity. Additional `message:` prefixed activities become regular clickable bubbles (and display the literal "message:" text).
2. **Button Activities**: Text to display in activity bubbles, which send the activity text as a prompt when clicked
Activities support [parameter substitution](#parameters), allowing you to create dynamic, personalized activity bubbles. After users provide parameter values in the **Recipe Parameters** dialog, the values are substituted into the activity text before the bubbles are displayed.
- The message activity displays instructions with substituted parameter values, for example: "Click an option below to start reviewing rust code with a focus on best practices."
- The first two activity bubbles use parameter substitution, for example: "Review the current file for best practices"
- The last two activity bubbles are static prompts that work regardless of parameters
The `extensions` field allows you to specify which Model Context Protocol (MCP) servers and other extensions the recipe needs to function. Each extension in the `extensions` array has the following schema:
The `delegate` and `load` tools are provided by the `summon` platform extension. When a recipe specifies an explicit `extensions` block, only the listed extensions are available — default platform extensions like `summon` are not automatically included. If your recipe needs subagent delegation, add `summon` to your extensions list:
```yaml
extensions:
- type: platform
name: summon
```
Recipes that define [`sub_recipes`](/docs/guides/recipes/subrecipes) have `summon` auto-injected and do not need to list it explicitly.
3. Values are stored securely in the system keyring and reused for subsequent runs
To update a stored secret, remove it from the system keyring and run the recipe again to be re-prompted.
:::info
This feature is designed to prompt for and securely store secrets (such as API keys), but `env_keys` can include any environment variable needed by the extension (such as API endpoints, configuration values, etc.).
Users can press `ESC` to skip entering a variable if it's optional for the extension.
The `parameters` field allows you to create dynamic, reusable recipes that can be customized for different contexts. Parameters define placeholders that users fill in when running the recipe, making the recipe more flexible and adaptable.
Parameter substitution uses Jinja-style template syntax with `{{ parameter_name }}` placeholders. Each parameter in the `parameters` array has the following schema:
- `required`: Parameter must be provided when using the recipe
- `optional`: Can be omitted if a default value is specified
- `user_prompt`: Will interactively prompt the user for input if not provided
The `required` and `optional` parameters work best for recipes opened in goose Desktop. If a value isn't provided for a `user_prompt` parameter, the parameter won't be substituted and may appear as literal `{{ parameter_name }}` text in the recipe output.
#### Input Types
- `string`: Default type. The parameter value is used as-is in template substitution
- `number`: Numeric values. Desktop UI provides number input validation
- Optional parameters MUST have a default value specified
- Required parameters cannot have default values
- File parameters cannot have default values regardless of requirement type to prevent unintended importing of sensitive files
- Select parameters MUST have an `options` field with available choices
- Parameter keys must match any template variables used in instructions, prompt, or activities
:::
#### Parameter Substitution in Desktop
When a recipe with parameters is opened in goose Desktop, users are presented with a **Recipe Parameters** dialog where they can:
- Provide values for required parameters
- Modify or accept default values for optional parameters
- Enter values for `user_prompt` parameters
Once parameter values are submitted, they are substituted into the recipe's `instructions`, `prompt`, and `activities` fields before the recipe starts.
### Response
The `response` field enables recipes to enforce a final structured JSON output. When you specify a `json_schema`, goose will:
This feature is designed for **non-interactive automation** to ensure consistent, parseable output. Recipes can produce structured output when run from either the goose CLI or goose Desktop. See [use cases and ideas for automation workflows](/docs/guides/recipes/session-recipes#structured-output-for-automation).
The `retry` field enables recipes to automatically retry execution if success criteria are not met. This is useful for recipes that might need multiple attempts to achieve their goal, or for implementing automated validation and recovery workflows.
The `settings` field allows you to configure the AI model and provider settings for the recipe. This overrides the default configuration when the recipe is executed.
| `max_turns` | Number | - | Maximum number of turns for subagent tasks created by this recipe |
#### Understanding max_turns
The `max_turns` setting controls how many iterations an agent can perform before stopping. When set in a recipe's settings, it applies to that recipe's execution and any subagents or subrecipes it creates (unless they specify their own value).
Settings specified in a recipe will override your default goose configuration when that recipe is executed. If no settings are specified, goose will use your configured defaults.
:::
### Subrecipes
The `sub_recipes` field specifies the [subrecipes](/docs/guides/recipes/subrecipes) that the main recipe calls to perform specific tasks. Each subrecipe in the `sub_recipes` array has the following schema:
#### Subrecipe Schema
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | String | ✅ | Unique identifier for the subrecipe |
| `path` | String | ✅ | Relative or absolute path to the subrecipe file |
| `values` | Object | - | Pre-configured parameter values that are passed to the subrecipe |
| `sequential_when_repeated` | Boolean | - | Forces sequential execution of multiple subrecipe instances. See [Running Subrecipes In Parallel](/docs/tutorials/subrecipes-in-parallel) for details |
| `description` | String | - | Optional description of the subrecipe |
#### Example Subrecipe Configuration
```yaml
sub_recipes:
- name: "security_scan"
path: "./subrecipes/security-analysis.yaml"
values: # in key-value format: {parameter_name}: {parameter_value}
Recipes saved from goose Desktop include additional metadata fields. These fields are used by the Desktop app for organization and management but are ignored by CLI operations.
Use the `indent()` filter to ensure multi-line parameter values are properly indented and can be resolved as valid JSON or YAML format. This example uses `{{ raw_data | indent(2) }}` to specify an indentation of two spaces when passing data to a subrecipe:
| `recipe_dir` | Automatically set to the directory containing the recipe file. Use it to reference companion files, for example: `{{ recipe_dir }}/style-guide.md` |
Validation rules from [`validate_recipe.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/recipe/validate_recipe.rs) are enforced when loading recipes and used by the [`goose recipe validate`](/docs/guides/goose-cli-commands#recipe) subcommand:
- `validate_prompt_or_instructions` - At least one of `instructions` or `prompt` must be present
- `validate_json_schema` - JSON response schema must be valid if `response.json_schema` is specified
### Parameter Validation
- `validate_parameters_in_template` - All template variables must have corresponding parameter definitions, and all defined parameters must be used (no unused parameters)
- `validate_optional_parameters` - Optional parameters must have default values
- `validate_optional_parameters` - File parameters cannot have default values to prevent importing sensitive files
:::info
Basic field requirements (required fields, types, character limits) are documented in the [Core Recipe Schema](#core-recipe-schema) table.