Skip to main content
Recipes are YAML files that define automated workflows for goose. They allow you to parameterize tasks, compose complex workflows, and share common patterns.

What are Recipes?

Recipes package instructions, parameters, and extension requirements into a reusable format:
name: "api-builder"
version: 1.0.0
description: "Build a REST API with authentication and tests"

parameters:
  - name: "language"
    type: "string"
    description: "Programming language to use"
    required: true
  - name: "database"
    type: "string"
    description: "Database type (postgres, mysql, sqlite)"
    default: "postgres"

extensions:
  - type: builtin
    name: developer

instructions: |
  Build a REST API in {{language}} with:
  1. User authentication using JWT tokens
  2. CRUD endpoints for users and resources
  3. {{database}} database integration
  4. Input validation and error handling
  5. Unit and integration tests
  6. API documentation

Parameters

Define inputs with types, defaults, and validation

Instructions

Template-driven instructions with Jinja2

Extensions

Specify required tools and capabilities

Running Recipes

From a File

goose run --recipe ./my-recipe.yaml
Goose will prompt for required parameters:
Parameter 'language' (string): python
Parameter 'database' (string) [postgres]: 

Starting recipe: api-builder
...

With Parameter Values

Provide parameters directly:
goose run --recipe ./my-recipe.yaml \
  --recipe-param language=python \
  --recipe-param database=sqlite

From GitHub

Run recipes from repositories:
goose run --recipe github:block/goose-recipes/web-scraper.yaml
Goose downloads and caches the recipe automatically.

From URL

Fetch recipes from any URL:
goose run --recipe https://example.com/recipes/deploy.yaml

Recipe Structure

Basic Fields

name
string
required
Unique identifier for the recipe
version
string
Semantic version (e.g., “1.2.0”)
description
string
Human-readable description of what the recipe does
instructions
string
required
Template-driven instructions using Jinja2 syntax

Parameters

parameters
array
List of input parameters
parameters[].name
string
required
Parameter name (alphanumeric + underscores)
parameters[].type
string
required
Parameter type: string, integer, boolean, float, array, or object
parameters[].description
string
Human-readable description
parameters[].required
boolean
default:"false"
Whether the parameter is required
parameters[].default
any
Default value if not provided

Extensions

extensions
array
Required MCP extensions for this recipe
extensions[].type
string
required
Extension type: builtin, stdio, or sse
extensions[].name
string
required
Extension name or identifier
For stdio and sse extensions, additional fields like command, args, and env can be specified.

Templating with Jinja2

Recipe instructions support Jinja2 templating:

Variable Substitution

instructions: |
  Create a {{language}} project called {{project_name}}.

Conditionals

instructions: |
  {% if include_tests %}
  Write comprehensive unit tests for all functions.
  {% endif %}
  
  {% if database == "postgres" %}
  Use PostgreSQL with SQLAlchemy ORM.
  {% elif database == "mysql" %}
  Use MySQL with PyMySQL driver.
  {% else %}
  Use SQLite with the built-in sqlite3 library.
  {% endif %}

Loops

parameters:
  - name: "features"
    type: "array"
    description: "List of features to implement"

instructions: |
  Implement the following features:
  {% for feature in features %}
  - {{feature}}
  {% endfor %}

Filters

instructions: |
  Create a file named {{project_name | lower | replace(' ', '_')}}.py
Available filters: lower, upper, title, capitalize, replace, trim, default

Sub-Recipes

Compose complex workflows from smaller recipes:
name: "full-stack-app"
description: "Build a complete full-stack application"

parameters:
  - name: "app_name"
    type: "string"
    required: true

sub_recipes:
  - name: "backend"
    recipe: "./backend-api.yaml"
    parameters:
      language: "python"
      database: "postgres"
      app_name: "{{app_name}}_api"
  
  - name: "frontend"
    recipe: "./react-app.yaml"
    parameters:
      framework: "react"
      app_name: "{{app_name}}_web"
      api_url: "http://localhost:8000"
  
  - name: "deployment"
    recipe: "./docker-deploy.yaml"
    parameters:
      services:
        - backend
        - frontend

instructions: |
  I'm orchestrating the creation of a full-stack application called {{app_name}}.
  
  The sub-recipes will handle:
  1. Backend API development
  2. Frontend web app
  3. Docker deployment configuration
  
  Coordinate between the sub-recipes to ensure they integrate properly.
Sub-recipes execute sequentially and can pass data between stages.

Response Schemas

Define structured output formats:
name: "security-audit"
description: "Perform a security audit of a codebase"

