Skip to main content
Glama
Recipe MCP

Recipe MCP

by ashitamv

Recipe MCP

A recipe research and meal planning server for MCP-compatible AI hosts. Search for dishes, inspect recipes, save complete meal plans with repeatable writes, and generate consolidated shopping lists with traceable quantities. Run entirely offline for a portfolio demonstration or connect to TheMealDB for live recipes.

Quick start

Requires Python 3.12 or newer (3.12–3.14 supported) and uv. From the extracted project directory:

uv sync --locked
uv run python scripts/demo.py

The demo starts a real in-process MCP client, discovers capabilities, searches offline recipes, saves a plan, repeats the request with the same idempotency key, and checks the persisted resource. It uses a temporary database, makes no external API calls, and needs no model API key.

Run a server for a local desktop host:

uv run recipe-mcp --demo

This starts stdio, so waiting silently is normal. An MCP client must send protocol messages; this is not an interactive command prompt. Live mode is the default: omit --demo.

Related MCP server: yes_chef_mcp

Connect a host

Use the executable path returned by command -v uv (or where uv on Windows) and replace the project and database paths with absolute paths on your computer. Example Claude Desktop MCP server entry:

{
  "mcpServers": {
    "recipes": {
      "command": "/absolute/path/to/uv",
      "args": ["--directory", "/absolute/path/to/recipe-mcp", "run", "--locked", "recipe-mcp", "--demo"],
      "env": {"RECIPE_DATABASE_PATH": "/absolute/path/to/recipe-mcp/data/demo.sqlite3"}
    }
  }
}

Remove --demo for live recipes. Keep separate database paths for live and demo modes. In VS Code, use the same command/args/env under servers.recipes in .vscode/mcp.json and add "type": "stdio". Restart/reload the host after editing its configuration. Host UI labels and configuration locations may vary; the protocol tests verify the server, not a particular installed desktop application.

Try: “Find orzo recipes, show their ingredients, and propose a plan called Weeknight dinners. Ask before saving it.” The host controls model access and user confirmation. The server neither runs an LLM nor enforces the host's approval UI.

After saving a plan, try: “Use generate_shopping_list for the saved plan. Show the consolidated quantities, ingredients that need review, and any unit warnings. Keep unresolved measurements visible.” The tool reads local saved data without changing the plan or contacting the recipe API. See the shopping-list guide for its quantity rules and limitations.

Architecture

flowchart TD
    H["AI host and MCP client"] --> M["MCP adapter"]
    M --> S["Recipe service"]
    S --> P["Provider interface"]
    S --> R["SQLite repository"]
    S --> C["Pure shopping-list consolidation"]
    P --> A["TheMealDB with bounded cache and retries"]
    P --> D["Offline demo recipes"]
    R --> DB["Persistent SQLite database"]

The adapter owns MCP schemas and errors. The service coordinates use cases. Providers normalize external data; the repository owns transactions. Async HTTP handles network waits and whole SQLite operations run in worker threads. All acquisition paths persist full details. Recipe IDs are unique; meal plans snapshot summaries so later recipe refreshes do not alter saved plan names or categories.

Shopping lists use a consistent database read of the saved plan and its current saved recipes, followed by pure, deterministic quantity consolidation. Ingredients are not historical plan snapshots: the response explicitly identifies ingredient_source as current_saved_recipes. Refreshing a saved recipe can therefore change a later shopping list without changing the plan's summary snapshot. Existing databases and plans remain compatible; this feature does not change schema version 1.

Capabilities

Tool

Behavior

search_recipes(dish_name, max_results=5)

Dish-name search; returns IDs and summaries and saves full details.

search_by_first_letter(letter, max_results=5)

One ASCII letter; saves complete results.

get_recipe_details(recipe_id)

Reads saved data, otherwise fetches and saves by ID.

get_random_recipe()

Fetches and saves one recipe.

create_meal_plan(recipe_ids, plan_name, idempotency_key)

Validates all IDs and atomically saves one complete plan.

get_meal_plan(plan_id)

Retrieves the immutable saved summary snapshot.

generate_shopping_list(plan_id)

Reads a saved plan and its locally stored recipes; combines compatible quantities and returns provenance, unresolved measurements, and review warnings.

