Recipes

Pesquise cinco sites de receitas de uma vez, em francês e inglês, e ajuste as quantidades. Sem chave de API.

Documentação

mcp-recipes

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

As receitas vivem em muitos sites, e cada um as escreve do seu jeito: um site de culinária francês publica em francês, com suas próprias medidas e sua própria ideia do que é uma porção, e um livro de receitas wiki em inglês, com listas de equipamentos e prosa para a qual o primeiro não tem campo. Fazer uma pergunta a um deles responde sobre um deles.

Este servidor lê seis. Três publicam em francês, Marmiton, Ptitchef e Supertoinette; dois em inglês, o Wikibooks Cookbook e o BBC Good Food; e um em espanhol, Pequerecetas. Você pode pesquisar em todos eles com uma única pergunta, ler uma receita de qualquer um deles em um único formato, colocar várias versões do mesmo prato lado a lado e redimensionar qualquer lista de ingredientes. Não precisa de chave de API nem de conta.

Versão em francês


Instalação

Instalação com um clique

Install in Cursor Install in VS Code

Claude Code

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

Claude Desktop, Cursor e qualquer cliente que use o formato de configuração padrão

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

Node 24 ou posterior é necessário, e nenhuma variável de ambiente precisa ser definida.

Com Docker

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

-i mantém o stdin aberto, que é por onde o protocolo trafega, e -t é omitido porque um TTY reescreve o fluxo. O contêiner precisa de HTTPS de saída para www.marmiton.org, api.wikimedia.org, www.ptitchef.com, www.bbcgoodfood.com, www.supertoinette.com e www.pequerecetas.com, e nada mais: sem volume, sem porta, sem credencial.

Pacote, sem npm

Baixe mcp-recipes-4.0.0.mcpb de a versão mais recente e abra-o. Um cliente que suporta pacotes MCP o instala por conta própria, sem npm e sem arquivo de configuração para editar. O pacote carrega suas dependências, então nada é baixado no momento da instalação.

O que você pode perguntar

  • "Encontre receitas de carbonara, de onde você puder."
  • "Compare as versões francesa e inglesa desse prato."
  • "Leia a segunda para oito pessoas."
  • "Qual delas usa creme?"
  • "Redimensione esta lista do meu caderno por 1,5."

O caminho comum vai de uma busca a uma leitura: uma linha carrega um id nomeando sua fonte, e get_recipe a recebe.

As fontes

FonteSiteIdioma
marmitonwww.marmiton.orgFrancês
cookbookWikibooks CookbookInglês
ptitchefwww.ptitchef.comFrancês
goodfoodwww.bbcgoodfood.comInglês
supertoinettewww.supertoinette.comFrancês
pequerecetaswww.pequerecetas.comEspanhol

O id de uma linha nomeia sua fonte, então um identificador lido de uma resposta volta para o site certo. Contagens nunca são somadas entre fontes, e uma fonte que falhou é relatada como tendo falhado, em vez de como não tendo encontrado nada.

Cada site é lido no seu próprio ritmo: dois deles pedem três segundos entre requisições, e uma configuração publicada para todos eles só pode tornar este servidor mais paciente do que o mais lento pede.

Dois desses sites arquivam algo que não é uma receita no endereço onde uma receita vive. O Wikibooks Cookbook mantém páginas sobre um ingrediente ao lado das receitas que o usam, e o Pequerecetas publica artigos que reúnem receitas. Uma busca diz isso, e get_recipe diz o que leu da página.

Ferramentas

FerramentaO que faz
search_recipesPesquisa em todas as fontes com uma única pergunta.
get_recipeLê uma receita de qualquer fonte, em um único formato.
compare_recipesColoca várias versões do mesmo prato lado a lado.
scale_ingredientsRedimensiona qualquer lista de ingredientes, sem requisição a nenhum site.

search_recipes

Pesquisa em todas as fontes com uma única pergunta.

