mcp-marmiton 2.0.1 → 2.1.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 +8 -0
- package/PRIVACY.md +12 -10
- package/README.md +7 -4
- package/dist/index.js +41 -2
- package/dist/index.js.map +1 -1
- package/dist/marmiton/client.d.ts +2 -0
- package/dist/marmiton/client.js +41 -2
- package/dist/marmiton/client.js.map +1 -1
- package/package.json +11 -10
- package/server.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.1.0
|
|
4
|
+
|
|
5
|
+
- **The largest page this reads is a setting, and pages past it are refused.**
|
|
6
|
+
A deadline abandons a body that arrives slowly; one that arrives quickly and
|
|
7
|
+
large is never abandoned by it, and it lands in memory in one piece before
|
|
8
|
+
anything looks at it. The body is read in pieces and stopped at
|
|
9
|
+
`MARMITON_MAX_BODY_BYTES`, eight megabytes by default.
|
|
10
|
+
|
|
3
11
|
## 2.0.1
|
|
4
12
|
|
|
5
13
|
- **Every tool is documented, with its arguments and what its answer carries.**
|
package/PRIVACY.md
CHANGED
|
@@ -55,11 +55,12 @@ becomes of them. `MARMITON_LOG_LEVEL` governs how much is written and defaults t
|
|
|
55
55
|
|
|
56
56
|
## The settings that change any of this
|
|
57
57
|
|
|
58
|
-
| Variable
|
|
59
|
-
|
|
|
60
|
-
| `MARMITON_USER_AGENT`
|
|
61
|
-
| `MARMITON_CACHE_TTL_MS`
|
|
62
|
-
| `
|
|
58
|
+
| Variable | What it changes |
|
|
59
|
+
| ------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
60
|
+
| `MARMITON_USER_AGENT` | Adds your own identifier in front of this project's, which stays appended so the site can always reach a person. |
|
|
61
|
+
| `MARMITON_CACHE_TTL_MS` | How long an answer is held in memory. `0` turns the cache off. |
|
|
62
|
+
| `MARMITON_MAX_BODY_BYTES` | The largest page this reads. A page past it is refused rather than held. |
|
|
63
|
+
| `MARMITON_LOG_LEVEL` | How much is written to stderr. |
|
|
63
64
|
|
|
64
65
|
## Children
|
|
65
66
|
|
|
@@ -131,11 +132,12 @@ qu'ils deviennent. `MARMITON_LOG_LEVEL` règle leur quantité et vaut `error` pa
|
|
|
131
132
|
|
|
132
133
|
## Les réglages qui changent tout cela
|
|
133
134
|
|
|
134
|
-
| Variable
|
|
135
|
-
|
|
|
136
|
-
| `MARMITON_USER_AGENT`
|
|
137
|
-
| `MARMITON_CACHE_TTL_MS`
|
|
138
|
-
| `
|
|
135
|
+
| Variable | Ce qu'elle change |
|
|
136
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
137
|
+
| `MARMITON_USER_AGENT` | Ajoute votre identifiant devant celui du projet, qui reste accolé pour que le site puisse toujours joindre une personne. |
|
|
138
|
+
| `MARMITON_CACHE_TTL_MS` | Combien de temps une réponse est gardée en mémoire. `0` éteint le cache. |
|
|
139
|
+
| `MARMITON_MAX_BODY_BYTES` | La plus grande page lue. Au-delà, la page est refusée plutôt que gardée. |
|
|
140
|
+
| `MARMITON_LOG_LEVEL` | La quantité écrite sur stderr. |
|
|
139
141
|
|
|
140
142
|
## Les enfants
|
|
141
143
|
|
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.smeet666/mcp-marmiton)
|
|
7
7
|
[](https://glama.ai/mcp/servers/smeet666/mcp-marmiton)
|
|
8
8
|
[](https://m8ven.ai/mcp/smeet666-mcp-marmiton-1f9qvs)
|
|
9
|
+
[](https://lobehub.com/mcp/smeet666-mcp-marmiton)
|
|
9
10
|
[](https://cursor.com/en/install-mcp?name=marmiton&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1jcC1tYXJtaXRvbiJdfQ%3D%3D)
|
|
10
11
|
[](https://insiders.vscode.dev/redirect/mcp/install?name=marmiton&config=%7B%22name%22%3A%22marmiton%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-marmiton%22%5D%7D)
|
|
11
12
|
|
|
@@ -62,7 +63,7 @@ Node 24 or later is required, and no environment variable has to be set.
|
|
|
62
63
|
"mcpServers": {
|
|
63
64
|
"marmiton": {
|
|
64
65
|
"command": "docker",
|
|
65
|
-
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-marmiton:2.0
|
|
66
|
+
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-marmiton:2.1.0"]
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
}
|
|
@@ -74,7 +75,7 @@ because a TTY rewrites the stream. The container needs outbound HTTPS to
|
|
|
74
75
|
|
|
75
76
|
### Bundle, without npm
|
|
76
77
|
|
|
77
|
-
Download `mcp-marmiton-2.0.
|
|
78
|
+
Download `mcp-marmiton-2.1.0.mcpb` from
|
|
78
79
|
[the latest release](https://github.com/smeet666/mcp-marmiton/releases/latest)
|
|
79
80
|
and open it. A client that supports MCP bundles installs it on its own, with no
|
|
80
81
|
npm and no configuration file to edit. The bundle carries its dependencies, so
|
|
@@ -193,6 +194,7 @@ Every variable is optional. Set them in the `env` block of your client config.
|
|
|
193
194
|
| `MARMITON_MAX_RETRIES` | `3` | Attempts after a transient failure, from 0 to 10. |
|
|
194
195
|
| `MARMITON_CACHE_TTL_MS` | `900000` | How long a page stays in memory, from 0 to 86400000. |
|
|
195
196
|
| `MARMITON_CACHE_MAX_ENTRIES` | `200` | Pages held in memory at once, from 0 to 10000. |
|
|
197
|
+
| `MARMITON_MAX_BODY_BYTES` | `8000000` | Largest page this reads, in bytes, from 100000 to 64000000. |
|
|
196
198
|
| `MARMITON_LOG_LEVEL` | `error` | `silent`, `error`, `info` or `debug`, written to stderr. |
|
|
197
199
|
|
|
198
200
|
A value outside its range falls back to the default, and the reason is written to
|
|
@@ -331,7 +333,7 @@ renseigner.
|
|
|
331
333
|
"mcpServers": {
|
|
332
334
|
"marmiton": {
|
|
333
335
|
"command": "docker",
|
|
334
|
-
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-marmiton:2.0
|
|
336
|
+
"args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-marmiton:2.1.0"]
|
|
335
337
|
}
|
|
336
338
|
}
|
|
337
339
|
}
|
|
@@ -344,7 +346,7 @@ aucun identifiant.
|
|
|
344
346
|
|
|
345
347
|
### Bundle, sans npm
|
|
346
348
|
|
|
347
|
-
Téléchargez `mcp-marmiton-2.0.
|
|
349
|
+
Téléchargez `mcp-marmiton-2.1.0.mcpb` depuis
|
|
348
350
|
[la dernière publication](https://github.com/smeet666/mcp-marmiton/releases/latest)
|
|
349
351
|
et ouvrez-le. Un client qui gère les bundles MCP l'installe seul, sans npm et
|
|
350
352
|
sans fichier de configuration à modifier. Le bundle emporte ses dépendances, donc
|
|
@@ -466,6 +468,7 @@ configuration du client.
|
|
|
466
468
|
| `MARMITON_MAX_RETRIES` | `3` | Tentatives après un échec passager, de 0 à 10. |
|
|
467
469
|
| `MARMITON_CACHE_TTL_MS` | `900000` | Durée pendant laquelle une page reste en mémoire, de 0 à 86400000. |
|
|
468
470
|
| `MARMITON_CACHE_MAX_ENTRIES` | `200` | Pages gardées en mémoire à la fois, de 0 à 10000. |
|
|
471
|
+
| `MARMITON_MAX_BODY_BYTES` | `8000000` | Plus grande page lue, en octets, de 100000 à 64000000. |
|
|
469
472
|
| `MARMITON_LOG_LEVEL` | `error` | `silent`, `error`, `info` ou `debug`, écrit sur la sortie d'erreur. |
|
|
470
473
|
|
|
471
474
|
Une valeur hors de sa plage retombe sur le défaut, et la raison est écrite sur la
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
8
8
|
import process from "process";
|
|
9
9
|
|
|
10
10
|
// src/version.ts
|
|
11
|
-
var PKG_VERSION = "2.0
|
|
11
|
+
var PKG_VERSION = "2.1.0";
|
|
12
12
|
var REPO_URL = "https://github.com/smeet666/mcp-marmiton";
|
|
13
13
|
|
|
14
14
|
// src/config.ts
|
|
@@ -19,6 +19,10 @@ var DEFAULTS = {
|
|
|
19
19
|
maxRetries: 3,
|
|
20
20
|
cacheTtlMs: 15 * 60 * 1e3,
|
|
21
21
|
cacheMaxEntries: 200,
|
|
22
|
+
// Recipe pages run to tens of kilobytes. A body an order of magnitude past
|
|
23
|
+
// that is a page this reader has no reading for, and finding that out by
|
|
24
|
+
// holding it costs the caller the memory and the site the transfer.
|
|
25
|
+
maxBodyBytes: 8e6,
|
|
22
26
|
logLevel: "error"
|
|
23
27
|
};
|
|
24
28
|
var MIN_ALLOWED_INTERVAL_MS = 500;
|
|
@@ -99,6 +103,11 @@ function loadConfig(env = process.env) {
|
|
|
99
103
|
max: 1e4,
|
|
100
104
|
fallback: DEFAULTS.cacheMaxEntries
|
|
101
105
|
}),
|
|
106
|
+
maxBodyBytes: readNumber("MARMITON_MAX_BODY_BYTES", env, {
|
|
107
|
+
min: 1e5,
|
|
108
|
+
max: 64e6,
|
|
109
|
+
fallback: DEFAULTS.maxBodyBytes
|
|
110
|
+
}),
|
|
102
111
|
logLevel
|
|
103
112
|
};
|
|
104
113
|
}
|
|
@@ -324,6 +333,36 @@ function readAnswer(url, status, body, retryAfterMs, ownGuessMs) {
|
|
|
324
333
|
}
|
|
325
334
|
return { kind: "usable" };
|
|
326
335
|
}
|
|
336
|
+
async function readBounded(response, maxBytes, url) {
|
|
337
|
+
const stream = response.body;
|
|
338
|
+
if (!stream) {
|
|
339
|
+
return await response.text();
|
|
340
|
+
}
|
|
341
|
+
const reader = stream.getReader();
|
|
342
|
+
const decoder = new TextDecoder();
|
|
343
|
+
const parts = [];
|
|
344
|
+
let held = 0;
|
|
345
|
+
try {
|
|
346
|
+
for (; ; ) {
|
|
347
|
+
const { done, value } = await reader.read();
|
|
348
|
+
if (done) {
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
held += value.byteLength;
|
|
352
|
+
if (held > maxBytes) {
|
|
353
|
+
throw parseFailure(
|
|
354
|
+
url,
|
|
355
|
+
`the page carries more than the ${maxBytes} bytes this reads for one page`
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
parts.push(decoder.decode(value, { stream: true }));
|
|
359
|
+
}
|
|
360
|
+
} finally {
|
|
361
|
+
await reader.cancel().catch(() => void 0);
|
|
362
|
+
}
|
|
363
|
+
parts.push(decoder.decode());
|
|
364
|
+
return parts.join("");
|
|
365
|
+
}
|
|
327
366
|
async function fetchHtml(url, deps) {
|
|
328
367
|
const { config, limiter, logger } = deps;
|
|
329
368
|
const doFetch = deps.fetchImpl ?? fetch;
|
|
@@ -353,7 +392,7 @@ async function fetchHtml(url, deps) {
|
|
|
353
392
|
});
|
|
354
393
|
status = response.status;
|
|
355
394
|
retryAfterMs = parseRetryAfter(response.headers.get("retry-after"));
|
|
356
|
-
body = await response.
|
|
395
|
+
body = await readBounded(response, config.maxBodyBytes, url);
|
|
357
396
|
} catch (error) {
|
|
358
397
|
lastError = asTransportError(error, url);
|
|
359
398
|
logger.debug(`${lastError.code} for ${url}: ${lastError.message}`);
|