Skip to main content
Glama
timo-reymann

mealie-mcp-server

by timo-reymann

mealie-mcp-server

LICENSE GitHub Actions GitHub Release Renovate

A Model Context Protocol (MCP) server for Mealie recipe management. Exposes 46 tools and 1 prompt for AI assistants to search, create, and manage recipes, meal plans, shopping lists, categories, and tags.

Features

  • Recipe Management — Search, create, patch, duplicate, and delete recipes. Batch-fetch multiple recipes with bounded concurrency.

  • Ingredient-Based Recipe Discoveryfind_recipes_for_ingredients resolves human-readable ingredient names (never Mealie food UUIDs) against Mealie's food taxonomy and finds matching recipes via Mealie's Recipe Finder, falling back to normal recipe search when there's no exact food match — useful for "what can I make with X" style discovery, including ingredients Mealie doesn't know by that exact name (the calling LLM broadens the search with substitute terms; the MCP itself never guesses substitutions).

  • Recipe Categories & Tags Assignment — Assign Categories and Tags to existing recipes with merge/replace semantics, name/slug/ID resolution, and optional auto-creation of missing values, without disturbing ingredients, instructions, nutrition, or any other recipe field. Available via patch_recipe, update_recipe_taxonomy, and update_recipe_taxonomy_batch.

  • Meal Planning — View, create, and bulk-create meal plans. Composite tool fetches meal plans with embedded recipe details (including nutrition) using concurrent batch requests, eliminating N+1 queries.

  • Shopping Lists — Full CRUD for lists and items, bulk operations, and recipe-to-list integration.

  • Categories & Tags — Full CRUD for organizing recipes, including empty-category/tag detection.

  • Batch & Composite Toolsget_recipes_batch and get_recipes_detailed_batch for bounded-concurrency recipe lookup, get_mealplan_with_recipes for meal plans with embedded recipe data and client-side date filtering, update_recipe_taxonomy_batch for bounded-concurrency category/tag updates across many recipes.

  • Zero Runtime Dependencies Beyond the SDK — Uses native fetch, no axios or httpx.

Related MCP server: mcp-mealie

Requirements

Installation

Quick start (npx)

MEALIE_BASE_URL=https://your-mealie-instance.com \
MEALIE_API_KEY=your-api-key \
npx mealie-mcp-server

opencode config

Add to your opencode.json:

{
  "mcp": {
    "mealie-mcp-server": {
      "type": "local",
      "command": ["npx", "mealie-mcp-server"],
      "enabled": true,
      "environment": {
        "MEALIE_BASE_URL": "https://your-mealie-instance.com",
        "MEALIE_API_KEY": "your-api-key"
      }
    }
  }
}

Docker

Run the MCP server in a container:

docker run -d \
  --name mealie-mcp-server \
  -e MEALIE_BASE_URL=https://your-mealie-instance.com \
  -e MEALIE_API_KEY=your-api-key \
  ghcr.io/timo-reymann/mealie-mcp-server:main

Or with Docker Compose:

version: '3.8'
services:
  mealie-mcp-server:
    image: ghcr.io/timo-reymann/mealie-mcp-server:main
    environment:
      MEALIE_BASE_URL: https://your-mealie-instance.com
      MEALIE_API_KEY: your-api-key
    restart: unless-stopped

Local development

git clone https://github.com/timo-reymann/mealie-mcp-server.git
cd mealie-mcp-server
corepack enable
yarn install
cp .env.template .env
# Edit .env with your MEALIE_BASE_URL and MEALIE_API_KEY
yarn dev

Make sure MEALIE_BASE_URL and MEALIE_API_KEY are set in your environment or opencode config.

Documentation

See API Coverage for a detailed breakdown of all 46 tools and their corresponding Mealie API endpoints.

Finding Recipes by Ingredient

find_recipes_for_ingredients lets an AI assistant discover recipes from human-readable ingredient names (e.g. "branzino", "chicken thighs") without ever needing to know Mealie's internal food UUIDs. The MCP handles all Mealie-specific mechanics — resolving names to Mealie Food objects, calling Mealie's Recipe Finder (GET /api/recipes/suggestions) or normal recipe search — while ingredient substitution/broadening (e.g. deciding that "sea bass" or "whole fish" are reasonable stand-ins for "branzino") is left to the calling LLM.

Ingredient resolution, in order, per ingredient:

  1. Exact case-insensitive match on the food's name.

  2. Exact case-insensitive match on the food's plural name or one of its aliases (Mealie's Food object has no slug field, unlike Category/Tag).

  3. A single unique result from Mealie's food search, if nothing above matched.

If a name matches multiple foods with no unique candidate (e.g. "fish"), it's reported back as ambiguous with the candidate names — the tool never guesses.

Search strategy, depending on what resolved:

{ "ingredients": ["salmon"], "categories": ["Dinner"] }

Resolves salmon to a Food, then uses Mealie's Recipe Finder — recipes are ranked by how many of the resolved ingredients they use and how few other ingredients they're missing. matchSource: "suggestions".