ArgumentoTipoObrigatórioO que faz
querystring, 1 a 200 caracteressimO prato ou o ingrediente a procurar.
limit_per_sourceinteiro, 1 a 25, padrão 5nãoLinhas a manter de cada fonte.
sourcesarray de ids de fontenãoPerguntar apenas a estas fontes.
fan_outbooleano, padrão truenãoPerguntar a todas as fontes em vez de parar na primeira que responder.

Em retorno: results, linhas carregando id, que get_recipe recebe; source e source_name dizendo qual site publicou a linha; title; url; image_url; e um excerpt onde a fonte oferece um. per_source dá um relatório por site com seu status, lendo answered ou failed, o count que contribuiu, e seu reported_total junto com reported_total_means, que diz o que esse número conta naquele site. names_the_dish diz quantas das linhas daquele site carregam o prato no título, de count: um índice de busca responde às palavras que recebe, então um site pode oferecer linhas e nenhuma delas ser o prato. order diz em palavras como a lista foi construída.

get_recipe

Lê uma receita de qualquer fonte, em um único formato.

ArgumentoTipoObrigatórioO que faz
idstring, 1 a 500 caracteressimO identificador que uma linha carrega, como marmiton:44078. Duas fontes endereçam uma receita por um número puro, então soletre um id com sua fonte.
servingsinteiro, 1 a 500nãoRedimensionar os ingredientes para este número de porções.
sectionsarray de ingredients, steps, times, nutrition, tips, equipment, padrão ["ingredients", "steps"]nãoQuais partes retornar.
max_stepsinteiro, 1 a 100, padrão 20nãoPassos a servir.
max_gatheredinteiro, 1 a 500, padrão 30nãoReceitas e títulos a retornar de um endereço que reúne receitas.
max_step_charsinteiro, 80 a 4000, padrão 600nãoCaracteres mantidos por passo.

Em retorno: kind diz o que o endereço continha. Uma resposta recipe carrega recipe e nenhum collection; uma resposta collection carrega collection e nenhum recipe, e é um artigo que reúne outras receitas, com o headings do qual é construído e o recipes para o qual aponta, cada um legível com get_recipe.

Uma receita vem no formato no qual toda fonte é renderizada, seja qual for a que a publicou: seu título, seu endereço, seus ingredientes com o scaling e o is_equipment de cada linha, seus passos e as seções pedidas. Um campo que uma fonte publica e outra não tem noção dele volta ausente, em vez de inventado. rest_minutes carrega um tempo de descanso de uma fonte que o imprime separado, e não está em nenhum outro tempo aqui. steps_as_one_block diz quando uma fonte publicou seu método como um bloco de prosa em vez de passos. withheld nomeia uma parte que uma fonte mantém para seus assinantes, que é uma parte que a página tem, em vez de uma parte que não pôde ser lida. scaling_summary conta as linhas de quatro maneiras, e as quatro somam a lista. Aumente max_step_chars quando um passo foi cortado no meio de uma frase.

compare_recipes

Coloca várias versões do mesmo prato lado a lado.

ArgumentoTipoObrigatórioO que faz
dishstring, 1 a 200 caracteressimO prato a comparar.
servingsinteiro, 1 a 500nãoRedimensionar cada versão para este número de porções.
sectionsarray de ingredients, steps, times, nutrition, tips, equipment, padrão ["ingredients"]nãoQuais partes retornar por versão.
max_stepsinteiro, 1 a 100, padrão 10nãoPassos a servir por versão.
max_step_charsinteiro, 80 a 4000, padrão 600nãoCaracteres mantidos por passo.
sourcesarray de ids de fontenãoComparar apenas estas fontes.

Em retorno: versions, uma receita por fonte que respondeu, todas redimensionadas para o mesmo número de porções para que suas quantidades possam ser lidas umas contra as outras, e differences, o que as separa. per_source relata cada site como uma busca faz.

