mcp-pequerecetas
This server lets a chat client search, read, and rescale Spanish home-cooking recipes from Pequerecetas, and rescale Spanish ingredient lists offline.
search_recipes: Find recipes by dish, ingredient, or technique in Spanish; returns rows with ids that
get_recipeaccepts.get_recipe: Read a recipe or collection by slug; optionally rescale quantities to a given number of servings; returns ingredients, steps, nutrition, author, images, and more.
list_facets: List the values each taxonomy publishes — diet, age, ingredient, occasion, moment of day, appliance, cuisine, and dish type.
browse_recipes: Page through a taxonomy's recipes using slugs from
list_facets; reports which page was served and whether more pages exist.scale_ingredients: Rescale any Spanish ingredient list offline by a factor or from/to servings; marks lines as scaled, rounded, or unscaled and flags equipment lines.
Click on "Install 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., "@mcp-pequerecetasFind a paella recipe and scale it for 8 people"
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.
mcp-pequerecetas
Pequerecetas is a Spanish home-cooking site written for families. It holds a few thousand recipes with their ingredients, their steps and their photographs, and files each one under the diet it suits, the appliance it is cooked in, the occasion it is made for and the age of whoever eats it, from six months up.
This server connects a chat client to that site. You can search its recipes, read one with its quantities rescaled to the number of people at your table, list the values each taxonomy publishes, walk a taxonomy page by page, and rescale any Spanish ingredient list you already hold. It needs no API key and no account.
Install
One-click install
Claude Code
claude mcp add pequerecetas -- npx -y mcp-pequerecetasClaude Desktop, Cursor, and any client using the standard config format
{
"mcpServers": {
"pequerecetas": {
"command": "npx",
"args": ["-y", "mcp-pequerecetas"]
}
}
}Node 24 or later is required, and no environment variable has to be set.
With Docker
{
"mcpServers": {
"pequerecetas": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-pequerecetas:1.0.0"]
}
}
}-i keeps stdin open, which is where the protocol travels, and -t is left out
because a TTY rewrites the stream. The container needs outbound HTTPS to
www.pequerecetas.com, and nothing else: no volume, no port, no credential.
Bundle, without npm
Download mcp-pequerecetas-1.0.0.mcpb from
the latest release
and open it. A client that supports MCP bundles installs it on its own, with no
npm and no configuration file to edit. The bundle carries its dependencies, so
nothing is fetched at install time.
Related MCP server: spoonacular-mcp
What you can ask
« Búscame una receta de paella de marisco. »
"Read me that recipe for eight people."
"What can I cook in an air fryer on this site?"
"Show me the purées it files under six months."
"Scale this Spanish ingredient list by three."
Pequerecetas is written in Spanish and its search matches the words a page was
written with, so recipes are found in Spanish. The ordinary path runs from a
search or a taxonomy to a recipe: a row carries an id, and get_recipe takes
that id.
Tools
Tool | What it does |
| Reads one page of the recipe section, rescaled on request. |
| Finds recipes by dish or by ingredient. |
| Lists the values each taxonomy publishes. |
| Reads one taxonomy, page by page. |
| Rescales any Spanish ingredient list, with no request to the site. |
get_recipe
Reads one page of the recipe section, and rescales its quantities when a number of servings is given.
Argument | Type | Required | What it does |
| string, 1 to 200 characters | yes | The slug in a recipe's address, as a row carries it. |
| integer, 1 to 1000 | no | Rescale the quantities to this many. |
In return: kind, which reads recipe or collection. The site publishes
both at this kind of address and describes them alike, so this is what tells them
apart: a collection is an article gathering other recipes, and it comes back with
headings and recipes, the rows it points at, in place of a recipe's fields.
A recipe carries source_shape, reading structured when the block the page
publishes for search engines held its ingredients and article when they were
read from the body of the page, which is where most of this site's recipes keep
them. Then come title, url, description, published_at, modified_at,
prep_minutes, cook_minutes, total_minutes, categories, cuisines,
keywords, author, author_url, rating, nutrition and images, each
null or empty where the page states nothing. yield says what the recipe was
written for and what it was rescaled to; a page stating no number of servings
comes back with factor at 1 and a note saying why. Each line of ingredients
carries scaling, reading scaled, rounded or unscaled, and is_equipment,
which marks a line naming a tool rather than something eaten.
search_recipes
Searches the recipes for a dish or an ingredient.
Argument | Type | Required | What it does |
| string, 1 to 120 characters | yes | A dish or an ingredient, in Spanish. |
| integer, 1 to 60 | no | Rows to return. |
In return: rows carrying id, which get_recipe takes, title, url and
image_url. Alongside come result_count for the rows returned and
total_available, which is always null: the site publishes no count of what a
search matched. The site serves its search on a single page and answers a request
for a second with the first again, so these are all the rows it offers for a
query. Some rows are articles gathering recipes, which get_recipe reports as a
collection.
list_facets
Lists the values the site browses its recipes by, read from the sitemap each taxonomy publishes.
Argument | Type | Required | What it does |
| string, 1 character and up | no | One taxonomy. All eight when left out. |
The taxonomies are dieta, edad, ingrediente, ocasion, recetas-de,
tecnica, tipo-de-cocina and tipo-plato: diet, the age of whoever eats it,
main ingredient, occasion, moment of the day, appliance, cuisine and kind of
dish.
In return: facets, each carrying name, value_count and values, whose
value is the slug browse_recipes takes. The values keep the order the site
publishes them in. Reading all eight costs one request per taxonomy. A taxonomy
that could not be read is named in notes and left out of facets, so a
listing short of one never reads like a site that has seven.
browse_recipes
Reads one page of a taxonomy's recipes.
Argument | Type | Required | What it does |
| string, 1 character and up | yes | The taxonomy to browse. |
| string, 1 to 120 characters | yes | A slug from |
| integer, 1 to 200 | no | Which page to read, the first by default. |
In return: rows of the same shape search_recipes returns, with
page_served for the page the site actually served, has_more for whether its
own pagination offers another, and total_available, always null because the
site prints no count on these pages. The site writes its own slugs, so one built
by hand reaches a page it does not hold and comes back as not_found. The
taxonomies cannot be combined: the site offers no way to ask for two at once.
scale_ingredients
Rescales a list of Spanish ingredient lines. It reaches no site.
Argument | Type | Required | What it does |
| array of 1 to 200 strings | yes | The lines to rescale, as written. |
| number, greater than 0 up to 1000 | one of | What to multiply the quantities by. |
| integer, 1 to 1000 | one of | How many the list was written for. |
| integer, 1 to 1000 | one of | How many it should serve. |
Give factor, or from_servings and to_servings together. Naming both ways at
once is refused, because they can ask for different things.
In return: each line with text as it now reads, original as it was given,
amount, amount_max, unit, and scaling, which carries the honesty of the
answer: scaled when the arithmetic landed exactly, rounded when the value
moved to stay something a kitchen can measure out, unscaled when the line
carries no quantity. is_equipment marks a line naming a tool. Alongside come
scaled_count, rounded_count and unscaled_count. Nothing is converted
between unit systems, and an approximate measure such as a pizca keeps the size
the cook gives it.
Configuration
Variable | Default | Bounds | What it does |
| unset | Prefixed to this server's own User-Agent. | |
|
| 3000 to 60000 | Milliseconds between two requests. |
|
| 1000 to 120000 | How long one request may take. |
|
| 0 to 8 | Attempts at a request the site did not answer. |
|
| 0 to 86400000 | How long a read is held. Zero turns the store off. |
|
| 1 to 5000 | Reads held at once. |
|
| silent, error, info, debug | What goes to stderr. |
The interval has a floor of 3000 milliseconds. A value below it is refused and the default stands, which is stated on stderr rather than applied in silence.
Errors
Code | What it means | What to do |
| The site holds nothing at that address. | Check the slug against |
| The arguments cannot produce a request. | The message names the argument. |
| The site asked this client to slow down. | Wait and ask again. The thing asked for still exists. |
| A page arrived in a shape this cannot read. | Report it; the site may have changed. |
| The request could not be completed. | Try again. |
| No answer arrived in time. | Try again, or raise |
As a library
The reading layer is published on its own, with its pacing, its store and its error vocabulary, and no protocol attached.
import { PequerecetasClient } from "mcp-pequerecetas/client";
const client = new PequerecetasClient();
const read = await client.getRecipe("paella-de-marisco");Built with nothing, it takes its settings from the environment and sends its
diagnostics to stderr. loadConfig and createLogger come from the same entry
point for a caller who would rather set them in code:
import { createLogger, loadConfig, PequerecetasClient } from "mcp-pequerecetas/client";
const client = new PequerecetasClient({
config: { ...loadConfig(), minIntervalMs: 5000 },
logger: createLogger("debug"),
});Every read returns { data, cached }, and cached says whether the answer came
from the store rather than from the site.
Pacing and attribution
One request at a time, three seconds apart, and the interval widens when the site pushes back. The User-Agent carries the project's name, its version and an address where a person can be reached.
Pequerecetas is free to read and pays for its own hosting. When you show a recipe to someone, credit the site and link the page it came from.
This server is not affiliated with Pequerecetas.
Privacy
Nothing is collected. The server reads www.pequerecetas.com and no other host,
keeps what it read in memory for fifteen minutes by default, writes nothing to
disk, and sends its diagnostics to stderr. It carries no credential, because the
site asks for none. See PRIVACY.md.
Development
npm install
npm run build:fixtures
npm test
npm run coverage
npm run checkThe corpus the suite reads is written by scripts/build-fixtures.mjs and holds
invented recipes, so no third-party content is stored here. A live suite runs
behind PQR_LIVE=1, one request per route.
Contributing
Issues and pull requests are welcome. See CONTRIBUTING.md.
License
MIT. See LICENSE.
mcp-pequerecetas (français)
Pequerecetas est un site espagnol de cuisine familiale. Il tient quelques milliers de recettes avec leurs ingrédients, leurs étapes et leurs photographies, et range chacune sous le régime auquel elle convient, l'appareil qui la cuit, l'occasion pour laquelle on la fait et l'âge de celui qui la mange, à partir de six mois.
Ce serveur relie un client de conversation à ce site. On peut chercher ses recettes, en lire une avec ses quantités mises à l'échelle du nombre de personnes à table, lister les valeurs que publie chaque taxonomie, parcourir une taxonomie page par page, et mettre à l'échelle n'importe quelle liste d'ingrédients espagnole qu'on a déjà. Il ne demande ni clé d'API ni compte.
Installation
Installation en un clic
Claude Code
claude mcp add pequerecetas -- npx -y mcp-pequerecetasClaude Desktop, Cursor, et tout client au format de configuration standard
{
"mcpServers": {
"pequerecetas": {
"command": "npx",
"args": ["-y", "mcp-pequerecetas"]
}
}
}Node 24 ou plus récent est requis, et aucune variable d'environnement n'est à définir.
Avec Docker
{
"mcpServers": {
"pequerecetas": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-pequerecetas:1.0.0"]
}
}
}-i garde stdin ouvert, où passe le protocole, et -t est laissé de côté parce
qu'un TTY réécrit le flux. Le conteneur a besoin de joindre
www.pequerecetas.com en HTTPS sortant, et de rien d'autre : aucun volume, aucun
port, aucun identifiant.
Bundle, sans npm
Télécharger mcp-pequerecetas-1.0.0.mcpb depuis
la dernière publication
et l'ouvrir. Un client qui gère les bundles MCP l'installe seul, sans npm et sans
fichier de configuration à modifier. Le bundle emporte ses dépendances, donc rien
n'est téléchargé à l'installation.
Ce qu'on peut demander
« Búscame una receta de paella de marisco. »
« Lis-moi cette recette pour huit personnes. »
« Qu'est-ce que je peux cuisiner à la friteuse à air sur ce site ? »
« Montre-moi les purées qu'il range sous six mois. »
« Multiplie cette liste d'ingrédients espagnole par trois. »
Pequerecetas est écrit en espagnol et sa recherche compare les mots dont une page
est faite, donc les recettes se trouvent en espagnol. Le chemin ordinaire va
d'une recherche ou d'une taxonomie vers une recette : une ligne porte un id, et
get_recipe prend cet id.
Les outils
Outil | Ce qu'il fait |
| Lit une page de la section des recettes, mise à l'échelle sur demande. |
| Trouve des recettes par plat ou par ingrédient. |
| Liste les valeurs que publie chaque taxonomie. |
| Lit une taxonomie, page par page. |
| Met à l'échelle une liste d'ingrédients espagnole, sans requête. |
get_recipe
Lit une page de la section des recettes, et met ses quantités à l'échelle quand un nombre de parts est donné.
Argument | Type | Requis | Ce qu'il fait |
| chaîne, 1 à 200 caractères | oui | Le slug dans l'adresse d'une recette. |
| entier, 1 à 1000 | non | Met les quantités à l'échelle de ce nombre. |
En retour : kind, qui vaut recipe ou collection. Le site publie les deux
à ce genre d'adresse et les décrit pareillement, donc c'est ce qui les distingue :
une collection est un article qui rassemble d'autres recettes, et elle revient
avec headings et recipes, les lignes qu'elle désigne, à la place des champs
d'une recette.
Une recette porte source_shape, qui vaut structured quand le bloc que la page
publie pour les moteurs de recherche portait ses ingrédients, et article quand
ils ont été lus dans le corps de la page, où la plupart des recettes de ce site
les gardent. Viennent ensuite title, url, description, published_at,
modified_at, prep_minutes, cook_minutes, total_minutes, categories,
cuisines, keywords, author, author_url, rating, nutrition et
images, chacun null ou vide là où la page n'énonce rien. yield dit pour
combien la recette a été écrite et vers combien elle a été portée ; une page qui
n'énonce aucun nombre de parts revient avec factor à 1 et une note qui le dit.
Chaque ligne d'ingredients porte scaling, qui vaut scaled, rounded ou
unscaled, et is_equipment, qui marque une ligne nommant un ustensile plutôt
que quelque chose qui se mange.
search_recipes
Cherche les recettes par plat ou par ingrédient.
Argument | Type | Requis | Ce qu'il fait |
| chaîne, 1 à 120 caractères | oui | Un plat ou un ingrédient, en espagnol. |
| entier, 1 à 60 | non | Lignes à rendre. |
En retour : des lignes portant id, que prend get_recipe, title, url et
image_url. À côté viennent result_count pour les lignes rendues et
total_available, toujours null : le site ne publie aucun compte de ce qu'une
recherche a trouvé. Le site sert sa recherche sur une seule page et répond à une
demande de deuxième page par la première à l'identique, donc ce sont là toutes
les lignes qu'il offre pour cette requête. Certaines lignes sont des articles qui
rassemblent des recettes, ce que get_recipe rend comme une collection.
list_facets
Liste les valeurs par lesquelles le site parcourt ses recettes, lues dans le plan de site que chaque taxonomie publie.
Argument | Type | Requis | Ce qu'il fait |
| chaîne, 1 caractère et plus | non | Une taxonomie. Les huit quand il manque. |
Les taxonomies sont dieta, edad, ingrediente, ocasion, recetas-de,
tecnica, tipo-de-cocina et tipo-plato : le régime, l'âge de celui qui
mange, l'ingrédient principal, l'occasion, le moment de la journée, l'appareil,
la cuisine et le type de plat.
En retour : facets, portant chacune name, value_count et values, dont
value est le slug que prend browse_recipes. Les valeurs gardent l'ordre dans
lequel le site les publie. Lire les huit coûte une requête par taxonomie. Une
taxonomie qui n'a pas pu être lue est nommée dans notes et laissée hors de
facets, pour qu'une liste amputée d'une taxonomie ne se lise pas comme un site
qui en aurait sept.
browse_recipes
Lit une page des recettes d'une taxonomie.
Argument | Type | Requis | Ce qu'il fait |
| chaîne, 1 caractère et plus | oui | La taxonomie à parcourir. |
| chaîne, 1 à 120 caractères | oui | Un slug de |
| entier, 1 à 200 | non | La page à lire, la première par défaut. |
En retour : des lignes de la forme que rend search_recipes, avec
page_served pour la page que le site a servie, has_more pour savoir si sa
pagination en offre une autre, et total_available, toujours null parce que le
site n'imprime aucun compte sur ces pages. Le site écrit ses propres slugs, donc
un slug construit à la main atteint une page qu'il ne tient pas et revient en
not_found. Les taxonomies ne se croisent pas : le site n'offre aucun moyen d'en
demander deux à la fois.
scale_ingredients
Met à l'échelle une liste de lignes d'ingrédients espagnoles. Il ne joint aucun site.
Argument | Type | Requis | Ce qu'il fait |
| tableau de 1 à 200 chaînes | oui | Les lignes à mettre à l'échelle. |
| nombre, supérieur à 0 jusqu'à 1000 | l'un | Ce par quoi multiplier les quantités. |
| entier, 1 à 1000 | l'un | Pour combien la liste a été écrite. |
| entier, 1 à 1000 | l'un | Pour combien elle doit servir. |
Donner factor, ou from_servings et to_servings ensemble. Nommer les deux
manières à la fois est refusé, parce qu'elles peuvent demander deux choses
différentes.
En retour : chaque ligne avec text telle qu'elle se lit maintenant,
original telle qu'elle a été donnée, amount, amount_max, unit, et
scaling, qui porte l'honnêteté de la réponse : scaled quand l'arithmétique
est tombée juste, rounded quand la valeur a bougé pour rester une quantité
qu'une cuisine mesure, unscaled quand la ligne ne porte aucune quantité.
is_equipment marque une ligne qui nomme un ustensile. À côté viennent
scaled_count, rounded_count et unscaled_count. Rien n'est converti d'un
système d'unités à un autre, et une mesure approximative comme une pizca garde
la taille que lui donne le cuisinier.
Configuration
Variable | Défaut | Bornes | Ce qu'elle fait |
| non défini | Préfixé au User-Agent du serveur. | |
|
| 3000 à 60000 | Millisecondes entre deux requêtes. |
|
| 1000 à 120000 | Durée maximale d'une requête. |
|
| 0 à 8 | Tentatives sur une requête sans réponse. |
|
| 0 à 86400000 | Durée de conservation d'une lecture. Zéro éteint le cache. |
|
| 1 à 5000 | Lectures gardées à la fois. |
|
| silent, error, info, debug | Ce qui part sur stderr. |
L'intervalle a un plancher de 3000 millisecondes. Une valeur en dessous est refusée et le défaut s'applique, ce qui est dit sur stderr plutôt qu'appliqué en silence.
Erreurs
Code | Ce que ça veut dire | Le geste suivant |
| Le site ne tient rien à cette adresse. | Vérifier le slug avec |
| Les arguments ne peuvent pas produire de requête. | Le message nomme l'argument. |
| Le site a demandé de ralentir. | Attendre et redemander. La chose demandée existe toujours. |
| Une page est arrivée sous une forme illisible. | Le signaler ; le site a pu changer. |
| La requête n'a pas abouti. | Réessayer. |
| Aucune réponse n'est arrivée à temps. | Réessayer, ou élargir |
Comme bibliothèque
La couche de lecture est publiée seule, avec son rythme, son cache et son vocabulaire d'erreurs, sans protocole attaché.
import { PequerecetasClient } from "mcp-pequerecetas/client";
const client = new PequerecetasClient();
const read = await client.getRecipe("paella-de-marisco");Construit sans rien, il prend ses réglages dans l'environnement et envoie ses
diagnostics sur stderr. loadConfig et createLogger viennent du même point
d'entrée pour qui préfère les fixer dans le code :
import { createLogger, loadConfig, PequerecetasClient } from "mcp-pequerecetas/client";
const client = new PequerecetasClient({
config: { ...loadConfig(), minIntervalMs: 5000 },
logger: createLogger("debug"),
});Toute lecture rend { data, cached }, et cached dit si la réponse vient du
cache plutôt que du site.
Rythme et attribution
Une requête à la fois, trois secondes d'écart, et l'intervalle s'élargit quand le site demande de la place. Le User-Agent porte le nom du projet, sa version et une adresse où joindre une personne.
Pequerecetas se lit gratuitement et paie son hébergement. Quand on montre une recette à quelqu'un, on crédite le site et on lie la page d'où elle vient.
Ce serveur n'est pas affilié à Pequerecetas.
Confidentialité
Rien n'est collecté. Le serveur lit www.pequerecetas.com et aucun autre hôte,
garde ce qu'il a lu en mémoire quinze minutes par défaut, n'écrit rien sur
disque, et envoie ses diagnostics sur stderr. Il ne porte aucun identifiant,
puisque le site n'en demande aucun. Voir PRIVACY.md.
Développement
npm install
npm run build:fixtures
npm test
npm run coverage
npm run checkLe corpus que lit la suite est écrit par scripts/build-fixtures.mjs et tient
des recettes inventées, donc aucun contenu tiers n'est stocké ici. Une suite en
direct tourne derrière PQR_LIVE=1, une requête par route.
Contribuer
Les issues et les pull requests sont bienvenues. Voir CONTRIBUTING.md.
Licence
MIT. Voir LICENSE.
Available Tools
5 toolsbrowse_recipesRead one taxonomy's recipesARead-onlyIdempotent
Browse the recipes a taxonomy holds, one page at a time. 'facet' is one of dieta, edad, ingrediente, ocasion, recetas-de, tecnica, tipo-de-cocina, tipo-plato, and 'value' is a slug from list_facets: the site writes its own slugs and answers one built by hand with a page it does not hold. Read 'page_served' rather than assuming the page asked for, and 'has_more' to know whether the site offers another. 'total_available' is null because the site prints no count on these pages. The taxonomies cannot be combined: this site offers no way to ask for two at once.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Which page to read. The first when left out. | |
| facet | Yes | The taxonomy to browse: dieta, edad, ingrediente, ocasion, recetas-de, tecnica, tipo-de-cocina, tipo-plato. | |
| value | Yes | A slug from list_facets, such as 'thermomix'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| facet | Yes | |
| notes | Yes | |
| value | Yes | |
| cached | Yes | |
| results | Yes | |
| has_more | Yes | Whether the site's own pagination offers a page after this one. |
| page_served | Yes | The page the site actually served. |
| result_count | Yes | |
| total_available | Yes | Always null: the site prints no count on these pages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, idempotent, and non-destructive, but the description adds substantial behavioral detail: hand-built slugs return a page the taxonomy does not hold, 'page_served' must be trusted over the requested page, 'has_more' drives pagination, and 'total_available' is always null. This goes well beyond the annotations and significantly improves call correctness.
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 compact and front-loaded with the core purpose, then each subsequent sentence adds a distinct, useful caveat or behavior. There is no filler or redundant restatement of the tool name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description covers all necessary call-related quirks: how to source valid slugs, what to trust in the response, why a count is missing, and the impossibility of combining taxonomies. The agent has enough context to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description reinforces that 'value' must be a slug from list_facets and adds the caveat that made-up slugs receive an unexpected page, which adds meaning beyond the schema's simple examples. It does not add new information about the 'page' parameter beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Browse the recipes a taxonomy holds, one page at a time,' which is a specific verb and resource. It clearly conveys the paginated browsing scope, though it does not explicitly contrast with sibling tools like search_recipes or get_recipe, so it stops short of a 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?
The description gives clear operational context: 'value' must come from list_facets, the site writes its own slugs, and taxonomies cannot be combined. It does not explicitly state when to prefer this tool over its siblings, but the browsing-oriented language and pagination details imply the intended use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recipeRead one recipeARead-onlyIdempotent
Read one page of the recipe section by the slug in its address, such as 'paella-de-marisco'. 'kind' says what the page turned out to be: a 'recipe', or a 'collection', which is an article gathering other recipes and carries no ingredients of its own. A recipe says under 'source_shape' where its ingredients were read: 'structured' from the block the page publishes for search engines, 'article' from the body of the page, which is where most of this site's recipes keep them. Pass 'servings' to rescale the quantities; a recipe whose page states no number of servings comes back unscaled and says so. A line naming a tool rather than an ingredient is marked and never multiplied.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The slug in a recipe's address, from search_recipes or browse_recipes. | |
| servings | No | Rescale the quantities to this many, up to 1000. Left out, the recipe comes back as published. |
Output Schema
| Name | Required | Description |
|---|---|---|
| kind | Yes | |
| notes | Yes | |
| cached | Yes | |
| recipe | No | |
| collection | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (read-only, idempotent), the description discloses significant behaviors: the response 'kind' can be 'recipe' or 'collection', 'source_shape' indicates whether ingredients came from structured data or article text, rescaling is skipped without a stated serving size, and tool-lines are never multiplied. These details greatly exceed the annotation metadata.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph but logically proceeds through key facts: what it reads, the 'kind' distinction, 'source_shape' meanings, servings behavior, and the tool-line rule. Sentences are purposeful though some are long and could be broken up; overall it earns its 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?
Given the output schema exists, the description does not need to explain return types. It thoroughly covers the non-obvious behaviors needed to interpret the result correctly (kind, source_shape, servings fallback, tool-line handling). An agent has enough context to invoke the tool and understand the response without surprises.
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 100%, so the baseline is 3. The description adds value by giving a concrete slug example and explaining important edge-case behavior for 'servings' (e.g., unscaled response when the page states no servings, and marking tool lines rather than multiplying). This is meaningful beyond the schema's own parameter descriptions.
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?
Description uses a specific verb 'Read' and identifies the resource as 'one page of the recipe section', clearly distinguishing this from siblings like search_recipes or browse_recipes by requiring a slug. The inclusion of an example slug ('paella-de-marisco') makes the target concrete.
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 clearly implies when to use this tool: when you have a slug for a specific recipe page and need its details, as opposed to searching or browsing. However, it does not explicitly name alternative tools or state when not to use it, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_facetsList the taxonomies recipes are browsed byARead-onlyIdempotent
List the values the site browses its recipes by. The taxonomies are dieta, edad, ingrediente, ocasion, recetas-de, tecnica, tipo-de-cocina, tipo-plato: diet, the age of whoever eats it, main ingredient, occasion, moment of the day, appliance, cuisine and kind of dish. Call this before browse_recipes rather than spelling a value yourself. Pass 'facet' for one taxonomy, or leave it out for all eight, which costs one request per taxonomy.
| Name | Required | Description | Default |
|---|---|---|---|
| facet | No | One taxonomy: dieta, edad, ingrediente, ocasion, recetas-de, tecnica, tipo-de-cocina, tipo-plato. All eight when left out. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| cached | Yes | |
| facets | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is read-only, idempotent, open-world, and non-destructive. The description adds useful behavioral context beyond that, especially that omitting facet triggers eight underlying requests, one per taxonomy. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the tool's purpose in the first sentence, followed by a compact list of taxonomies and then actionable usage guidance. Every sentence adds useful information with no filler.
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 single optional parameter, a comprehensive schema, an output schema, and annotations covering safety and world behavior. The description fills the remaining practical gaps: how to call it, why to call it before browse_recipes, and the request-cost implication of omitting the facet parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the facet parameter and its allowed values, so the baseline is 3. The description adds human-readable meanings for each taxonomy and the important distinction that passing facet returns one taxonomy while omitting it fetches all eight, with a note about request cost.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific operation: listing the taxonomic values the site uses to browse recipes. It also names all eight taxonomies and ties itself to browse_recipes, so an agent can distinguish it from sibling tools like get_recipe or search_recipes.
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 explicitly directs when to call this tool: 'Call this before browse_recipes rather than spelling a value yourself.' This gives a clear use case and a reason to prefer it over hard-codng values, and the optional facet parameter behavior is fully explained.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scale_ingredientsRescale a list of ingredientsARead-onlyIdempotent
Rescale a list of Spanish ingredient lines, offline. Give either 'factor', or 'from_servings' and 'to_servings' together. Each line comes back with what was done to it: 'scaled' when the arithmetic landed exactly, 'rounded' when the value had to move to stay something a kitchen can measure out, and 'unscaled' when the line carries no quantity at all. Nothing is converted between unit systems, and an approximate measure such as a pizca keeps its own size. A line naming a tool rather than an ingredient is marked 'is_equipment' and left as it was given.
| Name | Required | Description | Default |
|---|---|---|---|
| factor | No | What to multiply the quantities by. Give this, or the two servings counts. | |
| ingredients | Yes | The lines to rescale, as the recipe wrote them. | |
| to_servings | No | How many it should serve. | |
| from_servings | No | How many the list was written for. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| factor | Yes | What the quantities were multiplied by. |
| ingredients | Yes | |
| scaled_count | Yes | Lines whose arithmetic landed exactly. |
| rounded_count | Yes | Lines whose value had to move. |
| unscaled_count | Yes | Lines carrying no quantity. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnly, openWorld, idempotent, and non-destructive behavior. The description adds rich behavioral detail beyond that: it explains the three possible per-line outcomes ('scaled', 'rounded', 'unscaled'), states that no unit conversion occurs, preserves approximate measures like 'pizca', and marks equipment lines as 'is_equipment'. This gives the agent a clear mental model of what the tool actually does at the line level.
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 compact and information-dense. The first sentence states the core action and scope, the second explains the parameter grouping, and subsequent sentences explain output behavior and edge cases. Every sentence earns its place with no repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, the presence of a complete input schema, rich annotations, and an output schema (per context signals), the description covers all essential non-schema semantics: parameter combos, per-line statuses, equipment handling, unit behavior, and offline execution. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents each parameter with a description, so baseline is 3. The description adds a critical constraint not fully explicit in the schema: the mutual exclusivity/grouping of 'factor' versus 'from_servings' and 'to_servings' together. This is exactly the kind of semantic that helps an agent build a valid request.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies a specific operation: 'Rescale a list of Spanish ingredient lines, offline.' It names the resource (ingredient lines) and the verb (rescale), and the sibling tools are all about retrieving or browsing recipes, so there is no ambiguity about which tool to pick.
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 gives direct usage instructions: 'Give either factor, or from_servings and to_servings together.' This tells the agent how to invoke the tool correctly. It doesn't explicitly say when not to use it versus siblings, but sibling names make it obvious that this is the only rescaling option, so the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_recipesSearch the recipesARead-onlyIdempotent
Search Pequerecetas for a dish or an ingredient, in Spanish. The site serves its search on one page and offers no second page, so 'result_count' counts the rows served and 'total_available' is null: the site publishes no count of what a search matched. The rows come in the site's own order, which is not by how well they match, so a dish named in the query can sit well down the page and 'limit' cuts in that order. A row carries the slug that get_recipe takes. Some rows are articles gathering recipes rather than recipes, which get_recipe reports as a 'collection'. To narrow by diet, ingredient, technique or the age of the eater, use list_facets and browse_recipes instead: this site's search takes no filters.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Rows to return, at most 60. Left out, every row served comes back. | |
| query | Yes | What to search for, in Spanish: a dish, an ingredient, a technique. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| query | Yes | |
| cached | Yes | |
| results | Yes | |
| result_count | Yes | Rows returned. |
| total_available | Yes | Always null: the site publishes no count of what a search matched. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, idempotent, and non-destructive hints. The description adds valuable behavioral context beyond annotations: the one-page limit, the null total_available, the ordering not being relevance-based, and the possibility of collection rows. However, it does not fully elaborate on the output schema, but the output schema exists, reducing the burden.
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 dense but well-organized: it front-loads the core search behavior, then explains edge cases (ordering, collections) and alternatives. Every sentence adds information, though a few could be tighter. The length is justified by the complexity of the site's behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the site's unusual behavior (no pagination, null total, non-relevance ordering, collection items), the description covers these critical quirks thoroughly. It also redirects to sibling tools for filtering. The output schema exists, so return value details are covered elsewhere. Minor gap: no explicit mention of error cases, but overall complete for confident 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 coverage is 100%, so both parameters are already described in the schema. The description reinforces query semantics (Spanish, dish/ingredient/technique) and explains the effect of limit in the context of the site's ordering. This adds meaningful context beyond the schema fields, justifying a score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches Pequerecetas for a dish or ingredient in Spanish, and explicitly distinguishes it from sibling tools like get_recipe, list_facets, and browse_recipes. The verb 'search' plus the target resource and language specificity make the purpose 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 explicitly explains when to use this tool vs alternatives: it notes that search takes no filters and recommends list_facets and browse_recipes for narrowing by diet, ingredient, technique, or age. It also clarifies the lack of pagination and result counting, which guides proper invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a clearly distinct purpose: get_recipe retrieves by slug, search_recipes does full-text search, list_facets enumerates taxonomy values, browse_recipes navigates taxonomies, and scale_ingredients rescales ingredient lists. The descriptions eliminate any ambiguity, and even where search and browse both discover recipes, their use cases are well separated.
All tool names follow a consistent verb_noun pattern with lower_snake_case: get_recipe, search_recipes, list_facets, browse_recipes, scale_ingredients. The verbs are distinct and the nouns clearly indicate the object of action.
Five tools is well-scoped for a recipe site MCP. The set covers the core actions needed for recipe discovery and retrieval without redundant or unnecessary tools.
The tool surface covers the key workflows for a read-only recipe website: direct access by slug, searching, browsing by facets, and scaling ingredients. No obvious dead ends or missing core operations.
Maintenance
Related MCP Connectors
Spoonacular food API: recipes, nutrition, ingredients, meal plans. Free 150/day.
Search, save, organize, cook, and share recipes with any AI assistant.
Your personal recipe kitchen: save, fork, and cook recipes, build cookbooks, and shopping lists.
Recipes MCP — wraps TheMealDB API (free tier, no auth)
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables querying food nutritional information, discovering recipes by ingredients or diet type, getting ingredient substitutions, and receiving personalized food recommendations based on mood and season.
- AlicenseBqualityCmaintenanceEnables AI assistants to search for recipes, get nutritional information, find ingredients, and more through the Spoonacular Food API using natural language.6145ISC
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to search recipes, compose nutritionally balanced meals, optimize weekly meal plans based on macro targets for family members, and generate consolidated grocery lists from a personal recipe database.
- AlicenseAqualityDmaintenanceEnables AI assistants to search New York Times Cooking recipes, fetch full recipes with ingredients and steps without login, and browse personal saved recipe box with optional authentication.461MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/smeet666/mcp-pequerecetas'
If you have feedback or need assistance with the MCP directory API, please join our Discord server