Better Mealie MCP
๐ฒ Better Mealie MCP
An MCP server exposing every Mealie API endpoint โ all 250+ operations, none excluded. Manage recipes, meal plans, shopping lists, households and more from any AI assistant, in natural language.
Built with FastMCP from_openapi: tools are
generated straight from Mealie's OpenAPI spec, so the server stays in sync with
Mealie and nothing is hand-maintained. See TOOLS.md for the full
tool list.
๐ฌ What can you do with it?
You say | What happens |
"Add a chicken tikka masala recipe from this URL" | Scrapes and imports the recipe |
"What can I cook with what's in my pantry?" | Searches recipes by your ingredients |
"Plan my dinners for next week" | Creates meal-plan entries |
"Build a shopping list for those meals" | Generates a consolidated shopping list |
"Tag all my soups as 'winter'" | Bulk-updates recipe tags |
๐ง Setup Wizard
Don't hand-write JSON. The wizard walks you through every choice and emits a ready-to-paste config for your combination:
Install โ Docker image or from source.
Client โ Claude Code, Claude Desktop, Cursor, VS Code, Gemini CLI, or ChatGPT (it knows each one's config shape).
Connection โ stdio or HTTP, API token or username/password.
Limit tools (optional) โ trim the 259 tools to just the groups you need, for leaner context or clients that cap tool counts. Start from a pack (Cooking, Meal planning, Sharing & browse, Admin & users) or pick groups individually; tap a group's โ to see every tool inside it. Your choice is baked into the generated config as
MEALIE_INCLUDE_TAGS.
๐ Setup
Docker (GHCR image):
docker pull ghcr.io/djwmarcx/better-mealie-mcp
docker run -i --rm \
-e MEALIE_BASE_URL=http://host.docker.internal:9925 \
-e MEALIE_API_TOKEN=... \
ghcr.io/djwmarcx/better-mealie-mcp # stdio; add `--http 8000` for HTTPImages are published on each release, tagged <mealie-version> and latest.
Inside a container, localhost is the container โ point MEALIE_BASE_URL at
host.docker.internal (macOS/Windows) or your host's LAN IP (Linux).
From source:
git clone https://github.com/djwmarcx/better-mealie-mcp
cd better-mealie-mcp
uv sync # install deps
cp .env.example .env # then edit .env with your Mealie URL + tokenAuth (set in .env or the environment):
Var | Meaning |
| Mealie base URL (default |
| Long-lived API token (preferred) โ Mealie โ Profile โ Manage API Tokens |
| Alternative: logs in at startup to fetch a token |
| Per-request timeout, seconds (default 60) |
| Verify TLS cert; |
| MCP name advertised to clients (default |
| Expose only these API groups, comma-separated (e.g. |
| Expose everything except these groups (e.g. |
| Trim redundant schema noise โ default |
| Also collapse nullable |
| Emit per-tool output schemas + validate results โ default |
Groups are the first path segment of the API (recipes, households, admin,
organizers, users, explore, foods, units, โฆ). Unset = every tool.
INCLUDE wins if both are set. See TOOLS.md for the current
groups and what's in each, or let the
Setup Wizard pick them โ its
group picker (with one-click packs like Cooking or Meal planning) fills
MEALIE_INCLUDE_TAGS for you.
Context size (schema detail)
Every tool this server exposes ships its JSON schema to the model on every request โ that "idle context" is pure overhead until a tool is actually called. With all 259 tools the full schemas are ~240k tokens, so the server trims them. Three preset modes (all endpoints stay callable โ only the schema detail the model sees changes):
Mode | Env | Idle context | What it does |
Lean (default) | (none โ the default) | ~61k tok | Drops redundant |
Leanest |
| ~51k tok | Everything Lean does, plus collapses nullable |
Full |
| ~240k tok | Complete, untrimmed input and output schemas, with client-side result validation. Use only if your client relies on structured-output schemas. |
Everything the model needs to make a correct call (format, real
descriptions, required fields) is kept in every mode. Combine with tag
filtering above to shrink further โ the
Setup Wizard shows a live token
estimate for your exact combination.
โถ๏ธ Run
uv run better-mealie-mcp # stdio transport (for MCP clients)
uv run better-mealie-mcp --http 8000 # streamable-http on 127.0.0.1:8000
uv run server.py # same server, back-compat entry
fastmcp run fastmcp.json # via FastMCP project config (stdio)
fastmcp run fastmcp-http.json # via FastMCP project config (http)In --http mode the bind address comes from MCP_HOST (default 127.0.0.1;
the Docker image sets 0.0.0.0 so -p port mapping works).
๐งช Test against a local Mealie (Docker)
docker run -d --name mealie -p 9925:9000 \
-e ALLOW_SIGNUP=true -e BASE_URL=http://localhost:9925 -e TZ=UTC \
ghcr.io/mealie-recipes/mealie:latestDefault admin login: changeme@example.com / MyPassword.
๐ Notes
Exposing every endpoint is a lot of tools โ a lot of idle context. Most clients handle it fine. If yours caps tool counts or you want a leaner context, trim the toolset with
MEALIE_INCLUDE_TAGS/MEALIE_EXCLUDE_TAGS(see Setup) or the wizard's group picker.
Versioning
This MCP's version mirrors the Mealie version its spec targets โ MCP
3.20.1 โ Mealie v3.20.1. The server advertises it to clients, and
VERSIONS.md maps every release to its Mealie version and date.
MCP-only changes (features/fixes with no Mealie version change) ship as a
revision of the same Mealie version: the REVISION counter
bumps and the release/image tag gains a -r<n> suffix โ e.g. v3.20.1-r2
(-r1 is the base and carries no suffix). A new Mealie version resets the
counter. :latest always points at the newest build.
openapi.json is a vendored copy of Mealie's spec. The
update-spec workflow runs daily and
auto-tracks the latest stable Mealie release (mealie:latest): it boots that
image, reads its real version from /api/app/about
(MEALIE_VERSION), pulls /openapi.json, regenerates
TOOLS.md + counts, and โ only when the spec actually changed โ
bumps the version and opens a pull request (main is protected, so every
change lands via PR). When that PR merges,
release-on-spec cuts a
release (spec attached,
notes listing added/removed tools). Volatile server-clock defaults are stripped
so an unchanged run is a true no-op.
To freeze on one release instead of tracking latest, set MEALIE_TAG_DEFAULT in
the workflow to a specific tag (e.g. v3.20.1), or run it manually with a
mealie_tag input (latest, nightly, or any tag).
A few endpoints (
list_auth_oauth*) return 500 unless OIDC is configured on the Mealie side โ that's Mealie behavior, not the server.