Skip to main content
Glama
Mealie MCP Server

Mealie MCP Server

by bitmonster

Mealie MCP Server

A security-conscious Model Context Protocol server for self-hosted Mealie instances.

It exposes recipe search and import, shopping lists, meal plans, organizers, ingredient parsing, OCR helpers, recipe images/assets, Chefkoch lookup, and a guarded bridge to non-sensitive Mealie OpenAPI operations.

Community project. Not affiliated with or endorsed by Mealie.

Security defaults

  • Read-only by default: mutations require MEALIE_MCP_ALLOW_MUTATIONS=true.

  • Fail-closed scopes: no write is allowed unless its path matches an explicit scope.

  • Explicit confirmation: every helper that persists data and every generic write requires confirmed_by_user=true.

  • Sensitive API denylist: admin, authentication, user, group, invitation, webhook, and household self-service endpoints remain blocked even when mutations are enabled.

  • Outbound fetches off by default: URL imports and remote file sources require separate opt-in flags in addition to mutation scopes.

  • SSRF protection: enabled remote sources must resolve to public HTTP(S) addresses; loopback, private, link-local, and other non-public destinations are rejected.

  • Local-file confinement: multipart uploads may only read from the MCP data directory or explicitly configured local roots.

  • Credential redaction: configured tokens and passwords are removed from reported errors.

  • Bounded work: JSON/OpenAPI responses, local/remote sources, downloads, image pixels, pagination, and OCR runtime have limits.

  • Transport safety: remote Mealie origins require HTTPS, and authenticated Mealie requests reject redirects.

Review SECURITY.md before enabling writes.

Related MCP server: Mealie MCP Server

Requirements

  • Python 3.11+

  • uv

  • A reachable Mealie instance (tested against Mealie OpenAPI v3.21.0)

  • A Mealie long-lived API token, recommended

  • Optional: Tesseract for OCR (tesseract-ocr plus the desired language packs)

Quick start

git clone https://github.com/bitmonster/mealie-mcp-server.git
cd mealie-mcp-server
uv sync --frozen
chmod +x run_mealie_mcp.sh

Create a long-lived token in Mealie under Profile → API tokens. Pass it through your MCP client environment; do not put it in source control.

Hermes Agent

mcp_servers:
  mealie:
    command: /absolute/path/to/mealie-mcp-server/run_mealie_mcp.sh
    env:
      MEALIE_BASE_URL: http://localhost:9000
      MEALIE_PUBLIC_URL: https://mealie.example.com
      MEALIE_API_TOKEN: "[REDACTED]"
      MEALIE_MCP_ALLOW_MUTATIONS: "false"
      MEALIE_MCP_MUTATION_SCOPE: none
      MEALIE_MCP_ALLOW_URL_IMPORTS: "false"
      MEALIE_MCP_ALLOW_REMOTE_SOURCES: "false"

Restart Hermes after changing MCP configuration, then run:

hermes mcp test mealie

Generic stdio MCP client

Configure the command as:

/absolute/path/to/mealie-mcp-server/run_mealie_mcp.sh

Set the environment variables shown in .env.example. The server reserves stdout for MCP JSON-RPC and writes startup errors to stderr.

Authentication

Preferred:

MEALIE_API_TOKEN=[REDACTED]

Optional fallback for local testing:

MEALIE_USERNAME=[REDACTED]
MEALIE_PASSWORD=[REDACTED]

The fallback performs a normal /api/auth/token login and caches the short-lived token in memory. Do not embed credentials in the repository or starter script.

Mutation scopes

Mutations require both:

MEALIE_MCP_ALLOW_MUTATIONS=true
MEALIE_MCP_MUTATION_SCOPE=<comma-separated scopes>

Scope

Allowed write areas

recipe_import

Recipe creation/PATCH, images, assets, duplicate, last-made, ZIP/image/URL imports

shopping

Shopping lists, items, bulk operations, recipe ingredients added to lists