Search limits are 1–25. Names are limited to 100 characters. Plans accept 1–30 IDs, deduplicated in order. A reused idempotency key with the same normalized name and ordered IDs returns the same plan; changed content produces idempotency_conflict. Without a key, every call creates a new plan. Unknown IDs cause the entire plan to fail; recipes fetched successfully along the way may remain in the cache.

Shopping quantities apply once per unique recipe, using its original ingredient quantities; there is no serving scaling. Metric mass and volume use exact conversions within their own families; pounds and ounces share a separate mass family. Uncertain measurements remain visible, different units remain separate, and requires_review is true whenever there are unresolved entries or warnings. No LLM calculates these quantities. See the supported units and examples.

Resources: recipes://cuisines, recipes://stats, recipes://meal-plans (latest 50), recipes://cuisine/{cuisine} (up to 100), and recipes://recipe/{recipe_id}. Resources never fetch upstream or create state. Unlike the original course's collection URI, the cuisine URI filters actual provider cuisine labels.

Five prompts preserve the course's recipe search, meal planning, cooking lesson, ingredient exploration, and cultural cuisine workflows. They distinguish sourced recipe facts from estimates. Dish-name search is not cuisine or ingredient filtering. Serving counts, nutrition, cost, cooking times and allergy safety are not reliably available from the provider.

Portfolio improvements

  1. Resilient provider access: pooled asynchronous HTTP, finite timeouts, bounded transient retries with backoff, capped Retry-After handling, TTL/LRU cache, and duplicate concurrent lookup suppression. Random selection is never cached. Error messages use stable codes and do not expose upstream credentials.

  2. Transactional and testable meal planning: SQLite constraints and transactions, UUID plan identities, persistent idempotency keys, complete-plan validation, and automated domain/provider/protocol/HTTP/stdio tests.

  3. Deterministic shopping lists: exact rational arithmetic, conservative ingredient matching and unit conversion, source attribution for every ingredient line, and explicit review of ambiguous measurements. Missing recipe data fails the operation instead of returning an apparently complete list.

The current stable official MCP SDK is pinned through uv.lock (2.2.0 at implementation time, September 19, 2026). The course's FastMCP import from SDK v1 was migrated to MCPServer, transport options moved to the run/app boundary, and clients use v2 snake_case result attributes. The external recipe adapter uses httpx; the SDK independently uses httpx2 for MCP transport. Neither client is passed to the other library.

HTTP and configuration

uv run recipe-mcp --demo --transport http

Endpoint: http://127.0.0.1:8000/mcp. Liveness: /healthz. Readiness: /readyz checks database readability. Readiness does not prove upstream availability or available disk space for writes.

Copy .env.example to .env for your local settings. Environment variables override .env; explicit CLI arguments override both. PORT is accepted for managed hosting.

Variable

Default

Purpose

RECIPE_MODE

live

live or demo.

RECIPE_DATABASE_PATH

data/recipes.sqlite3

Durable database path; use different files per mode.

RECIPE_HOST / RECIPE_PORT

127.0.0.1 / 8000

HTTP bind.

RECIPE_AUTH_TOKEN

unset

32–256 visible ASCII characters; required outside loopback.

RECIPE_ALLOWED_HOSTS

localhost and loopback

JSON array of exact allowed hosts; :* permits ports.

RECIPE_ALLOWED_ORIGINS

localhost and loopback

JSON array of trusted origins; no global wildcard.

RECIPE_API_KEY

1

TheMealDB development/educational key.

RECIPE_CACHE_TTL / RECIPE_CACHE_SIZE

300 / 128

Cache seconds / maximum entries.

RECIPE_REQUEST_TIMEOUT / RECIPE_RETRIES

10 / 2

Per-attempt timeout / additional attempts.

Live recipe details already saved in SQLite are durable snapshots and do not expire when the provider's in-memory cache does. Searching or random retrieval may refresh them. Plan snapshots remain unchanged. This avoids claiming TTL freshness for all saved data.

HTTP access uses one shared bearer token for a private, single-tenant deployment, not full MCP OAuth. Use HTTPS at the edge and a client that can send the Authorization header. It does not provide per-user permissions or tenant isolation, and some hosted MCP clients require OAuth instead. Host/Origin checks, a 64 KiB request limit, and a shared 120-request-per-minute process quota apply to protocol traffic. Health routes intentionally reveal only minimal status and do not require a token. The quota resets on restart and is not a distributed rate limiter.

