Mealie MCP
# Mealie MCP
[](LICENSE)
An [MCP](https://modelcontextprotocol.io) server that exposes a self-hosted [Mealie](https://mealie.io) instance to MCP clients like Claude — recipes, meal plans, shopping lists, and organizers (categories/tags).
## What it does
- **Recipes** — list/search, get details, create, import from a URL, update, delete
- **Meal Plans** — get today's meals, list a date range, create/delete entries, add a random recipe
- **Shopping Lists** — list, get, create, delete, add a recipe's ingredients, add a single item, check off items
- **Organizers** — list categories and tags
- **Utilities** — get a recipe's nutrition info
## Project layout
```
src/mealiemcp/
├── app.py # FastMCP instance + auth setup
├── config.py # environment variable loading
├── client.py # Mealie HTTP client factory
├── security.py # input validation (slug/id allowlists, SSRF guard)
├── audit.py # logs which tool was called, by whom, and when
├── recipes.py ┐
├── meal_plans.py ├─ tool modules, one per Mealie domain
├── shopping_lists.py │
├── organizers.py ┘
└── server.py # registers tool modules, entry point (main())
tests/ # unit tests (pytest)
```
## Setup
Requires [uv](https://docs.astral.sh/uv/).
```bash
uv sync
cp .env.example .env # fill in your Mealie URL and API token
uv run mealiemcp
```
Run the tests with:
```bash
uv run pytest
```
Environment variables (see `src/mealiemcp/config.py` for details):
| Variable | Purpose |
|---|---|
| `MEALIE_BASE_URL` | URL of your Mealie instance |
| `MEALIE_API_TOKEN` | Mealie API token this server uses to call Mealie |
| `MCP_TRANSPORT` | `stdio` (default, for local clients like Claude Desktop/Code) or `streamable-http` (to expose over a network) |
| `MCP_HOST` / `MCP_PORT` | Bind address/port when using `streamable-http` |
| `MCP_AUTH_TOKEN` | Bearer token remote clients must present — required when `MCP_TRANSPORT` isn't `stdio` |
| `MCP_AUTH_TOKEN_EXPIRES_AT` | `YYYY-MM-DD` (UTC) — `MCP_AUTH_TOKEN` stops being accepted after this date, forcing periodic rotation. Required alongside `MCP_AUTH_TOKEN` |
A `Dockerfile` is included for running in `streamable-http` mode behind a reverse proxy.
### Auth model
This is designed for a single user running their own instance, not a multi-tenant service. Remote access is a single shared bearer token (`MCP_AUTH_TOKEN`) rather than full OAuth — proportionate for one person's personal Mealie server. To limit the blast radius of a leaked token:
- It has a hard expiry (`MCP_AUTH_TOKEN_EXPIRES_AT`) and must be rotated periodically
- Every tool call is logged (tool name, authenticated client, success/failure, duration) via `audit.py`, so a misused token leaves a trace
## License and disclaimer
This project is free to use, for any purpose, with no warranty of any kind. **The author assumes no liability** for any use of this software or any consequences arising from it — you use it entirely at your own risk. See the [LICENSE](LICENSE) file for the full terms.
**This entire codebase was generated by AI.** It has only been tested through the author's personal use against their own Mealie instance and has not been independently audited or reviewed. Review the code yourself before relying on it, especially before exposing it to a network.
TDQS
Scored across 21 tools
Tools are mostly distinct, with slight overlap between add_random_meal_plan and create_meal_plan, and between add_shopping_item and add_recipe_to_shopping_list. Descriptions are clear enough for an agent to choose correctly.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., create_recipe, list_recipes, delete_meal_plan). The naming is predictable and easy to understand.
With 21 tools, the set is slightly above the ideal range but still well-scoped for a meal planning and recipe management server. Each tool serves a clear purpose without excessive overlap.
The tool set covers most CRUD operations for recipes, meal plans, and shopping lists. Missing updates for meal plans and shopping lists, and deletion of individual shopping items, but core workflows are supported.