Tandoor Recipe CLI
by @dcenatiempo
Manage recipes, meal plans, and shopping lists on a Tandoor Recipe Manager instance via CLI.
clawhub install tandoor-cliπ About This Skill
name: tandoor-recipe-cli description: Manage recipes, meal plans, and shopping lists on a Tandoor Recipe Manager instance via CLI. version: 1.1.3 compatibility: ">=18" license: MIT metadata: author: dcenatiempo repository: https://github.com/dcenatiempo/tandoor-cli
Tandoor CLI Skill
This skill provides AI agents with the ability to interact with a Tandoor Recipe Manager instance using the tandoor-cli command-line tool.
Prerequisites
The tandoor-cli tool must be installed and configured.
Version Compatibility: This skill documentation corresponds to the version specified in the metadata above. Before using this skill:
1. Verify your installed CLI version: tandoor -V
2. Ensure the installed version matches the skill version to avoid unexpected behavior or missing commands
3. If versions don't match, reinstall the CLI tool following the setup instructions in references/SETUP.md
If tandoor -V produces no valid version, see the setup instructions in references/SETUP.md.
Security & Permission Model
β οΈ IMPORTANT: This skill provides mutation authority over your Tandoor instance.
Token Security:
Supply Chain:
tandoor-cli npm packagenpm install -g tandoor-cli@ (replace with the skill version)Invocation
tandoor [options]
Commands
#### Read Operations (Safe)
Recipes:
| Command | Description |
|---|---|
| list [--limit N] | List recipes (default 20, max 100) |
| search | Search recipes by keyword |
| get | Get full recipe details |
| random | Get a random recipe |
Meal Plans:
| Command | Description |
|---|---|
| mealplan list [--startdate DATE] [--enddate DATE] | List meal plan entries (optionally filtered by date range) |
Shopping List:
| Command | Description |
|---|---|
| shopping list | List shopping list entries |
Food Ingredients:
| Command | Description |
|---|---|
| food list [--limit N] [--search TERM] [--ignored] | List food ingredients |
Cook Logs:
| Command | Description |
|---|---|
| cooklog list [--recipe ID] [--limit N] [--startdate YYYY-MM-DD] [--enddate YYYY-MM-DD] [--min-rating 1-5] [--max-rating 1-5] | List cook log entries (sorted by most recent first) |
| cooklog ingredient | Find cook logs by ingredient name (e.g., "when did we last have eggs?") |
Households & Users:
| Command | Description |
|---|---|
| household list | List all households |
| household get | Get household details by ID |
| household users list | List all users in the space |
| household users memberships | List user-space memberships |
| household invite list | List all invite links |
#### Write Operations (Require Confirmation)
| Command | Description | Approval Required |
|---|---|---|
| add [--json file] | Create a recipe | β Before execution |
| update | Patch an existing recipe | β Before execution |
| import | Import a recipe from a URL | β Before execution |
| image | Upload an image to a recipe | β Before execution |
| mealplan add --recipe ID --date YYYY-MM-DD --meal-type N | Add a meal plan entry | β Before execution |
| shopping add --food NAME --amount N --unit UNIT | Add a shopping list item | β Before execution |
| shopping check | Mark a shopping item as checked | β Before execution |
| food edit | Edit a food's ignore_shopping flag | β Before execution |
| food ignore | Set or clear ignore_shopping by ID or name | β Before execution |
| food onhand | Set or clear the on-hand flag by ID or name | β Before execution |
| cooklog add --recipe ID --servings N [--rating 1-5] [--date ISO8601] | Add a cook log entry | β Before execution |
| cooklog update | Update a cook log entry | β Before execution |
#### Destructive Operations (Require Explicit Confirmation)
| Command | Description | Approval Required |
|---|---|---|
| delete | Delete a recipe | ββ Explicit confirmation required |
| mealplan delete | Delete a meal plan entry | ββ Explicit confirmation required |
| shopping clear [--force] | Clear all checked items | ββ Explicit confirmation (bulk operation) |
| shopping check --all | Mark all items as checked | ββ Explicit confirmation (bulk operation) |
| cooklog delete | Delete a cook log entry | ββ Explicit confirmation required |
#### Administrative Operations (Require Privileged Token + Explicit Confirmation)
Important: Tandoor uses households to organize users and recipes. Users are added to households via invite links β you cannot create users directly via the API.
> Permission Requirements: Household management commands require special permissions in Tandoor. Most operations need admin/staff privileges. The household invite create command specifically requires space owner authentication β even superusers or staff members will receive a 403 Permission Denied error if they're not the space owner. If you encounter permission errors, you must use the space owner's API token or contact your Tandoor administrator.
| Command | Description | Approval Required |
|---|---|---|
| household add | Create a new household | ββ Admin token + explicit confirmation |
| household edit | Rename a household | ββ Admin token + explicit confirmation |
| household delete | Delete a household | ββ Admin token + explicit confirmation |
| household users assign | Assign user to household | ββ Admin token + explicit confirmation |
| household invite create | Create invite link | ββ Space-owner token + explicit confirmation |
| household invite delete | Delete invite link | ββ Admin token + explicit confirmation |
All read commands accept --json for machine-readable output suitable for agent pipelines.
Agent Behavior Rules
Before executing any command, the agent MUST:
1. For read operations: Proceed without confirmation 2. For write operations: Describe the action and wait for user approval 3. For destructive operations: - Clearly explain what will be deleted/modified - Warn that the action cannot be easily reversed - Wait for explicit user confirmation (e.g., "yes, delete recipe 42") 4. For bulk operations: - State how many items will be affected - Wait for explicit confirmation 5. For administrative operations: - Verify the user has provided an admin/space-owner token - Explain the scope of the change (e.g., "this will move user X to household Y") - Wait for explicit confirmation
The agent MUST NOT:
--force flags without explicit user instructionTANDOOR_API_TOKEN value in any outputConfiguration
The CLI supports three configuration methods (in precedence order):
1. Environment variables β TANDOOR_URL and TANDOOR_API_TOKEN in the current shell
2. Config file β ~/.config/tandoor-cli/config.json (created by tandoor configure)
3. .env file β a .env file in the current working directory
Run tandoor configure once to save credentials interactively.
Examples
Configure credentials:
tandoor configure
Read example β list recipes as JSON:
tandoor list --limit 5 --json
Write example β create a recipe from a JSON file:
# Agent should first ask: "I will create a new recipe from recipe.json. Proceed?"
Only after user confirms:
tandoor add --json recipe.json
Recipe JSON Schema
When creating recipes with tandoor add --json , the JSON file must conform to the following structure:
TypeScript Definition:
interface RecipeCreatePayload {
name: string; // Required: Recipe name
description?: string; // Optional: Recipe description
servings?: number; // Optional: Number of servings
working_time?: number; // Optional: Active cooking time in minutes
waiting_time?: number; // Optional: Passive time (baking, marinating) in minutes
steps: StepCreatePayload[]; // Required: At least one step
}interface StepCreatePayload {
instruction: string; // Required: Step instructions
order: number; // Required: Step order (1, 2, 3, ...)
ingredients: IngredientCreatePayload[]; // Required: Can be empty array
}
interface IngredientCreatePayload {
food: { name: string }; // Required: Ingredient name
unit: { name: string } | null; // Optional: Unit of measurement (null if not applicable)
amount: number; // Required: Quantity
note?: string; // Optional: Additional notes (e.g., "finely chopped")
order?: number | null; // Optional: Order within the step
}
Example Recipe JSON:
{
"name": "Scrambled Eggs",
"description": "Quick and easy scrambled eggs",
"servings": 2,
"working_time": 5,
"steps": [
{
"instruction": "Crack eggs into a bowl, add milk and salt. Whisk until well combined.",
"order": 1,
"ingredients": [
{
"food": { "name": "eggs" },
"unit": { "name": "whole" },
"amount": 4
},
{
"food": { "name": "milk" },
"unit": { "name": "tbsp" },
"amount": 2
},
{
"food": { "name": "salt" },
"unit": null,
"amount": 1,
"note": "to taste"
}
]
},
{
"instruction": "Heat butter in a pan over medium heat. Pour in egg mixture and stir gently until cooked to desired consistency.",
"order": 2,
"ingredients": [
{
"food": { "name": "butter" },
"unit": { "name": "tbsp" },
"amount": 1
}
]
}
]
}
Key Points for Agents:
name and steps are required fieldsinstruction, order, and ingredients (can be empty array)food.name and amountnull for unit when no unit applies (e.g., "to taste", "pinch")g, kg, ml, l, cup, tbsp, tsp, whole, pinchDestructive example β delete a recipe:
# Agent should first ask: "This will permanently delete recipe 42. This cannot be undone. Confirm deletion?"
Only after explicit user confirmation:
tandoor delete 42 --force
Image example β upload an image to a recipe:
# Agent should first ask: "I will upload my-recipe-photo.jpg to recipe 42. Proceed?"
Only after user confirms:
tandoor image 42 ./my-recipe-photo.jpg
Household example β create a household and generate an invite link:
# Agent should first ask: "I will create a new household named 'My Family'. This requires admin privileges. Proceed?"
Only after user confirms:
tandoor household add "My Family"Agent should first ask: "I will create an invite link for household 1. This requires space-owner token. Proceed?"
Only after user confirms:
tandoor household invite create 1 --email user@example.com --expires 2026-12-31
Shopping list example β add items and check them off:
# Agent should first ask: "I will add flour (500g) to the shopping list. Proceed?"
Only after user confirms:
tandoor shopping add --food flour --amount 500 --unit gAgent should first ask: "This will mark ALL shopping items as checked. Confirm?"
Only after explicit confirmation:
tandoor shopping check --all
Cook log example β track when you cook a recipe:
# Agent should first ask: "I will add a cook log entry for recipe 42 (4 servings, rating 5). Proceed?"
Only after user confirms:
tandoor cooklog add --recipe 42 --servings 4 --rating 5Read example β list cook logs for a specific recipe:
tandoor cooklog list --recipe 42 --jsonRead example β find when you last had eggs:
tandoor cooklog ingredient eggsRead example β count how many times you had chicken last month:
tandoor cooklog ingredient chicken --startdate 2026-04-01 --enddate 2026-04-30Read example β find highly-rated egg recipes (4-5 stars):
tandoor cooklog ingredient eggs --min-rating 4Read example β find poorly-rated recipes from last month (1-2 stars):
tandoor cooklog list --startdate 2026-04-01 --enddate 2026-04-30 --max-rating 2Agent should first ask: "This will delete cook log entry 2. Confirm?"
Only after explicit confirmation:
tandoor cooklog delete 2
Installation & Setup
Before first use:
1. Verify the npm package: https://www.npmjs.com/package/tandoor-cli
2. Review the source code: https://github.com/dcenatiempo/tandoor-cli
3. Recommended: Install the pinned version matching this skill: npm install -g tandoor-cli@ (see version in metadata above)
4. Generate a token with minimal required permissions (see SECURITY.md)
5. Consider using a test Tandoor instance first
Reference
references/SETUP.md for detailed setup documentation including authentication configurationSECURITY.md for comprehensive security guidelines and token management best practicesπ‘ Examples
Configure credentials:
tandoor configure
Read example β list recipes as JSON:
tandoor list --limit 5 --json
Write example β create a recipe from a JSON file:
# Agent should first ask: "I will create a new recipe from recipe.json. Proceed?"
Only after user confirms:
tandoor add --json recipe.json
Recipe JSON Schema
When creating recipes with tandoor add --json , the JSON file must conform to the following structure:
TypeScript Definition:
interface RecipeCreatePayload {
name: string; // Required: Recipe name
description?: string; // Optional: Recipe description
servings?: number; // Optional: Number of servings
working_time?: number; // Optional: Active cooking time in minutes
waiting_time?: number; // Optional: Passive time (baking, marinating) in minutes
steps: StepCreatePayload[]; // Required: At least one step
}interface StepCreatePayload {
instruction: string; // Required: Step instructions
order: number; // Required: Step order (1, 2, 3, ...)
ingredients: IngredientCreatePayload[]; // Required: Can be empty array
}
interface IngredientCreatePayload {
food: { name: string }; // Required: Ingredient name
unit: { name: string } | null; // Optional: Unit of measurement (null if not applicable)
amount: number; // Required: Quantity
note?: string; // Optional: Additional notes (e.g., "finely chopped")
order?: number | null; // Optional: Order within the step
}
Example Recipe JSON:
{
"name": "Scrambled Eggs",
"description": "Quick and easy scrambled eggs",
"servings": 2,
"working_time": 5,
"steps": [
{
"instruction": "Crack eggs into a bowl, add milk and salt. Whisk until well combined.",
"order": 1,
"ingredients": [
{
"food": { "name": "eggs" },
"unit": { "name": "whole" },
"amount": 4
},
{
"food": { "name": "milk" },
"unit": { "name": "tbsp" },
"amount": 2
},
{
"food": { "name": "salt" },
"unit": null,
"amount": 1,
"note": "to taste"
}
]
},
{
"instruction": "Heat butter in a pan over medium heat. Pour in egg mixture and stir gently until cooked to desired consistency.",
"order": 2,
"ingredients": [
{
"food": { "name": "butter" },
"unit": { "name": "tbsp" },
"amount": 1
}
]
}
]
}
Key Points for Agents:
name and steps are required fieldsinstruction, order, and ingredients (can be empty array)food.name and amountnull for unit when no unit applies (e.g., "to taste", "pinch")g, kg, ml, l, cup, tbsp, tsp, whole, pinchDestructive example β delete a recipe:
# Agent should first ask: "This will permanently delete recipe 42. This cannot be undone. Confirm deletion?"
Only after explicit user confirmation:
tandoor delete 42 --force
Image example β upload an image to a recipe:
# Agent should first ask: "I will upload my-recipe-photo.jpg to recipe 42. Proceed?"
Only after user confirms:
tandoor image 42 ./my-recipe-photo.jpg
Household example β create a household and generate an invite link:
# Agent should first ask: "I will create a new household named 'My Family'. This requires admin privileges. Proceed?"
Only after user confirms:
tandoor household add "My Family"Agent should first ask: "I will create an invite link for household 1. This requires space-owner token. Proceed?"
Only after user confirms:
tandoor household invite create 1 --email user@example.com --expires 2026-12-31
Shopping list example β add items and check them off:
# Agent should first ask: "I will add flour (500g) to the shopping list. Proceed?"
Only after user confirms:
tandoor shopping add --food flour --amount 500 --unit gAgent should first ask: "This will mark ALL shopping items as checked. Confirm?"
Only after explicit confirmation:
tandoor shopping check --all
Cook log example β track when you cook a recipe:
# Agent should first ask: "I will add a cook log entry for recipe 42 (4 servings, rating 5). Proceed?"
Only after user confirms:
tandoor cooklog add --recipe 42 --servings 4 --rating 5Read example β list cook logs for a specific recipe:
tandoor cooklog list --recipe 42 --jsonRead example β find when you last had eggs:
tandoor cooklog ingredient eggsRead example β count how many times you had chicken last month:
tandoor cooklog ingredient chicken --startdate 2026-04-01 --enddate 2026-04-30Read example β find highly-rated egg recipes (4-5 stars):
tandoor cooklog ingredient eggs --min-rating 4Read example β find poorly-rated recipes from last month (1-2 stars):
tandoor cooklog list --startdate 2026-04-01 --enddate 2026-04-30 --max-rating 2Agent should first ask: "This will delete cook log entry 2. Confirm?"
Only after explicit confirmation:
tandoor cooklog delete 2
Installation & Setup
Before first use:
1. Verify the npm package: https://www.npmjs.com/package/tandoor-cli
2. Review the source code: https://github.com/dcenatiempo/tandoor-cli
3. Recommended: Install the pinned version matching this skill: npm install -g tandoor-cli@ (see version in metadata above)
4. Generate a token with minimal required permissions (see SECURITY.md)
5. Consider using a test Tandoor instance first
Reference
references/SETUP.md for detailed setup documentation including authentication configurationSECURITY.md for comprehensive security guidelines and token management best practicesβοΈ Configuration
The CLI supports three configuration methods (in precedence order):
1. Environment variables β TANDOOR_URL and TANDOOR_API_TOKEN in the current shell
2. Config file β ~/.config/tandoor-cli/config.json (created by tandoor configure)
3. .env file β a .env file in the current working directory
Run tandoor configure once to save credentials interactively.
Examples
Configure credentials:
tandoor configure
Read example β list recipes as JSON:
tandoor list --limit 5 --json
Write example β create a recipe from a JSON file:
# Agent should first ask: "I will create a new recipe from recipe.json. Proceed?"
Only after user confirms:
tandoor add --json recipe.json
Recipe JSON Schema
When creating recipes with tandoor add --json , the JSON file must conform to the following structure:
TypeScript Definition:
interface RecipeCreatePayload {
name: string; // Required: Recipe name
description?: string; // Optional: Recipe description
servings?: number; // Optional: Number of servings
working_time?: number; // Optional: Active cooking time in minutes
waiting_time?: number; // Optional: Passive time (baking, marinating) in minutes
steps: StepCreatePayload[]; // Required: At least one step
}interface StepCreatePayload {
instruction: string; // Required: Step instructions
order: number; // Required: Step order (1, 2, 3, ...)
ingredients: IngredientCreatePayload[]; // Required: Can be empty array
}
interface IngredientCreatePayload {
food: { name: string }; // Required: Ingredient name
unit: { name: string } | null; // Optional: Unit of measurement (null if not applicable)
amount: number; // Required: Quantity
note?: string; // Optional: Additional notes (e.g., "finely chopped")
order?: number | null; // Optional: Order within the step
}
Example Recipe JSON:
{
"name": "Scrambled Eggs",
"description": "Quick and easy scrambled eggs",
"servings": 2,
"working_time": 5,
"steps": [
{
"instruction": "Crack eggs into a bowl, add milk and salt. Whisk until well combined.",
"order": 1,
"ingredients": [
{
"food": { "name": "eggs" },
"unit": { "name": "whole" },
"amount": 4
},
{
"food": { "name": "milk" },
"unit": { "name": "tbsp" },
"amount": 2
},
{
"food": { "name": "salt" },
"unit": null,
"amount": 1,
"note": "to taste"
}
]
},
{
"instruction": "Heat butter in a pan over medium heat. Pour in egg mixture and stir gently until cooked to desired consistency.",
"order": 2,
"ingredients": [
{
"food": { "name": "butter" },
"unit": { "name": "tbsp" },
"amount": 1
}
]
}
]
}
Key Points for Agents:
name and steps are required fieldsinstruction, order, and ingredients (can be empty array)food.name and amountnull for unit when no unit applies (e.g., "to taste", "pinch")g, kg, ml, l, cup, tbsp, tsp, whole, pinchDestructive example β delete a recipe:
# Agent should first ask: "This will permanently delete recipe 42. This cannot be undone. Confirm deletion?"
Only after explicit user confirmation:
tandoor delete 42 --force
Image example β upload an image to a recipe:
# Agent should first ask: "I will upload my-recipe-photo.jpg to recipe 42. Proceed?"
Only after user confirms:
tandoor image 42 ./my-recipe-photo.jpg
Household example β create a household and generate an invite link:
# Agent should first ask: "I will create a new household named 'My Family'. This requires admin privileges. Proceed?"
Only after user confirms:
tandoor household add "My Family"Agent should first ask: "I will create an invite link for household 1. This requires space-owner token. Proceed?"
Only after user confirms:
tandoor household invite create 1 --email user@example.com --expires 2026-12-31
Shopping list example β add items and check them off:
# Agent should first ask: "I will add flour (500g) to the shopping list. Proceed?"
Only after user confirms:
tandoor shopping add --food flour --amount 500 --unit gAgent should first ask: "This will mark ALL shopping items as checked. Confirm?"
Only after explicit confirmation:
tandoor shopping check --all
Cook log example β track when you cook a recipe:
# Agent should first ask: "I will add a cook log entry for recipe 42 (4 servings, rating 5). Proceed?"
Only after user confirms:
tandoor cooklog add --recipe 42 --servings 4 --rating 5Read example β list cook logs for a specific recipe:
tandoor cooklog list --recipe 42 --jsonRead example β find when you last had eggs:
tandoor cooklog ingredient eggsRead example β count how many times you had chicken last month:
tandoor cooklog ingredient chicken --startdate 2026-04-01 --enddate 2026-04-30Read example β find highly-rated egg recipes (4-5 stars):
tandoor cooklog ingredient eggs --min-rating 4Read example β find poorly-rated recipes from last month (1-2 stars):
tandoor cooklog list --startdate 2026-04-01 --enddate 2026-04-30 --max-rating 2Agent should first ask: "This will delete cook log entry 2. Confirm?"
Only after explicit confirmation:
tandoor cooklog delete 2
Installation & Setup
Before first use:
1. Verify the npm package: https://www.npmjs.com/package/tandoor-cli
2. Review the source code: https://github.com/dcenatiempo/tandoor-cli
3. Recommended: Install the pinned version matching this skill: npm install -g tandoor-cli@ (see version in metadata above)
4. Generate a token with minimal required permissions (see SECURITY.md)
5. Consider using a test Tandoor instance first
Reference
references/SETUP.md for detailed setup documentation including authentication configurationSECURITY.md for comprehensive security guidelines and token management best practices