TheMealDB documents key 1 for development/education and separate requirements for public app-store releases. Review its current API guidance for your intended release and configure your own key as appropriate. Recipe/image content remains attributable to TheMealDB and its linked sources. Demo recipes are original illustrative fixtures.

Verification

uv run pytest --cov=recipe_mcp --cov-report=term-missing
uv run ruff check .
uv run ruff format --check .
uv run mypy

Tests use temporary SQLite files and mocked upstream HTTP; they do not require a live recipe API. Real MCP client exchanges cover discovery, inputs, structured results, resources and prompts. HTTP-level tests cover authentication and transport defenses. A subprocess test exercises stdio framing.

Run the optional live smoke test separately:

uv run python scripts/live_smoke.py

Deployment and operations

The MCP host supplies the user interface. A public multi-user service needs OAuth, authorization on stored records, and a database/operational design appropriate to the workload. Horizontal scaling is not supported by this SQLite deployment.

Available Tools

7 tools
create_meal_planA

Atomically save a complete plan. Reuse the same key and payload when retrying.

Requires user confirmation. Unknown IDs fail the entire plan. A reused key with different content fails with idempotency_conflict.

Inputs: recipe_ids (required), plan_name, idempotency_key. Returns: id, recipes, plan_name, created_at, +1 more

generate_shopping_listA
Read-onlyIdempotent

Consolidate a saved plan's ingredients into a shopping list, without writes.

Uses current locally saved recipe details, once per unique recipe at its original batch size. Combines compatible quantities exactly. Show every unresolved measurement and warning to the user; never treat a partial known quantity as the complete amount. No serving-size scaling or regional cup/spoon conversions are inferred. No upstream API is called.

Inputs: plan_id (required). Returns: items, plan_id, warnings, plan_name, +4 more

get_meal_planA
Read-onlyIdempotent

Read a saved meal plan by its generated UUID.

Inputs: plan_id (required). Returns: id, recipes, plan_name, created_at, +1 more

get_random_recipeA

Fetch and save one random recipe. Each call can return a different result.

Inputs: no named parameters. Returns: id, name, tags, cuisine, +6 more

get_recipe_detailsA
Idempotent

Read saved details or fetch and save a recipe by numeric ID.

Inputs: recipe_id (required). Returns: id, name, tags, cuisine, +6 more

search_by_first_letterB
Idempotent

Find and save recipes whose names begin with one ASCII letter.

Inputs: letter (required), max_results. Returns: count, recipes, recipe_ids

search_recipesB
Idempotent

Find recipes by dish name, save their details and return IDs and summaries.

Inputs: dish_name (required), max_results. Returns: count, recipes, recipe_ids

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 7 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes: recipe discovery (search, first-letter, random, by-ID), meal plan creation/reading, and shopping list generation. The only mild overlap is that multiple recipe tools all fetch and save recipe details, but their lookup modes are distinct enough to avoid serious misselection.

    Naming Consistency5/5

    All tool names follow a consistent snake_case verb-first pattern: create_, search_, get_, generate_. Even search_by_first_letter fits the convention with a descriptive prepositional modifier. There is no mixing of styles or vague verbs.

    Tool Count5/5

    Seven tools is a well-scoped size for a recipe/meal-planning server. Each tool covers a meaningful step in the workflow—recipe discovery, detail retrieval, plan creation/retrieval, and shopping list generation—without unnecessary redundancy.

    Completeness4/5

    The core workflow is covered end-to-end: find recipes, fetch details, create a meal plan, read it, and generate a shopping list. The main gaps are the lack of update/delete operations for saved recipes or meal plans and no way to list saved recipes, but these do not break the primary use case.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      B
      maintenance
      Enables AI assistants to search recipes, compose nutritionally balanced meals, optimize weekly meal plans based on macro targets for family members, and generate consolidated grocery lists from a personal recipe database.
      -
    • F
      license
      Not graded
      quality
      B
      maintenance
      Enables MCP-compatible clients like ChatGPT and Claude to manage a household's shared food inventory, meal plans, recipes, and preferences through natural language, with atomic updates and audit logging.
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Provides recipe search and authoring, meal planning, shopping lists, and pantry tracking via task-shaped MCP tools.
      52 npm
      MIT