mealplan

Meal-plan entries, random suggestions, and meal-plan rules

parser

Generic parser API mutations; the dedicated non-persisting ingredient parser does not require mutation mode

organizers

Categories, tags, foods, and units

cookbooks

Household cookbooks

comments

Recipe comments

timeline

Recipe timeline events and images

recipe_actions

Household recipe actions

all

Every non-sensitive mutation; use only for tightly trusted clients

Example for recipe imports and organizer cleanup:

MEALIE_MCP_ALLOW_MUTATIONS=true
MEALIE_MCP_MUTATION_SCOPE=recipe_import,organizers

Scopes do not override the sensitive-endpoint denylist or confirmation requirements. URL imports additionally require MEALIE_MCP_ALLOW_URL_IMPORTS=true. Remote image or asset sources additionally require MEALIE_MCP_ALLOW_REMOTE_SOURCES=true.

Main capabilities

The server currently registers 38 MCP tools, including:

  • recipe search, lookup, suggestions, URL/text imports, duplication, last-made updates;

  • image replacement, source asset upload, cover cropping, and cookbook-image OCR;

  • shopping-list and meal-plan CRUD helpers using Mealie v3 full-model updates;

  • organizer listing and ingredient parsing;

  • Chefkoch search and recipe extraction;

  • live OpenAPI catalog search;

  • generic JSON/multipart requests and controlled binary downloads for non-sensitive operations.

Use mealie_api_operations before a generic OpenAPI call. It validates operation IDs, path/query parameters, required body fields, content type, sensitivity, confirmation, and mutation scope.

File and download configuration

Variable

Default

Purpose

MEALIE_MCP_DATA_DIR

~/.cache/mealie-mcp

Runtime data root

MEALIE_MCP_DOWNLOAD_DIR

$DATA_DIR/downloads

Controlled download directory

MEALIE_MCP_ALLOWED_LOCAL_ROOTS

empty

Additional local upload roots, separated by the OS path separator

MEALIE_MCP_MAX_DOWNLOAD_BYTES

100 MiB

Maximum binary download size

MEALIE_MCP_MAX_JSON_BYTES

10 MiB

Maximum JSON response size

MEALIE_MCP_MAX_OPENAPI_BYTES

20 MiB

Maximum OpenAPI response size

MEALIE_MCP_MAX_IMAGE_PIXELS

40,000,000

Maximum decoded image pixels

MEALIE_MCP_OCR_TIMEOUT

60 seconds

Tesseract timeout per OCR call

MEALIE_MCP_TIMEOUT

30 seconds

HTTP timeout

MEALIE_MCP_ALLOW_URL_IMPORTS

false

Allow Mealie to fetch validated public recipe URLs

MEALIE_MCP_ALLOW_REMOTE_SOURCES

false

Allow this MCP process to fetch validated public file URLs

Default local upload roots are $DATA_DIR/imports and the download directory. Add the narrowest possible absolute path when another client-managed media cache is needed.

Development

uv sync --frozen --all-groups
uv run python -m compileall -q mealie_server.py tests
uv run ruff check mealie_server.py tests
uv run python -m unittest discover -s tests -p 'test_*.py' -v
uv run pip-audit --skip-editable

The regression suite mocks network and filesystem boundaries. It covers mutation gating, confirmation, sensitive-path blocking, OpenAPI validation, SSRF/local-file confinement, multipart limits, Mealie v3 request shapes, ingredient preservation, and credential-safe status output.

Known boundaries

  • This is a stdio MCP server, not a remotely exposed HTTP service.

  • Mealie streaming/SSE import operations are intentionally unsupported.

  • Generic operations follow the live Mealie OpenAPI, but dedicated helper tools may need adaptation after breaking Mealie API changes.

  • Raw API paths are fail-closed unless they match a live OpenAPI operation; sensitive path prefixes and OpenAPI tags remain denied.

  • Public-address validation reduces SSRF risk but cannot enforce the network behavior of Mealie itself. When enabling URL imports or remote sources, also restrict container/host egress and DNS at the deployment layer.

  • Chefkoch integration is optional functionality supplied through the get-chefkoch dependency.

  • OCR quality depends on the local Tesseract installation and source image quality.

