Recipe MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Recipe MCPFind quick dinner recipes and propose a meal plan"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.pyThe 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 --demoThis 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: Recipe Manager MCP Server
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 |
| Dish-name search; returns IDs and summaries and saves full details. |
| One ASCII letter; saves complete results. |
| Reads saved data, otherwise fetches and saves by ID. |
| Fetches and saves one recipe. |
| Validates all IDs and atomically saves one complete plan. |
| Retrieves the immutable saved summary snapshot. |
| 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
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.
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.
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 httpEndpoint: 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 |
|
|
|
|
| Durable database path; use different files per mode. |
|
| HTTP bind. |
| unset | 32–256 visible ASCII characters; required outside loopback. |
| localhost and loopback | JSON array of exact allowed hosts; |
| localhost and loopback | JSON array of trusted origins; no global wildcard. |
|
| TheMealDB development/educational key. |
|
| Cache seconds / maximum entries. |
|
| 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 mypyTests 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.pyDeployment 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 toolscreate_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.
| Name | Required | Description | Default |
|---|---|---|---|
| plan_name | No | My Meal Plan | |
| recipe_ids | Yes | ||
| idempotency_key | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| recipes | Yes | |
| plan_name | Yes | |
| created_at | Yes | |
| total_recipes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by explaining atomic all-or-nothing behavior, retry semantics, the need for user confirmation, failure on unknown IDs, and the idempotency_conflict outcome. These are meaningful behavioral details that an agent cannot infer from the input schema or the generic annotation flags.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences deliver the essential behavior, retry rule, confirmation requirement, and failure semantics with no filler. The most important phrase is front-loaded, and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a create operation with an output schema available, the description covers the critical success/failure behavior, idempotency rules, and user-confirmation prerequisite. Nothing essential for invoking the tool correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does so well for idempotency_key by explaining exact reuse semantics and conflict behavior, and for recipe_ids by noting that unknown IDs fail the entire plan. plan_name is left implicit, but its meaning is self-evident from the title and default value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Atomically save a complete plan,' which clearly states the verb (save), the resource (a complete meal plan), and a defining behavioral property (atomicity). This separates it from the read/search siblings like get_meal_plan or search_recipes. The wording is specific and not a tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear operational context: it must be used to save an entire plan, requires user confirmation, and enforces idempotency on retries. It does not explicitly name alternatives like get_meal_plan or generate_shopping_list, but the save-versus-read/generate distinction is strongly implied by the tool name and description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_shopping_listARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| plan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| plan_id | Yes | |
| warnings | Yes | |
| plan_name | Yes | |
| unresolved | Yes | |
| recipe_count | Yes | |
| requires_review | Yes | |
| ingredient_source | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond annotations: it uses locally saved recipe details once per unique recipe at original batch size, combines compatible quantities exactly, surfaces unresolved measurements instead of hiding them, and avoids inferred conversions. This goes well beyond the readOnly/idempotent hints and gives the agent reliable expectations about edge-case handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then uses every subsequent sentence to communicate meaningful behavioral constraints and edge-case policies. No filler or redundant restatement of the schema is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only tool with rich annotations and an output schema, the description covers all essential context: input source, uniqueness and batching behavior, quantity combination policy, and explicit non-behaviors. Nothing critical for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only provides the name and length for plan_id, with 0% description coverage. The description compensates by clarifying that plan_id refers to a saved plan whose locally stored recipe details are consumed. For a single, simple identifier this is sufficient context, though it does not describe how to obtain or validate the ID.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Consolidate a saved plan's ingredients into a shopping list.' This clearly distinguishes the tool from siblings like get_meal_plan (which likely returns the plan itself) and search_recipes (which finds recipes). It also includes the important scope qualifier 'without writes'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used when a saved plan exists and a consolidated ingredient list is needed, and it states what the tool does not do (no scaling, no conversions, no upstream API calls). However, it does not explicitly name sibling alternatives or state when to prefer another tool, such as get_meal_plan or get_recipe_details.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_meal_planARead-onlyIdempotent
Read a saved meal plan by its generated UUID.
| Name | Required | Description | Default |
|---|---|---|---|
| plan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| recipes | Yes | |
| plan_name | Yes | |
| created_at | Yes | |
| total_recipes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the description's 'Read' aligns with them. It adds no extra behavioral context (e.g., errors, response format), but the annotations cover safety, so a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no unnecessary words. It directly states the action and resource, earning its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one parameter and has an output schema and annotations covering safety. The description is sufficient for an agent to call it correctly; nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description specifies that plan_id is a 'generated UUID', adding semantic meaning beyond the schema's length constraints. Since schema coverage is 0%, this helps the agent understand the expected format, though it is minimal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Read' and the resource 'saved meal plan', and identifies the identifier as a 'generated UUID'. This distinguishes it from siblings like create_meal_plan (write) and search_recipes (search).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used when you have a UUID and want to read a specific meal plan, providing clear context. It doesn't explicitly mention alternatives or exclusions, but the purpose is unambiguous given the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_random_recipeA
Fetch and save one random recipe. Each call can return a different result.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | Yes | |
| tags | No | |
| cuisine | Yes | |
| category | Yes | |
| image_url | No | |
| source_url | No | |
| ingredients | Yes | |
| youtube_url | No | |
| instructions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose non-read-only (readOnlyHint=false) and non-idempotent (idempotentHint=false) behavior. The description adds that it 'saves' a recipe (a side effect) and that each call can differ (consistent with idempotent=false). It does not provide additional behavioral context like rate limits, side effects on data, or prerequisites. Since annotations cover the core safety profile, the description adds only marginal value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no filler. The primary action and the variable output are stated immediately. Every word contributes to the tool's understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and an output schema that defines the return, the description is fully sufficient. It conveys the tool's purpose, side effect (saving), and variability. Nothing an agent needs to decide whether to call it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so the description has nothing to add beyond the empty schema. Baseline for zero-parameter tools is 4; the description correctly avoids inventing parameter details and keeps the tool's call signature self-evident.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states a specific action (fetch and save) on a specific resource (one random recipe). The 'random' qualifier distinguishes it from search_recipes and get_recipe_details, which are targeted lookups. No ambiguity about what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a use case (when you need a random recipe) but does not explicitly contrast it with sibling tools like search_recipes or get_recipe_details. It lacks any 'when not to use' guidance or alternative references, leaving the decision to the agent's inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recipe_detailsAIdempotent
Read saved details or fetch and save a recipe by numeric ID.
| Name | Required | Description | Default |
|---|---|---|---|
| recipe_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| name | Yes | |
| tags | No | |
| cuisine | Yes | |
| category | Yes | |
| image_url | No | |
| source_url | No | |
| ingredients | Yes | |
| youtube_url | No | |
| instructions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate non-read-only, idempotent, open-world behavior. The description adds meaningful context by revealing the two-mode behavior (reading saved details vs fetching and saving), which is not derivable from annotations alone. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. Every word contributes to conveying the purpose and behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with an output schema, the description covers the essential behavior (read or fetch-and-save) and the input type. It could be more explicit about when to use it versus sibling search tools, but the output schema handles return-value documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no description for recipe_id (0% coverage), so the description must compensate. It mentions 'numeric ID', which aligns with the schema pattern, and clarifies that the ID identifies a recipe. However, it adds little beyond what the schema pattern already conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action (read or fetch-and-save) on a recipe by numeric ID, which clearly distinguishes it from search tools that take text criteria or random selection. It is not a tautology and names the resource and input scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use when you have a numeric recipe ID, but it does not explicitly contrast with sibling tools like search_recipes or get_random_recipe, nor does it state when not to use it. The when-to-use is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_by_first_letterBIdempotent
Find and save recipes whose names begin with one ASCII letter.
| Name | Required | Description | Default |
|---|---|---|---|
| letter | Yes | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| recipes | Yes | |
| recipe_ids | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false (mutation expected), idempotentHint=true, and destructiveHint=false. The description says 'save recipes', which implies a write operation, aligning with readOnlyHint=false. However, it provides no additional context about what 'save' means (e.g., persists to a database, what happens on repeated calls), nor does it explain the side effect beyond the annotations. With annotations present, the bar is lower, but the description adds minimal behavioral context beyond 'save'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no redundant words. It front-loads the core purpose and is appropriately concise. However, it could have added parameter guidance without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return values are likely defined elsewhere. However, the description lacks clarification on the 'save' behavior, the meaning of max_results, and how this tool differs from search_recipes. Given the complexity (2 params, mutation side effect, open world hint), the description is incomplete for an agent to confidently invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for explaining both parameters. However, the description only mentions the 'letter' parameter ('whose names begin with one ASCII letter') and does not explain the 'max_results' parameter (limit/controls the number of recipes returned). Since max_results has a default and bounds but no description, the agent lacks guidance on its meaning. This is a significant gap given zero coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Find and save recipes') and a specific resource ('recipes') with a clear criterion (names begin with one ASCII letter). It is not a tautology and conveys a clear purpose. However, it does not explicitly differentiate from sibling tools like search_recipes, but the first-letter criterion is a distinctive behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: use this tool when you need recipes starting with a specific letter. It does not provide explicit when-not-to-use guidance or mention alternatives like search_recipes for general searches. The 'save' behavior hints at a side effect, but no exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_recipesBIdempotent
Find recipes by dish name, save their details and return IDs and summaries.
| Name | Required | Description | Default |
|---|---|---|---|
| dish_name | Yes | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| recipes | Yes | |
| recipe_ids | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey idempotence and non-destructiveness, and the description adds the behavioral detail of 'save their details' plus returning IDs and summaries. However, it does not clarify what 'save' actually does, whether it causes side effects, or what happens to previously saved data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler and the core action ('Find recipes by dish name') is front-loaded. Every clause contributes identifiable information, even if 'save their details' is ambiguous in meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be elaborated, but the description still omits max_results semantics and fails to position the tool against search_by_first_letter. The ambiguous 'save their details' behavior also leaves an important gap for an agent deciding to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It mentions 'dish name', which maps to the dish_name parameter, but it never addresses max_results, its default value, or how result limiting behaves. Thus, one of two parameters is left entirely undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Find') and resource ('recipes') with a filtering criterion ('by dish name') and expected outputs ('IDs and summaries'). However, the phrase 'save their details' is ambiguous about whether the tool persists data, and it does not differentiate this from the sibling search_by_first_letter.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives such as search_by_first_letter or get_recipe_details. The description implies searching by dish name but does not state exclusions, prerequisites, or preferred contexts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v1.1.0- First observed
create_meal_plan - First observed
generate_shopping_list - First observed
get_meal_plan - First observed
get_random_recipe - First observed
get_recipe_details - First observed
search_by_first_letter - First observed
search_recipes
TDQS
Scored across 7 tools
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.
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.
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.
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
Related MCP Connectors
Household-aware cooking brain: pantry, meal suggestions, dietary safety, recipes, shopping lists.
AI-powered recipe platform: 18 MCP tools for meal planning, grocery lists & Instacart.
Search, save, organize, cook, and share recipes with any AI assistant.
AI-powered kitchen management — pantry, recipes, meal plans, shopping lists
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to interact with Mealie recipe databases through MCP clients like Claude Desktop.141MIT
- FlicenseNot gradedqualityDmaintenanceEnables managing recipes via a web UI and MCP tools, allowing retrieval and saving of recipe data through natural language.-
- FlicenseNot gradedqualityDmaintenanceEnables 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.-
- FlicenseNot gradedqualityBmaintenanceEnables 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.-