response_schema:
  type: "object"
  properties:
    vulnerabilities:
      type: "array"
      items:
        type: "object"
        properties:
          severity:
            type: "string"
            enum: ["critical", "high", "medium", "low"]
          description:
            type: "string"
          file:
            type: "string"
          line:
            type: "integer"
          recommendation:
            type: "string"
    summary:
      type: "object"
      properties:
        total_files_scanned:
          type: "integer"
        issues_found:
          type: "integer"
        risk_level:
          type: "string"

instructions: |
  Perform a security audit of the codebase.
  Return results in the specified JSON format.
Goose will validate the agent’s output against the schema and retry if invalid.

Real-World Recipe Examples

Web Scraper

name: "web-scraper"
version: 1.0.0
description: "Scrape data from websites and save to structured format"

parameters:
  - name: "url"
    type: "string"
    description: "URL to scrape"
    required: true
  - name: "selectors"
    type: "object"
    description: "CSS selectors for data extraction"
    required: true
  - name: "output_format"
    type: "string"
    description: "Output format (json, csv, excel)"
    default: "json"

extensions:
  - type: builtin
    name: computercontroller
  - type: builtin
    name: developer

instructions: |
  Scrape data from {{url}} using these selectors:
  {% for key, selector in selectors.items() %}
  - {{key}}: {{selector}}
  {% endfor %}
  
  Save the results to a {{output_format}} file named "scraped_data.{{output_format}}".
  
  Handle pagination if present, and implement rate limiting to be respectful.

Database Migration

name: "db-migration"
version: 1.0.0
description: "Generate and apply database migrations"

parameters:
  - name: "operation"
    type: "string"
    description: "Migration operation"
    required: true
  - name: "table_name"
    type: "string"
    required: true
  - name: "columns"
    type: "array"
    required: false

extensions:
  - type: stdio
    name: postgres
    command: uvx
    args: ["mcp-server-postgres", "${DATABASE_URL}"]

instructions: |
  {% if operation == "create_table" %}
  Create a new table named {{table_name}} with these columns:
  {% for col in columns %}
  - {{col.name}} ({{col.type}}{% if col.required %}, NOT NULL{% endif %})
  {% endfor %}
  
  {% elif operation == "add_column" %}
  Add column {{columns[0].name}} ({{columns[0].type}}) to table {{table_name}}.
  
  {% elif operation == "drop_column" %}
  Drop column {{columns[0].name}} from table {{table_name}}.
  
  {% endif %}
  
  Generate the migration SQL and apply it to the database.
  Create a rollback script as well.

CI/CD Pipeline

name: "setup-cicd"
version: 1.0.0
description: "Set up CI/CD pipeline with testing and deployment"

parameters:
  - name: "platform"
    type: "string"
    description: "CI platform (github-actions, gitlab-ci, circle-ci)"
    required: true
  - name: "test_command"
    type: "string"
    default: "npm test"
  - name: "deploy_target"
    type: "string"
    description: "Deployment target (vercel, aws, gcp)"
    required: true

extensions:
  - type: builtin
    name: developer

instructions: |
  Set up a {{platform}} pipeline that:
  1. Runs on every push and pull request
  2. Installs dependencies
  3. Runs tests: {{test_command}}
  4. Runs linting and type checking
  5. Builds the project
  6. Deploys to {{deploy_target}} on main branch merges
  
  Include:
  - Caching for dependencies
  - Secrets management
  - Status badges for README

Recipe Management

Listing Recipes

View cached recipes:
goose recipe list

Validating Recipes

Check recipe syntax:
goose recipe validate ./my-recipe.yaml
Generate shareable URLs:
goose recipe deeplink ./my-recipe.yaml
Outputs a URL that others can use to run the recipe directly.

Programmatic Recipe Execution

REST API

curl -X POST http://localhost:3000/agents \
  -H "Content-Type: application/json" \
  -d '{
    "recipe": "api-builder",
    "recipe_values": {
      "language": "python",
      "database": "postgres"
    }
  }'

Agent Client Protocol (ACP)

Execute recipes via ACP:
import asyncio
from acp_client import ACPClient

async def run_recipe():
    client = ACPClient("goose-acp-server")
    await client.connect()
    
    session = await client.create_session(
        recipe="api-builder",
        recipe_values={
            "language": "python",
            "database": "postgres"
        }
    )
    
    async for event in client.stream_events(session.id):
        print(f"Event: {event}")

asyncio.run(run_recipe())

Next Steps

Recipes Concept

Deep dive into recipe architecture and composition

Recipe Command

CLI reference for recipe commands

Extensions

Learn how to specify and use extensions in recipes

Sub-recipes

Build complex multi-stage workflows

Build docs developers (and LLMs) love