Skip to main content
Glama
smeet666

mcp-recipes

mcp-recipes

npm CI license MCP Registry Glama M8ven Install in Cursor Install in VS Code

Recipes live on many sites, and each one writes them its own way: a French cooking site publishes in French, with its own measures and its own idea of what a serving is, and a wiki cookbook in English, with equipment lists and prose the first has no field for. Asking a question of one of them answers about one of them.

This server reads five, three in French: Marmiton, Ptitchef and Supertoinette, and two in English: the Wikibooks Cookbook and BBC Good Food. You can search them all with one question, read a recipe from any of them in one shape, put several versions of the same dish side by side, and rescale any ingredient list. It needs no API key and no account.

Version française


Install

One-click install

Install in Cursor Install in VS Code

Claude Code

claude mcp add recipes -- npx -y mcp-recipes

Claude Desktop, Cursor, and any client using the standard config format

{
  "mcpServers": {
    "recipes": {
      "command": "npx",
      "args": ["-y", "mcp-recipes"]
    }
  }
}

Node 24 or later is required, and no environment variable has to be set.

With Docker

{
  "mcpServers": {
    "recipes": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-recipes:3.0.1"]
    }
  }
}

-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.marmiton.org, api.wikimedia.org, www.ptitchef.com, www.bbcgoodfood.com and www.supertoinette.com, and nothing else: no volume, no port, no credential.

Bundle, without npm

Download mcp-recipes-3.0.1.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: mealplan-mcp

What you can ask

  • "Find me carbonara recipes, from wherever you can."

  • "Compare the French and English versions of that dish."

  • "Read the second one for eight people."

  • "Which of them uses cream?"

  • "Scale this list from my notebook by 1.5."

The ordinary path runs from a search to a reading: a row carries an id naming its source, and get_recipe takes it.

The sources

Source

Site

Language

marmiton

www.marmiton.org

French

cookbook

Wikibooks Cookbook

English

ptitchef

www.ptitchef.com

French

goodfood

www.bbcgoodfood.com

English

supertoinette

www.supertoinette.com

French

A row's id names its source, so an identifier read from one answer goes back to the right site. Counts are never added across sources, and a source that failed is reported as having failed rather than as having found nothing.

Tools

Tool

What it does

search_recipes

Searches every source with one question.

get_recipe

Reads one recipe from any source, in one shape.

compare_recipes

Puts several versions of the same dish side by side.

scale_ingredients

Rescales any ingredient list, with no request to any site.

search_recipes

Searches every source with one question.

Argument

Type

Required

What it does

query

string, 1 to 200 characters

yes

The dish or the ingredient to look for.

limit_per_source

integer, 1 to 25, default 5

no

Rows to keep from each source.

sources

array of source ids

no

Ask these sources alone.

fan_out

boolean, default true

no

Ask every source rather than stopping at the first that answers.

In return: results, rows carrying id, which get_recipe takes; source and source_name saying which site published the row; title; url; image_url; and an excerpt where the source offers one. per_source gives one report per site with its status, reading answered or failed, the count it contributed, and its reported_total alongside reported_total_means, which says what that number counts on that site. order says in words how the list was built.

get_recipe

Reads one recipe from any source, in one shape.

Argument

Type

Required

What it does

id

string, 1 to 500 characters

yes

The identifier a row carries, such as marmiton:44078. Two sources address a recipe by a bare number, so spell an id with its source.

servings

integer, 1 to 500

no

Rescale the ingredients to this many servings.

sections

array of ingredients, steps, times, nutrition, tips, equipment, default ["ingredients", "steps"]

no

Which parts to return.

max_steps

integer, 1 to 100, default 20

no

Steps to serve.

max_step_chars

integer, 80 to 4000, default 600

no

Characters kept per step.

In return: the recipe in the shape every source is rendered into, whichever published it: its title, its address, its ingredients with each line's scaling, its steps, and the sections asked for. A field one source publishes and another has no notion of comes back absent rather than invented. rest_minutes carries a resting time from a source that prints one apart, and is in no other time here. steps_as_one_block says when a source published its method as one block of prose rather than as steps. withheld names a part a source keeps for its subscribers, which is a part the page has rather than a part that could not be read. Raise max_step_chars when a step was cut mid-sentence.

compare_recipes

Puts several versions of the same dish side by side.

Argument

Type

Required

What it does

dish

string, 1 to 200 characters

yes

The dish to compare.

servings

integer, 1 to 500

no

Rescale every version to this many servings.

sections

array of ingredients, steps, times, nutrition, tips, equipment, default ["ingredients"]

no

Which parts to return per version.

max_steps

integer, 1 to 100, default 10

no

Steps to serve per version.

max_step_chars

integer, 80 to 4000, default 600

no

Characters kept per step.

sources

array of source ids

no