License

MIT — see LICENSE.

Available Tools

38 tools
mealie_aboutB

Return public Mealie app/version information.

Inputs: no named parameters. Returns: object

mealie_add_recipe_to_shopping_listC

Add a recipe's ingredients to a shopping list using Mealie v3.

Inputs: recipe_id (required), shopping_list_id (required), confirmed_by_user, recipe_increment_quantity.

mealie_add_shopping_itemA

Add an item to a shopping list after explicit user confirmation.

Inputs: display (required), shopping_list_id (required), note, checked, +2 more. Returns: object

mealie_api_downloadC

Download a non-sensitive binary GET operation to a controlled local directory.

Inputs: operation_id (required), output_name, path_params, query_params. Returns: object

mealie_api_getC

Generic authenticated GET validated against live OpenAPI and security tags.

Inputs: path (required), params.

mealie_api_multipart_operation_requestC

Execute a non-sensitive multipart Mealie operation by OpenAPI operation ID.

file_sources maps multipart field names to direct HTTP(S)/file URLs or local paths. Mutations require explicit confirmation and an enabled scope.

Inputs: operation_id (required), fields, path_params, file_sources, +2 more.

mealie_api_operation_requestA

Execute a non-sensitive JSON Mealie operation by OpenAPI operation ID.

Use mealie_api_operations first. Mutations require explicit confirmation and remain restricted by MEALIE_MCP_MUTATION_SCOPE. Multipart/binary operations require a dedicated MCP tool.

Inputs: operation_id (required), body, path_params, query_params, +1 more.

mealie_api_operationsA

Search the live Mealie OpenAPI operation catalog.

Returns operation IDs, methods, paths, tags, parameters, and content types. Admin/auth/user/backup/maintenance operations are hidden by default and are documentation-only even when include_sensitive=True.

Inputs: tag, limit, query, method, +1 more. Returns: object

mealie_api_requestA

Generic JSON Mealie API request for non-sensitive paths.

Non-GET methods require explicit user confirmation and an enabled mutation scope. Prefer mealie_api_operation_request because it validates against the live OpenAPI document.

Inputs: path (required), method (required), body, params, +1 more.

mealie_create_mealplanB

Create a household mealplan entry. Date must be ISO yyyy-mm-dd.

Inputs: date (required), text, title, recipe_id, +2 more. Returns: object

mealie_create_recipe_from_textA

Create a Mealie recipe from OCR/vision-extracted text and optional images.

Requires mutations enabled AND confirmed_by_user=True. Use this after showing the user a preview of title, ingredients, steps, tags, and asking for explicit confirmation. Ingredient lines are stored in display and note so Mealie mobile renders them correctly.

For cookbook/photo imports, the agent may choose a title-image crop itself: pass cover_crop_box=[left, top, right, bottom] with cover_crop_units="percent" (default, 0..100; fractional 0..1 is accepted too) or "pixels". The crop is taken from cover_crop_source_url, otherwise main_image_url, otherwise source_image_url, and uploaded as the Mealie recipe cover. The full source_image_url can still be uploaded as the original cookbook asset.

Inputs: name (required), ingredients (required), instructions (required), tags, +15 more. Returns: object

mealie_create_recipe_from_urlA

Import/create a recipe from a public web URL after explicit confirmation.

Inputs: url (required), include_tags, confirmed_by_user, include_categories. Returns: object

mealie_create_shopping_listB

Create a shopping list after explicit user confirmation.

Inputs: name (required), confirmed_by_user. Returns: object

mealie_delete_mealplanA

