Cookidoo MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Cookidoo MCP Server find quick vegetarian recipes with zucchini under 30 minutes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Cookidoo MCP Server
An MCP (Model Context Protocol) server for interacting with the Thermomix Cookidoo platform, built with FastMCP.
Disclaimer: This is an unofficial project. The developers are not affiliated with, endorsed by, or connected to Cookidoo, Vorwerk, Thermomix, or any of their subsidiaries or trademarks. It uses Cookidoo's private web API with your own account: that may conflict with Cookidoo's terms of use, and it can break whenever Cookidoo changes its site (a weekly live test watches for that). Use it at your own risk.
Features
Recipe Search: Find recipes by keywords and/or ingredients, with a maximum total time
Recipe Details: Fetch ingredients, steps and times of any Cookidoo recipe
Custom Recipes: List, read, create, update and delete the recipes on your own account
Shopping List: Add recipes and items, tick them off, rename, remove or clear
Meal Plan: See the week, plan recipes on a day or remove them
Collections: List, follow and create collections, add and remove their recipes
Account: Subscription and linked Thermomix devices
Guided Cooking: Steps can carry Thermomix settings (time, temperature, speed, reverse), preset on the machine
Guided Prompt:
create_thermomix_recipewalks the assistant through writing a proper Thermomix recipe (EN / FR / DE)
Related MCP server: cookidoo-mcp
Setup
Requires Python 3.12+ and uv.
uv sync
cp .env.example .env # then fill in your Cookidoo credentialsVariable | Default | Description |
| — | Cookidoo account email (required) |
| — | Cookidoo account password (required) |
|
| Cookidoo site country code ( |
|
| Site language (e.g. |
| — (detected) | Thermomix recipes are written for ( |
| — (upload disabled) | Folders |
|
|
|
|
| HTTP bind address. Any non-loopback address requires |
|
| HTTP port |
| — | Bearer token for HTTP mode, at least 32 characters (e.g. |
| — | Live tests only: a dedicated test account (see Live tests) |
|
| Live tests only: the test account's site |
Usage
Claude Code
claude mcp add cookidoo -- uv run --directory /path/to/mcp-cookidoo server.pyClaude Desktop
Bundle (easiest): download mcp-cookidoo-<version>.mcpb from the
latest release and open it with
Claude Desktop. It asks for your Cookidoo e-mail, password (kept in the system's secure
storage), site and Thermomix; Claude Desktop installs Python and the dependencies itself.
From a checkout:
Add to claude_desktop_config.json:
{
"mcpServers": {
"cookidoo": {
"command": "uv",
"args": ["run", "--directory", "/path/to/mcp-cookidoo", "server.py"]
}
}
}Docker
Images for amd64 and arm64 are published to GitHub Container Registry: edge is built from
every change on main, version tags (1, 1.2, 1.2.0) from releases. Keep the credentials
in an env file (chmod 600) rather than in the client configuration:
{
"mcpServers": {
"cookidoo": {
"command": "docker",
"args": ["run", "--rm", "-i", "--env-file", "/path/to/cookidoo.env",
"ghcr.io/herp75/mcp-cookidoo:edge"]
}
}
}cookidoo.env holds the variables of the table above (COOKIDOO_EMAIL=…, one per line).
To build the image yourself: docker build -t mcp-cookidoo .; it runs as a non-root user.
Verifying a release
Images are signed keyless with cosign by the Docker workflow of this repository; release files carry GitHub build provenance:
cosign verify ghcr.io/herp75/mcp-cookidoo:2.0.0 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/herp75/mcp-cookidoo/\.github/workflows/docker\.yml@'
gh attestation verify mcp-cookidoo-2.0.0.mcpb --repo herp75/mcp-cookidooThe server is also listed in the MCP Registry as
io.github.herp75/mcp-cookidoo.
HTTP
uv run server.py --transport http # http://127.0.0.1:8000/mcp
# Reachable from other machines: a token is required, the server refuses to start without one
COOKIDOO_MCP_TOKEN=$(openssl rand -hex 32) COOKIDOO_MCP_HOST=0.0.0.0 uv run server.py --transport httpClients then send Authorization: Bearer <token>. GET /health returns {"status":"ok"}.
With Docker, the server must bind to all interfaces inside the container, so a token is
required; publish the port on loopback only:
docker run --rm --env-file cookidoo.env -e COOKIDOO_MCP_HOST=0.0.0.0 \
-e COOKIDOO_MCP_TOKEN="$(openssl rand -hex 32)" -p 127.0.0.1:8000:8000 \
ghcr.io/herp75/mcp-cookidoo:edge --transport httpUse server.py rather than fastmcp run … --transport http, which skips these checks.
Development
uv run fastmcp dev inspector fastmcp.json # MCP InspectorAvailable Tools
Type: read = read-only; write = changes the account; destructive = deletes or
overwrites data. Tools marked † refuse to run unless called with confirm=true, as a second
safety layer on top of your client's approval prompt.
Tool | Type | Description |
Recipes | ||
| read | Search recipes by query, ingredients and max total time |
| read | Get ingredients, steps and times of a recipe by ID |
Custom recipes | ||
| read | List the custom recipes on your account |
| read | Get a custom recipe as editable JSON |
| read | Validate a new recipe for a Thermomix (TM5/TM6/TM7) and return its JSON |
| write | Create a custom recipe from that JSON, for a Thermomix |
| destructive | Replace an existing custom recipe with that JSON |
| write | Copy a catalogue recipe into a new custom recipe, to adapt it |
| destructive | Set a custom recipe's photo from a local image (see |
| destructive | Permanently delete a custom recipe |
Shopping list | ||
| read | Recipes, ingredients and hand-added items, with ticked state and IDs |
| write | Add the ingredients of catalogue and/or custom recipes |
| destructive | Remove recipes and their ingredients |
| write | Add items by hand ("milk", "2 lemons") |
| destructive | Rename items added by hand |
| write | Tick items off, or put them back |
| destructive | Delete items added by hand |
| destructive | Empty the whole shopping list |
Meal plan | ||
| read | The planned recipes of the 7 days starting at a day |
| write | Plan catalogue and/or custom recipes on a day |
| destructive | Move a planned recipe to another day (rolled back on failure) |
| destructive | Remove recipes from a day (the recipes are kept) |
Collections | ||
| read | Your own and followed collections with their recipes (paginated) |
| write / destructive | Follow or unfollow a Cookidoo collection |
| write | Create a custom collection |
| destructive | Delete a custom collection (its recipes are kept) |
| write / destructive | Add or remove recipes in a custom collection |
Thermomix | ||
| read | Settings and modes a device supports, with limits and examples |
Account | ||
| read | Check the configuration / force a fresh login (optional, tools log in automatically) |
| read | User, Cookidoo site, subscription and devices |
| read | Thermomix devices linked to the account |
Recipe steps
A step is either plain text, or an object with Thermomix settings preset in guided cooking
and/or ingredient links. The text holds one {settings} placeholder per setting, replaced
by the setting written out in the account's language (COOKIDOO_LANGUAGE): French,
English and German are supported, other languages are written in English. The settings preset
on the Thermomix are the same in every language.
{
"text": "Add the onion and the olive oil, then sauté {settings}.",
"settings": [{"time": 180, "temperature": "120", "speed": "1", "reverse": true}],
"ingredients": [{"text": "the onion", "ingredient": "1 onion, halved"}]
}A setting's mode selects its fields. The limits are those of the Cookidoo recipe editor
(snapshot of cookidoo.de, 2026-10-20), and they depend on the Thermomix the recipe is for:
| Devices | Fields and limits | Written as (fr) | Written as (de) |
| TM5, TM6, TM7 |
|
|
|
| TM6, TM7 |
|
|
|
| TM7 |
|
|
|
| TM7 |
|
|
|
| TM6, TM7 |
|
|
|
| TM6, TM7 | none |
|
|
| TM6, TM7 |
|
|
|
| TM6, TM7 |
|
|
|
speed is "soft" (stirring speed, Sanftrührstufe) or "0.5" to "10" by halves
(written Stufe 0,5 in German). Cookidoo has no other mode for custom recipes (sous-vide,
slow cooking, fermentation… only exist in catalogue recipes).
Target device. generate_recipe_structure, upload_custom_recipe and
update_custom_recipe take an optional device (TM5, TM6, TM7) and refuse settings that
device does not support, naming the allowed values. Without it: for an update, the recipe's
own devices; then COOKIDOO_DEVICE; then the devices linked to the account (TM6 rules if a
TM6 is among them, as TM6-valid steps also run on a TM7); then TM6. Times off the editor's
grid (10 s steps up to 5 min, 30 s up to 20 min, then whole minutes) only give a warning.
Which modes exist and which are TM7-only is read from the Cookidoo recipe editor of your
account (cached for an hour), with the built-in snapshot as fallback; the tool output says
which was used. Recipes already on Cookidoo are always readable, whatever their values, and
are only checked when saved again.
Modes are written with their name, so the text should not repeat it ("then start {settings}" rather than "knead {settings}").
ingredients links words of the step text (their first occurrence) to a line of the
ingredient list. Invalid settings and links are rejected. get_custom_recipe returns steps
in the same format, so a recipe keeps its settings and links when edited.
Security
The server stores your real Cookidoo password (Cookidoo has no OAuth): use a unique password.
Prefer stdio. Use HTTP only with a token, on a trusted network.
TLS certificate verification is always on; secrets are redacted from logs and error messages.
Recipe content is untrusted input to the model. Keep your client's approval prompt on for write tools.
upload_custom_recipe_imageis the only tool that reads a local file and sends it to the internet. It is off until you setCOOKIDOO_IMAGE_DIRS: point it at a folder that holds only recipe photos, not your home directory. Files outside it (also through symlinks) and anything but JPEG/PNG/WebP up to 10 MB are refused; images are re-encoded and their metadata (EXIF, GPS location) removed before upload. With Docker, mount that folder read-only (-v ~/RecipePhotos:/photos:ro -e COOKIDOO_IMAGE_DIRS=/photos).
See SECURITY.md for the threat model and how to report a vulnerability.
Development
See CONTRIBUTING.md for the workflow and docs/architecture.md for how the code is organised.
uv sync
uv run pytest --cov # tests, coverage must stay at 85 % or more
uv run ruff check . && uv run ruff format .
uv run pyright
scripts/check_insecure_patterns.sh # TLS / bind-address guard, also run in CICI also runs pip-audit, gitleaks, CodeQL, dependency review and a Trivy scan of the Docker image.
Live tests
tests/live runs against the real Cookidoo API. Use a dedicated test account, never your
own: the write tests create and delete recipes, a collection, shopping-list items and meal-plan
entries (all named "MCP live test …").
cp .env.live.example .env.live && chmod 600 .env.live # then fill in the test account
uv run pytest tests/live --live -p no:logging --assert=plain # read-only
uv run pytest tests/live --live-write -p no:logging --assert=plain # also writes, cleans upThey read only COOKIDOO_TEST_* and refuse to run with the account in COOKIDOO_EMAIL.
The "Live tests" workflow runs them weekly with the secrets COOKIDOO_TEST_EMAIL and
COOKIDOO_TEST_PASSWORD of the live environment (deployment branch main only; optional
variables COOKIDOO_TEST_COUNTRY, COOKIDOO_TEST_LANGUAGE, default ch / de-CH). It also
compares the Cookidoo recipe editor with devices.py and opens an issue if they differ.
Credits
alexandrepa/mcp-cookidoo by Alexandre Patelli: the original server this fork extends.
tobilektri/mcp-cookidoo (MIT): German Thermomix notation, mode limits per device, the editor-page parser and fixtures.
vitaliemiron/cookidoo-mcp (Apache-2.0): recipe image upload and the meal-plan move; see NOTICE.
danielkliem/mcp-cookidoo and sisques-labs/cookidoo-mcp: feature inspiration only, no code copied.
cookidoo-api by miaucl: the Python client for the Cookidoo platform everything here is built on.
Everyone who opened pull requests on the original repository: their ideas (search, recipe editing, Docker/STDIO support) shaped it.
License
Available Tools
33 toolsadd_recipes_to_shopping_listAdd Recipes To Shopping ListB
Add the ingredients of recipes to the shopping list.
Inputs: recipe_ids, custom_recipe_ids. Returns: result
add_shopping_list_itemsAdd Shopping List ItemsB
Add items by hand to the shopping list (e.g. "milk", "2 lemons").
Inputs: items (required). Returns: result
add_to_collectionAdd To CollectionB
Add Cookidoo catalogue recipes to one of the user's custom collections.
Inputs: recipe_ids (required), collection_id (required). Returns: result
add_to_meal_planAdd To Meal PlanC
Plan recipes on a day of the meal plan.
Inputs: day (required), recipe_ids, custom_recipe_ids. Returns: result
clear_shopping_listClear Shopping ListADestructive
Empty the whole shopping list: every recipe, ingredient and item added by hand. This cannot be undone. Requires confirm=true after the user explicitly agreed.
Inputs: confirm. Returns: result
connect_to_cookidooConnect To CookidooARead-only
Authenticate with Cookidoo using the credentials from the environment / .env file.
Optional: every other tool connects automatically on first use. Call this to check the configuration or to force a fresh login.
Inputs: no named parameters. Returns: result
copy_recipe_to_customCopy Recipe To CustomA
Copy a Cookidoo catalogue recipe into a new custom recipe on the user's account, to adapt it. Returns the new custom recipe ID: read it with get_custom_recipe, edit it, and save it with update_custom_recipe. The catalogue recipe is not changed. Each call creates another copy.
Inputs: recipe_id (required), servings. Returns: result
create_collectionCreate CollectionA
Create a new, empty custom collection on the user's account. Each call creates another collection.
Inputs: name (required). Returns: result
delete_collectionDelete CollectionADestructive
Delete one of the user's custom collections. The recipes in it are not deleted, but the collection and its organisation are lost; this cannot be undone. Requires confirm=true after the user explicitly agreed.
Inputs: collection_id (required), confirm. Returns: result
delete_custom_recipeDelete Custom RecipeADestructive
Permanently delete one of the user's custom recipes, with its ingredients, steps and settings. This cannot be undone. Requires confirm=true after the user explicitly agreed.
Inputs: recipe_id (required), confirm. Returns: result
edit_shopping_list_itemsEdit Shopping List ItemsADestructiveIdempotent
Rename items that were added by hand (not recipe ingredients). The old name is replaced.
Inputs: items (required). Returns: result
follow_collectionFollow CollectionB
Follow (save) a Cookidoo collection, adding it to the user's followed collections.
Inputs: collection_id (required). Returns: result
generate_recipe_structureGenerate Recipe StructureARead-only
Generate and validate a recipe structure ready for upload to Cookidoo. Changes nothing on Cookidoo.
Returns a JSON structure to show to the user and then pass to upload_custom_recipe or update_custom_recipe. Thermomix settings are checked against what the target device supports (see get_thermomix_modes).
Inputs: name (required), steps (required), ingredients (required), hints, +4 more.
get_account_infoGet Account InfoARead-only
Show the Cookidoo account: user name, Cookidoo site, subscription and linked devices.
Inputs: no named parameters. Returns: result
get_custom_recipeGet Custom RecipeARead-only
Get one of the user's custom recipes as JSON, in the format expected by update_custom_recipe. Use it as the starting point before editing. Steps with machine settings or ingredient links come back as structured steps.
Inputs: recipe_id (required). Returns: result
get_meal_plan_weekGet Meal Plan WeekARead-only
Show the meal plan for the 7 days starting at a day (default: today).
Inputs: day. Returns: result
get_recipe_detailsGet Recipe DetailsARead-only
Get the full details of a Cookidoo catalogue recipe: ingredients, steps, times.
Inputs: recipe_id (required). Returns: result
get_shopping_listGet Shopping ListARead-only
Show the shopping list: the recipes on it, their ingredients, and items added by hand.
[x] marks items already ticked off (owned). IDs are for mark_shopping_list_items, edit_shopping_list_items and remove_shopping_list_items.
Inputs: no named parameters. Returns: result
get_thermomix_modesGet Thermomix ModesARead-only
List the Thermomix settings and modes a device supports, with their limits and an example of each, as accepted by generate_recipe_structure. Call it before writing a recipe that uses modes. Modes are read from the Cookidoo recipe editor when possible.
Inputs: device. Returns: result
list_collectionsList CollectionsARead-only
List recipe collections with their recipes: the user's own ("custom") and the Cookidoo collections they follow ("managed"). Results are paginated.
Inputs: kind, page. Returns: result
list_custom_recipesList Custom RecipesBRead-only
List the custom recipes created on the user's Cookidoo account.
Inputs: no named parameters. Returns: result
list_devicesList DevicesARead-only
List the Thermomix devices linked to the Cookidoo account (e.g. TM6, TM7).
Inputs: no named parameters. Returns: result
mark_shopping_list_itemsMark Shopping List ItemsAIdempotent
Tick items off the shopping list (owned=true), or untick them (owned=false). Works for recipe ingredients and for items added by hand.
Inputs: item_ids (required), owned. Returns: result
move_in_meal_planMove In Meal PlanADestructive
Move a planned recipe (catalogue or custom) from one day of the meal plan to another. It is added to the new day before it is removed from the old one; if that fails, the change is rolled back.
Inputs: to_day (required), from_day (required), recipe_id (required). Returns: result
remove_from_collectionRemove From CollectionADestructiveIdempotent
Remove recipes from one of the user's custom collections. The recipes themselves are not deleted.
Inputs: recipe_ids (required), collection_id (required). Returns: result
remove_from_meal_planRemove From Meal PlanADestructive
Remove recipes from one day of the meal plan. The recipes themselves are not deleted.
Inputs: day (required), recipe_ids, custom_recipe_ids. Returns: result
remove_recipes_from_shopping_listRemove Recipes From Shopping ListADestructive
Remove recipes and all their ingredient items from the shopping list, including the ticked state of those items. Items added by hand are kept.
Inputs: recipe_ids, custom_recipe_ids. Returns: result
remove_shopping_list_itemsRemove Shopping List ItemsADestructive
Delete items that were added by hand from the shopping list. Recipe ingredients are removed with remove_recipes_from_shopping_list instead.
Inputs: item_ids (required). Returns: result
search_recipesSearch RecipesARead-only
Search the Cookidoo recipe catalogue.
Use this to find inspiration or recipes based on what is in the fridge, then pass the returned IDs to get_recipe_details.
Inputs: query, ingredients, max_results, max_total_time. Returns: result
unfollow_collectionUnfollow CollectionADestructiveIdempotent
Stop following a Cookidoo collection. It disappears from the user's followed collections (it can be followed again later).
Inputs: collection_id (required). Returns: result
update_custom_recipeUpdate Custom RecipeADestructiveIdempotent
Replace the content of an existing custom recipe on Cookidoo. The previous name, ingredients, steps and hints are overwritten and cannot be restored.
Get the current version with get_custom_recipe, edit it, show the result to the user and only call this after their explicit approval. The recipe's devices are not changed.
Inputs: recipe_id (required), recipe_json (required), device. Returns: result
upload_custom_recipeUpload Custom RecipeA
Create a brand new custom recipe on the user's Cookidoo account, for one Thermomix.
Only call this after the user explicitly approved the recipe. Each call creates another recipe: to change one already uploaded, use update_custom_recipe instead.
Inputs: recipe_json (required), device. Returns: result
upload_custom_recipe_imageUpload Custom Recipe ImageADestructiveIdempotent
Set the photo of one of the user's custom recipes from a local image file, replacing the current photo (which is lost). The file is sent to Cookidoo's image storage.
Only files inside the folders listed in the server's COOKIDOO_IMAGE_DIRS setting can be used; .jpg, .jpeg, .png and .webp up to 10 MB. The image is re-encoded as JPEG and all metadata (EXIF, GPS location, camera details) is removed before upload. Only call this with a file the user explicitly chose for this recipe.
Inputs: recipe_id (required), image_path (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 33 tools
Most tools target clearly distinct resources and actions, and descriptions explicitly clarify boundaries such as remove_recipes_from_shopping_list versus remove_shopping_list_items. A few shopping-list operations (clear, remove items, remove recipes) require careful reading, but the set is generally well-separated.
Tool names consistently use snake_case verb_noun or verb_noun_qualifier patterns (e.g. search_recipes, get_recipe_details, add_to_meal_plan, remove_from_collection). There are no mixed conventions or ambiguous bare nouns.
33 tools is a large surface for one server, exceeding the comfortable 3-15 range, and the domain spans several distinct sub-areas (recipes, collections, meal plans, shopping lists, devices/account). While each tool earns its place within its sub-area, the overall set is heavy and likely to burden selection.
Coverage is broad: catalogue and custom recipe lifecycle, collections, meal planning, shopping list operations, devices, and account info are present. Minor gaps exist, such as no obvious way to add custom recipes to custom collections or fetch a single collection directly, but workarounds are mostly available.
Maintenance
Related MCP Connectors
Authenticated MCP server for ClearPolicy policy and compliance workflows.
An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform
Remote MCP server for training, nutrition, wellness, and performance data with OAuth 2.0.
Unofficial community ClickUp MCP via personal API token. Not affiliated with ClickUp.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables interaction with Mealie for managing recipes, meal plans, shopping lists, foods, units, tags, categories, and more through MCP.MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for Cookidoo, enabling AI tools to search recipes, manage shopping lists, and retrieve account and subscription information.2GPL 3.0
- AlicenseAqualityCmaintenanceEnables interaction with the Thermomix Cookidoo platform, including authentication, recipe management, meal planning, and shopping list access through natural language.1644 PyPI2Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to search and read recipes, import recipes from URLs or text, plan meals, and manage shopping lists in Mealie, with OAuth-protected remote access.MIT