Compare these sources alone.

In return: versions, one recipe per source that answered, all rescaled to the same number of servings so their quantities can be read against each other, and differences, what separates them. per_source reports each site as a search does.

scale_ingredients

Rescales any ingredient list, with no request to either site.

Argument

Type

Required

What it does

ingredients

array of 1 to 200 lines

yes

The lines to rescale.

factor

number, up to 1000

one of two

The multiplier to apply.

from_servings

integer, 1 to 500

one of two

How many servings the list is written for.

to_servings

integer, 1 to 500

one of two

How many servings are wanted.

language

auto, fr or en, default auto

no

How each line is read.

Pass factor, or the from_servings and to_servings pair. auto reads each line on its own, which is what a list holding both languages needs; naming a language reads every line that way.

In return: the rescaled lines in the shape get_recipe returns, each with its scaling.

Rescaling the quantities

A quantity is stated in the unit that suits it, so a line can come back in a different unit from the one the recipe used: 200 g multiplied by twenty reads 4 kg.

How finely an ingredient can be divided depends on what it is. A baguette can be cut in two, in three or in four; an egg cannot be shared out. A quantity landing between the two is rounded, and the rescaled recipe then departs a little from the proportions of the original. The line carries rounded, and its note says what was done.

The sources write their quantities in their own languages, and a line is read in the language it was written in. The figures are this server's arithmetic, so say they were recomputed when you show them.

What an answer states about the sources

Every answer accounts for each source separately. A site that failed, one nobody asked, and one that answered with nothing are three different things, and they are reported as three. A total stays beside the source that published it, with what that source counts when it says it: one site counts a whole category and the other counts the rows it served.

Configuration

Every variable is optional. Set them in the env block of your client config.

Variable

Default

What it does

RECIPES_USER_AGENT

the project identity

Names your application to both sites, with an address where a person can be reached.

RECIPES_MIN_INTERVAL_MS

1000

Gap between two requests to one site, from 500 to 60000.

RECIPES_TIMEOUT_MS

20000

Deadline for one request, from 1000 to 120000.

RECIPES_MAX_RETRIES

3

Attempts after a transient failure, from 0 to 8.

RECIPES_CACHE_TTL_MS

900000

How long an answer stays in memory, from 0 to 86400000.

RECIPES_CACHE_MAX_ENTRIES

200

Answers held in memory at once, from 1 to 5000.

RECIPES_LOG_LEVEL

error

silent, error, info or debug, written to stderr.

A value outside its range falls back to the default, and the reason is written to stderr.

Errors

Every failure carries one of six codes, a message, and where it helps a hint naming the next move.

Code

What happened

What to do

not_found

A source answered, and holds no such recipe.

Check the identifier with search_recipes.

invalid_input

The arguments were refused before any request went out.

Read the message, which names the argument.

rate_limited

A source asked this client to slow down.

Wait, then call again with the same arguments. The recipe is still there.

parse_failure

A page loaded and the expected content was absent.

Report it at the issue tracker.

network_error

The request did not complete.

Try again shortly.

timeout

The request passed its deadline.

Raise RECIPES_TIMEOUT_MS, or ask for fewer rows.

A source that failed is reported per source rather than failing the whole answer, so one silent site never hides the other.

As a library

The layer reading the two sites is published on its own, with its pacing, its cache and its errors, and with no protocol attached.

import { RecipesClient } from "mcp-recipes/client";

const client = new RecipesClient();
const read = await client.search({ query: "carbonara", limitPerSource: 3 });
console.log(read.data.results.length);

Each read answers { data, cached }, and throws an error carrying one of the six codes. Each site keeps its own pace, and the floor holds here as well.

Pacing and attribution

Each site is paced on its own, one request at a time with at least a second between two, and the floor of half a second holds however the server is configured. Asking every site at once therefore costs each of them one request, never two. The User-Agent always ends with the project identity and an address where a person can be reached.

Every row carries the address of the recipe's own page and the name of the site that published it. The Cookbook pages are published under CC BY-SA 4.0, which asks that what is built on them be shared under the same licence. Marmiton, Ptitchef, BBC Good Food and Supertoinette state no terms on a recipe page, and their recipes belong to those sites and to the cooks who wrote them. Silence is not a grant, so credit the site and link the page you took a recipe from.

A recipe BBC Good Food keeps for its subscribers comes back without its ingredients and its method, named as a recipe held back, with the address of its page. This server does not reconstruct what that site chose to sell.

Two figures the sites publish are not repeated here. A difficulty is a word each site writes its own way, on no scale any of them publishes, so it sits on no axis along which two versions could be put. A cost is a price in euros on one site and a rank inside its own list on another, and one field holding both would invite them to be compared.

This MCP server is an unofficial project, with no affiliation to any of the sites it reads.

Privacy