scale_ingredients

Redimensiona qualquer lista de ingredientes, sem requisição a nenhum site.

ArgumentoTipoObrigatórioO que faz
ingredientsarray de 1 a 200 linhassimAs linhas a serem redimensionadas.
factornúmero, até 1000um de doisO multiplicador a ser aplicado.
from_servingsinteiro, de 1 a 500um de doisPara quantas porções a lista foi escrita.
to_servingsinteiro, de 1 a 500um de doisQuantas porções são desejadas.
languageauto, fr, en ou es, padrão autonãoComo cada linha é lida.

Passe factor, ou o par from_servings e to_servings. auto lê cada linha individualmente, que é o que uma lista com mais de um idioma precisa; nomear um idioma lê cada linha dessa forma.

Em retorno: as linhas redimensionadas no formato que get_recipe retorna, cada uma com seu scaling.

Redimensionando as quantidades

Uma quantidade é expressa na unidade que melhor se adequa, então uma linha pode voltar em uma unidade diferente daquela usada na receita: 200 g multiplicado por vinte lê-se 4 kg.

O quão finamente um ingrediente pode ser dividido depende do que ele é. Uma baguete pode ser cortada em dois, em três ou em quatro; um ovo não pode ser compartilhado. Uma quantidade que cai entre os dois é arredondada, e a receita redimensionada então se afasta um pouco das proporções do original. A linha carrega rounded, e sua nota diz o que foi feito.

As fontes escrevem suas quantidades em seus próprios idiomas, e uma linha é lida no idioma em que foi escrita. Os números são aritmética deste servidor, então diga que foram recalculados quando você os exibir.

O que uma resposta afirma sobre as fontes

Cada resposta considera cada fonte separadamente. Um site que falhou, um que ninguém consultou e um que respondeu com nada são três coisas diferentes, e são relatados como três. Um total permanece ao lado da fonte que o publicou, com o que essa fonte conta quando o diz: um site conta uma categoria inteira, outro conta as linhas que serviu, e um terceiro não publica total algum.

Configuração

Todas as variáveis são opcionais. Defina-as no bloco env da configuração do seu cliente.

VariávelPadrãoO que faz
RECIPES_USER_AGENTa identidade do projetoNomeia seu aplicativo para os sites, com um endereço onde uma pessoa pode ser contatada.
RECIPES_MIN_INTERVAL_MS1000Intervalo entre duas solicitações a um site, de 500 a 60000.
RECIPES_TIMEOUT_MS20000Prazo para uma solicitação, de 1000 a 120000.
RECIPES_MAX_RETRIES3Tentativas após uma falha transitória, de 0 a 8.
RECIPES_CACHE_TTL_MS900000Por quanto tempo uma resposta permanece na memória, de 0 a 86400000.
RECIPES_CACHE_MAX_ENTRIES200Respostas mantidas na memória de uma vez, de 1 a 5000.
RECIPES_LOG_LEVELerrorsilent, error, info ou debug, escritos em stderr.

Um valor fora do intervalo cai para o padrão, e o motivo é escrito em stderr.

Erros

Cada falha carrega um de seis códigos, uma mensagem e, onde ajuda, uma dica nomeando o próximo passo.

CódigoO que aconteceuO que fazer
not_foundUma fonte respondeu e não contém tal receita.Verifique o identificador com search_recipes.
invalid_inputOs argumentos foram recusados antes de qualquer solicitação sair.Leia a mensagem, que nomeia o argumento.
rate_limitedUma fonte pediu que este cliente desacelerasse.Espere, então chame novamente com os mesmos argumentos. A receita ainda está lá.
parse_failureUma página carregou e o conteúdo esperado estava ausente.Reporte em o rastreador de problemas.
network_errorA solicitação não foi concluída.Tente novamente em breve.
timeoutA solicitação passou do prazo.Aumente RECIPES_TIMEOUT_MS, ou peça menos linhas.

