Recipes
Busca en cinco sitios de recetas a la vez, en francés e inglés, y ajusta las cantidades. Sin clave de API.
Documentación
mcp-recipes
Las recetas viven en muchos sitios, y cada uno las escribe a su manera: un sitio de cocina francés publica en francés, con sus propias medidas y su propia idea de lo que es una ración, y un libro de cocina wiki en inglés, con listas de utensilios y prosa para la que el primero no tiene campo. Preguntar a uno de ellos responde sobre uno de ellos.
Este servidor lee seis. Tres publican en francés, Marmiton, Ptitchef y Supertoinette; dos en inglés, el Libro de cocina de Wikibooks y BBC Good Food; y uno en español, Pequerecetas. Puedes buscarlos todos con una pregunta, leer una receta de cualquiera de ellos en un mismo formato, poner varias versiones del mismo plato lado a lado, y reescalar cualquier lista de ingredientes. No necesita clave de API ni cuenta.
Instalación
Instalación en un clic
Claude Code
claude mcp add recipes -- npx -y mcp-recipes
Claude Desktop, Cursor, y cualquier cliente que use el formato de configuración estándar
{
"mcpServers": {
"recipes": {
"command": "npx",
"args": ["-y", "mcp-recipes"]
}
}
}
Se requiere Node 24 o posterior, y no hay que establecer ninguna variable de entorno.
Con Docker
{
"mcpServers": {
"recipes": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-recipes:4.0.0"]
}
}
}
-i mantiene stdin abierto, que es por donde viaja el protocolo, y -t se omite
porque una TTY reescribe el flujo. El contenedor necesita HTTPS saliente hacia
www.marmiton.org, api.wikimedia.org, www.ptitchef.com,
www.bbcgoodfood.com, www.supertoinette.com y www.pequerecetas.com, y
nada más: sin volumen, sin puerto, sin credencial.
Paquete, sin npm
Descarga mcp-recipes-4.0.0.mcpb desde
la última versión y
ábrelo. Un cliente que admita paquetes MCP lo instala por sí solo, sin npm
y sin archivo de configuración que editar. El paquete lleva sus dependencias,
así que no se descarga nada en el momento de la instalación.
Lo que puedes preguntar
- "Encuéntrame recetas de carbonara, de donde puedas."
- "Compara las versiones francesa e inglesa de ese plato."
- "Lee la segunda para ocho personas."
- "¿Cuál de ellas usa crema?"
- "Escala esta lista de mi cuaderno por 1.5."
El camino habitual va de una búsqueda a una lectura: una fila lleva un id que nombra
su fuente, y get_recipe lo toma.
Las fuentes
| Fuente | Sitio | Idioma |
|---|---|---|
marmiton | www.marmiton.org | Francés |
cookbook | Libro de cocina de Wikibooks | Inglés |
ptitchef | www.ptitchef.com | Francés |
goodfood | www.bbcgoodfood.com | Inglés |
supertoinette | www.supertoinette.com | Francés |
pequerecetas | www.pequerecetas.com | Español |
El id de una fila nombra su fuente, así que un identificador leído de una respuesta vuelve a
el sitio correcto. Los recuentos nunca se suman entre fuentes, y una fuente que
falló se informa como fallida en lugar de como si no hubiera encontrado nada.
Cada sitio se lee a su propio ritmo: dos de ellos piden tres segundos entre solicitudes, y una configuración publicada para todos ellos solo puede hacer que este servidor sea más paciente de lo que el más lento pide.
Dos de estos sitios archivan algo que no es una receta en la dirección donde vive una receta.
El Libro de cocina de Wikibooks mantiene páginas sobre un ingrediente junto a las recetas que lo usan, y Pequerecetas publica artículos que reúnen recetas. Una
búsqueda lo dice, y get_recipe dice lo que leyó de la página.
Herramientas
| Herramienta | Qué hace |
|---|---|
search_recipes | Busca en cada fuente con una pregunta. |
get_recipe | Lee una receta de cualquier fuente, en un mismo formato. |
compare_recipes | Pone varias versiones del mismo plato lado a lado. |
scale_ingredients | Reescala cualquier lista de ingredientes, sin solicitar nada a ningún sitio. |
search_recipes
Busca en cada fuente con una pregunta.
| Argumento | Tipo | Obligatorio | Qué hace |
|---|---|---|---|
query | cadena, de 1 a 200 caracteres | sí | El plato o el ingrediente que buscar. |
limit_per_source | entero, de 1 a 25, por defecto 5 | no | Filas que conservar de cada fuente. |
sources | matriz de identificadores de fuente | no | Preguntar solo a estas fuentes. |
fan_out | booleano, por defecto true | no | Preguntar a cada fuente en lugar de detenerse en la primera que responda. |
A cambio: results, filas que llevan id, que get_recipe toma;
source y source_name que dicen qué sitio publicó la fila; title; url;
image_url; y un excerpt donde la fuente ofrece uno. per_source da un
informe por sitio con su status, leyendo answered o failed, el count que
aportó, y su reported_total junto a reported_total_means, que
dice qué cuenta ese número en ese sitio. names_the_dish dice cuántas de las
filas de ese sitio llevan el plato en su título, de count: un índice de búsqueda responde
a las palabras que se le dan, así que un sitio puede ofrecer filas y ninguna ser el plato.
order dice en palabras cómo se construyó la lista.
get_recipe
Lee una receta de cualquier fuente, en un mismo formato.
| Argumento | Tipo | Obligatorio | Qué hace |
|---|---|---|---|
id | cadena, de 1 a 500 caracteres | sí | El identificador que lleva una fila, como marmiton:44078. Dos fuentes dirigen una receta por un número simple, así que escribe un id con su fuente. |
servings | entero, de 1 a 500 | no | Reescalar los ingredientes a este número de raciones. |
sections | matriz de ingredients, steps, times, nutrition, tips, equipment, por defecto ["ingredients", "steps"] | no | Qué partes devolver. |
max_steps | entero, de 1 a 100, por defecto 20 | no | Pasos que servir. |
max_gathered | entero, de 1 a 500, por defecto 30 | no | Recetas y encabezados que devolver de una dirección que reúne recetas. |
max_step_chars | entero, de 80 a 4000, por defecto 600 | no | Caracteres conservados por paso. |
A cambio: kind dice qué contenía la dirección. Una respuesta recipe lleva
recipe y no collection; una respuesta collection lleva collection y no
recipe, y es un artículo que reúne otras recetas, con el headings del que
está construido y el recipes al que apunta, cada uno legible con
get_recipe.
Una receta viene en el formato en el que se renderiza cada fuente, sea cual sea la que
la publicó: su título, su dirección, sus ingredientes con el scaling de cada línea
y is_equipment,
sus pasos, y las secciones solicitadas. Un campo que una fuente publica y otra
no tiene noción de él vuelve ausente en lugar de inventado. rest_minutes lleva un
tiempo de reposo de una fuente que lo imprime aparte, y no está en ningún otro tiempo aquí.
steps_as_one_block dice cuándo una fuente publicó su método como un bloque de
prosa en lugar de como pasos. withheld nombra una parte que una fuente guarda para sus
suscriptores, que es una parte que la página tiene en lugar de una parte que no se pudo
leer. scaling_summary cuenta las líneas de cuatro maneras, y las cuatro suman la
lista. Eleva max_step_chars cuando un paso se cortó a mitad de frase.
compare_recipes
Pone varias versiones del mismo plato lado a lado.
| Argumento | Tipo | Obligatorio | Qué hacer |
|---|---|---|---|
dish | cadena, de 1 a 200 caracteres | sí | El plato que comparar. |
servings | entero, de 1 a 500 | no | Reescalar cada versión a este número de raciones. |
sections | matriz de ingredients, steps, times, nutrition, tips, equipment, por defecto ["ingredients"] | no | Qué partes devolver por versión. |
max_steps | entero, de 1 a 100, por defecto 10 | no | Pasos que servir por versión. |
max_step_chars | entero, de 80 a 4000, por defecto 600 | no | Caracteres conservados por paso. |
sources | matriz de identificadores de fuente | no | Comparar solo estas fuentes. |
A cambio: versions, una receta por fuente que respondió, todas reescaladas a
el mismo número de raciones para que sus cantidades se puedan leer entre sí,
y differences, lo que las separa. per_source informa de cada sitio como una
búsqueda.
scale_ingredients
Reescala cualquier lista de ingredientes, sin solicitar nada a ningún sitio.
| Argumento | Tipo | Obligatorio | Qué hace |
|---|---|---|---|
ingredients | matriz de 1 a 200 líneas | sí | Las líneas a reescalar. |
factor | número, hasta 1000 | uno de dos | El multiplicador a aplicar. |
from_servings | entero, de 1 a 500 | uno de dos | Para cuántas raciones está escrita la lista. |
to_servings | entero, de 1 a 500 | uno de dos | Cuántas raciones se desean. |
language | auto, fr, en o es, por defecto auto | no | Cómo se lee cada línea. |
Pasa factor, o el par from_servings y to_servings. auto lee cada
línea por su cuenta, que es lo que necesita una lista con más de un idioma; nombrar un
idioma lee cada línea de esa manera.
A cambio: las líneas reescaladas en la forma que devuelve get_recipe, cada una con
su scaling.
Reescalado de las cantidades
Una cantidad se expresa en la unidad que le conviene, así que una línea puede volver en una
unidad distinta de la que usó la receta: 200 g multiplicados por veinte se leen
como 4 kg.
Lo finamente que puede dividirse un ingrediente depende de qué sea. Una baguette puede
cortarse en dos, en tres o en cuatro; un huevo no puede compartirse. Una cantidad que cae
entre ambos se redondea, y la receta reescalada se aparta entonces un poco de
las proporciones del original. La línea lleva rounded, y su nota dice
qué se hizo.
Las fuentes escriben sus cantidades en sus propios idiomas, y una línea se lee en el idioma en que fue escrita. Las cifras son aritmética de este servidor, así que di que fueron recalculadas cuando las muestres.
Qué dice una respuesta sobre las fuentes
Cada respuesta da cuenta de cada fuente por separado. Un sitio que falló, uno al que nadie preguntó y uno que respondió con nada son tres cosas distintas, y se informan como tres. Un total permanece junto a la fuente que lo publicó, con lo que esa fuente cuenta cuando lo dice: un sitio cuenta una categoría entera, otro cuenta las filas que sirvió, y un tercero no publica ningún total.
Configuración
Toda variable es opcional. Configúralas en el bloque env de la configuración de tu cliente.
| Variable | Por defecto | Qué hace |
|---|---|---|
RECIPES_USER_AGENT | la identidad del proyecto | Nombra tu aplicación ante los sitios, con una dirección donde se pueda contactar a una persona. |
RECIPES_MIN_INTERVAL_MS | 1000 | Intervalo entre dos solicitudes a un sitio, de 500 a 60000. |
RECIPES_TIMEOUT_MS | 20000 | Plazo para una solicitud, de 1000 a 120000. |
RECIPES_MAX_RETRIES | 3 | Intentos tras un fallo transitorio, de 0 a 8. |
RECIPES_CACHE_TTL_MS | 900000 | Cuánto tiempo permanece una respuesta en memoria, de 0 a 86400000. |
RECIPES_CACHE_MAX_ENTRIES | 200 | Respuestas retenidas en memoria a la vez, de 1 a 5000. |
RECIPES_LOG_LEVEL | error | silent, error, info o debug, escritos en stderr. |
Un valor fuera de su rango cae al valor por defecto, y la razón se escribe en stderr.
Errores
Cada fallo lleva uno de seis códigos, un mensaje y, donde ayuda, una pista que nombra el siguiente paso.
| Código | Qué pasó | Qué hacer |
|---|---|---|
not_found | Una fuente respondió y no tiene tal receta. | Comprueba el identificador con search_recipes. |
invalid_input | Los argumentos fueron rechazados antes de enviar cualquier solicitud. | Lee el mensaje, que nombra el argumento. |
rate_limited | Una fuente pidió a este cliente que fuera más lento. | Espera y vuelve a llamar con los mismos argumentos. La receta sigue ahí. |
parse_failure | Una página cargó y faltaba el contenido esperado. | Repórtalo en el rastreador de incidencias. |
network_error | La solicitud no se completó. | Inténtalo de nuevo en breve. |
timeout | La solicitud superó su plazo. | Aumenta RECIPES_TIMEOUT_MS, o pide menos filas. |
Una fuente que falló se informa por fuente en lugar de hacer fallar toda la respuesta, así que un sitio silencioso nunca oculta a los demás.
Como biblioteca
La capa que lee los sitios se publica por separado, con su ritmo, su caché y sus errores, y sin protocolo adjunto.
import { RecipesClient } from "mcp-recipes/client";
const client = new RecipesClient();
const { rows, reports } = await client.searchRecipes("carbonara", 3);
console.log(
rows.length,
reports.map((report) => report.status),
);
const { recipe } = await client.getRecipe(rows[0].id);
searchRecipes(query, limitPerSource, sources?, options?) respuestas
{ rows, reports }: un informe por fuente, que dice si respondió y qué
medía su propio recuento, de modo que una fuente que falló nunca se lee como una fuente que
no tiene nada. getRecipe(id) responde { recipe, cached, read } y lanza un
error con uno de los seis códigos. client.profiles enumera las fuentes que
registra la compilación.
El escalador se publica por separado en mcp-recipes/scale y funciona sin conexión en
cualquier lista:
import { scaleIngredients } from "mcp-recipes/scale";
scaleIngredients(["200 g de harina", "4 oeufs", "1 cup milk"], { factor: 2 });
Cada sitio mantiene su propio ritmo, y los mínimos también se aplican aquí.
Ritmo y atribución
Cada sitio tiene su propio ritmo, una solicitud a la vez con al menos un segundo
entre dos, y el mínimo de medio segundo se mantiene sin importar cómo esté
configurado el servidor. Dos de los sitios piden más, tres segundos entre dos
solicitudes, y lo obtienen: una configuración publicada para cada fuente puede aumentar
el espaciado de un sitio y nunca reducirlo. Preguntar a todos los sitios a la vez
cuesta, por tanto, una solicitud a cada uno, nunca dos. El User-Agent siempre
termina con la identidad del proyecto y una dirección donde se pueda contactar a una persona.
Cada fila lleva la dirección de la página propia de la receta y el nombre del sitio que la publicó. Las páginas del Cookbook se publican bajo CC BY-SA 4.0, que pide que lo construido sobre ellas se comparta bajo la misma licencia. Marmiton, Ptitchef, BBC Good Food, Supertoinette y Pequerecetas no declaran términos en una página de receta, y sus recetas pertenecen a esos sitios y a los cocineros que las escribieron. El silencio no es una concesión, así que da crédito al sitio y enlaza la página de la que tomaste una receta.
Una receta que BBC Good Food reserva para sus suscriptores vuelve sin sus ingredientes y su método, nombrada como receta retenida, con la dirección de su página. Este servidor no reconstruye lo que ese sitio eligió vender.
Dos cifras que publican los sitios no se repiten aquí. Una dificultad es una palabra que cada sitio escribe a su manera, sin escala que ninguno publique, así que no se asienta en ningún eje sobre el que puedan compararse dos versiones. Un costo es un precio en euros en un sitio y un rango dentro de su propia lista en otro, y un solo campo que contenga ambos invitaría a compararlos.
Este servidor MCP es un proyecto no oficial, sin afiliación con ninguno de los sitios que lee.
Privacidad
Este servidor no recopila nada sobre ti y no envía nada a su autor. Se ejecuta
en tu máquina, contacta a www.marmiton.org, api.wikimedia.org,
www.ptitchef.com, www.bbcgoodfood.com, www.supertoinette.com y
www.pequerecetas.com y a nada
más, mantiene sus respuestas en memoria mientras se ejecuta
y no escribe nada en disco. PRIVACY.md establece qué lleva una solicitud
y qué ajustes cambian algo de eso.
Desarrollo
npm install
npm run build:fixtures
npm test
npm run check
Las pruebas se ejecutan contra accesorios generados y no hacen ninguna solicitud de red. La suite en vivo,
npm run test:live, hace una solicitud por ruta y se ejecuta cada noche contra los
propios sitios.
Contribuciones
Errores, preguntas e ideas van en el rastreador de incidencias. Las solicitudes de extracción son bienvenidas; abrir una incidencia primero ayuda a acordar la forma del cambio. Consulta CONTRIBUTING.md.
Licencia
MIT, ver LICENSE. Las recetas pertenecen a los sitios que las publicaron y a sus autores.
mcp-recipes (français)
Las recetas viven en muchos sitios, y cada uno las escribe a su manera: un sitio de cocina francés publica en francés, con sus medidas y su idea de lo que es una ración, y un wiki de cocina en inglés, con listas de utensilios y una prosa para la que el primero no tiene ningún campo. Hacer una pregunta a uno de ellos responde sobre el tema de uno de ellos.
Este servidor lee seis. Tres publican en francés, Marmiton, Ptitchef y Supertoinette; dos en inglés, el Cookbook de Wikibooks y BBC Good Food; uno en español, Pequerecetas. Se puede buscar en los seis con una sola pregunta, leer una receta de cualquiera bajo una sola forma, poner varias versiones de un mismo plato lado a lado y adaptar cualquier lista de ingredientes. Sin clave de API, sin cuenta.
Instalación
Instalación en un clic
Claude Code
claude mcp add recipes -- npx -y mcp-recipes
Claude Desktop, Cursor y cualquier cliente con formato de configuración estándar
{
"mcpServers": {
"recipes": {
"command": "npx",
"args": ["-y", "mcp-recipes"]
}
}
}
Se necesita Node 24 o más reciente, y no hay ninguna variable de entorno que rellenar.
Con Docker
{
"mcpServers": {
"recipes": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-recipes:4.0.0"]
}
}
}
-i mantiene abierta la entrada estándar, que es el canal del protocolo, y -t se
omite porque un TTY reescribe el flujo. El contenedor necesita acceso HTTPS
saliente hacia www.marmiton.org, api.wikimedia.org, www.ptitchef.com,
www.bbcgoodfood.com, www.supertoinette.com y www.pequerecetas.com, y a
nada más: sin volúmenes, sin puertos, sin identificadores.
Bundle, sin npm
Descarga mcp-recipes-4.0.0.mcpb desde
la última publicación
y ábrelo. Un cliente que gestione bundles MCP lo instala solo, sin npm y
sin archivo de configuración que modificar. El bundle lleva sus dependencias, así que
no se descarga nada en la instalación.
Qué se puede pedir
- «Encuéntrame recetas de carbonara, de donde puedas.»
- «Compara las versiones francesa e inglesa de este plato.»
- «Léeme la segunda para ocho personas.»
- «¿Cuál usa crema?»
- «Multiplica por 1,5 esta lista de mi cuaderno.»
El camino habitual va de una búsqueda a una lectura: una línea lleva un id
que nombra su fuente, y get_recipe lo retoma.
Las fuentes
| Fuente | Sitio | Idioma |
|---|---|---|
marmiton | www.marmiton.org | francés |
cookbook | Cookbook Wikibooks | inglés |
ptitchef | www.ptitchef.com | francés |
goodfood | www.bbcgoodfood.com | inglés |
supertoinette | www.supertoinette.com | francés |
pequerecetas | www.pequerecetas.com | español |
El id de una línea nombra su fuente, por lo que un identificador leído en una respuesta | ||
| devuelve al sitio correcto. **Las cuentas nunca se suman entre | ||
| fuentes**, y una fuente que ha fallado se reporta como que ha fallado en lugar de | ||
| como que no encontró nada. |
Cada sitio se lee a su propio ritmo: dos de ellos requieren tres segundos entre dos solicitudes, y un ajuste establecido para todos solo puede hacer que este servidor sea más paciente de lo que el más lento requiere.
Dos de estos sitios guardan algo distinto a una receta en la dirección donde vive una
receta. El Cookbook de Wikibooks mantiene páginas sobre un ingrediente junto a las
recetas que lo emplean, y Pequerecetas publica artículos que reúnen
recetas. Una búsqueda lo dice, y get_recipe dice lo que leyó en la
página.
Las herramientas
| Herramienta | Lo que hace |
|---|---|
search_recipes | Busca en todas las fuentes con una sola pregunta. |
get_recipe | Lee una receta de cualquier fuente, bajo una sola forma. |
compare_recipes | Pone varias versiones de un mismo plato lado a lado. |
scale_ingredients | Adapta cualquier lista de ingredientes, sin consulta. |
search_recipes
Busca en todas las fuentes con una sola pregunta.
| Argumento | Tipo | Requerido | Lo que hace |
|---|---|---|---|
query | cadena, 1 a 200 caracteres | sí | El plato o ingrediente buscado. |
limit_per_source | entero, 1 a 25, predeterminado 5 | no | Líneas a conservar de cada fuente. |
sources | arreglo de identificadores de fuente | no | Consultar solo estas fuentes. |
fan_out | booleano, predeterminado true | no | Consultar cada fuente en lugar de detenerse en la primera que responda. |
En retorno: results, líneas que llevan id, que get_recipe retoma;
source y source_name que dicen qué sitio publicó la línea; title;
url; image_url; y un excerpt donde la fuente ofrece uno.
per_source da un informe por sitio con su status, que vale answered o
failed, el count que proporcionó, y su reported_total acompañado de
reported_total_means, que dice qué cuenta ese número en ese sitio.
names_the_dish dice cuántas de las líneas de ese sitio llevan el plato en su
título, sobre count: un índice de búsqueda responde a las palabras que se le ofrecen, por lo
que un sitio puede devolver líneas de las cuales ninguna es el plato. order dice en palabras
cómo se construyó la lista.
get_recipe
Lee una receta de cualquier fuente, bajo una sola forma.
| Argumento | Tipo | Requerido | Lo que hace |
|---|---|---|---|
id | cadena, 1 a 500 caracteres | sí | El identificador de una línea, tal como marmiton:44078. Dos fuentes abordan una receta por un número desnudo: escriba el id con su fuente. |
servings | entero, 1 a 500 | no | Adapta los ingredientes a este número de porciones. |
sections | arreglo de ingredients, steps, times, nutrition, tips, equipment, predeterminado ["ingredients", "steps"] | no | Las partes a devolver. |
max_gathered | entero, 1 a 500, predeterminado 30 | no | Recetas e intertítulos devueltos para una dirección que reúne recetas. |
max_steps | entero, 1 a 100, predeterminado 20 | no | Pasos a servir. |
max_step_chars | entero, 80 a 4000, predeterminado 600 | no | Caracteres conservados por paso. |
En retorno: kind dice qué llevaba la dirección. Una respuesta recipe lleva
recipe y no collection; una respuesta collection lleva collection y
no recipe, y es un artículo que reúne otras recetas, con los
headings de los que está construido y los recipes hacia los que apunta, cada una
legible por get_recipe.
Una receta viene en la forma en que todas las fuentes se devuelven, sea
cual sea la que la publicó: su título, su dirección, sus ingredientes con el
scaling y la is_equipment de cada línea, sus pasos, y las partes
solicitadas. Un campo que una
fuente publica y del que otra no tiene noción regresa ausente en lugar de
inventado. rest_minutes lleva el tiempo de reposo de una fuente que lo imprime por
separado, y no entra en ningún otro tiempo devuelto aquí. steps_as_one_block dice
cuándo una fuente publicó su método en un solo bloque de prosa en lugar de en pasos.
scaling_summary cuenta las líneas de cuatro maneras, y las cuatro suman el
total de la lista. withheld nombra la parte que una fuente reserva a sus suscriptores, que es una
parte que la página lleva y no una parte ilegible. Aumente max_step_chars
cuando un paso se cortó a mitad de una frase.
compare_recipes
Pone varias versiones de un mismo plato lado a lado.
| Argumento | Tipo | Requerido | Lo que hace |
|---|---|---|---|
dish | cadena, 1 a 200 caracteres | sí | El plato a comparar. |
servings | entero, 1 a 500 | no | Adapta cada versión a este número de porciones. |
sections | arreglo de ingredients, steps, times, nutrition, tips, equipment, predeterminado ["ingredients"] | no | Las partes a devolver por versión. |
max_steps | entero, 1 a 100, predeterminado 10 | no | Pasos a servir por versión. |
max_step_chars | entero, 80 a 4000, predeterminado 600 | no | Caracteres conservados por paso. |
sources | arreglo de ids de fuente | no | Comparar solo estas fuentes. |
En retorno: versions, una receta por fuente que haya respondido, todas adaptadas
al mismo número de porciones para que sus cantidades se lean una contra otra,
y differences, lo que las separa. per_source reporta cada sitio como lo
hace una búsqueda.
scale_ingredients
Adapta cualquier lista de ingredientes, sin consulta a ningún sitio.
| Argumento | Tipo | Requerido | Lo que hace |
|---|---|---|---|
ingredients | arreglo de 1 a 200 líneas | sí | Las líneas a adaptar. |
factor | número, hasta 1000 | uno de los dos | El multiplicador a aplicar. |
from_servings | entero, 1 a 500 | uno de los dos | El número de porciones de la lista original. |
to_servings | entero, 1 a 500 | uno de los dos | El número de porciones deseado. |
language | auto, fr, en o es, predeterminado auto | no | Cómo se lee cada línea. |
Pase factor, o el par from_servings y to_servings. auto lee cada
línea por sí misma, lo que necesita una lista que lleva varios idiomas;
nombrar un idioma lee todas las líneas así.
En retorno: las líneas adaptadas en la forma que devuelve get_recipe, cada una
con su scaling y su is_equipment, verdadero para una línea que nombra una herramienta
y que se deja tal cual. scaled_count, rounded_count, unscaled_count
y equipment_count suman el total de las líneas enviadas.
La adaptación de las cantidades
Una cantidad se expresa en la unidad que le conviene. Después de la adaptación, una
línea puede aparecer en una unidad distinta a la de la receta: 200 g
multiplicados por veinte dan 4 kg.
La finura con la que un ingrediente se corta depende de su naturaleza. Una baguette se
corta en dos, en tres o en cuatro; un huevo no se divide. Una cantidad
que cae entre las dos se redondea, y la receta adaptada se aparta entonces
un poco de las proporciones de la original. La línea lleva rounded, y su nota dice
lo que se hizo.
Las fuentes escriben sus cantidades en su propio idioma, y una línea se lee en el idioma en que fue escrita. Los números son la aritmética de este servidor, así que diga que fueron recalculados cuando los muestre.
Lo que una respuesta dice de las fuentes
Cada respuesta da cuenta de cada fuente por separado. Un sitio que ha fallado, uno al que nadie consultó y uno que respondió vacío son tres cosas distintas, y se reportan como tres. Un total permanece junto a la fuente que lo publicó, con lo que esa fuente cuenta al decirlo: uno cuenta una categoría entera, otro cuenta las líneas que sirvió, y un tercero no publica ningún total.
Configuración
Cada variable es opcional. Se colocan en el bloque env de la
configuración del cliente.
| Variable | Défaut | Ce qu'elle fait |
|---|---|---|
RECIPES_USER_AGENT | l'identité du projet | Nomme votre application auprès des 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 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 { rows, reports } = await client.searchRecipes("carbonara", 3);
console.log(
rows.length,
reports.map((report) => report.status),
);
const { recipe } = await client.getRecipe(rows[0].id);
searchRecipes(query, limitPerSource, sources?, options?) répond
{ rows, reports } : un rapport par source, disant si elle a répondu et ce que
son propre compte mesure, pour qu'une source en échec ne se lise jamais comme une
source qui ne détient rien. getRecipe(id) répond { recipe, cached, read }, et
lève une erreur portant un des six codes. client.profiles énumère les sources
que cette construction enregistre.
La mise à l'échelle est publiée à part, sous mcp-recipes/scale, et travaille
hors ligne sur n'importe quelle liste :
import { scaleIngredients } from "mcp-recipes/scale";
scaleIngredients(["200 g de harina", "4 oeufs", "1 cup milk"], { factor: 2 });
Chaque site garde son propre rythme, et les planchers tiennent é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. Deux des sites en demandent davantage, trois secondes entre deux
requêtes, et ils l'obtiennent : un réglage posé pour toutes les sources peut
élargir l'écart d'un site, jamais le réduire. 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, Supertoinette et Pequerecetas 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, www.supertoinette.com et
www.pequerecetas.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.