This server collects nothing about you and sends nothing to its author. It runs on your machine, contacts www.marmiton.org, api.wikimedia.org, www.ptitchef.com, www.bbcgoodfood.com and www.supertoinette.com and nothing else, holds its answers in memory while it runs, and writes nothing to disk. PRIVACY.md states what a request carries and which settings change any of it.

Development

npm install
npm run build:fixtures
npm test
npm run check

Tests run against generated fixtures and make no network request. The live suite, npm run test:live, makes one request per route and runs nightly against the sites themselves.

Contributing

Bugs, questions and ideas belong in the issue tracker. Pull requests are welcome; opening an issue first helps agree on the shape of the change. See CONTRIBUTING.md.

License

MIT, see LICENSE. The recipes belong to the sites that published them and to their authors.


mcp-recipes (français)

English version

Les recettes vivent sur beaucoup de sites, et chacun les écrit à sa façon : un site de cuisine français publie en français, avec ses mesures et son idée de ce qu'est une part, et un wiki de cuisine en anglais, avec des listes de matériel et une prose pour lesquelles le premier n'a aucun champ. Poser une question à l'un d'eux répond au sujet de l'un d'eux.

Ce serveur en lit cinq, trois en français : Marmiton, Ptitchef et Supertoinette, et deux en anglais : le Cookbook des Wikibooks et BBC Good Food. On peut chercher dans les cinq avec une seule question, lire une recette de n'importe lequel sous une seule forme, mettre plusieurs versions d'un même plat côte à côte, et adapter n'importe quelle liste d'ingrédients. Aucune clé d'API, aucun compte.

Installation

Installation en un clic

Install in Cursor Install in VS Code

Claude Code

claude mcp add recipes -- npx -y mcp-recipes

Claude Desktop, Cursor, et tout client au format de configuration standard

{
  "mcpServers": {
    "recipes": {
      "command": "npx",
      "args": ["-y", "mcp-recipes"]
    }
  }
}

Node 24 ou plus récent est nécessaire, et aucune variable d'environnement n'est à renseigner.

Avec Docker

{
  "mcpServers": {
    "recipes": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-recipes:3.0.1"]
    }
  }
}

-i garde l'entrée standard ouverte, qui est le canal du protocole, et -t est omis parce qu'un TTY réécrit le flux. Le conteneur a besoin d'un accès HTTPS sortant vers www.marmiton.org, api.wikimedia.org, www.ptitchef.com, www.bbcgoodfood.com et www.supertoinette.com, et de rien d'autre : aucun volume, aucun port, aucun identifiant.

Bundle, sans npm

Téléchargez mcp-recipes-3.0.1.mcpb depuis la dernière publication et ouvrez-le. 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

  • « Trouve-moi des recettes de carbonara, d'où que tu puisses. »

  • « Compare les versions française et anglaise de ce plat. »

  • « Lis-moi la seconde pour huit personnes. »

  • « Laquelle utilise de la crème ? »

  • « Multiplie par 1,5 cette liste de mon carnet. »

Le chemin ordinaire va d'une recherche à une lecture : une ligne porte un id qui nomme sa source, et get_recipe le reprend.

Les sources

Source

Site

Langue

marmiton

www.marmiton.org

français

cookbook

Cookbook Wikibooks

anglais

ptitchef

www.ptitchef.com

français

goodfood

www.bbcgoodfood.com

anglais

supertoinette

www.supertoinette.com

français

L'id d'une ligne nomme sa source, donc un identifiant lu dans une réponse retourne vers le bon site. Les comptes ne sont jamais additionnés entre sources, et une source qui a échoué est rapportée comme ayant échoué plutôt que comme n'ayant rien trouvé.

Les outils

Outil

Ce qu'il fait

search_recipes

Cherche dans toutes les sources avec une seule question.

get_recipe

Lit une recette de l'une ou l'autre, sous une seule forme.

compare_recipes

Met plusieurs versions d'un même plat côte à côte.

scale_ingredients

Adapte n'importe quelle liste d'ingrédients, sans requête.

search_recipes

Cherche dans toutes les sources avec une seule question.

Argument

Type

Requis

Ce qu'il fait

query

chaîne, 1 à 200 caractères

oui

Le plat ou l'ingrédient cherché.

limit_per_source

entier, 1 à 25, défaut 5

non

Lignes à garder de chaque source.

sources

tableau d'identifiants de source

non

N'interroger que ces sources.

fan_out

booléen, défaut true

non

Interroger chaque source plutôt que s'arrêter à la première qui répond.

En retour : results, des lignes portant id, que get_recipe reprend ; source et source_name qui disent quel site a publié la ligne ; title ; url ; image_url ; et un excerpt là où la source en propose un. per_source donne un rapport par site avec son status, valant answered ou failed, le count qu'il a fourni, et son reported_total accompagné de reported_total_means, qui dit ce que ce nombre compte sur ce site. order dit en mots comment la liste a été bâtie.

