In Part 1 we set up Tandoor Recipes. Now we are going to connect it to an AI agent that can actually do things with those recipes: find them, plan the week, and build shopping lists automatically.
What we are building#
The idea is simple: instead of opening Tandoor, picking recipes, exporting ingredients, and manually adding things to a shopping list, I just ask Remy.
“Hey remy, plan me 4 vegan dinners for this week, nothing too fancy.”
And Remy:
- Searches the web for recipes (with sources, never invents them)
- Checks what I already have in my Tandoor library
- Plans the week
- Builds a shopping list and sends it to Bring!
All through a Matrix chat. No app-switching, no manual copy-paste.
Prerequisites#
Before we connect the dots, you need a few things running:
- Tandoor Recipes - up and running from Part 1
- OpenClaw gateway - installed and configured. See the OpenClaw setup guide if you have not done this yet
- Matrix server - for chatting with the agent. I covered that in my Matrix Synapse post
- Bring! account - for the shopping list (there is a free tier)
[!TIP] If you want the background on why this architecture makes sense, check out my posts on what LLMs actually are and how MCP gives AI agents real tools.
Setting up Remy in OpenClaw#
Remy is one of my three OpenClaw agents. If you already followed the OpenClaw setup guide, you have the gateway running. Now we add (or configure) the Remy agent.
Agent configuration#
In your OpenClaw config.yaml, add the Remy agent (or update its system prompt if you already have it):
agents:
- name: remy
matrix:
userId: "@remy:your-domain.de"
password:
$secretRef: "matrix_remy_password"
homeserver: "https://matrix.your-domain.de"
workspace: "~/.openclaw/workspace-remy"
systemPrompt: |
You are remy, a vegan recipe assistant (named after the rat from Ratatouille).
Find recipes from the web - never invent them, always link to sources.
Build shopping lists via Bring!, help with meal planning.
Use metric units. Handle ingredient substitutions with difficulty and time estimates.
Only vegan recipes - flag non-vegan ingredients from sources and suggest swaps.
When the user asks for a meal plan, suggest specific recipes with links,
then offer to add the ingredients to the Bring! shopping list.
Each agent gets its own workspace directory so their files and memory do not collide.
Create the Matrix account#
If you have not already, register the Remy user on your Synapse server:
docker exec -it synapse register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008
Add the password to your ~/.openclaw/secrets.json:
{
"matrix_remy_password": "your-secure-password-here"
}
Connecting the tools: MCP servers#
This is the part that makes Remy actually useful. MCP servers give the agent real tools to interact with.
Tandoor MCP server#
The Tandoor API is how Remy interacts with your recipe library. There are a couple of options:
- Use an existing Tandoor MCP server (if one is available for your version)
- Build a simple one that wraps the Tandoor REST API
The key API endpoints Remy needs:
GET /api/recipe/- search and list recipesGET /api/recipe/{id}/- get recipe details (ingredients, steps, servings)POST /api/recipe/- create a new recipeGET /api/meal-plan/- read the meal planPOST /api/meal-plan/- add entries to the meal planGET /api/shopping-list/- export shopping list items
Configure it in your config.yaml:
mcpServers:
- name: tandoor
transport:
type: http
url: "https://rezepte.kohnkenet.de/api"
auth:
type: token
token:
$secretRef: "tandoor_api_token"
You can generate an API token in Tandoor under Settings → API Access.
Bring! MCP server#
Bring! is the shopping list app. Remy uses it to push ingredients directly to my phone.
I built a small MCP server for Bring! that runs locally:
- name: bring
transport:
type: stdio
command: "node"
args: ["/home/user/mcp/bring-mcp/index.js"]
env:
BRING_EMAIL:
$secretRef: "bring_email"
BRING_PASSWORD:
$secretRef: "bring_password"
The Bring! MCP server exposes tools like:
list_shopping_lists- see your listsadd_items- add items to a specific listremove_items- remove itemsget_items- see what is already on the list
This is how Remy goes from “here are the ingredients you need” to “I added them to your Bring! list.”
Talking to Remy on Matrix#
Once everything is connected, you can open Element (or any Matrix client) and start a conversation with Remy.
A typical interaction looks like this:
Me: “Hey remy, I need 4 easy vegan dinners for this week. Nothing that takes more than 30 minutes.”
Remy:
- Searches the web for quick vegan dinner recipes
- Returns 4 options with links to the original sources
- Lists ingredients and estimated time for each
Me: “Perfect. Add the second and fourth one to the Bring! list.”
Remy:
- Parses the ingredients from both recipes
- Deduplicates and normalizes (more on this in Part 3)
- Sends them to Bring!
And just like that, my shopping list is ready on my phone. No manual entry, no forgetting the one ingredient I always forget (it is always the lemon).
What to watch out for#
A few things I ran into while setting this up:
Tandoor API pagination. If you have a lot of recipes, the API paginates results. Make sure the MCP server handles that, or Remy will only see the first page.
Ingredient naming is inconsistent. Different recipes call the same thing by different names. This is the messy part we tackle properly in Part 3.
Bring! rate limiting. The Bring! API is not really designed for automation. If you spam it with requests, it will rate-limit you. Batch your item additions.
Agent memory. Remy remembers past conversations through OpenClaw’s memory system. This means if I say “we are out of oat milk” on Monday, Remy will still know on Thursday when planning the weekend. Pretty neat.
What we have now#
At this point you have:
- Tandoor running with your recipe library
- An AI agent you can chat with on Matrix
- The agent connected to your recipes and your shopping list
- A working “ask for recipes → get a shopping list” flow
Not bad for a homelab project.
Next up#
In Part 3 we tackle ingredient normalization, deduplication, and optional grocery cart automation - closing the loop.
