mcpField
M
mcp-cookidoo

mcp-cookidoo

Local
github.com/herp75Games & Entertainment0Updated 2d ago

About mcp-cookidoo

mcp-cookidoo is an MCP server for people managing Cookidoo recipes and meal planning for Thermomix. It supports recipe search and editing, shopping lists, meal plans, collections, and guided-cooking settings; it is an unofficial project using Cookidoo's private web API.

Key features

  1. 01Search recipes and view details
  2. 02Create and edit custom recipes
  3. 03Manage shopping lists
  4. 04Plan recipes by day
  5. 05Create and manage collections
  6. 06Set Thermomix guided-cooking steps

Use cases

  1. 01Find recipes by ingredients and preparation time
  2. 02Adapt a catalogue recipe as a custom recipe
  3. 03Build a shopping list from planned recipes
  4. 04Organize recipes into a weekly meal plan

MCP support

Exposes Cookidoo account, recipe, shopping-list, meal-plan, collection, and Thermomix-device tools to MCP clients. It supports stdio and HTTP transports.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"herp75-mcp-cookidoo": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"COOKIDOO_EMAIL",
"-e",
"COOKIDOO_PASSWORD",
"-e",
"COOKIDOO_COUNTRY",
"-e",
"COOKIDOO_LANGUAGE",
"-e",
"COOKIDOO_DEVICE",
"-e",
"COOKIDOO_IMAGE_DIRS",
"ghcr.io/herp75/mcp-cookidoo:2.2.0"
],
"env": {
"COOKIDOO_EMAIL": "<COOKIDOO_EMAIL>",
"COOKIDOO_PASSWORD": "<COOKIDOO_PASSWORD>",
"COOKIDOO_COUNTRY": "<COOKIDOO_COUNTRY>",
"COOKIDOO_LANGUAGE": "<COOKIDOO_LANGUAGE>",
"COOKIDOO_DEVICE": "<COOKIDOO_DEVICE>",
"COOKIDOO_IMAGE_DIRS": "<COOKIDOO_IMAGE_DIRS>"
}
}
}
}
Run commanddocker run -i --rm -e COOKIDOO_EMAIL -e COOKIDOO_PASSWORD -e COOKIDOO_COUNTRY -e COOKIDOO_LANGUAGE -e COOKIDOO_DEVICE -e COOKIDOO_IMAGE_DIRS ghcr.io/herp75/mcp-cookidoo:2.2.0
Environment variables to set
COOKIDOO_EMAILCookidoo account e-mail
COOKIDOO_PASSWORDSecretCookidoo account password (use a unique one)
COOKIDOO_COUNTRYCookidoo site country code, e.g. ch, de, fr (default fr)
COOKIDOO_LANGUAGECookidoo site language, e.g. de-CH, de-DE, fr-FR (default fr-FR)
COOKIDOO_DEVICEThermomix recipes are written for: TM5, TM6 or TM7 (default: detected)
COOKIDOO_IMAGE_DIRSFolders upload_custom_recipe_image may read, ':'-separated; in the container, mount them read-only (default: upload disabled)

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
ocighcr.io/herp75/mcp-cookidoo:2.2.0

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

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_recipe walks the assistant through writing a proper Thermomix recipe (EN / FR / DE)

Setup

Requires Python 3.12+ and uv.

uv sync
cp .env.example .env   # then fill in your Cookidoo credentials
VariableDefaultDescription
COOKIDOO_EMAIL—Cookidoo account email (required)
COOKIDOO_PASSWORD—Cookidoo account password (required)
COOKIDOO_COUNTRYfrCookidoo site country code (fr, de, gb, es, …)
COOKIDOO_LANGUAGEfr-FRSite language (e.g. de-DE); also the language guided-cooking settings are written in
COOKIDOO_DEVICE— (detected)Thermomix recipes are written for (TM5, TM6, TM7). Unset: from the devices linked to the account (TM6 rules if a TM6 is among them), else TM6
COOKIDOO_IMAGE_DIRS— (upload disabled)Folders upload_custom_recipe_image may read images from, separated by : (; on Windows)
COOKIDOO_MCP_TRANSPORTstdiostdio or http (same as --transport)
COOKIDOO_MCP_HOST127.0.0.1HTTP bind address. Any non-loopback address requires COOKIDOO_MCP_TOKEN
COOKIDOO_MCP_PORT8000HTTP port
COOKIDOO_MCP_TOKEN—Bearer token for HTTP mode, at least 32 characters (e.g. openssl rand -hex 32)
COOKIDOO_TEST_EMAIL, COOKIDOO_TEST_PASSWORD—Live tests only: a dedicated test account (see Live tests)
COOKIDOO_TEST_COUNTRY, COOKIDOO_TEST_LANGUAGEch, de-CHLive tests only: the test account's site

Usage