Delete a mealplan entry after explicit confirmation.

Inputs: item_id (required), confirmed_by_user. Returns: object

mealie_delete_recipe_imageA

Delete an existing recipe cover image after explicit confirmation.

Inputs: slug_or_id (required), confirmed_by_user. Returns: object

mealie_delete_shopping_itemA

Delete one shopping list item after explicit confirmation.

Inputs: item_id (required), confirmed_by_user. Returns: object

mealie_duplicate_recipeB

Duplicate a recipe, optionally assigning a new name.

Inputs: slug_or_id (required), new_name, confirmed_by_user.

mealie_extract_recipe_text_from_imageA

OCR: Extrahiere Rohtext aus einem Kochbuchfoto/Screenshot.

Lädt das Bild von einer URL oder lokalem Pfad, bereitet es für OCR auf (Graustufen, Kontrast, Binarisierung) und gibt den erkannten Text zurück.

Der Rohtext kann dann per Text-LLM in Zutaten/Anweisungen strukturiert und mit mealie_create_recipe_from_text importiert werden.

Das spart teure Vision-API-Aufrufe.

Inputs: image_url (required), ocr_lang. Returns: object

mealie_get_chefkoch_recipeA

Rufe ein vollstaendiges Chefkoch-Rezept mit allen Details ab.

Liefert Zutaten-Liste, Schritt-fuer-Schritt-Anleitung, Zubereitungszeit, Kategorie, Bewertung und Naehrwerte (falls vorhanden) fuer ein Rezept.

Der Bot nutzt diese Daten, um das Rezept strukturiert anzuzeigen oder in Mealie zu importieren.

Inputs: url (required). Returns: object

mealie_get_recipeA

Fetch one recipe by slug or id.

Inputs: slug_or_id (required). Returns: object

mealie_get_shopping_itemA

Fetch one household shopping list item by id.

Inputs: item_id (required). Returns: object

mealie_get_shopping_listB

Fetch one household shopping list by id.

Inputs: shopping_list_id (required). Returns: object

mealie_get_todays_mealsA

Fetch today's household meal plan entries.

Inputs: no named parameters.

mealie_list_mealplansB

List household meal plans. Dates are ISO yyyy-mm-dd strings.

Inputs: page, end_date, per_page, start_date. Returns: object

mealie_list_organizersC

List tags, categories, foods, units, cookbooks, comments, or timeline events.

Inputs: kind (required), page, search, per_page.

mealie_list_shopping_itemsA

List shopping list items, optionally filtered by shopping list and checked state.

Inputs: page, checked, per_page, shopping_list_id. Returns: object

mealie_list_shopping_listsC

List household shopping lists.

Inputs: page, per_page. Returns: object

mealie_mark_recipe_madeB

Set a recipe's last-made timestamp using an ISO 8601 date-time.

Inputs: timestamp (required), slug_or_id (required), confirmed_by_user.

mealie_parse_ingredientsA

Parse ingredient lines via Mealie's ingredient parser.

Accepts a list of raw ingredient strings (e.g. '650 g Süßkartoffeln, in etwa 4 cm große Würfel geschnitten') and returns structured results with quantity, unit, food, and note fields.

The parsed results can be passed directly to mealie_update_recipe_ingredients for updating existing recipes.

Inputs: ingredients (required). Returns: object

mealie_recipe_suggestionsC

Return Mealie recipe suggestions.

Inputs: limit.

mealie_search_chefkochA

Suche Rezepte auf Chefkoch.de.

Durchsucht Chefkoch.de nach Rezepten passend zur Suchanfrage und gibt eine Liste mit Grundinformationen zurueck (Titel, URL, Beschreibung, Bild, Kategorie, Zubereitungszeit, Bewertung).

Verwendung: Vor einem Mealie-Import die Rezeptsuche, um das passende Rezept zu finden. Der Benutzer kann dann per URL oder per mealie_get_chefkoch_recipe die vollstaendigen Details abrufen.

