# Mealie MCP Connector Stellt die [Mealie](https://mealie.io/)-API als MCP-Server (Model Context Protocol) per HTTP bereit, damit Claude (claude.ai / Claude Desktop) lesend und schreibend auf Rezepte, Zutaten, Einkaufslisten, Essenspläne etc. zugreifen kann. Basiert auf dem Open-Source-Projekt [mdlopresti/mealie-mcp](https://github.com/mdlopresti/mealie-mcp) (FastMCP-basiert). ## Architektur ``` Claude Desktop (mcp-remote Bridge, --header X-Api-Key) │ HTTPS ▼ Pangolin Reverse Proxy (mealie-mcp.vogt.de.com) - terminiert TLS - prüft HTTP-Header X-Api-Key │ HTTP intern ▼ mealie-mcp Container (Docker, Port 8000, FastMCP HTTP-Transport) │ ▼ Mealie-Instanz (mealie.vogt.de.com) via REST-API + API-Token ``` **Wichtig:** Der Original-Container von `mdlopresti/mealie-mcp` läuft standardmäßig nur über **stdio** (gedacht für lokale Nutzung in Claude Code/Desktop via `.mcp.json`). Für einen **Custom Connector in claude.ai** bzw. eine Remote-Verbindung wird zwingend **Streamable HTTP** benötigt – daher wird der Container-Entrypoint überschrieben. ## Docker Compose ```yaml services: mealie-mcp: image: ghcr.io/mdlopresti/mealie-mcp:latest container_name: mealie-mcp restart: always environment: - MEALIE_URL=https://mealie.vogt.de.com - MEALIE_API_TOKEN=${MEALIE_API_TOKEN} entrypoint: ["fastmcp", "run", "src/server.py:mcp", "--transport", "http", "--host", "0.0.0.0", "--port", "8000"] ports: - '8082:8000' ``` `.env`: ``` MEALIE_API_TOKEN= ``` **Hinweis `entrypoint` vs. `command`:** Das Original-Image setzt bereits einen festen `ENTRYPOINT`. Ein reines `command:` würde nur als Argument angehängt und nichts bewirken – `entrypoint:` muss also komplett überschrieben werden. ## Reverse Proxy (Pangolin) - **Target:** `http://:8082` - **Domain:** `mealie-mcp.vogt.de.com` - **Pfad:** `/` (kein Pfad-Rewrite – der Server beantwortet selbst nur `/mcp`, die volle URL für Claude lautet `https://mealie-mcp.vogt.de.com/mcp`) - **Absicherung:** HTTP-Header-Regel, identisch zum Muster bei `gitea-mcp`: - Header-Name: `X-Api-Key` - Value: zufälliger Secret-String (`openssl rand -hex 32`) - Ohne korrekten Header blockt Pangolin den Request bereits auf Proxy-Ebene, bevor er den Container erreicht. ## Verbindung mit Claude **Wichtig:** claude.ai-Custom-Connectors (unter *Customize → Connectors*) unterstützen aktuell keine zuverlässige Möglichkeit, eigene HTTP-Header (wie `X-Api-Key`) mitzugeben. Daher läuft die Verbindung über die **lokale `mcp-remote`-Bridge in Claude Desktop**, die als lokaler Prozess startet und den Header serverseitig mitschickt. In der Claude-Desktop-Config (`claude_desktop_config.json`, Menü *Konnektoren → Lokale MCP-Server → Config bearbeiten*): ```json { "mcpServers": { "mealie": { "command": "npx", "args": [ "mcp-remote", "https://mealie-mcp.vogt.de.com/mcp", "--header", "X-Api-Key:${MEALIE_MCP_KEY}" ], "env": { "MEALIE_MCP_KEY": "" } } } } ``` Danach Claude Desktop neu starten. Die Mealie-Tools (Rezepte, Zutaten, Einkaufslisten, Essenspläne, …) stehen dann in jedem Chat zur Verfügung. ## Testen Handshake ohne Header (sollte von Pangolin blockiert werden, sobald der Header aktiv ist): ```bash curl -i https://mealie-mcp.vogt.de.com/mcp ``` Vollständiger MCP-Handshake mit korrekten Headern: ```bash curl -X POST https://mealie-mcp.vogt.de.com/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-Api-Key: " \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' ``` Eine erfolgreiche Antwort enthält `serverInfo` mit `"name":"mealie"`. ## Sicherheitshinweise - Der `mealie-mcp`-Server selbst hat **keine eigene Authentifizierung** – wer die URL ohne den `X-Api-Key`-Schutz erreicht, hat vollen Zugriff auf das hinterlegte Mealie-Konto (inkl. Löschen von Rezepten, Ändern von Einkaufslisten). - Empfohlen: dedizierter Mealie-Service-User statt des Haupt-Accounts für `MEALIE_API_TOKEN`. - Der Secret-Wert für `X-Api-Key` muss identisch in Pangolin und in der Claude-Desktop-Config gepflegt werden.