cookidoo-mcp

cookidoo-mcp

Enables LLMs to upload and manage Thermomix recipes on Cookidoo, including structured steps with Thermomix settings, images, and access to shopping lists and meal planning.

Category
访问服务器

README

cookidoo-mcp

An MCP server that bridges LLM sessions (Claude, Gemini, or any MCP client) to Cookidoo custom recipes on a Thermomix (TM7 by default). Describe a recipe in a chat, and the server uploads it as a Cookidoo custom recipe with proper structured Thermomix settings (time, temperature, speed, reverse) so it looks and behaves like an official recipe on the device.

The server ships its own German authoring guide as an MCP prompt and resource, so the writing rules for Thermomix steps do not have to live in your prompts.

Disclaimer: Cookidoo/Vorwerk offers no official public API. This project relies on the reverse-engineered API of miaucl/cookidoo-api and may break whenever the Cookidoo backend changes. Use at your own risk.

Prior art this project builds on:

  • miaucl/cookidoo-api - the unofficial Cookidoo API library used for login and session handling
  • alexandrepa/mcp-cookidoo - first Cookidoo MCP server, source of the create/patch upload flow
  • Xdev22/cookidoo-mcp - discovered the structured TTS and INGREDIENT annotations that make custom recipes look like official ones

Features

  • upload_recipe - upload a recipe with structured ingredients and steps. The LLM supplies semantics only (text, time, temperature, speed, reverse); the server renders the German settings notation and computes all Cookidoo annotations itself. Optional image_url/image_base64 parameters attach a photo in the same call.
  • set_recipe_image - set or replace the photo of an existing custom recipe, from an https URL or base64 data.
  • list_custom_recipes - list your custom recipes.
  • get_custom_recipe - fetch one custom recipe by id.
  • delete_custom_recipe - delete a custom recipe by id.
  • get_recipe_details - fetch any Cookidoo recipe by id.
  • get_shopping_list, add_items_to_shopping_list, add_recipe_to_shopping_list - read and fill the shopping list.
  • get_meal_plan, add_recipe_to_meal_plan - read and fill the weekly planner.
  • MCP prompt and resource with the full German Thermomix authoring guide, plus compact server instructions delivered to every client on connect.
  • Optional GitHub OAuth with a user allowlist and persistent client registrations for safe public exposure.

Recipe images

Custom recipes can carry a photo. Pass image_url or image_base64 (exactly one source; base64 works with or without a data URI prefix) to upload_recipe, or call set_recipe_image for a recipe that already exists. JPEG and PNG are supported, from 80x80 pixels (smaller images are rejected by Cookidoo) up to 10 MB. URL images are downloaded by the server itself (https only), and Cookidoo re-hosts every image on its own CDN. Clients should downscale images to about 800px (JPEG, quality around 70) before embedding them as base64. An image failure does not abort the recipe upload; the result then contains an image_warning instead.

Requirements

  • Python 3.12 or newer
  • uv
  • A Cookidoo account with an active subscription

Setup

uv sync
cp .env.example .env

Then edit .env and fill in your Cookidoo credentials:

Variable Meaning Default
COOKIDOO_EMAIL Cookidoo account email required
COOKIDOO_PASSWORD Cookidoo account password required
COOKIDOO_COUNTRY Country code de
COOKIDOO_LANGUAGE Language code de-DE
THERMOMIX_MODEL Device written to the recipe tools field TM7

Locale examples:

Country COOKIDOO_COUNTRY COOKIDOO_LANGUAGE
Germany de de-DE
Austria at de-AT

Running

uv run cookidoo-mcp

This starts the server with streamable HTTP transport on http://127.0.0.1:8000/mcp. Host and port are configurable via MCP_HOST and MCP_PORT.

For clients that spawn the server as a subprocess, use stdio transport instead:

MCP_TRANSPORT=stdio uv run cookidoo-mcp

Client configuration

Claude Code

claude mcp add --transport http cookidoo http://localhost:8000/mcp

Claude Desktop

Add the server to your claude_desktop_config.json:

