Build a recipe box your AI agent manages
Describe your recipes to Claude and get a Base76 base with linked cuisines, ingredient lists, weeknight filters, and recipe pages you can share.
Connect Base76 to your agent and describe the recipes you keep. The agent builds a base with two linked collections, recipes and cuisines, and fills it from whatever you paste in. Every recipe gets its own page, which you can print or send to someone as a link.
The prompt
Make me a recipe box in Base76. Each recipe has a title, a photo, a cuisine, tags, total time, servings, a 1-5 rating, an ingredient list (quantity, unit, item), the steps, and the source URL. Keep cuisines as their own list so I can browse by cuisine.
The agent calls create_base, then define_collection once per collection, then create for any recipes you hand it. Each write comes back with the base’s audience. A new base starts as private.
The schema
Your agent chooses the exact field names. Our demo base uses this one:
| Field | Type | Notes |
|---|---|---|
title | text | Display field: page titles and link slugs |
photo | file | accept: ["image/*"]; thumbnails are generated for you |
cuisine | relation to cuisines | Inverse recipes; deleting a cuisine clears it |
tags | multi_select | allow_new: true, so new tags don’t need a schema change |
total_time | duration | ISO 8601, such as PT45M |
servings | number | Whole numbers, at least 1 |
rating | rating | Out of 5 |
ingredients | list | Each item has qty (number), unit (text), item (text) |
steps | markdown | |
source | url |
cuisines is two fields: name (text) and region (select).
The relation is the part a spreadsheet can’t do:
{"key": "cuisine", "type": "relation",
"options": {"to": "cuisines", "inverse": "recipes",
"on_delete": "set_null"}}
inverse gives every cuisine a virtual recipes field, so you can ask from either side. on_delete: "set_null" means deleting a cuisine clears it from its recipes instead of refusing.
Ask it what’s for dinner
You’ll mostly ask in plain words: “What can I make on a weeknight in under 45 minutes?” The agent turns that into a find call. Here’s the same query over REST:
curl -s https://api.base76.com/v1/bases/tim/recipes/find \
-H "Authorization: Bearer $B76_KEY" \
-H 'content-type: application/json' \
-d '{"collection": "recipes",
"where": {"tags": {"has": "weeknight"},
"total_time": {"lte": "PT45M"}},
"sort": "-rating",
"select": ["title", "total_time", "rating"],
"include": {"cuisine": {"select": ["name"]}}}'
{"items": [
{"id": "rec_01m5…", "_version": 1, "title": "Chana masala",
"total_time": "PT45M", "rating": 5,
"cuisine": {"id": "rec_01m5…", "_version": 1, "name": "Indian"}},
{"id": "rec_01m5…", "_version": 1, "title": "Pad thai",
"total_time": "PT35M", "rating": 4,
"cuisine": {"id": "rec_01m5…", "_version": 1, "name": "Thai"}}
],
"has_more": false, "next_cursor": null, "seq": 31}
Durations compare by length, so lte: "PT45M" keeps the 45-minute chana masala and the 35-minute pad thai. Filters also cross the relation in both directions. This finds every cuisine with a five-star recipe:
{"collection": "cuisines",
"where": {"recipes": {"some": {"rating": {"gte": 5}}}}}
From a script or a page, the SDK sends the same query:
import { base } from "https://api.base76.com/sdk/v1.js";
const db = base("tim/recipes", { token: process.env.B76_KEY });
const { items } = await db.collection("recipes")
.where({ tags: { has: "weeknight" }, total_time: { lte: "PT45M" } })
.sort("-rating")
.find();
Share one recipe as a page
Every record has a page built from a template. The default comes from your field types, so recipes look decent from the first insert. Ask the agent to make it a proper recipe card and it calls set_template with blocks like these:
[{"type": "hero", "field": "photo"},
{"type": "title"},
{"type": "meta",
"fields": ["total_time", "servings", "rating", "cuisine"]},
{"type": "chips", "field": "tags"},
{"type": "table", "field": "ingredients",
"columns": ["qty", "unit", "item"], "heading": "Ingredients"},
{"type": "markdown", "field": "steps", "heading": "Method"},
{"type": "link", "field": "source", "label": "Original recipe"}]
Then say “share the chana masala recipe.” The agent calls share and hands back a read-only link shaped like https://app.base76.com/s/b76s_…. Whoever opens it sees that recipe and its photo and nothing else in the base. Add .md to the end of the link to get the same recipe as markdown, ready to paste into another chat. Revoke the link and it returns a 404 from then on.
If someone should add recipes too, the agent can make them a guest editor with add_guest. They need their own Base76 account.
Limits
- Share pages are read-only. There are no forms, so people without an account can’t add a recipe.
- Photos upload through a short-lived URL from
upload_file, so the agent needs a shell or a code tool to send the file. You can also attach photos in the app. - There are no formulas. Scaling a recipe from 4 servings to 8 is the agent’s job.