Uma fonte que falhou é relatada por fonte, em vez de falhar toda a resposta, então um site silencioso nunca esconde o outro.

Como biblioteca

A camada que lê os sites é publicada separadamente, com seu ritmo, seu cache e seus erros, e sem protocolo anexado.

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?) respostas { rows, reports }: um relatório por fonte, dizendo se respondeu e o que sua própria contagem mediu, para que uma fonte que falhou nunca seja lida como uma fonte que não contém nada. getRecipe(id) responde { recipe, cached, read }, e lança um erro carregando um dos seis códigos. client.profiles lista as fontes que a construção registra.

O escalador é publicado separadamente em mcp-recipes/scale, e funciona offline em qualquer lista:

import { scaleIngredients } from "mcp-recipes/scale";

scaleIngredients(["200 g de harina", "4 oeufs", "1 cup milk"], { factor: 2 });

Cada site mantém seu próprio ritmo, e os mínimos valem aqui também.

Ritmo e atribuição

Cada site é ritmado individualmente, uma solicitação por vez, com pelo menos um segundo entre duas, e o mínimo de meio segundo vale independentemente de como o servidor está configurado. Dois dos sites pedem mais, três segundos entre duas solicitações, e eles conseguem: uma configuração publicada para cada fonte pode aumentar o espaçamento de um site e nunca diminuí-lo. Perguntar a todos os sites de uma vez custa, portanto, a cada um deles uma solicitação, nunca duas. O User-Agent sempre termina com a identidade do projeto e um endereço onde uma pessoa pode ser contatada.

Cada linha carrega o endereço da página da própria receita e o nome do site que a publicou. As páginas do Cookbook são publicadas sob CC BY-SA 4.0, que pede que o que for construído sobre elas seja compartilhado sob a mesma licença. Marmiton, Ptitchef, BBC Good Food, Supertoinette e Pequerecetas não declaram termos em uma página de receita, e suas receitas pertencem a esses sites e aos cozinheiros que as escreveram. Silêncio não é uma concessão, então credite o site e link a página de onde você tirou uma receita.

Uma receita que a BBC Good Food mantém para seus assinantes volta sem seus ingredientes e seu método, nomeada como uma receita retida, com o endereço de sua página. Este servidor não reconstrói o que esse site escolheu vender.

Dois números que os sites publicam não são repetidos aqui. Uma dificuldade é uma palavra que cada site escreve à sua maneira, sem escala que qualquer um deles publique, então ela não se situa em nenhum eixo ao longo do qual duas versões poderiam ser comparadas. Um custo é um preço em euros em um site e uma classificação dentro de sua própria lista em outro, e um único campo que contivesse ambos os convidaria a serem comparados.

Este servidor MCP é um projeto não oficial, sem afiliação a nenhum dos sites que lê.

Privacidade

Este servidor não coleta nada sobre você e não envia nada ao seu autor. Ele roda na sua máquina, contata www.marmiton.org, api.wikimedia.org, www.ptitchef.com, www.bbcgoodfood.com, www.supertoinette.com e www.pequerecetas.com e nada mais, mantém suas respostas na memória enquanto roda, e não grava nada em disco. PRIVACY.md declara o que uma solicitação carrega e quais configurações alteram qualquer parte disso.

Desenvolvimento

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

Os testes rodam contra fixtures geradas e não fazem nenhuma solicitação de rede. A suíte ao vivo, npm run test:live, faz uma solicitação por rota e roda todas as noites contra os próprios sites.

Contribuindo

Bugs, perguntas e ideias pertencem a o rastreador de problemas. Pull requests são bem-vindos; abrir uma issue primeiro ajuda a concordar sobre a forma da mudança. Veja CONTRIBUTING.md.

Licença

MIT, veja LICENSE. As receitas pertencem aos sites que as publicaram e aos seus autores.