get_recipe

Lit une recette de n'importe quelle source, sous une seule forme.

Argument

Type

Requis

Ce qu'il fait

id

chaîne, 1 à 500 caractères

oui

L'identifiant d'une ligne, tel que marmiton:44078. Deux sources adressent une recette par un nombre nu : écrivez l'id avec sa source.

servings

entier, 1 à 500

non

Adapte les ingrédients à ce nombre de parts.

sections

tableau de ingredients, steps, times, nutrition, tips, equipment, défaut ["ingredients", "steps"]

non

Les parties à rendre.

max_steps

entier, 1 à 100, défaut 20

non

Étapes à servir.

max_step_chars

entier, 80 à 4000, défaut 600

non

Caractères gardés par étape.

En retour : la recette dans la forme où toutes les sources sont rendues, quelle que soit celle qui l'a publiée : son titre, son adresse, ses ingrédients avec le scaling de chaque ligne, ses étapes, et les parties demandées. Un champ qu'une source publie et dont une autre n'a pas la notion revient absent plutôt qu'inventé. rest_minutes porte le temps de repos d'une source qui l'imprime à part, et il n'entre dans aucun autre temps rendu ici. steps_as_one_block dit quand une source a publié sa méthode d'un seul bloc de prose plutôt qu'en étapes. withheld nomme la partie qu'une source réserve à ses abonnés, qui est une partie que la page porte et non une partie illisible. Augmentez max_step_chars quand une étape a été coupée au milieu d'une phrase.

compare_recipes

Met plusieurs versions d'un même plat côte à côte.

Argument

Type

Requis

Ce qu'il fait

dish

chaîne, 1 à 200 caractères

oui

Le plat à comparer.

servings

entier, 1 à 500

non

Adapte chaque version à ce nombre de parts.

sections

tableau de ingredients, steps, times, nutrition, tips, equipment, défaut ["ingredients"]

non

Les parties à rendre par version.

max_steps

entier, 1 à 100, défaut 10

non

Étapes à servir par version.

max_step_chars

entier, 80 à 4000, défaut 600

non

Caractères gardés par étape.

sources

tableau d'ids de source

non

Ne compare que ces sources.

En retour : versions, une recette par source ayant répondu, toutes adaptées au même nombre de parts pour que leurs quantités se lisent l'une contre l'autre, et differences, ce qui les sépare. per_source rapporte chaque site comme le fait une recherche.

scale_ingredients

Adapte n'importe quelle liste d'ingrédients, sans requête à l'un ou l'autre site.

Argument

Type

Requis

Ce qu'il fait

ingredients

tableau de 1 à 200 lignes

oui

Les lignes à adapter.

factor

nombre, jusqu'à 1000

l'un des deux

Le multiplicateur à appliquer.

from_servings

entier, 1 à 500

l'un des deux

Le nombre de parts de la liste d'origine.

to_servings

entier, 1 à 500

l'un des deux

Le nombre de parts voulu.

language

auto, fr ou en, défaut auto

non

Comment chaque ligne est lue.

Passez factor, ou le couple from_servings et to_servings. auto lit chaque ligne pour elle-même, ce dont a besoin une liste portant les deux langues ; nommer une langue lit toutes les lignes ainsi.

En retour : les lignes adaptées dans la forme que rend get_recipe, chacune avec son scaling.

L'adaptation des quantités

Une quantité est exprimée dans l'unité qui lui convient. Après adaptation, une ligne peut donc apparaître dans une autre unité que celle de la recette : 200 g multipliés par vingt donnent 4 kg.

La finesse à laquelle un ingrédient se coupe dépend de sa nature. Une baguette se coupe en deux, en trois ou en quatre ; un oeuf ne se partage pas. Une quantité qui tombe entre les deux est donc arrondie, et la recette adaptée s'écarte alors un peu des proportions de l'originale. La ligne porte rounded, et sa note dit ce qui a été fait.

Les sources écrivent leurs quantités dans leur propre langue, et une ligne est lue dans la langue où elle a été écrite. Les chiffres sont l'arithmétique de ce serveur, donc dites qu'ils ont été recalculés quand vous les montrez.

Ce qu'une réponse dit des sources

Chaque réponse rend compte de chaque source séparément. Un site qui a échoué, un que personne n'a interrogé et un qui a répondu vide sont trois choses différentes, et elles sont rapportées comme trois. Un total reste à côté de la source qui l'a publié, avec ce que cette source compte en le disant : l'un compte une catégorie entière et l'autre compte les lignes qu'il a servies.

Configuration

Chaque variable est facultative. Elles se posent dans le bloc env de la configuration du client.

Variable

Défaut

