mcp-recipes 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/PRIVACY.md +8 -6
- package/README.md +192 -103
- package/dist/index.js +1236 -249
- package/dist/index.js.map +1 -1
- package/dist/{language-BgfmjwtF.d.ts → language-B3VNNg7f.d.ts} +2 -2
- package/dist/recipe/scale.d.ts +13 -5
- package/dist/recipe/scale.js +616 -89
- package/dist/recipe/scale.js.map +1 -1
- package/dist/sources/client.d.ts +163 -9
- package/dist/sources/client.js +348 -50
- package/dist/sources/client.js.map +1 -1
- package/package.json +20 -17
- package/server.json +5 -5
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.smeet666/mcp-recipes)
|
|
7
7
|
[](https://glama.ai/mcp/servers/smeet666/mcp-recipes)
|
|
8
8
|
[](https://m8ven.ai/mcp/smeet666-mcp-recipes-1o0x5l)
|
|
9
|
+
[](https://lobehub.com/mcp/smeet666-mcp-recipes)
|
|
9
10
|
[](https://cursor.com/en/install-mcp?name=recipes&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1jcC1yZWNpcGVzIl19)
|
|
10
11
|
[](https://insiders.vscode.dev/redirect/mcp/install?name=recipes&config=%7B%22name%22%3A%22recipes%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-recipes%22%5D%7D)
|
|
11
12
|
|
|
@@ -15,17 +16,15 @@ a serving is, and a wiki cookbook in English, with equipment lists and prose the
|
|
|
15
16
|
first has no field for. Asking a question of one of them answers about one of
|
|
16
17
|
them.
|
|
17
18
|
|
|
18
|
-
This server reads
|
|
19
|
-
[Marmiton](https://www.marmiton.org),
|
|
20
|
-
[
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
[
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
of them in one shape, put several versions of the same dish side by side, and
|
|
28
|
-
rescale any ingredient list. It needs no API key and no account.
|
|
19
|
+
This server reads six. Three publish in French,
|
|
20
|
+
[Marmiton](https://www.marmiton.org), [Ptitchef](https://www.ptitchef.com) and
|
|
21
|
+
[Supertoinette](https://www.supertoinette.com); two in English, the
|
|
22
|
+
[Wikibooks Cookbook](https://en.wikibooks.org/wiki/Cookbook:Table_of_Contents)
|
|
23
|
+
and [BBC Good Food](https://www.bbcgoodfood.com); and one in Spanish,
|
|
24
|
+
[Pequerecetas](https://www.pequerecetas.com). You can search them all with
|
|
25
|
+
one question, read a recipe from any of them in one shape, put several versions
|
|
26
|
+
of the same dish side by side, and rescale any ingredient list. It needs no API
|
|
27
|
+
key and no account.
|
|
29
28
|
|
|
30
29
|
_[Version française](#mcp-recipes-français)_
|
|
31
30
|
|
|
@@ -66,7 +65,7 @@ Node 24 or later is required, and no environment variable has to be set.
|
|
|
66
65
|
"mcpServers": {
|
|
67
66
|
"recipes": {
|
|
68
67
|
"command": "docker",
|
|
69
|
-
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-recipes:
|
|
68
|
+
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-recipes:4.0.0"]
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
}
|
|
@@ -75,12 +74,12 @@ Node 24 or later is required, and no environment variable has to be set.
|
|
|
75
74
|
`-i` keeps stdin open, which is where the protocol travels, and `-t` is left out
|
|
76
75
|
because a TTY rewrites the stream. The container needs outbound HTTPS to
|
|
77
76
|
`www.marmiton.org`, `api.wikimedia.org`, `www.ptitchef.com`,
|
|
78
|
-
`www.bbcgoodfood.com` and `www.
|
|
79
|
-
no volume, no port, no credential.
|
|
77
|
+
`www.bbcgoodfood.com`, `www.supertoinette.com` and `www.pequerecetas.com`, and
|
|
78
|
+
nothing else: no volume, no port, no credential.
|
|
80
79
|
|
|
81
80
|
### Bundle, without npm
|
|
82
81
|
|
|
83
|
-
Download `mcp-recipes-
|
|
82
|
+
Download `mcp-recipes-4.0.0.mcpb` from
|
|
84
83
|
[the latest release](https://github.com/smeet666/mcp-recipes/releases/latest) and
|
|
85
84
|
open it. A client that supports MCP bundles installs it on its own, with no npm
|
|
86
85
|
and no configuration file to edit. The bundle carries its dependencies, so
|
|
@@ -106,11 +105,21 @@ its source, and `get_recipe` takes it.
|
|
|
106
105
|
| `ptitchef` | `www.ptitchef.com` | French |
|
|
107
106
|
| `goodfood` | `www.bbcgoodfood.com` | English |
|
|
108
107
|
| `supertoinette` | `www.supertoinette.com` | French |
|
|
108
|
+
| `pequerecetas` | `www.pequerecetas.com` | Spanish |
|
|
109
109
|
|
|
110
110
|
A row's `id` names its source, so an identifier read from one answer goes back to
|
|
111
111
|
the right site. **Counts are never added across sources**, and a source that
|
|
112
112
|
failed is reported as having failed rather than as having found nothing.
|
|
113
113
|
|
|
114
|
+
Each site is read at its own pace: two of them ask for three seconds between
|
|
115
|
+
requests, and a setting posted for all of them can only make this server more
|
|
116
|
+
patient than the slowest asks for.
|
|
117
|
+
|
|
118
|
+
Two of these sites file something other than a recipe at the address a recipe
|
|
119
|
+
lives at. The Wikibooks Cookbook keeps pages about an ingredient beside the
|
|
120
|
+
recipes using it, and Pequerecetas publishes articles that gather recipes. A
|
|
121
|
+
search says so, and `get_recipe` says what it read off the page.
|
|
122
|
+
|
|
114
123
|
## Tools
|
|
115
124
|
|
|
116
125
|
| Tool | What it does |
|
|
@@ -136,8 +145,10 @@ Searches every source with one question.
|
|
|
136
145
|
`image_url`; and an `excerpt` where the source offers one. `per_source` gives one
|
|
137
146
|
report per site with its `status`, reading `answered` or `failed`, the `count` it
|
|
138
147
|
contributed, and its `reported_total` alongside `reported_total_means`, which
|
|
139
|
-
says what that number counts on that site. `
|
|
140
|
-
|
|
148
|
+
says what that number counts on that site. `names_the_dish` says how many of that
|
|
149
|
+
site's rows carry the dish in their title, out of `count`: a search index answers
|
|
150
|
+
the words it is handed, so a site can offer rows and none of them be the dish.
|
|
151
|
+
`order` says in words how the list was built.
|
|
141
152
|
|
|
142
153
|
### `get_recipe`
|
|
143
154
|
|
|
@@ -149,17 +160,26 @@ Reads one recipe from any source, in one shape.
|
|
|
149
160
|
| `servings` | integer, 1 to 500 | no | Rescale the ingredients to this many servings. |
|
|
150
161
|
| `sections` | array of `ingredients`, `steps`, `times`, `nutrition`, `tips`, `equipment`, default `["ingredients", "steps"]` | no | Which parts to return. |
|
|
151
162
|
| `max_steps` | integer, 1 to 100, default `20` | no | Steps to serve. |
|
|
163
|
+
| `max_gathered` | integer, 1 to 500, default `30` | no | Recipes and headings to return from an address that gathers recipes. |
|
|
152
164
|
| `max_step_chars` | integer, 80 to 4000, default `600` | no | Characters kept per step. |
|
|
153
165
|
|
|
154
|
-
**In return:**
|
|
155
|
-
|
|
166
|
+
**In return:** `kind` says what the address held. A `recipe` answer carries
|
|
167
|
+
`recipe` and no `collection`; a `collection` answer carries `collection` and no
|
|
168
|
+
`recipe`, and is an article gathering other recipes, with the `headings` it is
|
|
169
|
+
built from and the `recipes` it points at, each of them readable with
|
|
170
|
+
`get_recipe`.
|
|
171
|
+
|
|
172
|
+
A recipe comes in the shape every source is rendered into, whichever
|
|
173
|
+
published it: its title, its address, its ingredients with each line's `scaling`
|
|
174
|
+
and `is_equipment`,
|
|
156
175
|
its steps, and the sections asked for. A field one source publishes and another
|
|
157
176
|
has no notion of comes back absent rather than invented. `rest_minutes` carries a
|
|
158
177
|
resting time from a source that prints one apart, and is in no other time here.
|
|
159
178
|
`steps_as_one_block` says when a source published its method as one block of
|
|
160
179
|
prose rather than as steps. `withheld` names a part a source keeps for its
|
|
161
180
|
subscribers, which is a part the page has rather than a part that could not be
|
|
162
|
-
read.
|
|
181
|
+
read. `scaling_summary` counts the lines four ways, and the four add up to the
|
|
182
|
+
list. Raise `max_step_chars` when a step was cut mid-sentence.
|
|
163
183
|
|
|
164
184
|
### `compare_recipes`
|
|
165
185
|
|
|
@@ -181,18 +201,18 @@ search does.
|
|
|
181
201
|
|
|
182
202
|
### `scale_ingredients`
|
|
183
203
|
|
|
184
|
-
Rescales any ingredient list, with no request to
|
|
204
|
+
Rescales any ingredient list, with no request to any site.
|
|
185
205
|
|
|
186
|
-
| Argument | Type
|
|
187
|
-
| --------------- |
|
|
188
|
-
| `ingredients` | array of 1 to 200 lines
|
|
189
|
-
| `factor` | number, up to 1000
|
|
190
|
-
| `from_servings` | integer, 1 to 500
|
|
191
|
-
| `to_servings` | integer, 1 to 500
|
|
192
|
-
| `language` | `auto`, `fr` or `
|
|
206
|
+
| Argument | Type | Required | What it does |
|
|
207
|
+
| --------------- | ------------------------------------------ | ---------- | ------------------------------------------ |
|
|
208
|
+
| `ingredients` | array of 1 to 200 lines | yes | The lines to rescale. |
|
|
209
|
+
| `factor` | number, up to 1000 | one of two | The multiplier to apply. |
|
|
210
|
+
| `from_servings` | integer, 1 to 500 | one of two | How many servings the list is written for. |
|
|
211
|
+
| `to_servings` | integer, 1 to 500 | one of two | How many servings are wanted. |
|
|
212
|
+
| `language` | `auto`, `fr`, `en` or `es`, default `auto` | no | How each line is read. |
|
|
193
213
|
|
|
194
214
|
Pass `factor`, or the `from_servings` and `to_servings` pair. `auto` reads each
|
|
195
|
-
line on its own, which is what a list holding
|
|
215
|
+
line on its own, which is what a list holding more than one language needs; naming a
|
|
196
216
|
language reads every line that way.
|
|
197
217
|
|
|
198
218
|
**In return:** the rescaled lines in the shape `get_recipe` returns, each with
|
|
@@ -219,22 +239,22 @@ say they were recomputed when you show them.
|
|
|
219
239
|
Every answer accounts for each source separately. A site that failed, one nobody
|
|
220
240
|
asked, and one that answered with nothing are three different things, and they
|
|
221
241
|
are reported as three. A total stays beside the source that published it, with
|
|
222
|
-
what that source counts when it says it: one site counts a whole category
|
|
223
|
-
|
|
242
|
+
what that source counts when it says it: one site counts a whole category, another
|
|
243
|
+
counts the rows it served, and a third publishes no total at all.
|
|
224
244
|
|
|
225
245
|
## Configuration
|
|
226
246
|
|
|
227
247
|
Every variable is optional. Set them in the `env` block of your client config.
|
|
228
248
|
|
|
229
|
-
| Variable | Default | What it does
|
|
230
|
-
| --------------------------- | -------------------- |
|
|
231
|
-
| `RECIPES_USER_AGENT` | the project identity | Names your application to
|
|
232
|
-
| `RECIPES_MIN_INTERVAL_MS` | `1000` | Gap between two requests to one site, from 500 to 60000.
|
|
233
|
-
| `RECIPES_TIMEOUT_MS` | `20000` | Deadline for one request, from 1000 to 120000.
|
|
234
|
-
| `RECIPES_MAX_RETRIES` | `3` | Attempts after a transient failure, from 0 to 8.
|
|
235
|
-
| `RECIPES_CACHE_TTL_MS` | `900000` | How long an answer stays in memory, from 0 to 86400000.
|
|
236
|
-
| `RECIPES_CACHE_MAX_ENTRIES` | `200` | Answers held in memory at once, from 1 to 5000.
|
|
237
|
-
| `RECIPES_LOG_LEVEL` | `error` | `silent`, `error`, `info` or `debug`, written to stderr.
|
|
249
|
+
| Variable | Default | What it does |
|
|
250
|
+
| --------------------------- | -------------------- | ----------------------------------------------------------------------------------- |
|
|
251
|
+
| `RECIPES_USER_AGENT` | the project identity | Names your application to the sites, with an address where a person can be reached. |
|
|
252
|
+
| `RECIPES_MIN_INTERVAL_MS` | `1000` | Gap between two requests to one site, from 500 to 60000. |
|
|
253
|
+
| `RECIPES_TIMEOUT_MS` | `20000` | Deadline for one request, from 1000 to 120000. |
|
|
254
|
+
| `RECIPES_MAX_RETRIES` | `3` | Attempts after a transient failure, from 0 to 8. |
|
|
255
|
+
| `RECIPES_CACHE_TTL_MS` | `900000` | How long an answer stays in memory, from 0 to 86400000. |
|
|
256
|
+
| `RECIPES_CACHE_MAX_ENTRIES` | `200` | Answers held in memory at once, from 1 to 5000. |
|
|
257
|
+
| `RECIPES_LOG_LEVEL` | `error` | `silent`, `error`, `info` or `debug`, written to stderr. |
|
|
238
258
|
|
|
239
259
|
A value outside its range falls back to the default, and the reason is written to
|
|
240
260
|
stderr.
|
|
@@ -258,25 +278,47 @@ so one silent site never hides the other.
|
|
|
258
278
|
|
|
259
279
|
## As a library
|
|
260
280
|
|
|
261
|
-
The layer reading the
|
|
262
|
-
|
|
281
|
+
The layer reading the sites is published on its own, with its pacing, its cache
|
|
282
|
+
and its errors, and with no protocol attached.
|
|
263
283
|
|
|
264
284
|
```ts
|
|
265
285
|
import { RecipesClient } from "mcp-recipes/client";
|
|
266
286
|
|
|
267
287
|
const client = new RecipesClient();
|
|
268
|
-
const
|
|
269
|
-
console.log(
|
|
288
|
+
const { rows, reports } = await client.searchRecipes("carbonara", 3);
|
|
289
|
+
console.log(
|
|
290
|
+
rows.length,
|
|
291
|
+
reports.map((report) => report.status),
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
const { recipe } = await client.getRecipe(rows[0].id);
|
|
270
295
|
```
|
|
271
296
|
|
|
272
|
-
|
|
273
|
-
|
|
297
|
+
`searchRecipes(query, limitPerSource, sources?, options?)` answers
|
|
298
|
+
`{ rows, reports }`: one report per source, saying whether it answered and what
|
|
299
|
+
its own count measured, so a source that failed is never read as a source that
|
|
300
|
+
holds nothing. `getRecipe(id)` answers `{ recipe, cached, read }`, and throws an
|
|
301
|
+
error carrying one of the six codes. `client.profiles` lists the sources the
|
|
302
|
+
build registers.
|
|
303
|
+
|
|
304
|
+
The scaler is published separately at `mcp-recipes/scale`, and works offline on
|
|
305
|
+
any list:
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
import { scaleIngredients } from "mcp-recipes/scale";
|
|
309
|
+
|
|
310
|
+
scaleIngredients(["200 g de harina", "4 oeufs", "1 cup milk"], { factor: 2 });
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Each site keeps its own pace, and the floors hold here as well.
|
|
274
314
|
|
|
275
315
|
## Pacing and attribution
|
|
276
316
|
|
|
277
317
|
Each site is paced on its own, one request at a time with at least a second
|
|
278
318
|
between two, and the floor of half a second holds however the server is
|
|
279
|
-
configured.
|
|
319
|
+
configured. Two of the sites ask for more, three seconds between two requests,
|
|
320
|
+
and they get it: a setting posted for every source can raise a site's spacing
|
|
321
|
+
and never lower it. Asking every site at once therefore costs each of them one request,
|
|
280
322
|
never two. The `User-Agent` always ends with the project identity and an address
|
|
281
323
|
where a person can be reached.
|
|
282
324
|
|
|
@@ -284,7 +326,7 @@ Every row carries the address of the recipe's own page and the name of the site
|
|
|
284
326
|
that published it. The Cookbook pages are published under
|
|
285
327
|
[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/), which asks that
|
|
286
328
|
what is built on them be shared under the same licence. Marmiton, Ptitchef, BBC
|
|
287
|
-
Good Food and
|
|
329
|
+
Good Food, Supertoinette and Pequerecetas state no terms on a recipe page, and their recipes
|
|
288
330
|
belong to those sites and to the cooks who wrote them. Silence is not a grant, so
|
|
289
331
|
credit the site and link the page you took a recipe from.
|
|
290
332
|
|
|
@@ -305,7 +347,8 @@ sites it reads.
|
|
|
305
347
|
|
|
306
348
|
This server collects nothing about you and sends nothing to its author. It runs
|
|
307
349
|
on your machine, contacts `www.marmiton.org`, `api.wikimedia.org`,
|
|
308
|
-
`www.ptitchef.com`, `www.bbcgoodfood.com
|
|
350
|
+
`www.ptitchef.com`, `www.bbcgoodfood.com`, `www.supertoinette.com` and
|
|
351
|
+
`www.pequerecetas.com` and nothing
|
|
309
352
|
else, holds its answers in memory while it runs,
|
|
310
353
|
and writes nothing to disk. [PRIVACY.md](PRIVACY.md) states what a request
|
|
311
354
|
carries and which settings change any of it.
|
|
@@ -349,18 +392,15 @@ qu'est une part, et un wiki de cuisine en anglais, avec des listes de matériel
|
|
|
349
392
|
une prose pour lesquelles le premier n'a aucun champ. Poser une question à l'un
|
|
350
393
|
d'eux répond au sujet de l'un d'eux.
|
|
351
394
|
|
|
352
|
-
Ce serveur en lit
|
|
353
|
-
[Marmiton](https://www.marmiton.org),
|
|
354
|
-
[
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
[
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
lire une recette de n'importe lequel sous une seule forme, mettre plusieurs
|
|
362
|
-
versions d'un même plat côte à côte, et adapter n'importe quelle liste
|
|
363
|
-
d'ingrédients. Aucune clé d'API, aucun compte.
|
|
395
|
+
Ce serveur en lit six. Trois publient en français,
|
|
396
|
+
[Marmiton](https://www.marmiton.org), [Ptitchef](https://www.ptitchef.com) et
|
|
397
|
+
[Supertoinette](https://www.supertoinette.com) ; deux en anglais, le
|
|
398
|
+
[Cookbook des Wikibooks](https://en.wikibooks.org/wiki/Cookbook:Table_of_Contents)
|
|
399
|
+
et [BBC Good Food](https://www.bbcgoodfood.com) ; un en espagnol,
|
|
400
|
+
[Pequerecetas](https://www.pequerecetas.com). On peut chercher dans les six
|
|
401
|
+
avec une seule question, lire une recette de n'importe lequel sous une seule
|
|
402
|
+
forme, mettre plusieurs versions d'un même plat côte à côte, et adapter
|
|
403
|
+
n'importe quelle liste d'ingrédients. Aucune clé d'API, aucun compte.
|
|
364
404
|
|
|
365
405
|
## Installation
|
|
366
406
|
|
|
@@ -398,7 +438,7 @@ renseigner.
|
|
|
398
438
|
"mcpServers": {
|
|
399
439
|
"recipes": {
|
|
400
440
|
"command": "docker",
|
|
401
|
-
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-recipes:
|
|
441
|
+
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-recipes:4.0.0"]
|
|
402
442
|
}
|
|
403
443
|
}
|
|
404
444
|
}
|
|
@@ -407,12 +447,12 @@ renseigner.
|
|
|
407
447
|
`-i` garde l'entrée standard ouverte, qui est le canal du protocole, et `-t` est
|
|
408
448
|
omis parce qu'un TTY réécrit le flux. Le conteneur a besoin d'un accès HTTPS
|
|
409
449
|
sortant vers `www.marmiton.org`, `api.wikimedia.org`, `www.ptitchef.com`,
|
|
410
|
-
`www.bbcgoodfood.com` et `www.
|
|
450
|
+
`www.bbcgoodfood.com`, `www.supertoinette.com` et `www.pequerecetas.com`, et de
|
|
411
451
|
rien d'autre : aucun volume, aucun port, aucun identifiant.
|
|
412
452
|
|
|
413
453
|
### Bundle, sans npm
|
|
414
454
|
|
|
415
|
-
Téléchargez `mcp-recipes-
|
|
455
|
+
Téléchargez `mcp-recipes-4.0.0.mcpb` depuis
|
|
416
456
|
[la dernière publication](https://github.com/smeet666/mcp-recipes/releases/latest)
|
|
417
457
|
et ouvrez-le. Un client qui gère les bundles MCP l'installe seul, sans npm et
|
|
418
458
|
sans fichier de configuration à modifier. Le bundle emporte ses dépendances, donc
|
|
@@ -438,20 +478,31 @@ qui nomme sa source, et `get_recipe` le reprend.
|
|
|
438
478
|
| `ptitchef` | `www.ptitchef.com` | français |
|
|
439
479
|
| `goodfood` | `www.bbcgoodfood.com` | anglais |
|
|
440
480
|
| `supertoinette` | `www.supertoinette.com` | français |
|
|
481
|
+
| `pequerecetas` | `www.pequerecetas.com` | espagnol |
|
|
441
482
|
|
|
442
483
|
L'`id` d'une ligne nomme sa source, donc un identifiant lu dans une réponse
|
|
443
484
|
retourne vers le bon site. **Les comptes ne sont jamais additionnés entre
|
|
444
485
|
sources**, et une source qui a échoué est rapportée comme ayant échoué plutôt que
|
|
445
486
|
comme n'ayant rien trouvé.
|
|
446
487
|
|
|
488
|
+
Chaque site est lu à son propre rythme : deux d'entre eux demandent trois
|
|
489
|
+
secondes entre deux requêtes, et un réglage posé pour tous ne peut que rendre ce
|
|
490
|
+
serveur plus patient que ce que le plus lent demande.
|
|
491
|
+
|
|
492
|
+
Deux de ces sites rangent autre chose qu'une recette à l'adresse où vit une
|
|
493
|
+
recette. Le Cookbook des Wikibooks garde des pages sur un ingrédient à côté des
|
|
494
|
+
recettes qui l'emploient, et Pequerecetas publie des articles qui rassemblent
|
|
495
|
+
des recettes. Une recherche le dit, et `get_recipe` dit ce qu'il a lu sur la
|
|
496
|
+
page.
|
|
497
|
+
|
|
447
498
|
## Les outils
|
|
448
499
|
|
|
449
|
-
| Outil | Ce qu'il fait
|
|
450
|
-
| ------------------- |
|
|
451
|
-
| `search_recipes` | Cherche dans toutes les sources avec une seule question.
|
|
452
|
-
| `get_recipe` | Lit une recette de
|
|
453
|
-
| `compare_recipes` | Met plusieurs versions d'un même plat côte à côte.
|
|
454
|
-
| `scale_ingredients` | Adapte n'importe quelle liste d'ingrédients, sans requête.
|
|
500
|
+
| Outil | Ce qu'il fait |
|
|
501
|
+
| ------------------- | ----------------------------------------------------------------- |
|
|
502
|
+
| `search_recipes` | Cherche dans toutes les sources avec une seule question. |
|
|
503
|
+
| `get_recipe` | Lit une recette de n'importe quelle source, sous une seule forme. |
|
|
504
|
+
| `compare_recipes` | Met plusieurs versions d'un même plat côte à côte. |
|
|
505
|
+
| `scale_ingredients` | Adapte n'importe quelle liste d'ingrédients, sans requête. |
|
|
455
506
|
|
|
456
507
|
### `search_recipes`
|
|
457
508
|
|
|
@@ -469,8 +520,11 @@ Cherche dans toutes les sources avec une seule question.
|
|
|
469
520
|
`url` ; `image_url` ; et un `excerpt` là où la source en propose un.
|
|
470
521
|
`per_source` donne un rapport par site avec son `status`, valant `answered` ou
|
|
471
522
|
`failed`, le `count` qu'il a fourni, et son `reported_total` accompagné de
|
|
472
|
-
`reported_total_means`, qui dit ce que ce nombre compte sur ce site.
|
|
473
|
-
|
|
523
|
+
`reported_total_means`, qui dit ce que ce nombre compte sur ce site.
|
|
524
|
+
`names_the_dish` dit combien des lignes de ce site portent le plat dans leur
|
|
525
|
+
titre, sur `count` : un index de recherche répond aux mots qu'on lui tend, donc
|
|
526
|
+
un site peut rendre des lignes dont aucune n'est le plat. `order` dit en mots
|
|
527
|
+
comment la liste a été bâtie.
|
|
474
528
|
|
|
475
529
|
### `get_recipe`
|
|
476
530
|
|
|
@@ -481,17 +535,26 @@ Lit une recette de n'importe quelle source, sous une seule forme.
|
|
|
481
535
|
| `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. |
|
|
482
536
|
| `servings` | entier, 1 à 500 | non | Adapte les ingrédients à ce nombre de parts. |
|
|
483
537
|
| `sections` | tableau de `ingredients`, `steps`, `times`, `nutrition`, `tips`, `equipment`, défaut `["ingredients", "steps"]` | non | Les parties à rendre. |
|
|
538
|
+
| `max_gathered` | entier, 1 à 500, défaut `30` | non | Recettes et intertitres rendus pour une adresse qui rassemble des recettes. |
|
|
484
539
|
| `max_steps` | entier, 1 à 100, défaut `20` | non | Étapes à servir. |
|
|
485
540
|
| `max_step_chars` | entier, 80 à 4000, défaut `600` | non | Caractères gardés par étape. |
|
|
486
541
|
|
|
487
|
-
**En retour :**
|
|
542
|
+
**En retour :** `kind` dit ce que l'adresse portait. Une réponse `recipe` porte
|
|
543
|
+
`recipe` et pas de `collection` ; une réponse `collection` porte `collection` et
|
|
544
|
+
pas de `recipe`, et c'est un article rassemblant d'autres recettes, avec les
|
|
545
|
+
`headings` dont il est bâti et les `recipes` vers lesquelles il pointe, chacune
|
|
546
|
+
lisible par `get_recipe`.
|
|
547
|
+
|
|
548
|
+
Une recette vient dans la forme où toutes les sources sont rendues, quelle
|
|
488
549
|
que soit celle qui l'a publiée : son titre, son adresse, ses ingrédients avec le
|
|
489
|
-
`scaling` de chaque ligne, ses étapes, et les parties
|
|
550
|
+
`scaling` et l'`is_equipment` de chaque ligne, ses étapes, et les parties
|
|
551
|
+
demandées. Un champ qu'une
|
|
490
552
|
source publie et dont une autre n'a pas la notion revient absent plutôt
|
|
491
553
|
qu'inventé. `rest_minutes` porte le temps de repos d'une source qui l'imprime à
|
|
492
554
|
part, et il n'entre dans aucun autre temps rendu ici. `steps_as_one_block` dit
|
|
493
555
|
quand une source a publié sa méthode d'un seul bloc de prose plutôt qu'en étapes.
|
|
494
|
-
`
|
|
556
|
+
`scaling_summary` compte les lignes de quatre façons, et les quatre font le
|
|
557
|
+
total de la liste. `withheld` nomme la partie qu'une source réserve à ses abonnés, qui est une
|
|
495
558
|
partie que la page porte et non une partie illisible. Augmentez `max_step_chars`
|
|
496
559
|
quand une étape a été coupée au milieu d'une phrase.
|
|
497
560
|
|
|
@@ -515,22 +578,24 @@ fait une recherche.
|
|
|
515
578
|
|
|
516
579
|
### `scale_ingredients`
|
|
517
580
|
|
|
518
|
-
Adapte n'importe quelle liste d'ingrédients, sans requête à
|
|
581
|
+
Adapte n'importe quelle liste d'ingrédients, sans requête à aucun site.
|
|
519
582
|
|
|
520
|
-
| Argument | Type
|
|
521
|
-
| --------------- |
|
|
522
|
-
| `ingredients` | tableau de 1 à 200 lignes
|
|
523
|
-
| `factor` | nombre, jusqu'à 1000
|
|
524
|
-
| `from_servings` | entier, 1 à 500
|
|
525
|
-
| `to_servings` | entier, 1 à 500
|
|
526
|
-
| `language` | `auto`, `fr` ou `
|
|
583
|
+
| Argument | Type | Requis | Ce qu'il fait |
|
|
584
|
+
| --------------- | ----------------------------------------- | ------------- | ----------------------------------------- |
|
|
585
|
+
| `ingredients` | tableau de 1 à 200 lignes | oui | Les lignes à adapter. |
|
|
586
|
+
| `factor` | nombre, jusqu'à 1000 | l'un des deux | Le multiplicateur à appliquer. |
|
|
587
|
+
| `from_servings` | entier, 1 à 500 | l'un des deux | Le nombre de parts de la liste d'origine. |
|
|
588
|
+
| `to_servings` | entier, 1 à 500 | l'un des deux | Le nombre de parts voulu. |
|
|
589
|
+
| `language` | `auto`, `fr`, `en` ou `es`, défaut `auto` | non | Comment chaque ligne est lue. |
|
|
527
590
|
|
|
528
591
|
Passez `factor`, ou le couple `from_servings` et `to_servings`. `auto` lit chaque
|
|
529
|
-
ligne pour elle-même, ce dont a besoin une liste portant
|
|
592
|
+
ligne pour elle-même, ce dont a besoin une liste portant plusieurs langues ;
|
|
530
593
|
nommer une langue lit toutes les lignes ainsi.
|
|
531
594
|
|
|
532
595
|
**En retour :** les lignes adaptées dans la forme que rend `get_recipe`, chacune
|
|
533
|
-
avec son `scaling
|
|
596
|
+
avec son `scaling` et son `is_equipment`, vrai pour une ligne qui nomme un outil
|
|
597
|
+
et qu'on laisse telle quelle. `scaled_count`, `rounded_count`, `unscaled_count`
|
|
598
|
+
et `equipment_count` font le total des lignes envoyées.
|
|
534
599
|
|
|
535
600
|
## L'adaptation des quantités
|
|
536
601
|
|
|
@@ -554,22 +619,23 @@ Chaque réponse rend compte de chaque source séparément. Un site qui a échou
|
|
|
554
619
|
que personne n'a interrogé et un qui a répondu vide sont trois choses
|
|
555
620
|
différentes, et elles sont rapportées comme trois. Un total reste à côté de la
|
|
556
621
|
source qui l'a publié, avec ce que cette source compte en le disant : l'un compte
|
|
557
|
-
une catégorie entière
|
|
622
|
+
une catégorie entière, un autre compte les lignes qu'il a servies, et un
|
|
623
|
+
troisième ne publie aucun total.
|
|
558
624
|
|
|
559
625
|
## Configuration
|
|
560
626
|
|
|
561
627
|
Chaque variable est facultative. Elles se posent dans le bloc `env` de la
|
|
562
628
|
configuration du client.
|
|
563
629
|
|
|
564
|
-
| Variable | Défaut | Ce qu'elle fait
|
|
565
|
-
| --------------------------- | -------------------- |
|
|
566
|
-
| `RECIPES_USER_AGENT` | l'identité du projet | Nomme votre application auprès des
|
|
567
|
-
| `RECIPES_MIN_INTERVAL_MS` | `1000` | Écart entre deux requêtes vers un même site, de 500 à 60000.
|
|
568
|
-
| `RECIPES_TIMEOUT_MS` | `20000` | Délai d'une requête, de 1000 à 120000.
|
|
569
|
-
| `RECIPES_MAX_RETRIES` | `3` | Tentatives après un échec passager, de 0 à 8.
|
|
570
|
-
| `RECIPES_CACHE_TTL_MS` | `900000` | Durée pendant laquelle une réponse reste en mémoire, de 0 à 86400000.
|
|
571
|
-
| `RECIPES_CACHE_MAX_ENTRIES` | `200` | Réponses gardées en mémoire à la fois, de 1 à 5000.
|
|
572
|
-
| `RECIPES_LOG_LEVEL` | `error` | `silent`, `error`, `info` ou `debug`, écrit sur la sortie d'erreur.
|
|
630
|
+
| Variable | Défaut | Ce qu'elle fait |
|
|
631
|
+
| --------------------------- | -------------------- | ----------------------------------------------------------------------------------- |
|
|
632
|
+
| `RECIPES_USER_AGENT` | l'identité du projet | Nomme votre application auprès des sites, avec une adresse où joindre une personne. |
|
|
633
|
+
| `RECIPES_MIN_INTERVAL_MS` | `1000` | Écart entre deux requêtes vers un même site, de 500 à 60000. |
|
|
634
|
+
| `RECIPES_TIMEOUT_MS` | `20000` | Délai d'une requête, de 1000 à 120000. |
|
|
635
|
+
| `RECIPES_MAX_RETRIES` | `3` | Tentatives après un échec passager, de 0 à 8. |
|
|
636
|
+
| `RECIPES_CACHE_TTL_MS` | `900000` | Durée pendant laquelle une réponse reste en mémoire, de 0 à 86400000. |
|
|
637
|
+
| `RECIPES_CACHE_MAX_ENTRIES` | `200` | Réponses gardées en mémoire à la fois, de 1 à 5000. |
|
|
638
|
+
| `RECIPES_LOG_LEVEL` | `error` | `silent`, `error`, `info` ou `debug`, écrit sur la sortie d'erreur. |
|
|
573
639
|
|
|
574
640
|
Une valeur hors de sa plage retombe sur le défaut, et la raison est écrite sur la
|
|
575
641
|
sortie d'erreur.
|
|
@@ -593,25 +659,47 @@ toute la réponse, donc un site silencieux n'en cache jamais un autre.
|
|
|
593
659
|
|
|
594
660
|
## Comme bibliothèque
|
|
595
661
|
|
|
596
|
-
La couche qui lit les
|
|
662
|
+
La couche qui lit les sites est publiée seule, avec son rythme, son cache et
|
|
597
663
|
ses erreurs, sans protocole attaché.
|
|
598
664
|
|
|
599
665
|
```ts
|
|
600
666
|
import { RecipesClient } from "mcp-recipes/client";
|
|
601
667
|
|
|
602
668
|
const client = new RecipesClient();
|
|
603
|
-
const
|
|
604
|
-
console.log(
|
|
669
|
+
const { rows, reports } = await client.searchRecipes("carbonara", 3);
|
|
670
|
+
console.log(
|
|
671
|
+
rows.length,
|
|
672
|
+
reports.map((report) => report.status),
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
const { recipe } = await client.getRecipe(rows[0].id);
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
`searchRecipes(query, limitPerSource, sources?, options?)` répond
|
|
679
|
+
`{ rows, reports }` : un rapport par source, disant si elle a répondu et ce que
|
|
680
|
+
son propre compte mesure, pour qu'une source en échec ne se lise jamais comme une
|
|
681
|
+
source qui ne détient rien. `getRecipe(id)` répond `{ recipe, cached, read }`, et
|
|
682
|
+
lève une erreur portant un des six codes. `client.profiles` énumère les sources
|
|
683
|
+
que cette construction enregistre.
|
|
684
|
+
|
|
685
|
+
La mise à l'échelle est publiée à part, sous `mcp-recipes/scale`, et travaille
|
|
686
|
+
hors ligne sur n'importe quelle liste :
|
|
687
|
+
|
|
688
|
+
```ts
|
|
689
|
+
import { scaleIngredients } from "mcp-recipes/scale";
|
|
690
|
+
|
|
691
|
+
scaleIngredients(["200 g de harina", "4 oeufs", "1 cup milk"], { factor: 2 });
|
|
605
692
|
```
|
|
606
693
|
|
|
607
|
-
Chaque
|
|
608
|
-
codes. Chaque site garde son propre rythme, et le plancher tient également ici.
|
|
694
|
+
Chaque site garde son propre rythme, et les planchers tiennent également ici.
|
|
609
695
|
|
|
610
696
|
## Rythme et attribution
|
|
611
697
|
|
|
612
698
|
Chaque site est cadencé pour lui-même, une requête à la fois avec au moins une
|
|
613
699
|
seconde entre deux, et le plancher d'une demi-seconde tient quelle que soit la
|
|
614
|
-
configuration.
|
|
700
|
+
configuration. Deux des sites en demandent davantage, trois secondes entre deux
|
|
701
|
+
requêtes, et ils l'obtiennent : un réglage posé pour toutes les sources peut
|
|
702
|
+
élargir l'écart d'un site, jamais le réduire. Les interroger toutes à la fois coûte donc à chacune une requête,
|
|
615
703
|
jamais deux. Le `User-Agent` se termine toujours par l'identité du projet et une
|
|
616
704
|
adresse où joindre une personne.
|
|
617
705
|
|
|
@@ -619,7 +707,7 @@ Chaque ligne porte l'adresse de la page de la recette et le nom du site qui l'a
|
|
|
619
707
|
publiée. Les pages du Cookbook sont publiées sous
|
|
620
708
|
[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.fr), qui
|
|
621
709
|
demande que ce qu'on bâtit dessus soit partagé sous la même licence. Marmiton,
|
|
622
|
-
Ptitchef, BBC Good Food et
|
|
710
|
+
Ptitchef, BBC Good Food, Supertoinette et Pequerecetas n'énoncent aucune condition sur une page
|
|
623
711
|
de recette, et leurs recettes appartiennent à ces sites et aux cuisiniers qui les
|
|
624
712
|
ont écrites. Le silence n'est pas une autorisation : créditez le site et liez la
|
|
625
713
|
page d'où vient la recette.
|
|
@@ -641,7 +729,8 @@ lit.
|
|
|
641
729
|
|
|
642
730
|
Ce serveur ne collecte rien sur vous et n'envoie rien à son auteur. Il tourne sur
|
|
643
731
|
votre machine, ne joint que `www.marmiton.org`, `api.wikimedia.org`,
|
|
644
|
-
`www.ptitchef.com`, `www.bbcgoodfood.com
|
|
732
|
+
`www.ptitchef.com`, `www.bbcgoodfood.com`, `www.supertoinette.com` et
|
|
733
|
+
`www.pequerecetas.com`, garde ses réponses en mémoire le temps qu'il tourne, et
|
|
645
734
|
n'écrit rien sur le disque. [PRIVACY.md](PRIVACY.md) dit ce qu'une requête
|
|
646
735
|
emporte et quels réglages changent cela.
|
|
647
736
|
|