{
  "mcpServers": {
    "cookidoo": {
      "type": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}

Public exposure and OAuth

Connectors on claude.ai (web, mobile app, and the Claude Desktop connector dialog) are established from Anthropic servers, so LAN-only deployments are not reachable there. To use the server from those clients it must be exposed to the internet - and then it MUST be protected, otherwise anyone could use your Cookidoo account.

The server supports GitHub OAuth via FastMCP:

  1. Register an OAuth app at https://github.com/settings/developers. Homepage: your MCP_BASE_URL; callback URL: <MCP_BASE_URL>/auth/callback.
  2. Set GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, MCP_BASE_URL, ALLOWED_GITHUB_USERS (and ideally MCP_JWT_SIGNING_KEY plus MCP_STATE_DIR for persistent client registrations - without it a restart disconnects all authorized clients) in the .env file and restart the container.
  3. Make the server publicly reachable (see below).
  4. Add the connector with your public https://.../mcp URL; Claude redirects you through the GitHub login once per client.

Only the GitHub accounts listed in ALLOWED_GITHUB_USERS are accepted; every other login is rejected after authentication. Without the GitHub variables the server runs unauthenticated as before - keep it LAN-only in that case.

Recommended public exposure: Cloudflare Tunnel

The battle-tested setup (and the one this project runs in production) is a Cloudflare Tunnel in front of a localhost-only server container:

  1. Put a domain on Cloudflare (free plan; only the nameservers change, the registration stays where it is), create a tunnel under Zero Trust -> Networks -> Tunnels, and map a public hostname such as cookidoo.example.com to http://localhost:8443.

  2. Run the connector next to the server (same host):

    docker run -d --name cloudflared --network host \
      --restart unless-stopped \
      -e TUNNEL_TOKEN=<your tunnel token> \
      cloudflare/cloudflared:latest tunnel run
    
  3. Bind the server container to localhost only (the deploy script does this), drop the MCP_SSL_* variables (Cloudflare terminates TLS with auto-renewing certificates) and set MCP_BASE_URL and the GitHub app URLs to the tunnel hostname.

This needs no router port forwarding and works behind DS-Lite or CGNAT, because the tunnel connects outbound and Cloudflare provides a dual-stack edge - important since the claude.ai connector infrastructure connects over IPv4 only, so an IPv6-only port release is never reached.

Known pitfall: Tailscale Funnel does NOT work as the public endpoint for claude.ai connectors. The funnel edge intermittently aborts TLS handshakes, and the multi-request OAuth flow of the connector broker gives up on the first failure, surfacing as "Couldn't reach the MCP server" with zero requests in your logs - even though curl and Claude Code work fine through the same funnel.

Testing

uv run pytest

Unit and integration tests run offline against mocked HTTP. The end-to-end tests in tests/test_e2e.py talk to the live Cookidoo API and are skipped unless real credentials are present in .env.

Docker

Prebuilt image (recommended)

Every push to main builds a multi-arch image (amd64/arm64) via GitHub Actions and publishes it as ghcr.io/jsaedtler/cookidoo-mcp-docker:latest. On the server you only need the credentials file and one script:

sudo mkdir -p /docker/cookidoo-mcp
sudo cp .env.example /docker/cookidoo-mcp/.env   # fill in your credentials
./deploy/update-cookidoo-mcp.sh

deploy/update-cookidoo-mcp.sh stops and removes the old container, pulls the latest image and starts it again with --restart=unless-stopped. Re-run it any time to update. Adjust the ENV_FILE, SSL_DIR, STATE_DIR and PORT variables at the top of the script to your setup.

HTTPS without a tunnel

When you do not use the Cloudflare Tunnel (for example LAN-only use with Claude Desktop, which requires an https URL), the server can terminate TLS itself: set MCP_SSL_CERTFILE and MCP_SSL_KEYFILE and mount a certificate directory into the container (the deploy script does this via SSL_DIR). Any certificate you already have works, for example a Let's Encrypt certificate from another service on the same host. The hostname in the MCP URL must match the certificate. After a certificate renewal restart the container (docker restart cookidoo-mcp) so it picks up the new files.

Build locally

cp .env.example .env   # fill in your Cookidoo credentials
docker compose up -d --build

The server then listens on http://<host>:8000/mcp (Streamable HTTP) for clients in your network. To change the port, adjust both sides of the ports mapping in docker-compose.yml.

Notes:

  • Credentials are injected at runtime via env_file; the .env file is never baked into the image (see .dockerignore).
  • The container binds :: (dual-stack). If the Docker daemon runs with ip6tables: true, published ports are DNATed to the container's IPv6 address, so a v4-only bind would time out for all IPv6 clients even though the port looks open on IPv4.
  • The image runs as a non-root user and builds on both amd64 and arm64.
  • Typical deployment on a server: clone the repository, create .env, run docker compose up -d --build. The restart: unless-stopped policy brings the container back after reboots.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选