Ce qu'elle fait

RECIPES_USER_AGENT

l'identité du projet

Nomme votre application auprès des deux sites, avec une adresse où joindre une personne.

RECIPES_MIN_INTERVAL_MS

1000

Écart entre deux requêtes vers un même site, de 500 à 60000.

RECIPES_TIMEOUT_MS

20000

Délai d'une requête, de 1000 à 120000.

RECIPES_MAX_RETRIES

3

Tentatives après un échec passager, de 0 à 8.

RECIPES_CACHE_TTL_MS

900000

Durée pendant laquelle une réponse reste en mémoire, de 0 à 86400000.

RECIPES_CACHE_MAX_ENTRIES

200

Réponses gardées en mémoire à la fois, de 1 à 5000.

RECIPES_LOG_LEVEL

error

silent, error, info ou debug, écrit sur la sortie d'erreur.

Une valeur hors de sa plage retombe sur le défaut, et la raison est écrite sur la sortie d'erreur.

Erreurs

Chaque échec porte un des six codes, un message, et quand cela aide une indication du geste suivant.

Code

Ce qui s'est passé

Que faire

not_found

Une source a répondu, et n'a pas cette recette.

Vérifiez l'identifiant avec search_recipes.

invalid_input

Les arguments ont été refusés avant toute requête.

Lisez le message, qui nomme l'argument.

rate_limited

Une source demande à ce client de ralentir.

Attendez, puis rappelez avec les mêmes arguments. La recette est toujours là.

parse_failure

Une page a chargé et le contenu attendu est absent.

Signalez-le sur le suivi d'incidents.

network_error

La requête n'a pas abouti.

Réessayez sous peu.

timeout

La requête a dépassé son délai.

Augmentez RECIPES_TIMEOUT_MS, ou demandez moins de lignes.

Une source qui échoue est rapportée source par source plutôt que de faire échouer toute la réponse, donc un site silencieux n'en cache jamais un autre.

Comme bibliothèque

La couche qui lit les deux sites est publiée seule, avec son rythme, son cache et ses erreurs, sans protocole attaché.

import { RecipesClient } from "mcp-recipes/client";

const client = new RecipesClient();
const read = await client.search({ query: "carbonara", limitPerSource: 3 });
console.log(read.data.results.length);

Chaque lecture répond { data, cached }, et lève une erreur portant un des six codes. Chaque site garde son propre rythme, et le plancher tient également ici.

Rythme et attribution

Chaque site est cadencé pour lui-même, une requête à la fois avec au moins une seconde entre deux, et le plancher d'une demi-seconde tient quelle que soit la configuration. Les interroger toutes à la fois coûte donc à chacune une requête, jamais deux. Le User-Agent se termine toujours par l'identité du projet et une adresse où joindre une personne.

Chaque ligne porte l'adresse de la page de la recette et le nom du site qui l'a publiée. Les pages du Cookbook sont publiées sous CC BY-SA 4.0, qui demande que ce qu'on bâtit dessus soit partagé sous la même licence. Marmiton, Ptitchef, BBC Good Food et Supertoinette n'énoncent aucune condition sur une page de recette, et leurs recettes appartiennent à ces sites et aux cuisiniers qui les ont écrites. Le silence n'est pas une autorisation : créditez le site et liez la page d'où vient la recette.

Une recette que BBC Good Food réserve à ses abonnés revient sans ses ingrédients ni sa méthode, nommée comme une recette retenue, avec l'adresse de sa page. Ce serveur ne reconstitue pas ce que ce site a choisi de vendre.

Deux chiffres que les sites publient ne sont pas repris ici. Une difficulté est un mot que chaque site écrit à sa façon, sur aucune échelle publiée : elle ne siège sur aucun axe le long duquel deux versions se compareraient. Un coût est un prix en euros sur un site et un rang dans sa propre liste sur un autre, et un seul champ portant les deux inviterait à les comparer.

Ce MCP est un projet non officiel, sans affiliation à aucun des sites qu'il lit.

Confidentialité

Ce serveur ne collecte rien sur vous et n'envoie rien à son auteur. Il tourne sur votre machine, ne joint que www.marmiton.org, api.wikimedia.org, www.ptitchef.com, www.bbcgoodfood.com et www.supertoinette.com, garde ses réponses en mémoire le temps qu'il tourne, et n'écrit rien sur le disque. PRIVACY.md dit ce qu'une requête emporte et quels réglages changent cela.

Développement

npm install
npm run build:fixtures
npm test
npm run check

Les tests s'exécutent sur des fixtures engendrées et n'émettent aucune requête. La suite en direct, npm run test:live, émet une requête par route et tourne chaque nuit contre les sites eux-mêmes.

Contribuer