Inputs: query (required), limit. Returns: result

mealie_search_recipesC

Search Mealie recipes. Supports Mealie queryFilter syntax for advanced filters.

Inputs: page, search, order_by, per_page, +2 more. Returns: object

mealie_statusA

Check server reachability and whether authentication works.

Inputs: no named parameters. Returns: object

mealie_update_mealplanB

Update a mealplan entry using Mealie v3's full-model PUT endpoint.

Inputs: item_id (required), updates (required), confirmed_by_user. Returns: object

mealie_update_recipe_imageA

Upload or replace the cover image of an existing Mealie recipe.

The image is read from an HTTP(S) URL, file:// URL, or local path and sent to Mealie as a real multipart file upload. It is never stored as an external URL in the recipe object. Requires mutations enabled and an explicit user confirmation. An optional crop uses [left, top, right, bottom] in percent (default), fraction, or pixels.

Inputs: slug_or_id (required), image_source (required), crop_box, crop_units, +1 more. Returns: object

mealie_update_recipe_ingredientsA

Replace the ingredient list of an existing Mealie recipe with structured data.

Each ingredient dict must contain at least 'quantity', 'unit', 'food', and optionally 'note' and 'display'. Supports both structured inputs (as returned by mealie_parse_ingredients) and raw strings (which get stored in the display/note format for backward compatibility).

The tool fetches the current recipe, replaces its ingredient list, applies any additional update_fields, and patches it back via the Mealie API.

Typical structured ingredient format: {"quantity": 650, "unit": {"name": "g"}, "food": {"name": "Süßkartoffeln"}, "note": "in etwa 4 cm große Würfel geschnitten"}

Raw string fallback: "650 g Süßkartoffeln, in etwa 4 cm große Würfel geschnitten"

Returns the updated recipe slug and ingredient count.

Inputs: slug (required), ingredients (required), update_fields, confirmed_by_user. Returns: object

mealie_update_shopping_itemC

Update a shopping item using Mealie v3's full-model PUT endpoint.

Inputs: item_id (required), updates (required), confirmed_by_user. Returns: object

mealie_upload_recipe_assetB

Upload a real file asset to an existing recipe via multipart.

Inputs: slug_or_id (required), asset_source (required), icon, asset_name, +1 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.1/5.0

    Scored across 38 tools

    Disambiguation3/5

    The domain-specific tools are clearly distinct, but the generic API tool cluster (mealie_api_operation_request, mealie_api_request, mealie_api_get, mealie_api_download, mealie_api_multipart_operation_request) creates ambiguity with overlapping purposes for GET/JSON operations. Descriptions differentiate them, but an agent could easily select the wrong one.

    Naming Consistency4/5

    Most tools follow a consistent mealie_<verb>_<object> pattern (e.g., create_shopping_list, get_recipe, delete_mealplan). Deviations include mealie_about, mealie_status, and the generic API tools that use noun-heavy or mixed naming, but these are a minority.

    Tool Count2/5

    38 tools is excessive for a recipe/meal planning server, even with external integrations and generic API passthrough. The count heavily exceeds the typical well-scoped range and dilutes the tool surface.

    Completeness3/5

    Core workflows for recipes, shopping lists, and meal plans are largely covered, but notable gaps exist: no dedicated delete-recipe tool, no general update-recipe metadata tool, and no get-mealplan-by-id. These gaps force reliance on generic API tools or workarounds.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server for managing recipes, meal plans, shopping lists, and more through a self-hosted Mealie instance.
      1
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      A read-only MCP server for Mealie that enables searching recipes, managing shopping lists, meal plans, and retrieving household/instance info via tools. Supports secure per-user authentication and multiple Mealie instances.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      An MCP server for Mealie that provides curated tools for recipes, meal plans, and cookbooks with compact responses, enabling natural language management of your Mealie instance.
      1
      MIT