mcp-recipes (francês)

Versão em inglês

As receitas vivem em muitos sites, e cada um as escreve à sua maneira: um site de culinária francês publica em francês, com suas medidas e sua ideia do que é uma porção, e um wiki de culinária em inglês, com listas de equipamentos e uma prosa para a qual o primeiro não tem nenhum campo. Fazer uma pergunta a um deles responde sobre o assunto de um deles.

Este servidor lê seis. Três publicam em francês, Marmiton, Ptitchef e Supertoinette; dois em inglês, o Cookbook dos Wikibooks e BBC Good Food; um em espanhol, Pequerecetas. Pode-se pesquisar nos seis com uma única pergunta, ler uma receita de qualquer um deles sob uma única forma, colocar várias versões do mesmo prato lado a lado, e adaptar qualquer lista de ingredientes. Nenhuma chave de API, nenhuma conta.

Instalação

Instalação em um clique

Install in Cursor Install in VS Code

Claude Code

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

Claude Desktop, Cursor, e qualquer cliente no formato de configuração padrão

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

Node 24 ou mais recente é necessário, e nenhuma variável de ambiente precisa ser preenchida.

Com Docker

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

-i mantém a entrada padrão aberta, que é o canal do protocolo, e -t é omitido porque um TTY reescreve o fluxo. O contêiner precisa de acesso HTTPS de saída para www.marmiton.org, api.wikimedia.org, www.ptitchef.com, www.bbcgoodfood.com, www.supertoinette.com e www.pequerecetas.com, e de nada mais: nenhum volume, nenhuma porta, nenhum identificador.

Bundle, sem npm

Baixe mcp-recipes-4.0.0.mcpb de a última publicação e abra-o. Um cliente que gerencia bundles MCP o instala sozinho, sem npm e sem arquivo de configuração para modificar. O bundle carrega suas dependências, então nada é baixado na instalação.

O que se pode pedir

  • « Encontre-me receitas de carbonara, de onde você puder. »
  • « Compare as versões francesa e inglesa deste prato. »
  • « Leia-me a segunda para oito pessoas. »
  • « Qual delas usa creme? »
  • « Multiplique por 1,5 esta lista do meu caderno. »

O caminho comum vai de uma pesquisa a uma leitura: uma linha carrega um id que nomeia sua fonte, e get_recipe o retoma.

As fontes

FonteSiteIdioma
marmitonwww.marmiton.orgfrancês
cookbookCookbook Wikibooksinglês
ptitchefwww.ptitchef.comfrancês
goodfoodwww.bbcgoodfood.cominglês
supertoinettewww.supertoinette.comfrancês
pequerecetaswww.pequerecetas.comespanhol
A linha id de uma busca nomeia sua fonte, portanto um identificador lido em uma resposta
retorna ao site correto. **As contagens nunca são somadas entre
fontes**, e uma fonte que falhou é relatada como tendo falhado, em vez de
como não tendo encontrado nada.

Cada site é lido no seu próprio ritmo: dois deles exigem três segundos entre duas requisições, e uma configuração definida para todos só pode tornar este servidor mais paciente do que o mais lento exige.

Dois desses sites guardam outra coisa além de uma receita no endereço onde vive uma receita. O Cookbook dos Wikibooks mantém páginas sobre um ingrediente ao lado das receitas que o utilizam, e o Pequerecetas publica artigos que reúnem receitas. Uma busca informa isso, e get_recipe informa o que leu na página.

As ferramentas

FerramentaO que faz
search_recipesBusca em todas as fontes com uma única pergunta.
get_recipeLê uma receita de qualquer fonte, em um único formato.
compare_recipesColoca várias versões do mesmo prato lado a lado.
scale_ingredientsAdapta qualquer lista de ingredientes, sem requisição.

search_recipes

Busca em todas as fontes com uma única pergunta.