{ "ingredients": ["branzino"] }

No Food match for branzino → falls back to Mealie's normal recipe search (matches recipe name, description, and ingredient text). If that also finds nothing useful, unresolvedIngredients reports it so the LLM can retry with a broader term like "sea bass" or "whole fish". matchSource: "text-search" (or "none" if nothing came back).

{ "ingredients": ["chicken thighs", "broccoli"], "requireAllIngredients": true }

With two or more resolved ingredients and requireAllIngredients: true, uses Mealie's normal recipe search with a strict food-based AND filter instead of the Finder. matchSource: "food-filter".

categories/tags are resolved the same way as get_recipes — by name, slug, or ID, case-insensitively — before any search runs, and sent to Mealie as canonical IDs for the food-filter and text-search paths; for the Recipe Finder path (which has no taxonomy filters of its own) they're applied to the returned candidates instead.

Each returned recipe includes name, slug, description, categories, tags, totalTime, which requested ingredients it matched, and (for Recipe Finder results) which other ingredients it's missing — enough to decide what's worth a closer look with get_recipe_detailed or get_recipes_batch, without an extra round trip per candidate.

Assigning Categories & Tags

Categories are broad groupings (e.g. Dinner, Dessert) used to organize the recipe book, while Tags are more specific, free-form attributes (e.g. Quick, Dairy-Free). Both can be assigned to an existing recipe via update_recipe_taxonomy (a focused tool for this one job) or via patch_recipe (which also accepts categories/tags/taxonomyMode/createMissing alongside its existing fields, so a name/description edit and a taxonomy change can be sent in one call).

Every value in categories/tags may be a name, a slug, or an ID — matching against existing categories/tags is case-insensitive on name and slug. Results are deduplicated automatically.

Add a category and some tags, keeping everything else the recipe already has (mode: "merge", the default):

{
  "slug": "chicken-shawarma",
  "categories": ["Dinner"],
  "tags": ["Dairy-Free", "Quick"],
  "mode": "merge",
  "createMissing": false
}

Replace the tag list outright, discarding whatever tags were there before:

{
  "slug": "chicken-shawarma",
  "tags": ["Weeknight", "Middle Eastern"],
  "mode": "replace",
  "createMissing": true
}

createMissing: true above means Weeknight and Middle Eastern are created automatically if they don't already exist.

Clear all categories from a recipe by passing an explicit empty array with mode: "replace" — omitting categories instead would leave it untouched:

{
  "slug": "chicken-shawarma",
  "categories": [],
  "mode": "replace"
}

Update many recipes at once with update_recipe_taxonomy_batch. Each entry is processed independently (bounded concurrency) and the response includes a per-recipe success or error result, so one bad slug doesn't fail the whole batch:

{
  "updates": [
    { "slug": "chicken-shawarma", "categories": ["Dinner"], "mode": "merge" },
    { "slug": "banana-bread", "tags": ["Dessert", "Baking"], "mode": "merge" },
    { "slug": "does-not-exist", "categories": ["Dinner"], "mode": "merge" }
  ]
}

Both tools return the recipe's id/slug plus, per collection, the final list after the update and which items were added, removed, or created — useful for confirming exactly what changed.

Contributing

I love your input! Please read the Contribution Guidelines to get started.

Development

Requirements

  • Node.js >= 22

  • Yarn (via Corepack: corepack enable)

  • A Mealie instance for integration testing (or mock the fetch layer)

Test

yarn test

Typecheck

yarn typecheck

Build

yarn build

Lint

yarn lint

Available Tools (46 total)

Recipes (14)

get_recipes, find_recipes_for_ingredients, get_recipe_detailed, get_recipe_concise, get_recipes_batch, get_recipes_detailed_batch, create_recipe, patch_recipe, update_recipe_taxonomy, update_recipe_taxonomy_batch, duplicate_recipe, mark_recipe_last_made, set_recipe_image_from_url, delete_recipe

Meal Plans (5)

get_all_mealplans, get_mealplan_with_recipes, create_mealplan, create_mealplan_bulk, get_todays_mealplan

Categories (7)

get_categories, get_empty_categories, create_category, get_category, get_category_by_slug, update_category, delete_category

Tags (7)

get_tags, get_empty_tags, create_tag, get_tag, get_tag_by_slug, update_tag, delete_tag

Shopping Lists (13)

get_shopping_lists, create_shopping_list, get_shopping_list, update_shopping_list, delete_shopping_list, add_recipe_to_shopping_list, remove_recipe_from_shopping_list, get_shopping_list_items, create_shopping_list_item, create_shopping_list_items_bulk, update_shopping_list_item, delete_shopping_list_item, delete_shopping_list_items_bulk

License

MIT

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
1hResponse time
3dRelease cycle
17Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

  • Markdown-first MCP server for Notion API with 8 composite tools and 39 actions.

  • Recipes MCP — wraps TheMealDB API (free tier, no auth)

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/timo-reymann/mealie-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server