Claude Code
claude mcp add cookidoo -- uv run --directory /path/to/mcp-cookidoo server.py
Claude 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). For upload_custom_recipe_image, mount the photo folder read-only and name it in COOKIDOO_IMAGE_DIRS: add "-v", "/path/to/photos:/photos:ro", "-e", "COOKIDOO_IMAGE_DIRS=/photos" before the image name. 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-cookidoo

The 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 http

Clients 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 http

Without a token, the server only answers requests addressed to localhost, 127.0.0.1 or [::1] (Host header) and, from a browser, only pages served from this machine (Origin): this stops web pages from reaching it through DNS rebinding. Behind a reverse proxy or under another host name, set a token.

Use server.py rather than fastmcp run … --transport http, which skips these checks.

Development
uv run fastmcp dev inspector fastmcp.json           # MCP Inspector

Available 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.

ToolTypeDescription
Recipes
search_recipesreadSearch recipes by query, ingredients and max total time
get_recipe_detailsreadGet ingredients, steps and times of a recipe by ID
Custom recipes
list_custom_recipesreadList the custom recipes on your account
get_custom_recipereadGet a custom recipe as editable JSON
generate_recipe_structurereadValidate a new recipe for a Thermomix (TM5/TM6/TM7) and return its JSON
upload_custom_recipewriteCreate a custom recipe from that JSON, for a Thermomix
update_custom_recipedestructiveReplace an existing custom recipe with that JSON
copy_recipe_to_customwriteCopy a catalogue recipe into a new custom recipe, to adapt it
upload_custom_recipe_imagedestructiveSet a custom recipe's photo from a local image (see COOKIDOO_IMAGE_DIRS)
delete_custom_recipe †destructivePermanently delete a custom recipe
Shopping list
get_shopping_listreadRecipes, ingredients and hand-added items, with ticked state and IDs
add_recipes_to_shopping_listwriteAdd the ingredients of catalogue and/or custom recipes
remove_recipes_from_shopping_listdestructiveRemove recipes and their ingredients
add_shopping_list_itemswriteAdd items by hand ("milk", "2 lemons")
edit_shopping_list_itemsdestructiveRename items added by hand
mark_shopping_list_itemswriteTick items off, or put them back
remove_shopping_list_itemsdestructiveDelete items added by hand
clear_shopping_list †destructiveEmpty the whole shopping list
Meal plan
get_meal_plan_weekreadThe planned recipes of the 7 days starting at a day
add_to_meal_planwritePlan catalogue and/or custom recipes on a day
move_in_meal_plandestructiveMove a planned recipe to another day (rolled back on failure)
remove_from_meal_plandestructiveRemove recipes from a day (the recipes are kept)
Collections
list_collectionsreadYour own and followed collections with their recipes (paginated)
follow_collection / unfollow_collectionwrite / destructiveFollow or unfollow a Cookidoo collection
create_collectionwriteCreate a custom collection
delete_collection †destructiveDelete a custom collection (its recipes are kept)
add_to_collection / remove_from_collectionwrite / destructiveAdd or remove recipes in a custom collection
Thermomix
get_thermomix_modesreadSettings and modes a device supports, with limits and examples
Account
connect_to_cookidooreadCheck the configuration / force a fresh login (optional, tools log in automatically)
get_account_inforeadUser, Cookidoo site, subscription and devices
list_devicesreadThermomix 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:

modeDevicesFields and limitsWritten as (fr)Written as (de)
manual (default)TM5, TM6, TM7time (1 s – 99 min), temperature (optional: "37"…"95" by 5, "98", "100"…"120" by 5, or "varoma" on the TM6 only), speed (at most "6" with a temperature), reverse3 min/120°C/vitesse 13 Min./120°C/Stufe 1
doughTM6, TM7time (up to 20 min)Pétrin/2 minTeig kneten/2 Min.
browningTM7time (up to 30 min), temperature ("140"…"160" by 5), power (gentle, intense)Rissolage/5 min/160°C/intenseAnbraten/5 Min./160°C/Intensiv
steamingTM7time (up to 99 min), speed (up to "5"), reverse, accessory (varoma, simmering_basket, varoma_and_simmering_basket)Cuisson vapeur/20 min/Varoma/vitesse 1Dampfgaren/20 Min./im Varoma/Stufe 1
turboTM6, TM7time (0.5, 1 or 2 s), pulses (1 to 9, TM7 only)Turbo/0.5 sec/3 foisTurbo/0.5 Sek./3x
rice_cookerTM6, TM7noneRice cookerReis kochen
warm_upTM6, TM7temperature ("37"…"90"), speed ("soft", "1", "2"; no time: Cookidoo drops it)Réchauffage/65°C/vitesse 2Erwärmen/65°C/Stufe 2
blendTM6, TM7time (10 s – 5 min), speed ("6"…"8")Mixage/1 min/vitesse 8Pürieren/1 Min./Stufe 8

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_image is the only tool that reads a local file and sends it to the internet. It is off until you set COOKIDOO_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 CI

CI 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 up

They 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

License

MIT, see LICENSE and NOTICE.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.