ArgumentoTipoObrigatórioO que faz
querytexto, 1 a 200 caracteressimO prato ou ingrediente procurado.
limit_per_sourceinteiro, 1 a 25, padrão 5nãoLinhas a manter de cada fonte.
sourceslista de identificadores de fontenãoConsultar apenas essas fontes.
fan_outbooleano, padrão truenãoConsultar cada fonte em vez de parar na primeira que responder.

Em retorno: results, linhas com id, que get_recipe retoma; source e source_name que indicam qual site publicou a linha; title; url; image_url; e um excerpt onde a fonte oferecer um. per_source fornece um relatório por site com seu status, valendo answered ou failed, o count que forneceu, e seu reported_total acompanhado de reported_total_means, que indica o que esse número conta naquele site. names_the_dish indica quantas das linhas daquele site trazem o prato no título, em count: um índice de busca responde às palavras que lhe são dadas, portanto um site pode retornar linhas das quais nenhuma é o prato. order descreve em palavras como a lista foi construída.

get_recipe

Lê uma receita de qualquer fonte, em um único formato.

ArgumentoTipoObrigatórioO que faz
idtexto, 1 a 500 caracteressimO identificador de uma linha, como marmiton:44078. Duas fontes endereçam uma receita por um número puro: escreva o id com sua fonte.
servingsinteiro, 1 a 500nãoAdapta os ingredientes a esse número de porções.
sectionslista de ingredients, steps, times, nutrition, tips, equipment, padrão ["ingredients", "steps"]nãoAs partes a retornar.
max_gatheredinteiro, 1 a 500, padrão 30nãoReceitas e subtítulos retornados para um endereço que reúne receitas.
max_stepsinteiro, 1 a 100, padrão 20nãoEtapas a servir.
max_step_charsinteiro, 80 a 4000, padrão 600nãoCaracteres mantidos por etapa.

Em retorno: kind indica o que o endereço continha. Uma resposta recipe traz recipe e não collection; uma resposta collection traz collection e não recipe, e é um artigo que reúne outras receitas, com os headings dos quais é composto e os recipes para os quais aponta, cada um legível por get_recipe.

Uma receita vem no formato em que todas as fontes são retornadas, independentemente de qual a publicou: seu título, seu endereço, seus ingredientes com o scaling e a is_equipment de cada linha, suas etapas, e as partes solicitadas. Um campo que uma fonte publica e do qual outra não tem a noção retorna ausente, em vez de inventado. rest_minutes traz o tempo de descanso de uma fonte que o imprime à parte, e ele não entra em nenhum outro tempo retornado aqui. steps_as_one_block indica quando uma fonte publicou seu método em um único bloco de prosa, em vez de em etapas. scaling_summary conta as linhas de quatro maneiras, e as quatro totalizam a lista. withheld nomeia a parte que uma fonte reserva aos seus assinantes, que é uma parte que a página contém e não uma parte ilegível. Aumente max_step_chars quando uma etapa foi cortada no meio de uma frase.

compare_recipes

Coloca várias versões do mesmo prato lado a lado.

ArgumentoTipoObrigatórioO que faz
dishtexto, 1 a 200 caracteressimO prato a comparar.
servingsinteiro, 1 a 500nãoAdapta cada versão a esse número de porções.
sectionslista de ingredients, steps, times, nutrition, tips, equipment, padrão ["ingredients"]nãoAs partes a retornar por versão.
max_stepsinteiro, 1 a 100, padrão 10nãoEtapas a servir por versão.
max_step_charsinteiro, 80 a 4000, padrão 600nãoCaracteres mantidos por etapa.
sourceslista de ids de fontenãoComparar apenas essas fontes.

Em retorno: versions, uma receita por fonte que respondeu, todas adaptadas ao mesmo número de porções para que suas quantidades se leiam uma contra a outra, e differences, o que as separa. per_source relata cada site como o faz uma busca.

scale_ingredients