Les anomalies, les questions et les idées ont leur place dans le suivi d'incidents. Les propositions de modification sont bienvenues ; ouvrir un ticket d'abord aide à s'accorder sur la forme du changement. Voir CONTRIBUTING.md.

Licence

MIT, voir LICENSE. Les recettes appartiennent aux sites qui les ont publiées et à leurs auteurs.

Available Tools

4 tools
compare_recipesOne dish, as each source writes itA
Read-onlyIdempotent

Take a dish and show how each source writes it, side by side. Each source's closest match is read in full, and all of them can be rescaled to the same number of servings so the ingredient lists stand comparison. The answer states what differs and leaves it there: the quantities each asks for, what each measures in, what each yields, and which fields each source publishes at all. No version is ranked above another. Some sources carry reader ratings and some have no author and no rating by nature, so there is no score they share. When only one source answers, the answer says so and shows that one rather than presenting part of a comparison as the whole of it.

ParametersJSON Schema
NameRequiredDescriptionDefault
dishYesThe dish to compare, in any of the languages the sources publish in.
sourcesNoSources to compare, by id. Left out, every source is read, which is the point of this tool. Name two or three to put particular traditions side by side. The ids are the ones 'per_source' reports.
sectionsNoWhich parts of each version to return. Several full recipes is a lot of text.
servingsNoRescale every version to this many, which is what makes the lists comparable.
max_stepsNoSteps to return per version.
max_step_charsNoCharacters kept per step. Raise it only if a step was cut mid-sentence.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dishYes
notesYes
versionsYes
per_sourceYes
differencesYesWhat differs between the versions, stated as fact. No version is ranked.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly, idempotent, and openWorld annotations, the description discloses meaningful behavioral traits: no ranking among versions, no shared score because some sources lack ratings, rescaled servings for comparability, and an explicit policy that a single matching source is shown rather than presenting a partial comparison. These details are not visible in the schema and materially shape output expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and each subsequent sentence earns its place by explaining comparison behavior, non-ranking, rating limitations, and single-source fallback. It is prose-style but compact and free of pointless decoration; every sentence contributes to correct invocation and interpretation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and a full input schema, the description covers the essential behavioral context: what comparison means, how rescaling works, what is reported, what is not compared, and how edge cases are handled. An agent has enough information to select this tool and set expectations for the response without guessing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description reinforces the purpose of servings rescaling and the idea of matching sources, but it does not add significant parameter-level meaning beyond what the schema already documents. It earns the baseline without exceeding it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Take a dish and show how each source writes it, side by side.' This unambiguously identifies the tool as a multi-source comparissor and distinguishes it from sibling tools like get_recipe or scale_ingredients by emphasizing side-by-side comparison and differing source treatments.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when this tool is appropriate: when an agent wants to see how different sources treat the same dish. It also explains the all-sources-by-default behavior and the single-source fallback. It does not explicitly name sibling alternatives or say 'use get_recipe instead for a single recipe,' but the comparative purpose is clear enough to infer the boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recipeRead one recipe, optionally rescaledA
Read-onlyIdempotent

Read one recipe in full: its ingredients, its steps, what it yields, and whatever times, rating and nutrition its source publishes. 'id' must come from search_recipes. It names the source, so this reads the right one without guessing; an identifier no source would have minted is refused, because sending it anywhere would answer about the wrong dish. Pass 'servings' to rescale. Quantities land where a kitchen can follow them: an egg stays whole, anything that pours or cuts can halve, a small measurement moves to a smaller unit before it is rounded, and anything unmultipliable is flagged rather than scaled. A page that states no number of servings comes back as published and says so, because dividing by a yield nobody wrote would answer for a number of people the page never claimed. A part this answer holds nothing for says which of two things happened: the page showed no sign of it, or this server failed to read what the page carries. An empty ingredient list is never evidence that an ingredient is absent from the dish. 'sections' decides what comes back, and 'sections_omitted' names what was left out: a field belonging to an omitted section is empty because nobody asked for it, never because the page states nothing. A field a source does not publish is null, never zero. Credit the source and link the url when you repeat any of it.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesFrom search_recipes, such as 'marmiton:44078', 'goodfood:recipes/carbonara' or 'cookbook:Cookbook:Carbonara'. Two sources address a recipe by a bare number, so spell an id with its source.
sectionsNoWhich parts to return. A full recipe is a lot of text, so this defaults to two.
servingsNoRescale to this many. Left out, the quantities come back as published.
max_stepsNoSteps to return. The answer says how many more there are.
max_step_charsNoCharacters kept per step. Raise it only if a step was cut mid-sentence.

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
recipeYes
id_read_asYesHow a raw identifier was routed, when it was not spelled with its source.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes far beyond the annotations by disclosing detailed behavioral edge cases: rescaling rules (eggs stay whole, pours/cuts may halve, unmultipliable fields are flagged), behavior when no serving count is published, how absent sections are reported, the meaning of empty ingredient lists, and the null-versus-zero convention. These are exactly the caveats an agent needs to interpret results correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured: the core purpose is front-loaded, followed by id provenance, rescaling behavior, and result interpretation rules. Each sentence contributes a distinct behavioral or usage nuance. A few sentences could be tightened, but for a tool with this many edge cases the length is justified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich output schema and annotations covering read-only, idempotent, and non-destructive behavior, the description covers everything an agent needs to call the tool correctly and interpret its results: identity constraints, rescaling semantics, section omission behavior, null-versus-zero conventions, and the significance of empty ingredient lists. No critical information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter already has a detailed description with defaults and constraints. The tool description adds minimal parameter-level meaning beyond the schema, mostly restating that servings triggers rescaling and sections selects output. This matches the baseline of 3 for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Read one recipe in full') and enumerates what is returned: ingredients, steps, yield, times, rating, nutrition. It also differentiates from the sibling search_recipes by requiring that 'id' come from it, so there is no ambiguity about which tool does what.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear operational guidance: the id must originate from search_recipes, servings can be passed to rescale, and sections controls what is returned. It also explains why unknown ids are refused. It does not explicitly name when to prefer a sibling such as scale_ingredients or compare_recipes, but the context is strong enough that an agent will know when 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.

