Sabor
Summary: This Sabor MCP server lets an agent manage recipes, meal plans, and shopping lists with preview/confirm safeguards for writes.
Discover the actual registered tool surface and configured capabilities with
sabor_capabilities.Import recipes with
import_recipeusing dry-run preview by default, then commit when approved.Search, read, create, update, tag, comment on, and log cooking events for recipes.
View weekly meal plans and add, delete, or clear meal-plan entries.
List, create, get-or-create, clear, or delete shopping lists.
Add items, recipes, or meal-plan ranges to shopping lists with an explicit servings multiplier.
Read, check, and remove shopping-list items.
Use preview/confirmation patterns for destructive or mutating operations such as deletion, clearing, and recipe updates.
Provides tools for interacting with a self-hosted Mealie instance, enabling management of recipes, meal plans, shopping lists, tags, comments, and cooking history. Mealie remains the source of truth for the kitchen data.
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., "@SaborPlan pasta for Monday and add the ingredients to my shopping list"
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.
Sabor
A kitchen-intelligence layer with built-in SQLite or optional Mealie/Postgres. Find or import recipes, plan the week, build a scaled shopping list, estimate its cost, then sync to Bring! with an explicit preview and digest-bound confirmation. The selected recipe store is the source of truth for cooking data; core workflows work without Mealie.
Brand guide: docs/marca/.
Optional non-secret config.toml settings use environment > file > defaults.
Set SABOR_CONFIG to select a file; see configuration keys and OS paths.
Secrets may use environment variables or setup-managed keyring/file references;
sabor_capabilities reports data.config_source. Run sabor-mcp doctor --json
to check store health, or sabor-mcp config show --json for masked values and
origins. See terminal diagnostics.
The everyday flow
Call
sabor_capabilities(); use only tools indata.registered_tools.Find recipes with
search_recipesorsuggest_recipes; inspect structured ingredients and instructions withget_recipe. Alternatively previewimport_recipe(source="https://example.org/recipe", kind="url"), ask the user, then repeat withdry_run=False.Agree a menu and use
set_mealplan_entryfor each approved entry.Create or select a store shopping list, then call
add_to_shopping_list(list_id="MEALIE_ID", mealplan_start="2026-10-19", mealplan_end="2026-10-25", servings_multiplier=2.0). Dates are inclusive. Each recipe occurrence is added; free-text entries are skipped with reasons. The multiplier scales native recipe yield, not a guessed diner count. This call writes immediately: obtain approval first.Reread
get_shopping_list_itemsand estimate the actual list withestimate_cost(source={"kind":"shopping_list","list_id":"MEALIE_ID"}, store={"provider":"mercadona"}). Show consumption and procurement subtotals, coverage and uncertainties. If over budget, propose changes and obtain new approval before changing the plan.Discover
get_shopping_sync_targets. Previewsync_shopping_list(mealie_list_id="MEALIE_ID", target={"provider":"bring","list_id":"BRING_ID"}). Show additions, removals, conflicts, skipped checked items andpreview_digest. Ask; repeat the same call withconfirm=True, preview_digest="APPROVED_DIGEST". A stale digest or any conflict blocks writes and returns a fresh preview; review and ask again rather than blindly retrying or switching to replace.
This is documented agent orchestration, not a composite tool or transaction. Plan → list → estimate_cost → sync crosses independent approval boundaries. List creation/additions write immediately; cost approval authorizes no purchase. Report each system's outcome; uncertain writes require readback/reconciliation, not automatic retries or an assumed cross-system rollback.
Related MCP server: Mealie MCP Server
Sabor solo vs Sabor + Mealie
Capability | Sabor solo | Sabor + Mealie |
Recipes, meal plans, shopping lists | Built-in SQLite; no account or token | Mealie URL + API token |
URL import | Offline recipe-scrapers / JSON-LD | Native Mealie scraper |
Text / image | The client agent extracts the recipe and calls | Same |
Video URL or local video file |
| Same |
Bring! sync / Mercadona estimates | Optional credentials / pricing opt-in | Same optional integrations |
Spanish catalog / legacy nutrition | Not supported | Mealie adapter required |
Cookbooks | Not supported | Mealie cookbooks ( |
Web UI to browse and edit recipes | None: chat only | Mealie's web interface |
sabor_capabilities reports Mealie-only toolsets that are unavailable in the
current instance under data.mealie_only, each with a reason
(requires_mealie_store for legacy_nutrition, requires_mealie for
legacy_catalog) and a short detail. Already running Mealie? Nothing to
migrate: keep MEALIE_BASE_URL and MEALIE_API_TOKEN and Sabor keeps using it.
Step-by-step clean installs for both paths: docs/install-beta.md.
Bootstrap the Spanish Mealie catalog outside the agent tool list:
sabor-mcp catalog status
sabor-mcp catalog apply
# Equivalent module entrypoints:
python -m sabor catalog status
python -m sabor catalog applyBoth require MEALIE_BASE_URL and MEALIE_API_TOKEN, independent of
SABOR_TOOLSETS. Status is a read-only dry-run; apply creates only missing
curated units and audits foods. Neither updates, merges, deletes nor runs seeders.
Results are indented UTF-8 JSON; exit codes: 0 when ok is true, 1 for
configuration/reconciliation failure, 2 for invalid arguments. Review nested
errors and conflicts even when ok is true (legacy semantics).
Capabilities and providers
Capability | Provider / requirements | Limits |
Core | Built-in SQLite, or Mealie URL + token | Recipes, suggestions, planning, shopping items and history; API baseline Mealie 3.22.0 |
Import: URL | SQLite: offline recipe-scrapers + schema.org JSON-LD; Mealie: native scraper | Read-only preview; pages without a recipe return |
Import: text, image | None: Sabor contains no AI provider |
|
Import: video URL | A recipe store; | Media bundle for the agent: metadata, platform subtitles and 8 frames as images; writes nothing |
Shopping sync | Bring! email + password and a recipe store | Only unchecked source items; does not check off Mealie items |
Pricing |
| Read-only quantity-aware estimates; Mercadona catalog or Open Prices observations |
Legacy | Explicit toolset selection plus provider configuration | Promotions, memory, nutrition and Spanish catalog |
Since 0.4.0 Sabor contains no AI provider client (#102): the client agent reads
text, images and video itself and saves the recipe with create_recipe. For a video
URL, import_recipe hands it the video's title, uploader, duration, date, platform
and description, the platform subtitles (original language first) and 8 frames of
640 px at most, sent as MCP images; without ffmpeg it sends the rest and a
limitations entry. It never writes a recipe, so dry_run has no effect. The
SABOR_LLM_*, GEMINI_API_KEY, VIDEO_RECIPE_GEMINI_MODEL and SABOR_VIDEO_PROVIDER
settings were removed: an old configuration keeps starting, they are ignored, and
sabor-mcp doctor warns once naming them.
Recipe stores and instance boundaries
RecipeStore is a typed persistence abstraction for recipes, calendar entries,
shopping lists/items, tags and history. Without MEALIE_BASE_URL, SQLite is
selected automatically at <data dir>/sabor.db; set SABOR_STORE_DB to change the
path. With a non-empty Mealie URL, Mealie remains selected (and requires its token).
Explicit SABOR_STORE=sqlite, SABOR_STORE=mealie or SABOR_STORE=postgres overrides that selection;
invalid values fail startup. SQLite construction and registration perform no
filesystem I/O. Runtime startup initializes the database before serving requests;
direct store use initializes on first operation. Missing parent directories are
created, and opening failures never silently fall back. Back up its data volume.
URL import works with SQLite and needs no AI. The Spanish catalog, legacy
nutrition and Mealie's native URL import still require Mealie; SQLite does not
advertise native imports.
Tandoor and KitchenOwl are not implemented integrations. Existing slug/list arguments remain unchanged,
including the historical mealie_list_id sync argument. There is no public
per-call backend URL or tenant selector.
For generic Postgres (including Supabase and Neon), install the optional extra
with pip install 'sabor-mcp[postgres]' or run
uvx --from 'sabor-mcp[postgres]' sabor-mcp. Select SABOR_STORE=postgres and
store the secret SABOR_DATABASE_URL through the environment or
sabor-mcp setup secret database_url. The adapter uses the private sabor schema,
requires no extensions and enables RLS without public policies. SQLite and Mealie
do not require the extra. See Postgres / Supabase operations
for role permissions, Supabase session-pooler settings and backups, and
docs/supabase-agentes.md to set up Supabase with an agent
(sabor-mcp setup supabase --create-role).
An AppContext binds settings, store, registry and pricing providers to registered
tools. Mealie sessions, Mercadona catalog caches and Bring authentication/cache
state are instance-owned. Every registered tool binds the server's configuration;
nutrition services, caches and locks, memory paths and Bring catalog overrides are isolated between registrations. This is
not a multi-tenant security boundary: legacy Mercadona promotion/catalog state
and direct-call compatibility globals remain process-wide. Use separate
processes/containers, credentials and data volumes for untrusted households;
isolated registrations must use distinct recipe-store, memory and nutrition database paths.
Direct Python compatibility calls are not equivalent to registered app contexts.
Discovery exposes data.capabilities.recipe_store and pricing with adapter IDs
and operations; data.mealie.configured remains a deprecated compatibility field.
Native import discovery includes url (preview/commit) only.
Configured means locally configured, never authenticated or healthy.
Quantity-aware pricing
Enable SABOR_MERCADONA_ENABLED=true and add pricing to SABOR_TOOLSETS
(for example core,import,shopping_sync,pricing). Defaults remain unchanged.
search_pricing_products finds candidates; get_product_price returns package
and normalized unit prices, quantity basis, timestamps, location, provenance and
uncertainty. estimate_cost reads only; it never modifies recipes or buys goods.
legacy_pricing now exposes only price drops and new arrivals.
Mercadona search is food-only (non-food top categories 20, 21, 22, 23, 25,
26 are excluded). Matching is by whole words, tolerating one trailing s/es
on either side (zanahoria finds Zanahorias; sal never finds Salsa).
A number that is part of the name (4 quesos, not an amount such as 500 g,
2 huevos or a fraction such as 1/2 kg) ranks products carrying it first, so they stay inside the 50-result
window. A written numeral from two up counts as its digits (cuatro quesos as
4 quesos); an article (un queso) is always an amount. Free-text shopping items
typed in a built-in store are matched on their original text, so 4 quesos keeps its
number; items from Mealie keep their previous selection (Beta A). The number must
modify the same word: Pizza 4 quesos carries 4 quesos, Pizza 3 quesos pack 4 unidades
does not, and estimate_cost applies the same rule. Then matches rank by unrequested processed or compound words (croquetas,
chicles, salsa, molido, a la jardinera, condensed milk...), then by the
number of normalized name words absent from the query (fewer is closer), food
metadata, name and ID. Requested modifiers are not penalized (croquetas de merluza finds croquetas), and entera, desnatada and semidesnatada stay neutral.
This is lexical closeness, not semantic ingredient identity.
estimate_cost(..., match_policy="cheapest") defaults to the compatible food
candidate (search window up to 50) with the lowest checkout cost for the
required quantity, that is whole packages times package price, then the lowest
unit price. For 200 g of flour this picks a 1 kg bag over a cheaper-per-kilo
5 kg bag. Multiple candidates produce estimated / auto_selected_cheapest
and up to five alternatives with names, normalized prices and
checkout_cost. A basic ingredient ignores processed or compound candidates
when an unprocessed one matches (merluza picks fillets over cheaper croquetas,
jengibre fresh ginger over chewing gum); they are used only when nothing else
matches. Show alternatives and
offer to switch using product_overrides; overrides take precedence, but cannot
price non-food. With at least two non-overridden lines sharing normalized name
words and base unit, known quantities are also evaluated together. A common
product replaces per-line choices only when its combined checkout cost is
strictly cheaper than the original grouped procurement; ties keep the original
choices, and basket procurement never increases. For 300 g + 300 g arroz,
500 g at EUR 0.60 loses to 1 kg at EUR 0.90 (EUR 1.20 → 0.90). For 200 g +
900 g with 1 kg at EUR 1.00, mixed choices stay (EUR 1.60, not EUR 1.80).
Changed lines add auto_selected_cheapest_group and grouped_selection evidence;
their alternatives show checkout costs for the summed quantity (up to five).
Use match_policy="strict" to leave ambiguity uncosted; strict is not grouped.
A positive quantity without a unit assumes pieces (estimated,
assumed_count), matched only to count products. Kitchen measures stay unknown.
Egg reference prices per dozen are divided by 12 for the per-piece basis.
store={"provider":"mercadona"} is a retail context, not a recipe backend.
Optional location_id and currency must match the configured adapter (stock
configuration: warehouse mad1, EUR); incompatible contexts are rejected, never
silently switched. Omit store only when exactly one pricing provider is present.
Mercadona's unofficial API can change. Todoist sync is planned, not shipped here.
Alternatively enable SABOR_OPEN_PRICES_ENABLED=true (default false) and the
pricing toolset. Select store={"provider":"open_prices","location_id":"ES","currency":"EUR"}
with estimate_cost or get_product_price; product IDs are barcodes. Country
is an ISO alpha-2 code (default ES), currency defaults to EUR. Open Prices is
universal crowd observations, not a current catalog: Spanish coverage is sparse
and old. The latest matching country observation wins (ties: latest ID), never
the cheapest. Missing locations/country observations return not_found, not zero.
Search returns up to ten products with observations; search_pricing_products
leaves out those without a quote in the requested country instead of failing the
whole search, and tries to fill the requested limit with the next quoted candidates
within the window the provider returns (Open Prices examines at most ten), so fewer
results can come back (get_product_price on such a product still returns not_found).
Its name filter is a substring match, so a one-word plural query that returns fewer
than ten also searches its singular to fill the remaining room (guisantes also
finds Guisante fino); original results always come first, and multi-word queries
are sent as given.
Quotes include observation date, public store/city, unknown availability and
observation always; stale_observation means older than 180 days, discounted
marks promotions, single_observation means only one matching observation in the
fetched window, and unknown_unit leaves package/unit pricing unknown.
Responses are cached per instance for ten minutes (up to 128 requests); prices
inspect only the latest 50 observations, so country coverage can be incomplete.
Attribution: Open Prices (Open Food Facts), ODbL, https://prices.openfoodfacts.org/.
Do not combine with non-free data into a redistributed database. Contributor
identifiers, proofs and coordinates are never included in quotes or errors.
Choose exactly one source shape:
{"kind":"items","items":[{"name":"arroz","quantity":"500","unit":"g","text":"500 g arroz"}]}
{"kind":"recipe","slug":"arroz-con-verduras","multiplier":"1"}
{"kind":"shopping_list","list_id":"MEALIE_ID"}
{"kind":"mealplan","start_date":"2026-10-19","end_date":"2026-10-25","multiplier":"1"}Inline items work without Mealie; stored references require a recipe store. Use decimal strings or integers for quantities/multipliers, not JSON floats. Limits: 500 resolved rows, 31 inclusive days, multiplier greater than zero and at most 20. Repeated meals remain separate occurrences; text-only entries remain uncosted. No automatic serving-count inference or pantry subtraction occurs.
consumption_subtotal: required quantity × comparable unit price.procurement_subtotal: whole packages to buy, rounding up after aggregating demand for the same product/location/currency. For 500 g from a 1 kg package priced at EUR 2, consumption is EUR 1 and procurement EUR 2.Decimal operands and money are JSON strings, with subtotals rounded to two places only for presentation. Missing prices are never zero; all-unknown or empty estimates have null subtotals. Partial subtotals are not complete budgets.
Inspect
complete,coverage,excluded_rows, per-lineuncertainty.level(known,estimated,unknown) and reasons. Unknown density, piece weight, units, ambiguous matches or package size stay unresolved. Availability and stale observations remain uncertainties, not purchase guarantees.product_overridesmaps returned linekeyvalues to selected product IDs; inspect candidates first. There is no cross-retailer fallback or mixed-currency total. Comparesource_digestto tell whether the resolved source (line keys, names, required quantities and units) changed; it ignores price refreshes.quote_digestalso covers quote observations and changes on every catalog refresh. Neither substitutes for sync'spreview_digest.
Choose the tool surface
SABOR_TOOLSETS defaults to core,import,shopping_sync. It is an allowlist,
intersected with configuration readiness. Empty means discovery only; whitespace
is trimmed, duplicates collapse, and unknown names prevent startup.
Toolset | Selection / configuration |
| Default; built-in SQLite or Mealie URL + token |
| Default; a recipe store; recipe web pages ( |
| Default; Bring! credentials + recipe store for the tools |
| Opt-in + |
| Opt-in + |
| Opt-in + |
| Opt-in; local |
| Opt-in; operations retain |
| Opt-in + Mealie |
With Mealie only, the current code registers 23 application tools plus discovery
(22 core tools and native import). The earlier planned baseline of 21 plus
discovery was superseded by added core functionality.
There are 52 selectable application tools plus the always-on
sabor_capabilities at full configuration. Counts are not a health check.
sabor_capabilities() reports version, requested toolsets, actual registered
names, configured capabilities/adapters, supported kinds/operations, disabled
reasons and warnings. It is local discovery, not a network health probe.
It omits credentials, private URLs, paths, email addresses and model IDs.
Restart and refresh client discovery after configuration changes.
Results and approval
Unwrap successful results through data:
{"ok":true,"data":{"preview":true,"actions":[]}}Failures use a sanitized envelope (optional data carries safe partial outcomes):
{"ok":false,"error":{"code":"provider_unconfigured","message":"Recipe store is not configured.","provider":"mealie"}}Codes: invalid_argument, provider_unconfigured, unsupported_operation,
not_found, ambiguous_target, authentication_failed, rate_limited,
timeout, upstream_error, invalid_response, conflict, partial_failure.
MCP schema validation can reject a call before a tool runs.
confirm=Falsepreviews recipe updates, shopping item removal, clear/delete lists, clear calendar ranges and both sync modes. Show preview → ask → confirm.Import defaults to
dry_run=True; preview fetches the recipe page but does not create recipes. Sabor itself calls no AI provider. With Mealie, a committed import runs Mealie's ingredient parser (SABOR_INGREDIENT_PARSER, defaultopenai), which may send ingredient text to the AI provider configured in Mealie.Other writes require client-side approval even without a server flag. Legacy
apply,publishandexecutegates retain their separate meanings.Sync accepts optional
preview_digest. Supplying the approved preview's digest binds confirmation to that source, target, mode, actions and application scope; a mismatch returnsconflictwith a fresh preview underdata.preview, zero writes. Any nonempty conflicts block confirmation even with a matching digest. Without a digest, compatibility behavior only rechecks current snapshots within the confirmed call; it does not bind to the user's earlier preview. Neither mode makes remote edits during apply atomic. Inspect partial outcomes before retrying.Append does not remove target entries; differing specifications are conflicts. Replace can clear all target purchase entries, including with an empty source. Unknown/ambiguous targets fail: there is no first-list fallback.
Recipe PATCH arrays replace entire arrays. Review removals, not just additions.
Install
1. With your AI (recommended)
Paste this into your coding agent (Claude Code, Cursor, Codex, Gemini CLI, Cline, OpenClaw…):
Install and configure Sabor by following
https://github.com/JlMoreno00/sabor/blob/main/llms-install.mdIn Cursor, open this prompt in the chat
(it only fills the chat; nothing runs until you send it). The agent asks a few
questions one at a time, configures Sabor with sabor-mcp setup in a terminal and
verifies configuration and store health with sabor-mcp doctor --json. This does
not check MCP transport or provider credentials; complete verification with
sabor_capabilities and the real round trip in llms-install.md. Secrets are typed by you in a terminal
(sabor-mcp setup secret <name>), never in the chat. See llms-install.md.
2. One click (local SQLite, no questions)
These links register uvx sabor-mcp and work after the first PyPI release;
until then use the uvx --from git+https://github.com/JlMoreno00/sabor sabor-mcp
form from Connect your MCP client.
Or from a terminal:
claude mcp add --scope user sabor -- uvx sabor-mcp
codex mcp add sabor -- uvx sabor-mcp
gemini mcp add --scope user sabor uvx sabor-mcp
code --add-mcp '{"name":"sabor","command":"uvx","args":["sabor-mcp"]}'Without a config.toml, Sabor starts with local SQLite in the OS data directory;
run sabor-mcp setup later to add Mealie, prices or Bring!.
3. Docker or Mealie (advanced)
See Quickstart: Docker — Sabor + Mealie and docs/install-beta.md.
Quickstart: Sabor solo
With Python 3.12+ and uv, the stdio install is:
uvx sabor-mcpOnly after the first PyPI release. Until then, use
uvx --from git+https://github.com/JlMoreno00/sabor sabor-mcp, or build a
local wheel with uv build and run
uvx --from dist/sabor_mcp-0.3.0-py3-none-any.whl sabor-mcp.
No Mealie configuration is needed. The console command defaults to stdio;
sabor-mcp --transport http instead serves Streamable HTTP on loopback
(127.0.0.1:8080/mcp) unless you set SABOR_HOST explicitly.
For standalone Docker (HTTP), only after the first GHCR release:
docker run -p 127.0.0.1:9170:8080 -v sabor-data:/data ghcr.io/jlmoreno00/sabor:0.3.0Until then build locally with docker build -t sabor:local . and use
sabor:local in that command. No Mealie variables are needed.
Connect to http://127.0.0.1:9170/mcp.
Data lives in SABOR_DATA_DIR when set, otherwise an existing /data
directory (Docker), otherwise the OS user data directory:
$XDG_DATA_HOME/sabor or ~/.local/share/sabor on Linux,
~/Library/Application Support/sabor on macOS, %LOCALAPPDATA%\\sabor on Windows.
SQLite, memory, nutrition and catalog cache paths derive from it; explicit
per-file overrides still win. Persist the Docker volume and back up local data.
Video frames in the agent media bundle need system ffmpeg / ffprobe (included
in Docker); install ffmpeg separately for uvx. Without them import_recipe still
returns the video's metadata and subtitles, with a no_frames limitation.
Quickstart: Docker — Sabor + Mealie
You need Docker with Compose v2. Nothing else: the mealie profile also starts
a Mealie for Sabor (pinned to the tested Mealie 3.22.0).
Configure. From the checkout run
cp .env.example .envand setMEALIE_BASE_URL=http://mealie:9000in.env.Start and connect Mealie. Run
docker compose --profile mealie up -d, open Mealie athttp://localhost:9925, sign in as the administrator and create an API token (profile > API Tokens > Generate). Paste it intoMEALIE_API_TOKENin.env.Apply and connect your agent. Run
docker compose --profile mealie up -d --force-recreate saborand registerhttp://127.0.0.1:9170/mcpin your MCP client (Connect your MCP client).
Add COMPOSE_PROFILES=mealie to .env to drop --profile mealie from later
commands. Already running Mealie? Leave the profile out and point
MEALIE_BASE_URL at it, for example http://host.docker.internal:9925 for a
Mealie on the Docker host; then docker compose up -d starts only Sabor. Data
persists in the sabor_data and mealie_data volumes, and both services
publish only on loopback (127.0.0.1:9170 and 127.0.0.1:9925; change the
Sabor port with SABOR_HOST_PORT and Mealie's in
docker-compose.override.yml). Sabor is built locally until a release image
is published to ghcr.io/jlmoreno00/sabor.
Check the transport without running an application tool:
curl -fsS -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"healthcheck","version":"1.0.0"}},"id":1}' \
http://127.0.0.1:9170/mcpAn initialize response checks the server and transport, not provider credentials.
Without Docker
Use Python 3.12. Local video processing also needs ffmpeg and curl.
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
export SABOR_HOST=127.0.0.1
export SABOR_PORT=9170
export SABOR_DATA_DIR="$PWD/.local-data"
python3 sabor_mcp.pyKeep .local-data outside version control. These environment variables set the
same endpoint as Docker; without them the runtime binds to 0.0.0.0:8080.
Nutrition remains disabled. Do not paste real tokens into shared shell history.
Connect your MCP client
For stdio, let the MCP client launch uvx (after the first PyPI release):
{
"mcpServers": {
"sabor": {
"command": "uvx",
"args": ["sabor-mcp", "--transport", "stdio"]
}
}
}Before that release use
"args": ["--from", "git+https://github.com/JlMoreno00/sabor", "sabor-mcp", "--transport", "stdio"].
Keep stdout reserved for the protocol; logs go to stderr.
For Docker or a running HTTP process, register a Streamable HTTP server named
sabor. A generic configuration is:
{
"mcpServers": {
"sabor": {
"type": "http",
"url": "http://127.0.0.1:9170/mcp"
}
}
}Configuration field names depend on your client. For Claude Code:
claude mcp add --transport http sabor http://127.0.0.1:9170/mcpLoopback works only when the client runs on the Docker host. For a containerized or remote client, configure private connectivity deliberately; do not expose this endpoint publicly without an authenticated access layer.
Tool reference by toolset
Signatures below are generated from decorated Python functions; None means
optional/unset. Stable IDs are required, not fuzzy list names. Use MCP discovery
for full schemas and current availability.
Always on
sabor_capabilities()core
search_recipes accepts sort="name" (default), created_at, updated_at,
rating, last_made, or random, with direction="asc" or "desc".
Random ignores direction and uses the UTC date (YYYY-MM-DD) as its daily
seed, keeping pagination stable within the day for unchanged recipes/filters.
Unrated and never-made recipes sort last in either direction. SQLite has no
ratings: sort="rating" returns unsupported_operation, not a substitute order.
add_recipe_comment(slug: str, text: str)
log_cooking_event(slug: str, subject: str, message: str | None=None)
get_mealplan_week(start_date: str, end_date: str)
set_mealplan_entry(date_str: str, entry_type: str, title: str, recipe_slug: str | None=None)
delete_mealplan_entry(entry_id: str)
clear_mealplan_week(start_date: str, end_date: str, confirm: bool=False)
search_recipes(query: str='', page: int=1, per_page: int=25, tag_ids: list[str] | None=None, category_ids: list[str] | None=None, food_ids: list[str] | None=None, tool_ids: list[str] | None=None, cookbook_id: str | None=None, require_all: bool=False, sort: str='name', direction: str='asc')
get_recipe(slug: str)
update_recipe(slug: str, patch: dict, confirm: bool=False)
suggest_recipes(foods: list[str], tools: list[str] | None=None, max_missing_foods: int=2, max_missing_tools: int=0, limit: int=10, include_foods_on_hand: bool=True)
create_recipe(name: str, description: str | None=None, recipe_yield: str | None=None, total_time: str | None=None, ingredients: list[str] | None=None, instructions: list[str] | None=None, tags: list[str] | None=None, source_url: str | None=None)
get_shopping_lists()
create_shopping_list(name: str)
delete_shopping_list(list_id: str, confirm: bool=False)
clear_shopping_list(list_id: str, confirm: bool=False)
get_or_create_shopping_list(name: str)
add_to_shopping_list(list_id: str, items: list[str] | None=None, recipe_slugs: list[str] | None=None, mealplan_start: str | None=None, mealplan_end: str | None=None, servings_multiplier: float=1.0)
get_shopping_list_items(list_id: str, checked: bool | None=None, page: int=1, per_page: int=100)
check_shopping_list_items(list_id: str, item_ids: list[str], checked: bool=True)
remove_shopping_list_items(list_id: str, item_ids: list[str], confirm: bool=False)
get_or_create_tag(name: str)
tag_recipe(slug: str, tags: list[str])import
import_recipe(source: str, kind: str='auto', dry_run: bool=True, language: str='en', max_recipes: int=8, min_confidence: float=0.55)shopping_sync
get_shopping_sync_targets(provider: str | None=None)
sync_shopping_list(mealie_list_id: str, target: dict, mode: str='append', confirm: bool=False, preview_digest: str | None=None)Pantry-aware estimates
The instance preferences default-profile pantry list is read
under the preferences lock, even when the preferences toolset is disabled.
Missing files mean an empty pantry. A corrupt file makes exclude_pantry: true
estimates fail with a sanitized invalid_response; estimates without it never
read preferences. Shopping additions are not blocked by a corrupt file (see
pantry_warning below). No pantry data is changed here.
Every estimate_cost source kind accepts optional exclude_pantry: bool:
estimate_cost(source={"kind":"recipe","slug":"rice","exclude_pantry":True}).
Absent/false leaves the full response unchanged and does not read preferences.
True skips pricing matched lines, keeps them in lines and excluded_rows with
uncertainty.reasons: ["in_pantry"], counts them in coverage excluded, and
adds pantry: {"applied": true, "matched": N}. Subtotals exclude those lines;
if nothing is costed, subtotals remain null, not zero.
Matching uses structured food names or ingredient_name on free text, then
casefolding, accent removal and collapsed whitespace. ingredient_name strips a
leading amount, a Spanish or English unit word (300 g de arroz and 300 grams of rice give arroz and rice) and the connector de/of. English unit words apply
with every store, Mealie included; Spanish lines are unchanged. Whole names must equal,
or equal after stripping one trailing s or es on either side. No fuzzy or
substring matching: huevo matches huevos, but sal never matches salsa.
This is lexical matching, not quantity-aware stock accounting.
add_to_shopping_list always adds every requested line. With a nonempty pantry,
its success data additionally contains pantry_matches, for example
[{"name":"huevos","pantry_entry":"huevo"}] (or [] if none match).
The field is absent for an empty/missing pantry. Pantry hints never block the
addition: if preferences are unreadable or matching fails, the lines are still
added and the response carries pantry_warning instead. SQLite, Mealie and Fake use
source lines: inline item text, or each occurrence's recipe ingredients read
before writing. IDs are deliberately omitted because stores can merge lines;
reread get_shopping_list_items to identify IDs, then ask for approval and use
remove_shopping_list_items if desired. No automatic removal or skipping occurs.
pricing
search_pricing_products(query: str, store: dict | None=None, limit: int=10)
get_product_price(product_id: str, store: dict | None=None)
estimate_cost(source: dict, store: dict | None=None, product_overrides: dict | None=None, match_policy: str='cheapest')legacy_spoonacular
spoonacular_search_recipes(query: str='', number: int=5, max_calories: float | None=None, min_calories: float | None=None, max_protein_g: float | None=None, min_protein_g: float | None=None, max_fat_g: float | None=None, min_fat_g: float | None=None, max_carbs_g: float | None=None, min_carbs_g: float | None=None)
spoonacular_nutrition_100g(ingredient: str)legacy_pricing
mercadona_get_price_drops()
mercadona_get_new_arrivals()preferences
Opt in with SABOR_TOOLSETS=core,import,shopping_sync,preferences; defaults
remain unchanged. These tools need no provider. Preferences are per instance /
household, not authenticated users; only the reserved default profile is used.
Both are provisional choices pending maintainer confirmation: the toolset stays
opt-in, and per-user profiles wait for authenticated users (#28).
Preview changes first, then repeat with confirm=True after approval.
get_preferences()
update_preferences(changes: dict, confirm: bool=False)changes accepts set (replace fields), add and remove (list fields only).
Fields: diet, dislikes, pantry, notes are lists of up to 200 strings;
strings are trimmed, non-empty, at most 200 characters and deduplicated ignoring
case. household_size is null or an integer from 1 to 20. Operations run in
set → add → remove order. Unknown keys or invalid values write nothing.
Responses include preferences, updated_at and source (defaults, file, or postgres);
updates also include a before/after field diff and preview flag. Preview does
not change the timestamp. Pantry is also available to pricing and list building
without enabling this toolset; see pantry-aware estimates.
legacy_memory
Deprecated in favor of preferences. These tools still use MEMORY.md unchanged,
including save_feedback; ratings/favorites/comments are not redirected.
See migration instructions.
save_feedback(recipe_name: str, rating: int | None=None, comment: str | None=None, tags: list[str] | None=None)
read_memory(section: str | None=None)
update_pantry(items: list[str])
update_learned_preference(preference: str)legacy_nutrition
nutrition_recipe_readiness(slug: str, include_suggestions: bool=True)
nutrition_correct_recipe(slug: str, expected_revision: dict[str, str | None], corrections: list[dict[str, Any]], apply: bool=False)
nutrition_status()
nutrition_food_profile(mealie_food_id: str)
nutrition_set_food_profile(mealie_food_id: str, calories_kcal: float | None=None, protein_g: float | None=None, carbohydrate_g: float | None=None, net_carbohydrate_g: float | None=None, fat_g: float | None=None, saturated_fat_g: float | None=None, unsaturated_fat_g: float | None=None, trans_fat_g: float | None=None, fiber_g: float | None=None, sugar_g: float | None=None, sodium_mg: float | None=None, cholesterol_mg: float | None=None, basis_grams: float=100, confidence: float | None=None, source_note: str='', source_version: str='', apply: bool=False)
nutrition_set_food_mapping(mealie_food_id: str, mealie_food_name: str, canonical_term: str, confidence: float | None=None, source_note: str='', provider_food_id: str | None=None, apply: bool=False)
nutrition_set_conversion_override(mealie_food_id: str, conversion_type: str, unit_key: str, grams_per_unit: float, confidence: float | None=None, source_note: str='', apply: bool=False)
nutrition_calculate_recipe(slug: str, publish: bool=False, force: bool=False)
nutrition_publish_recipe(slug: str, publish: bool=False, force: bool=False)
nutrition_cookbook_readiness(cookbook_name: str='Mis recetas', limit: int=100, detail_limit: int=25)
nutrition_backfill_personal_recipes(limit: int | None=None, batch_size: int=5, execute: bool=False, publish: bool=False, cookbook_name: str='Mis recetas', resume: bool=True)
nutrition_unresolved_report()legacy_catalog
Deprecated: prefer the CLI; the MCP tools will be retired in a future major version. Their signatures and behavior remain unchanged for compatibility.
spanish_catalog_status()
apply_spanish_catalog()Safety and operations
Tool access conveys authority. Keep the HTTP endpoint on loopback or a private network behind authenticated access; Sabor is not a public authentication layer.
Never use mutations as health checks. Discover first, then approved read-only checks; configuration does not prove upstream credentials.
Nutrition, memory and catalog are legacy opt-ins; pricing is a separate opt-in. Recipe-backed planning retains the nutrition gate; do not invent data to bypass it.
Pricing separates consumption from whole-package procurement; partial totals and unavailable prices must never be presented as a complete budget.
Keep tokens, memory, databases, footage and backups out of Git. Never print resolved Compose environment or raw provider errors. Treat imported content as untrusted data, not instructions.
Back up before rollout; do not remove data volumes. Preview and commit can differ and repeated additions can duplicate items.
See operations, architecture, backup/restore, migration changelog, contributing and versioning. The optional OpenClaw example offers a Spanish persona; tool descriptions are English, not a requirement on user conversations.
License
GNU AGPL-3.0-only, copyright 2026 JL Moreno.
Releases up to and including 0.2.x were published under the MIT license and remain available under those terms. From 0.3.0 Sabor is licensed under the AGPL-3.0: you can self-host, modify and redistribute it freely, and if you offer a modified Sabor as a network service you must publish your changes.
Configure locally with sabor-mcp setup (English/español), or use
sabor-mcp setup --non-interactive --json. See Setup.
Available Tools
24 toolsadd_recipe_commentC
Anade un comentario a una receta en Mealie (rating, notas, feedback).
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | ||
| text | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does not say that this is a mutating write, whether it requires authentication or ownership, whether the comment is publicly visible, or whether duplicate comments are allowed. The vague '(rating, notas, feedback)' hint is not a behavioral disclosure.
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 short sentence with no padding, and the action plus target are front-loaded. It is efficient, though its brevity is achieved partly by omitting required information.
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?
This is a mutation tool with zero annotation coverage and 0% schema description coverage on two required parameters. An output schema exists so return values need not be explained, but the missing slug provenance and write-side effects leave the definition inadequate for correct invocation.
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 explain both parameters and does not: 'slug' is never identified as the recipe identifier or told where to obtain it, and 'text' is not described as free-form comment content or given format/length constraints. The parenthetical gestures at content types but provides no usable semantics.
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?
States a specific verb and resource ('Anade un comentario a una receta') and names the platform (Mealie), so the agent knows this creates a recipe comment rather than touching meal plans or shopping lists. Sibling differentiation comes from the resource noun alone; the parenthetical '(rating, notas, feedback)' muddies rather than sharpens the purpose.
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?
No guidance on when to use this instead of update_recipe or tag_recipe, and no prerequisites such as the recipe needing to exist or the slug needing to come from search_recipes/get_recipe. The agent must infer all call conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_to_shopping_listB
Add exactly one source to a list. The client must get user approval before calling.
Items remain unparsed notes; recipe scaling uses the explicit servings multiplier.
| Name | Required | Description | Default |
|---|---|---|---|
| items | No | ||
| list_id | Yes | ||
| mealplan_end | No | ||
| recipe_slugs | No | ||
| mealplan_start | No | ||
| servings_multiplier | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does add value: human approval is required pre-call, items are stored as unparsed notes (no interpretation), and scaling uses the explicit multiplier. It still omits whether entries append or replace existing list contents, how duplicates are handled, and what happens if list_id is invalid.
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 short sentences with the behavioral constraint front-loaded and no filler. Slightly terse phrasing ("exactly one source") costs a bit of clarity, but nothing is wasted.
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 6-parameter mutation tool with no annotations and no output schema, the description covers the consent requirement and partial parameter meaning but leaves the agent guessing on append-vs-replace behavior, per-parameter roles for the mealplan dates, and the result shape.
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 coverage is 0% across 6 parameters, so the description must compensate. It clarifies the semantics of two of them (items as unparsed notes, servings_multiplier for recipe scaling) and implies mutual exclusivity of the three source parameters, but list_id, mealplan_start, and mealplan_end get no explanation at all.
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 verb (add) and general target (a list) are clear, but "exactly one source" is ambiguous — the schema shows three distinct source shapes (items, recipe_slugs, mealplan range) and the description never names them. It also doesn't distinguish itself from siblings like create_shopping_list or get_or_create_shopping_list.
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?
It gives a real precondition ("client must get user approval before calling") and an implicit constraint (exactly one source per call), which are useful usage rules. But there is no guidance on when to pick this tool versus create_shopping_list or get_or_create_shopping_list, nor any exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_shopping_list_itemsC
Set checked state only after verifying every requested item belongs to the list.
| Name | Required | Description | Default |
|---|---|---|---|
| checked | No | ||
| list_id | Yes | ||
| item_ids | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load, and it does disclose one meaningful behavioral trait: an all-or-nothing validation that every item must belong to the list before any state change. It does not say what happens on validation failure (error vs partial write), whether the operation is idempotent, or that it is a mutation.
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 sentence with no filler, so nothing is bloated. But it is front-loaded on a constraint rather than on the core purpose, which is a poor ordering choice for a one-sentence definition.
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 mutation tool with no annotations, no output schema, and 0% parameter documentation, this description is too thin. An agent still lacks the boolean semantics, failure behavior, and the relationship to the sibling read/add/remove tools.
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% with three parameters, so the description must compensate and largely does not. It implicitly touches all three ('checked state', 'every requested item', 'the list') but never explains that 'checked' is a boolean defaulting to true, so an agent cannot tell whether omitting it marks items checked or unchecks them.
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 ('Set checked state') tied to list items, and the tool name supplies the resource. However, it leads with an implementation precondition ('only after verifying...') rather than plainly saying it marks shopping-list items as checked/unchecked, and it does not distinguish itself from siblings like add_to_shopping_list or remove_shopping_list_items.
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 statement of when to use this versus the many sibling shopping-list tools (get_shopping_list_items to read state, add_to_shopping_list to add, clear_shopping_list to reset). The precondition is mentioned, but no usage context or exclusion is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_mealplan_weekA
Preview entries removed in a date range; pass confirm=True to clear them.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| end_date | Yes | ||
| start_date | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load and does disclose the most important behavior for a destructive tool: a dry-run default with an explicit confirm gate. It omits irreversibility, scope of deletion (all entries vs. only mealplan), and permission requirements.
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 tight sentence with zero filler, front-loading the dry-run behavior and then the action trigger. Nothing redundant.
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?
An output schema exists, so the preview/result shape needn't be explained. But for a destructive operation with no annotations, key facts are missing: whether deletion is irreversible, date format/inclusivity of the range, and whether 'week' in the name constrains the range.
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 coverage is 0%, so the description must compensate. It explains confirm meaningfully (default = preview, True = execute), which is the non-obvious parameter, but says nothing about start_date/end_date format or inclusivity despite both being required strings.
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?
States a specific verb (remove/clear) and resource (mealplan entries in a date range), plus the preview behavior. It implicitly distinguishes itself from the single-entry sibling delete_mealplan_entry, though it never names it, and the name's 'week' scope is broader in the description as an arbitrary date range.
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?
Gives a clear operating condition: call as-is to preview, pass confirm=True to actually clear. That is a real when-to-use rule for the two modes. It stops short of naming delete_mealplan_entry as the alternative for removing a single entry.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_shopping_listA
Preview removal of all shopping items; pass confirm=True to clear the list.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| list_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the disclosure burden and does the most important part: it flags a destructive bulk operation and documents the built-in dry-run safety gate via confirm. It omits whether the cleared items are recoverable and whether the list container survives, which are the remaining behavioral unknowns.
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 tight sentence that front-loads the default preview behavior and then the confirm escape hatch. No filler, no repetition of the tool name.
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?
An output schema exists, so return values needn't be described, and the two parameters' core semantics are covered. The remaining gap is relationship to the adjacent delete_shopping_list and remove_shopping_list_items tools, which a destructive tool should ideally disambiguate.
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 fully explains the confirm parameter's dual preview/execute semantics and default-off behavior, but says nothing about list_id beyond its name, leaving scope (which list, ID format) undocumented in both places.
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?
States a specific verb+resource: removes all shopping items from a list, and clarifies the operation is previewed by default. It contrasts implicitly with remove_shopping_list_items by emphasizing 'all', but never names that sibling to make the boundary explicit.
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?
Gives clear operational context: calling without confirm produces a preview, and passing confirm=True performs the clear. No exclusions or sibling routing are stated (e.g., use remove_shopping_list_items for selective removal or delete_shopping_list to remove the list itself), so the agent must infer those boundaries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_recipeA
Create a recipe in Mealie using structured fields, not URL import.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| tags | No | ||
| source_url | No | ||
| total_time | No | ||
| description | No | ||
| ingredients | No | ||
| instructions | No | ||
| recipe_yield | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden, yet it only says a recipe is created. It says nothing about required permissions/auth, duplicate-name behavior, which fields are ignored, or whether defaults are applied — all material for a mutation tool with eight inputs.
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 zero filler; the disambiguating clause is attached directly to the action statement.
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?
An output schema exists, so return values need not be explained, and the tool has no nested objects. But with zero annotation coverage and 0% parameter documentation, the definition leaves the agent without any of the field-level or behavioral context needed to call an 8-parameter create tool confidently.
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% across 8 parameters, so the description must compensate and does not: no parameter is named or explained beyond the vague phrase 'structured fields'. Format expectations for total_time, ingredients, or instructions — none of which are documented in the schema — are left entirely unstated.
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?
States a specific verb and resource (create a recipe) plus the mechanism (structured fields), and explicitly contrasts with URL import, which maps onto the import_recipe sibling. An agent can distinguish it from import_recipe and update_recipe without opening any schema.
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?
'not URL import' implicitly routes URL-based creation to import_recipe, giving a clear selection rule. It does not name the sibling explicitly or state other exclusions (e.g., when to use update_recipe instead), so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_shopping_listC
Crea una nueva lista de compra vacia con el nombre indicado.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. It usefully states the new list will be empty, but says nothing about duplicate-name handling, permissions, whether creation overwrites anything, or idempotency — the failure modes an agent most needs to know about for a create operation.
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 filler. It is perhaps too terse given the 0% schema coverage, but it is efficient rather than padded.
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?
An output schema exists, so return values need not be explained, and the single required parameter is simple. However, for a create tool with no annotations and an undocumented parameter, the description leaves duplicate-name behavior and post-creation state implicit.
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 the undocumented 'name' parameter. 'Con el nombre indicado' merely restates the parameter name; no constraints on format, uniqueness, or length are given.
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?
States a specific verb and resource ('Crea una nueva lista de compra') plus the key qualifier 'vacía', which distinguishes it from add_to_shopping_list or get_or_create_shopping_list. It stops short of explicitly naming the sibling it is not, so it lands at 4 rather than 5.
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 versus get_or_create_shopping_list or get_shopping_lists, both of which are plausible alternatives for the same intent. No mention of prerequisites or what happens if a list with that name already exists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_mealplan_entryC
Elimina una entrada del plan de comidas por su ID.
| Name | Required | Description | Default |
|---|---|---|---|
| entry_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It says deletion happens but omits whether the deletion is irreversible, what happens if the entry_id does not exist, and required permissions — all critical for a destructive operation.
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?
One short, front-loaded sentence with no wasted words; the action and targeting mechanism appear immediately. It is efficient, though efficiency here partly reflects under-specification rather than discipline.
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 (one required string) and an output schema exists, so return values need no explanation. However, for a delete operation with no annotations and an undocumented parameter, the description should at minimum flag irreversibility and where the entry_id comes from.
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% and the single parameter carries only the title 'Entry Id', so the description must compensate. 'por su ID' merely restates that the argument is an identifier without giving format, source (e.g., from get_mealplan_week), or validation expectations.
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?
States a specific verb (Elimina) and resource (entrada del plan de comidas) plus the identifier used to target it. It implicitly distinguishes itself from clear_mealplan_week and set_mealplan_entry by scoping the action to a single entry, though it never names those siblings explicitly.
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 instead of clear_mealplan_week or set_mealplan_entry, and no stated prerequisites such as needing a valid existing entry_id. The agent must infer usage purely from the name and one-line description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_shopping_listA
Preview deletion of a shopping list; pass confirm=True to delete it permanently.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| list_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and it does disclose the most important trait: the default is a non-destructive preview and only confirm=True destroys data, and the deletion is stated as permanent. It doesn't say what happens to the list's items, whether the call errors on a missing list, or what permissions are needed.
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?
One sentence, front-loaded with the default (preview) behavior and ending with the opt-in destructive action. Nothing extraneous to trim.
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?
An output schema exists, so return values needn't be explained, and with only two parameters the description covers the one that matters. Minor gaps remain around side effects on list items and behavior for an invalid list_id.
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 fully explains the confirm flag's two values and the default behavior, which is the only non-obvious parameter. list_id is left implicit, relying on the name alone.
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?
States a specific verb and resource (delete a shopping list) plus the two-mode semantics folded into the same sentence. It does not differentiate from the nearby clear_shopping_list or remove_shopping_list_items siblings, which an agent could plausibly confuse with this.
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?
Gives a clear operational rule: the default call previews, and confirm=True performs the permanent deletion. What's missing is any guidance on when to prefer this over clear_shopping_list or remove_shopping_list_items.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_mealplan_weekB
Obtiene el plan de comidas para un rango de fechas (YYYY-MM-DD).
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | Yes | ||
| start_date | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden and delivers almost nothing: no statement about permissions, what happens with an empty range, whether days with no entries are returned, or how the week is keyed. It only discloses the date format, which is a parameter detail rather than behavioral context.
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 zero padding; the date-format constraint is placed immediately after the scope. It is efficient, though so terse that the 'week' vs. 'range' tension in the name is never resolved.
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?
An output schema exists, so return values need not be explained, and the format hint covers the main invocation risk. Still, for a two-required-parameter tool with 0% schema coverage and no annotations, the description should state inclusive/exclusive bounds and range constraints to be complete.
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 coverage is 0% — the two properties carry only titles ('Start Date', 'End Date') — so the description's '(YYYY-MM-DD)' format note is genuinely valuable and prevents a common formatting error. However, it does not clarify whether start_date/end_date are inclusive, whether end must be >= start, or any maximum range, leaving real ambiguity for two required parameters.
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?
States a specific verb and resource ('Obtiene el plan de comidas') plus the scope ('un rango de fechas'), which clearly frames this as a read over a time window and separates it from mutation siblings like set_mealplan_entry and delete_mealplan_entry. Minor friction: the tool name says 'week' while the description describes an arbitrary range, leaving a small ambiguity about intended granularity.
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 read nature and date-range scope imply when the tool applies, but there is no explicit when-to-use, no mention of clear_mealplan_week or get_recipe as alternatives, and no prerequisites or limits stated. The agent must infer usage from the verb alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_or_create_shopping_listA
Busca una lista de compra por nombre; si no existe, la crea. Devuelve siempre el ID.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose the key side effect: a write occurs when the list doesn't exist. It also notes the return of the ID. It does not cover permission requirements, duplicate-name handling, or case sensitivity of the name match — meaningful gaps for a mutating tool.
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 short sentences with zero waste, and the conditional behavior is front-loaded before the return guarantee.
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 simple one-parameter tool with an output schema documenting the returned ID, the description covers the essential behavior. Minor missing context around name matching and permissions keeps it from a 5.
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 coverage is 0% for the single 'name' parameter, so the description must compensate. 'por nombre' indicates the name is both the lookup key and the creation value, which is useful, but format or uniqueness expectations are not specified.
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?
States a specific combined operation: looks up a shopping list by name and creates it if absent. The verb+resource is precise and the get-or-create semantics are unambiguous, though it doesn't explicitly name sibling tools like get_shopping_lists or create_shopping_list to differentiate itself.
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 implicit use case is clear — call it when you want a list by name without knowing whether it exists. However, there is no explicit guidance on when to prefer this over create_shopping_list or get_shopping_lists, nor any stated preconditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_or_create_tagA
Busca un tag por nombre (case-insensitive); si no existe, lo crea.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It does disclose the key non-obvious trait: this call has a write side effect (creates the tag when missing) and matching is case-insensitive. It does not state whether the call is idempotent under concurrent calls, whether it requires write permissions, or what happens on name conflicts, which are meaningful gaps for a get-or-create mutation.
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 compact sentence that front-loads the primary behavior (search) and then the conditional fallback (create). No filler, no repetition of the tool name.
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 output schema exists, so return values need not be explained. However, for a tool whose name suggests a read but which performs a conditional write with no annotations at all, the description should say more about permissions, failure modes, and duplicate-handling to be complete.
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% for the single `name` parameter, so the description must compensate. It adds real value by clarifying that `name` is the lookup key and that matching is case-insensitive, but it says nothing about format constraints (trimming, allowed characters, length limits) that determine whether the lookup will hit an existing tag or silently create a near-duplicate.
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 names a specific resource (tag) and states both behaviors: lookup by name and creation if absent, including the case-insensitive match rule. An agent immediately understands this is a lookup-or-create idiom rather than a pure read or pure write. It doesn't explicitly contrast with siblings, but no sibling duplicates this operation (tag_recipe attaches tags to recipes, which is a different action).
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?
Usage is only implied: an agent infers it should call this when it needs a tag reference without knowing whether the tag already exists. There is no explicit statement of when to prefer this over a plain lookup, no prerequisite or ordering guidance, and no note about what to do if the name is ambiguous or invalid.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recipeB
Read structured ingredients, instructions, taxonomy and times; unknowns stay null.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose one useful trait the schema cannot: missing data is returned as null rather than omitted. It does not address what happens for a nonexistent slug, whether access is scoped to the caller's own recipes, or whether the read is cached/rate-limited.
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?
One sentence, front-loaded with the verb and the returned content, with the null-handling caveat trailing where it belongs. No filler or redundant restatement of the name.
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?
An output schema exists, so return shape need not be explained and the description's field summary is a bonus. For a simple one-parameter read, though, the slug lookup semantics and not-found behavior are the remaining pieces an agent needs and they are absent.
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% and the single required parameter, slug, is never mentioned in the description, so an agent gets no guidance on its format (URL slug vs ID) or whether it must be an exact match. The description does nothing to compensate for the coverage gap.
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?
"Read structured ingredients, instructions, taxonomy and times" gives a specific verb and enumerates the resource contents, which clearly separates it from write siblings like update_recipe or create_recipe. It never says the resource is a recipe or that it targets a single one, relying on the tool name for that.
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?
No statement of when to use this versus search_recipes (discovery) or get_mealplan_week (plan context). Usage is only implied by the word "Read"; there are no alternatives or exclusions named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_shopping_list_itemsB
Read one list's items, optionally filter checked state, then paginate locally.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| checked | No | ||
| list_id | Yes | ||
| per_page | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does add real signal: 'Read' implies a non-mutating operation and 'paginate locally' discloses that paging happens after retrieval rather than server-side. It omits return shape, item ordering, and whether unchecked/checked/null all behave differently, so the disclosure is partial.
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 compact sentence with the resource and the two key behaviors front-loaded; no filler. It is slightly telegraphic ('paginate locally' is doing a lot of unexplained work), which keeps it from a 5.
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 4-param read tool with no annotations and no output schema, the agent still lacks the item record shape, ordering, and the exact checked-flag semantics. It is minimally sufficient to invoke but not to predict the result.
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, and it does touch all four params indirectly: 'one list's items' (list_id), 'filter checked state' (checked), 'paginate' (page/per_page). It leaves the checked polarity ambiguous (does true return only checked items or exclude them?) and never mentions the per_page=100 / page=1 defaults.
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?
States a specific verb and resource: 'Read one list's items', which separates it from the list-level sibling get_shopping_lists. It never names the item-mutating siblings it could be confused with (check_shopping_list_items, add_to_shopping_list), so it is clear but not sibling-differentiating.
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 (you need a known list_id and may want to filter by checked state) but gives no explicit when-to-use or when-not. It does not route the agent away from get_shopping_lists or toward check_shopping_list_items for item mutation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_shopping_listsA
Devuelve todas las listas de compra del hogar con sus IDs y nombres.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the scope of the result ('todas las listas del hogar') which is useful context, but says nothing about read-only nature, permissions, pagination, or behavior when the household has no lists.
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 filler. It is appropriately sized, though being one clause it cannot carry much structure.
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?
An output schema exists, so return-value explanation is not required, and there are no parameters to document. However, for a tool with no annotations at all, the description omits any mention of scope limits (e.g., shared vs personal lists) or safe read behavior, leaving minor gaps.
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 tool takes zero parameters, so there is nothing for the description to disambiguate; baseline is 4. The description correctly signals that no filtering arguments exist by saying 'todas'.
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?
States a specific verb and resource ('Devuelve todas las listas de compra del hogar') and names the returned fields (IDs and names), so the agent knows exactly what it gets. It does not distinguish itself from siblings like get_or_create_shopping_list or get_shopping_list_items, so an agent must infer the difference.
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?
Usage is only implied: 'todas las listas del hogar' suggests a discovery/listing call, typically used before add_to_shopping_list or get_shopping_list_items. There is no explicit when-to-use, when-not-to-use, or named alternative, so routing between the many shopping-list siblings is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_recipeB
Preview or import recipes. Video previews may download media and incur LLM costs.
Image creation has no read-only preview. Local media paths are unsupported.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | auto | |
| source | Yes | ||
| dry_run | No | ||
| language | No | en | |
| max_recipes | No | ||
| min_confidence | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description does real work: it warns that video previews can download media and incur LLM costs, and that image creation has no read-only preview (a genuine side-effect warning). It doesn't state what an import actually creates, whether it's reversible, or what is returned, so the burden from missing annotations isn't fully met.
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 short, factual sentences with the cost/side-effect caveats front-loaded after the core purpose. No filler, though it could be tighter by pairing caveats with the parameters they apply to.
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 cost-incurring import with no annotations and no output schema, the description covers the major risks (LLM cost, no image preview, unsupported local paths) but leaves parameter meanings and the result of a real import undocumented, so an agent still lacks enough to call it precisely.
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?
Six parameters at 0% schema coverage means the description must carry all parameter meaning, and it does not. It only implicitly gestures at dry_run ('preview' vs 'import'), kind ('video'/'image'), and source ('local media paths unsupported'); max_recipes, min_confidence, and language are entirely unexplained.
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?
States a specific verb ('import') and resource ('recipes'), plus the preview capability. It's distinguishable from create_recipe by implying ingestion from an external source, but it never names the adjacent siblings (create_recipe, add_recipe_comment) to sharpen the boundary.
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?
'Preview or import' plus the note that image creation has no read-only preview implies the when-to-use context (safely preview video, beware image). However there is no explicit guidance on choosing this over create_recipe, nor on defaults like dry_run=true, leaving the agent to infer usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
log_cooking_eventC
Registra un evento en el timeline de una receta (cooking log / historial).
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | ||
| message | No | ||
| subject | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it discloses almost nothing: 'Registra' implies an additive write, but there is no statement on permissions, whether entries are editable/removable, or whether repeated calls duplicate. No output schema explanation is needed, but for an unannotated mutation tool this is a significant gap.
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?
One tight sentence with the action and scope front-loaded and the bilingual gloss aiding disambiguation; no filler. Its brevity tips into under-specification rather than being wasteful.
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 an unannotated write tool with two required, undocumented parameters, the description leaves the agent guessing at the semantics of 'subject' and at the mutation's side effects. An output schema exists, so return values need not be described, but the input side is badly under-covered.
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% across three parameters, so the description must compensate and does not. It implies 'slug' identifies the recipe, but 'subject' — a required parameter — is never explained (event type? title?), nor is the optional 'message' differentiated from it.
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?
States a specific verb ('Registra') and resource ('un evento en el timeline de una receta'), with the parenthetical English gloss clarifying 'cooking log / historial'. An agent can tell it creates a log entry on a recipe timeline, though it never distinguishes itself from the closest sibling, add_recipe_comment, which also attaches text to a recipe.
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 when-to-use guidance, no exclusions, and no mention of the plausible alternative (add_recipe_comment) for attaching text to a recipe. The agent must infer that this is for cooking-history entries rather than comments purely from the noun 'timeline'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_shopping_list_itemsA
Preview item removal; confirm=True deletes exactly the verified item IDs.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| list_id | Yes | ||
| item_ids | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose the important safety trait: a dry-run default with an explicit confirm gate. It stops short of stating irreversibility, permission requirements, or what happens to item_ids that don't match verified list contents.
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 clause that puts the safety-relevant preview behavior first and the destructive trigger second. Zero filler and nothing buried.
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 destructive mutation with no annotations, no output schema, and zero parameter documentation, the description covers the execution gate but not the scope question (list_id), the ID verification mechanism, or any hint of the preview payload shape. Just enough to call it, not enough to call it confidently.
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 all three parameters. It explains confirm (default false → preview, true → executes) and adds the constraint that item_ids must be 'verified' IDs, but list_id and the format/verification source of item_ids are left 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?
States a specific verb and resource ('item removal') scoped to a shopping list, and the 'Preview ... confirm=True deletes' phrasing makes the two-phase nature explicit. It doesn't name distinguishing siblings like clear_shopping_list or delete_shopping_list, but the operation itself is unambiguous.
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 default call is a safe preview and that confirm=True is the destructive path, which is useful when-to-use signal. It never says when to prefer this over clear_shopping_list or delete_shopping_list, so the agent must infer the boundary from sibling names alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sabor_capabilitiesA
Describe configured toolsets and the actual registered tool surface.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full disclosure burden, and it does establish this is a non-mutating introspection call (it describes rather than changes configuration). It does not state whether the config is static or reflects live registration state, whether the response is cached, or the shape of the returned 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?
One front-loaded sentence with no filler; each phrase carries meaning (configured toolsets vs. actually registered tool surface). It is appropriately sized, though the terminology could be made more concrete without adding length.
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 no annotations, no parameters, and no output schema, the description is the only source of information, and it stops at naming the topic. An agent still doesn't know whether the response is a list of tool names, per-toolset configs, or enabled/disabled flags, which matters for a discovery tool with no schema to fall back on.
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 tool takes zero parameters, which is the baseline-4 case; no parameter semantics are needed or missing. The description correctly frames the call as argument-free by describing a global inspection of configuration.
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 pairs a specific verb ("Describe") with a concrete resource (configured toolsets and the registered tool surface), which is clearly distinct from every sibling's recipe/shopping-list/mealplan domain. The terms "toolsets" and "registered tool surface" are mildly abstract, leaving some ambiguity about exactly what is reported, so it stops short of 5.
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?
Usage is only implied: an agent can infer this is a discovery/introspection call to run before (or instead of) guessing which capabilities exist. There is no explicit statement of when to call it, when not to, or what to do with the result relative to the sibling recipe tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_recipesC
Search recipes by stable filter IDs with upstream pagination; sort by name.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| sort | No | name | |
| query | No | ||
| tag_ids | No | ||
| food_ids | No | ||
| per_page | No | ||
| tool_ids | No | ||
| direction | No | asc | |
| cookbook_id | No | ||
| require_all | No | ||
| category_ids | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It hints that pagination is handled 'upstream' and that filtering is by stable IDs rather than names, but never states that this is a read-only operation, what the defaults are, or how the 11 filters combine.
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 filler. It is efficient, though its brevity comes at the cost of the missing semantics noted above.
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?
Eleven undocumented parameters, zero schema descriptions, and no annotations means the agent must guess at filter-combination behavior and result sizes. Only the presence of an output schema lightens the burden slightly; the description as written is inadequate for a tool of this complexity.
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% across 11 parameters, so the description must compensate and barely does. It mentions sorting by name and pagination, but leaves opaque the critical 'require_all' flag (AND vs OR of filters), 'direction', 'per_page', and how tag_ids/food_ids/tool_ids/category_ids/cookbook_id interact.
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?
Names a specific verb ('Search') and resource ('recipes') and adds scope detail (filter-ID based, paginated, sortable by name). It does not distinguish itself from sibling 'suggest_recipes', which an agent could plausibly confuse with a text-search tool.
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 when-to-use or when-not-to-use guidance and no named alternative among the many recipe siblings (get_recipe, suggest_recipes, create_recipe). Usage is only implied by the verb 'Search'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_mealplan_entryC
Anade una entrada al calendario de Mealie. entry_type: lunch|dinner|breakfast|side.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| date_str | Yes | ||
| entry_type | Yes | ||
| recipe_slug | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It does not say whether an entry at the same date/type is overwritten or duplicated, what permissions or preconditions are required (e.g., recipe_slug must exist), or anything about the mutation's effects.
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 short sentences with no filler and the purpose is front-loaded. However, the brevity comes at the cost of under-specification rather than being a model of tight structure.
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?
An output schema exists, so return values needn't be explained. But for a 4-parameter mutation tool with zero annotation and zero schema-description coverage, key details (date format, recipe linkage, duplicate handling) are 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, and it only clarifies entry_type's allowed values (lunch|dinner|breakfast|side) — valuable since the schema lacks an enum. It leaves date_str's expected format, title's meaning, and the optional recipe_slug linkage completely 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?
States a specific verb ('Añade') and resource ('entrada al calendario de Mealie'), so the agent knows it creates a meal-plan entry. It is implicitly distinct from get_mealplan_week and delete_mealplan_entry, but doesn't name or contrast with them.
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 versus siblings like delete_mealplan_entry, clear_mealplan_week, or how it interacts with get_mealplan_week. The agent must infer the calling context entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_recipesC
Suggest recipes from food/tool IDs, preserving missing foods and tools.
| Name | Required | Description | Default |
|---|---|---|---|
| foods | Yes | ||
| limit | No | ||
| tools | No | ||
| max_missing_foods | No | ||
| max_missing_tools | No | ||
| include_foods_on_hand | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and 'preserving missing foods and tools' is the only behavioral hint — it vaguely gestures at allowing incomplete matches but doesn't state that results may omit ingredients, how they're ranked, or that this is a non-mutating query. Defaults like max_missing_tools=0 that silently restrict results go unmentioned.
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 filler, so it is concise, but for a six-parameter tool it is undersized — brevity here comes at the cost of information rather than from efficiency.
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?
An output schema exists, so return values needn't be described, but with no annotations, six undocumented parameters, and no differentiation from search_recipes, an agent lacks what it needs to invoke this confidently. The one-line description is not adequate for this complexity.
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 every parameter depends on prose. The sentence mentions foods and tools, but limit, max_missing_foods, max_missing_tools, and include_foods_on_hand are never explained, and even the two named params get no format or semantics beyond 'IDs'.
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 verb 'suggest' and resource 'recipes' are specific, and 'from food/tool IDs' narrows the input domain. However, it never distinguishes itself from the sibling search_recipes, so an agent cannot tell which of the two to pick without opening both schemas.
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?
No when-to-use guidance at all: nothing says this is for ingredient-driven recommendations versus explicit search, nor when the missing-ingredient tolerance should be relaxed. The relationship to search_recipes is left entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tag_recipeB
Asigna etiquetas a una receta. Conserva tags existentes y anade los nuevos.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | ||
| tags | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. It usefully discloses that the operation is additive and preserves existing tags, but it does not mention permissions, idempotency, duplicate handling, or error behavior.
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 two short, front-loaded sentences with no wasted text. The key behavior is stated immediately and clearly.
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 a simple two-parameter mutation with an output schema, but both parameters are undocumented and there are no annotations. The description covers additive behavior but leaves important parameter and operational context unspecified.
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 should compensate by explaining the parameters. It mentions tags conceptually and refers to a recipe, but does not clarify that 'slug' identifies the recipe or that 'tags' is an array of tag names.
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 verb and resource: assigning tags to a recipe. The additive behavior is also clear, but it does not explicitly distinguish this tool from alternatives such as update_recipe or create_recipe.
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 phrase 'Conserva tags existentes y anade los nuevos' implies that this tool should be used when appending tags without replacing existing ones. However, it does not explicitly name alternatives or state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_recipeC
Preview or PATCH selected fields. Arrays replace whole lists, not individual entries.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | ||
| patch | Yes | ||
| confirm | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations and no schema descriptions, the description carries the full behavioral burden. It discloses one important trait—arrays replace whole lists—and hints at preview mode, but says nothing about permissions, irreversible changes, the role of the confirm flag, or what happens on validation errors.
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 short sentences, front-loaded with the core action and followed by a critical semantic note about arrays. It is efficient and avoids waste, though its terseness leaves the reader wanting more detail given the tool's complexity.
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 a nested patch object, three parameters with zero schema descriptions, no annotations, and a confirm flag that is never explained. The description is far too thin to be helpful for correct invocation, even though an output schema exists to cover return values.
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 explains array replacement semantics for the patch object but never mentions the required slug, the confirm boolean, or the nested patch structure. It adds limited meaning beyond what the schema titles already imply.
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 says 'Preview or PATCH selected fields', which implies partial update but never names the resource (recipe). The tool name provides context, but the description alone gives only a vague purpose without explicitly distinguishing it from siblings like create_recipe or import_recipe.
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?
No explicit guidance on when to use this tool versus alternatives such as create_recipe or import_recipe. The mention of 'Preview or PATCH' hints at a dry-run vs apply pattern, but there are no conditions, prerequisites, or named alternatives to help an agent choose correctly.
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.
24 tool updates
v0.1.0- First observed
add_recipe_comment - First observed
add_to_shopping_list - First observed
check_shopping_list_items - First observed
clear_mealplan_week - First observed
clear_shopping_list - First observed
create_recipe - First observed
create_shopping_list - First observed
delete_mealplan_entry - First observed
delete_shopping_list - First observed
get_mealplan_week - First observed
get_or_create_shopping_list - First observed
get_or_create_tag - First observed
get_recipe - First observed
get_shopping_list_items - First observed
get_shopping_lists - First observed
import_recipe - First observed
log_cooking_event - First observed
remove_shopping_list_items - First observed
sabor_capabilities - First observed
search_recipes - First observed
set_mealplan_entry - First observed
suggest_recipes - First observed
tag_recipe - First observed
update_recipe
TDQS
Scored across 24 tools
Tools are grouped by resource (recipes, shopping lists, meal plans, tags), and most actions are distinct. However import_recipe vs create_recipe and create_shopping_list vs get_or_create_shopping_list can be confused, and delete/clear/remove shopping-list tools require careful selection.
Almost all tools use snake_case with verb_noun or verb_preposition_noun patterns. Outliers like sabor_capabilities and compound get_or_create_* names slightly break the pattern but remain readable and consistent in casing.
24 tools is heavy for a single MCP server; the broad domain justifies many but still sits in the borderline 16-25 range. Some meta or compound tools could potentially be consolidated.
Core workflows for recipes, shopping lists, and meal plans are covered with preview/confirm patterns. But there is no delete_recipe, no read/delete for recipe comments or cooking events, and no list/delete tags, leaving notable lifecycle gaps.
Maintenance
Related MCP Connectors
Recipe search, ingredient matching, nutrition filters and a private cookbook for any AI agent.
Scraps Kitchen gives any AI agent a persistent, household-aware kitchen memory. Unlike generic chatbot recall, Scraps maintains structured cooking data: what's in your fridge (with freshness tracking), who you cook for (with allergens, dietary restrictions, and preferences), your recipe collection (with cook notes and per-diner ratings), your shopping list, and your kitchen equipment. 27 tools across 6 domains let agents read kitchen context, suggest meals that respect dietary safety, update the pantry after cooking, and build a history of what works for your household. Every interaction makes the data richer. Cooking history, preference signals, kitchen awareness = better suggestions next time. All tools work via oAuth and a free scraps.kitchen account.
Persistent food journal for AI assistants. Log meals, save recipes, plan meals and track nutrition.
AI-powered kitchen management — pantry, recipes, meal plans, shopping lists
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Mealie for recipe management, meal planning, and shopping list operations. Supports searching and managing recipes, creating meal plans, and generating shopping lists from recipes or meal plans.6MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to interact with Mealie recipe databases, allowing users to manage and query their recipes through natural language conversations.21 npmMIT
- AlicenseNot gradedqualityDmaintenanceExposes Mealie recipe manager as LLM-callable tools for searching recipes, managing meal plans, and editing shopping lists.MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to manage recipes, meal plans, and shopping lists in Mealie through natural language, supporting CRUD operations and URL-based recipe imports.27193 npm8MIT