Adapta qualquer lista de ingredientes, sem requisição a nenhum site.

ArgumentoTipoObrigatórioO que faz
ingredientslista de 1 a 200 linhassimAs linhas a adaptar.
factornúmero, até 1000um dos doisO multiplicador a aplicar.
from_servingsinteiro, 1 a 500um dos doisO número de porções da lista original.
to_servingsinteiro, 1 a 500um dos doisO número de porções desejado.
languageauto, fr, en ou es, padrão autonãoComo cada linha é lida.

Passe factor, ou o par from_servings e to_servings. auto lê cada linha por si mesma, o que é necessário para uma lista com vários idiomas; nomear um idioma lê todas as linhas dessa forma.

Em retorno: as linhas adaptadas no formato que get_recipe retorna, cada uma com seu scaling e seu is_equipment, verdadeiro para uma linha que nomeia uma ferramenta e que é deixada como está. scaled_count, rounded_count, unscaled_count e equipment_count totalizam as linhas enviadas.

A adaptação das quantidades

Uma quantidade é expressa na unidade que lhe convém. Após a adaptação, uma linha pode, portanto, aparecer em outra unidade que não a da receita: 200 g multiplicados por vinte resultam em 4 kg.

A fineza com que um ingrediente se corta depende de sua natureza. Uma baguete se corta em dois, em três ou em quatro; um ovo não se divide. Uma quantidade que cai entre os dois é, portanto, arredondada, e a receita adaptada se desvia então um pouco das proporções da original. A linha traz rounded, e sua nota informa o que foi feito.

As fontes escrevem suas quantidades em seu próprio idioma, e uma linha é lida no idioma em que foi escrita. Os números são a aritmética deste servidor, portanto diga que foram recalculados quando os mostrar.

O que uma resposta informa sobre as fontes

Cada resposta presta contas de cada fonte separadamente. Um site que falhou, um que ninguém consultou e um que respondeu vazio são três coisas diferentes, e são relatados como três. Um total permanece ao lado da fonte que o publicou, com o que essa fonte conta ao informá-lo: um conta uma categoria inteira, outro conta as linhas que serviu, e um terceiro não publica nenhum total.

Configuração

Cada variável é opcional. Elas são definidas no bloco env da configuração do cliente.

VariávelPadrãoO que ela faz
RECIPES_USER_AGENTa identidade do projetoNomeia seu aplicativo junto aos sites, com um endereço para contatar uma pessoa.
RECIPES_MIN_INTERVAL_MS1000Intervalo entre duas requisições ao mesmo site, de 500 a 60000.
RECIPES_TIMEOUT_MS20000Tempo limite de uma requisição, de 1000 a 120000.
RECIPES_MAX_RETRIES3Tentativas após uma falha temporária, de 0 a 8.
RECIPES_CACHE_TTL_MS900000Duração durante a qual uma resposta permanece em memória, de 0 a 86400000.
RECIPES_CACHE_MAX_ENTRIES200Respostas mantidas em memória por vez, de 1 a 5000.
RECIPES_LOG_LEVELerrorsilent, error, info ou debug, escrito na saída de erro.

Um valor fora do intervalo cai no padrão, e o motivo é escrito na saída de erro.

Erros

Cada falha carrega um dos seis códigos, uma mensagem e, quando ajuda, uma indicação do próximo passo.

CódigoO que aconteceuO que fazer
not_foundUma fonte respondeu e não tem essa receita.Verifique o identificador com search_recipes.
invalid_inputOs argumentos foram recusados antes de qualquer requisição.Leia a mensagem, que nomeia o argumento.
rate_limitedUma fonte pede que este cliente desacelere.Aguarde e chame novamente com os mesmos argumentos. A receita ainda está lá.
parse_failureUma página carregou e o conteúdo esperado está ausente.Reporte em o rastreador de incidentes.
network_errorA requisição não foi concluída.Tente novamente em breve.
timeoutA requisição excedeu o tempo limite.Aumente RECIPES_TIMEOUT_MS, ou peça menos linhas.