scale_ingredientsScale an ingredient list, in either languageA
Read-onlyIdempotent

Multiply a list of ingredient lines, in French, in English, or in a list holding both. Give either 'factor', or 'from_servings' and 'to_servings' and the factor is worked out from them. Quantities land where a kitchen can follow them: an egg stays whole because half of one is not something a cook takes out of the shell, while anything that pours, weighs or cuts can halve, a spoonful shrinks into the smaller spoon before it is rounded, and a pinch keeps whatever size a hand gives it while its count is multiplied. Every line comes back with 'scaling': 'scaled' when the arithmetic landed on the exact product, 'rounded' when something had to move for the line to stay usable, 'unscaled' when the line carries nothing to multiply. A rounded line says what it was rounded from and in which direction. No quantity is converted between measuring systems: grams stay grams and cups stay cups, because a conversion changes what the recipe said.

ParametersJSON Schema
NameRequiredDescriptionDefault
factorNoWhat to multiply by. Give exactly one of: 'factor', or both 'from_servings' and 'to_servings'.
languageNo'auto' reads each line on its own, which is what a list holding both languages needs. Name a language to read every line that way.auto
ingredientsYesThe lines as written, one ingredient each, such as '200 g de farine' or '3 eggs'. One line, not a whole recipe.
to_servingsNoWhat it should serve. Give it with 'from_servings', and without 'factor'.
from_servingsNoWhat the list serves now. Give it with 'to_servings', and without 'factor'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
factorYesWhat every quantity was multiplied by.
languageYesHow the lines were read.
ingredientsYes
scaled_countYesLines whose arithmetic came out exact.
rounded_countYesLines whose value moved to stay usable.
unscaled_countYesLines carrying nothing that can be multiplied.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint and idempotentHint annotations, the description discloses rich behavioral traits: rounding rules ('an egg stays whole', 'a spoonful shrinks into the smaller spoon'), the exact 'scaling' status values ('scaled', 'rounded', 'unscaled'), and the constraint that no quantity is converted between measuring systems. This provides significant added value for predicting tool behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured with a clear opening statement of function, followed by input guidance, then detailed behavioral rules. Every sentence contributes unique information—from language support to output scaling categories to the no-conversion constraint—without unnecessary repetition. It is detailed yet efficiently organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 essential aspects: language handling, parameter alternatives, rounding behavior, scaling statuses, and conversion constraints. The agent has enough information to select and invoke the tool correctly, and with the output schema available, return values do not need to be re-explained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes all parameters with 100% coverage, including the factor/servings exclusivity. The description reinforces this relationship and adds context about output rounding, but it does not add substantial new meaning to individual parameters beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Multiply a list of ingredient lines' in multiple language contexts. This specific verb-resource pairing distinguishes it from sibling tools like get_recipe, search_recipes, and compare_recipes, which focus on retrieval and comparison rather than scaling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains the two input modes: give either 'factor', or 'from_servings' and 'to_servings', and clarifies that the factor is worked out from servings. It does not mention alternative tools or exclusions, but the context for using this scaling tool is clear and directly actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_recipesSearch every recipe source at onceA
Read-onlyIdempotent

Search every recipe source this server reads, at the same time, for a dish or an ingredient, and get one merged list. Each row carries the id get_recipe takes, and that id names the source it came from, so nothing has to be guessed afterwards. The sources are written in different languages and count their own results differently, so 'per_source' says what each one answered, what its own number means, and names any that failed. A short list is never evidence of what exists. Some sources keep recipes and reference pages together, so a row can be a page about an ingredient rather than a recipe using it. Only get_recipe can tell them apart, and it says what it read off the page. The query goes to each source's own search as free text. There is no filtering: a word naming a diet, a time or a calorie count matches only where that source's index happens to carry it. Ask in a whole sentence if that is the question. These indexes answer the words they are handed, so a sentence is also sent as the words naming the dish and as the dish word alone, and the rows are the union; 'per_source' lists every wording and what it returned. What the question says the recipe must not hold is set aside from those shorter wordings rather than searched for, and named back in the notes: a negation, an allergy stated as one, a diet named in one word, and the number of people at the table. No source filters on any of it, so open a row with get_recipe and read the ingredient list before calling it suitable. A condition is read with the food on whichever side of it the sentence put one, so 'allergique aux noix' and 'peanut allergy' both name the nut. Where a sentence puts a food on neither side, the notes say a condition was stated and that its food was not read, because naming the wrong word would hide a dish and search for the food being avoided at once. Rows are interleaved one source at a time rather than ranked, because the sources share no score that could order them against each other.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesA dish or an ingredient, in any of the languages the sources publish in.
fan_outNoWhether a question may also be sent in shorter wordings derived from it. On, because these indexes answer the words they are handed: a question written as a sentence comes back empty from a corpus holding several of the dish. Turn it off to send exactly the words typed; 'per_source' then names the wordings that were withheld.
sourcesNoSources to ask, by id. Left out, they are all asked, which is the point of this tool. The ids are the ones 'per_source' reports.
limit_per_sourceNoRows to take from each source, so one source cannot fill the whole list.

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
orderYesHow the list was built, in words.
queryYes
resultsYes
per_sourceYes
result_countYesRows in this answer, across every source.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnly, openWorld, idempotent), it reveals per-source language/count differences, the meaning of 'per_source', the possibility of reference pages, the fan_out union behavior, negation/allergy handling, and interleaved ordering. This is extensive behavioral disclosure that goes far beyond the structured metadata.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose and every sentence adds value, but it is a single dense paragraph that could benefit from logical section breaks (e.g., fan_out, per_source, limitations). Given the tool's complexity, the verbosity is justified, but structure could be improved.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers language differences, per_source failure reporting, false-negative warnings, page-type ambiguity, fan_out mechanics, negation handling, and ranking behavior. With an output schema present and annotations covering safety, it is remarkably complete for a complex search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers all parameters with descriptions (100% coverage), so the baseline is 3. The description adds meaningful extra context for query (sent as free text with no filtering), fan_out (additional wordings and union results), and sources (ids from per_source). It does not add much for limit_per_source, but the schema already explains it adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Search every recipe source this server reads, at the same time, for a dish or an ingredient, and get one merged list.' This clearly states the tool's function and differentiates it from the sibling get_recipe by noting that each row carries the id get_recipe takes, implying search is the discovery step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs when to use get_recipe instead: 'open a row with get_recipe and read the ingredient list before calling it suitable.' It also explains when to turn fan_out off, and warns that a short list is not evidence. These are clear, actionable usage guidelines.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4.7/5.0
Disambiguation5/5

Each tool targets a distinct operation: search_recipes returns merged result lists, get_recipe retrieves one full recipe, scale_ingredients transforms standalone ingredient lines, and compare_recipes produces a side-by-side source comparison. Overlap in searching and scaling is acknowledged but clearly scoped, so an agent should not confuse them.

Naming Consistency5/5

All four names follow a consistent verb_noun snake_case pattern: search, get, scale, and compare, each paired with a clear object. The only minor variation is get_recipe being singular, but that is semantically appropriate since it returns one recipe.

Tool Count5/5

Four tools is a well-scoped size for a read-only recipe aggregation server. Each tool earns its place by covering a distinct stage: discovery, retrieval, scaling, and comparison.

Completeness5/5

The surface covers the full read-oriented workflow: search across sources, retrieve full recipe details, rescale ingredients, and compare sources side by side. Since the underlying sources are external and read-only, create/update/delete operations are not expected, and source metadata is surfaced through per_source and id naming.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    MCP server for meal planning and grocery list generation, enabling recipe storage, meal plan creation, and automated grocery lists with ignored ingredients.
    8
    2
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    MCP server that provides cooking recipe lookup, classification, and weekly meal planning based on dietary restrictions and allergies.
    5
  • A
    license
    A
    quality
    B
    maintenance
    MCP server that searches French recipes from Marmiton, reads ingredients and steps, and rescales quantities to any number of servings without requiring an API key.
    6
    3
    614
    MIT

Latest Blog Posts

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-recipes'

If you have feedback or need assistance with the MCP directory API, please join our Discord server