Uma fonte que falha é reportada fonte por fonte, em vez de fazer toda a resposta falhar, então um site silencioso nunca esconde outro.

Como biblioteca

A camada que lê os sites é publicada sozinha, com seu ritmo, seu cache e seus erros, sem protocolo anexado.

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?) responde { rows, reports }: um relatório por fonte, dizendo se ela respondeu e o que sua própria conta mede, para que uma fonte em falha nunca seja lida como uma fonte que não possui nada. getRecipe(id) responde { recipe, cached, read }, e levanta um erro com um dos seis códigos. client.profiles enumera as fontes que esta construção registra.

A escalabilidade é publicada separadamente, sob mcp-recipes/scale, e trabalha offline em qualquer lista:

import { scaleIngredients } from "mcp-recipes/scale";

scaleIngredients(["200 g de harina", "4 oeufs", "1 cup milk"], { factor: 2 });

Cada site mantém seu próprio ritmo, e os mínimos também valem aqui.

Ritmo e atribuição

Cada site é ritmado por si mesmo, uma requisição por vez com pelo menos um segundo entre duas, e o mínimo de meio segundo vale independentemente da configuração. Dois dos sites pedem mais, três segundos entre duas requisições, e eles conseguem: uma configuração definida para todas as fontes pode ampliar o intervalo de um site, nunca reduzi-lo. Consultar todos ao mesmo tempo custa, portanto, uma requisição a cada um, nunca duas. O User-Agent sempre termina com a identidade do projeto e um endereço para contatar uma pessoa.

Cada linha carrega o endereço da página da receita e o nome do site que a publicou. As páginas do Cookbook são publicadas sob CC BY-SA 4.0, que exige que o que se constrói sobre elas seja compartilhado sob a mesma licença. Marmiton, Ptitchef, BBC Good Food, Supertoinette e Pequerecetas não declaram nenhuma condição sobre uma página de receita, e suas receitas pertencem a esses sites e aos cozinheiros que as escreveram. O silêncio não é uma autorização: credite o site e linke a página de onde vem a receita.

Uma receita que a BBC Good Food reserva aos seus assinantes retorna sem seus ingredientes nem seu método, nomeada como uma receita retida, com o endereço de sua página. Este servidor não reconstrói o que esse site escolheu vender.

Dois números que os sites publicam não são reproduzidos aqui. Uma dificuldade é uma palavra que cada site escreve à sua maneira, sem nenhuma escala publicada: ela não se assenta em nenhum eixo ao longo do qual duas versões se comparariam. Um custo é um preço em euros em um site e uma posição em sua própria lista em outro, e um único campo carregando ambos convidaria a compará-los.

Este MCP é um projeto não oficial, sem afiliação a nenhum dos sites que ele lê.

Privacidade

Este servidor não coleta nada sobre você e não envia nada ao seu autor. Ele roda na sua máquina, junta apenas www.marmiton.org, api.wikimedia.org, www.ptitchef.com, www.bbcgoodfood.com, www.supertoinette.com e www.pequerecetas.com, mantém suas respostas em memória enquanto roda, e não escreve nada no disco. PRIVACY.md diz o que uma requisição carrega e quais configurações mudam isso.

Desenvolvimento

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

Os testes são executados em fixtures geradas e não emitem nenhuma requisição. A suíte ao vivo, npm run test:live, emite uma requisição por rota e roda todas as noites contra os próprios sites.

Contribuindo

Anomalias, perguntas e ideias têm seu lugar em o rastreador de incidentes. As propostas de modificação são bem-vindas; abrir um ticket primeiro ajuda a concordar sobre a forma da mudança. Veja CONTRIBUTING.md.

Licença

MIT, veja LICENSE. As receitas pertencem aos sites que as publicaram e aos seus autores.