@documonster/mcp 0.17.1 → 0.18.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.
@@ -0,0 +1,455 @@
1
+ /**
2
+ * `text_write` — upload a text file under @output/ in numbered parts.
3
+ *
4
+ * A tool argument has to be generated in full before the client sends the call,
5
+ * so no argument can be longer than one model reply. A long translation, a large
6
+ * JSON payload or thousands of rows of CSV therefore cannot travel in a single
7
+ * call, whatever the server does — the call is aborted on the client before this
8
+ * process ever sees it, and MCP has no streamed arguments to split it with.
9
+ *
10
+ * This tool is the one place that limit is lifted. Content arrives in parts, each
11
+ * small enough for one reply, and the finished file is an ordinary file every
12
+ * tool reads by path (`doc_write.from`, `template_fill.dataFrom`,
13
+ * `sheet_write.sheetsFrom`, `sheet_edit.opsFrom`, `form_fill.valuesFrom`, …).
14
+ *
15
+ * ## State model
16
+ *
17
+ * A session is a directory holding immutable part files and one manifest,
18
+ * `meta.json`. **The manifest is the only commit point.** A part's bytes go to a
19
+ * new, uniquely named file first; the manifest is then replaced atomically to
20
+ * point at it. A crash or failure between the two leaves an unreferenced file and
21
+ * the previous, still-consistent state — never a manifest describing bytes that
22
+ * are not there.
23
+ *
24
+ * Every change to content (a part's text, or `total`) increments `revision`.
25
+ * Publishing records the revision and the SHA-256 of what it wrote. So "is the
26
+ * published file current" is a comparison of two numbers, not a guess from the
27
+ * last call, and any call — including a bare status call — publishes whenever the
28
+ * upload is complete and the published revision is behind.
29
+ *
30
+ * Publishing writes the manifest twice: a `pending` record (revision and hash)
31
+ * just before the file is installed, and `published` just after. If the process
32
+ * dies between install and the second write, the next publish finds the file
33
+ * matching `pending` and knows it wrote it, rather than refusing it as someone
34
+ * else's.
35
+ *
36
+ * ## Guarantees
37
+ *
38
+ * - Nothing is published until parts 1…total are all present.
39
+ * - A late or retried call from an earlier upload carries that upload's id, so it
40
+ * cannot land in a newer upload's content.
41
+ * - Resending a part with identical text changes nothing.
42
+ * - The size limit is checked for the whole request before anything is written,
43
+ * and again from the manifest before every publish.
44
+ * - A republish replaces the file only if it still holds exactly what this upload
45
+ * wrote (by hash); otherwise it is refused and nothing is overwritten.
46
+ * - Calls on one session, and publishes to one destination, are serialised.
47
+ *
48
+ * ## Deliberate limits
49
+ *
50
+ * Serialisation is within this server process. Two server processes sharing one
51
+ * output root and one session could still race on the manifest, and a program
52
+ * that ignores this tool entirely can write the destination in the instant between
53
+ * the hash check and the rename; closing that needs an OS-level lock, and a
54
+ * single MCP client drives a single session. Two different texts sent for the same
55
+ * part concurrently leave whichever arrived last — the tool cannot know which the
56
+ * caller meant.
57
+ */
58
+ import { createHash, randomBytes } from "node:crypto";
59
+ import { createReadStream, createWriteStream } from "node:fs";
60
+ import { mkdir, readdir, readFile, rm, stat, unlink, utimes } from "node:fs/promises";
61
+ import path from "node:path";
62
+ import { z } from "zod";
63
+ import { formatToolError, toolError } from "../errors.js";
64
+ import { assertWritable, outputDisplay, resolveOutputPath } from "../sandbox.js";
65
+ import { exists, writeFileAtomic, writeWithPolicy } from "./fs-helpers.js";
66
+ import { formatBytes, textResult } from "./result.js";
67
+ import { defineTool } from "./types.js";
68
+ /** Where sessions live, below the output root; hidden so listings show real output. */
69
+ const UPLOADS_DIRECTORY = ".documonster-uploads";
70
+ /**
71
+ * Highest part number. Bounds the manifest, which lists every part, at a few
72
+ * hundred kilobytes — and at a few thousand words a part it is far beyond any
73
+ * document a model will write.
74
+ */
75
+ const MAX_PART = 10_000;
76
+ /** A session untouched this long is abandoned, and swept when a new one starts. */
77
+ const SESSION_TTL_MS = 24 * 60 * 60 * 1000;
78
+ const UPLOAD_ID = /^[0-9a-f]{20}$/;
79
+ /** The path, relative to --output-root, of a session's directory or one of its files. */
80
+ function sessionPath(id, file) {
81
+ return file === undefined ? `${UPLOADS_DIRECTORY}/${id}` : `${UPLOADS_DIRECTORY}/${id}/${file}`;
82
+ }
83
+ /**
84
+ * Resolve a file inside a session through the sandbox. The names are the server's
85
+ * own, but the directory sits in a writable root: a symlink planted where a part
86
+ * belongs must not make this tool read or write outside it.
87
+ */
88
+ function sessionFile(config, id, file) {
89
+ return resolveOutputPath(config, sessionPath(id, file));
90
+ }
91
+ async function readMeta(config, id) {
92
+ const file = await sessionFile(config, id, "meta.json");
93
+ const text = await readFile(file, "utf8").catch((cause) => {
94
+ if (cause.code === "ENOENT") {
95
+ throw toolError.notFound(`no upload session ${JSON.stringify(id)}`, "Sessions expire after 24 hours unused. Start a new one with path and total (and no upload).");
96
+ }
97
+ throw cause;
98
+ });
99
+ let meta;
100
+ try {
101
+ meta = JSON.parse(text);
102
+ }
103
+ catch (cause) {
104
+ throw toolError.invalidInput(`upload ${id} has an unreadable manifest`, "Something other than this tool changed the session. Start a new upload.", { cause });
105
+ }
106
+ if (meta.version !== 2) {
107
+ throw toolError.invalidInput(`upload ${id} was started by an incompatible version of this server`, "Start a new upload.");
108
+ }
109
+ return meta;
110
+ }
111
+ /** Commit a new manifest. Everything a call changes becomes visible here, at once. */
112
+ async function commit(config, id, meta) {
113
+ await writeFileAtomic(await sessionFile(config, id, "meta.json"), JSON.stringify(meta));
114
+ }
115
+ function partNumbers(meta) {
116
+ return Object.keys(meta.parts)
117
+ .map(Number)
118
+ .sort((a, b) => a - b);
119
+ }
120
+ function missingParts(meta) {
121
+ const missing = [];
122
+ for (let part = 1; part <= meta.total; part += 1) {
123
+ if (meta.parts[part] === undefined) {
124
+ missing.push(part);
125
+ }
126
+ }
127
+ return missing;
128
+ }
129
+ /** Bytes the published file would have: parts 1…total only. */
130
+ function includedSize(meta) {
131
+ let size = 0;
132
+ for (const [part, stored] of Object.entries(meta.parts)) {
133
+ if (Number(part) <= meta.total) {
134
+ size += stored.size;
135
+ }
136
+ }
137
+ return size;
138
+ }
139
+ /** Compress `[1,2,3,5]` to `1–3, 5` so a long session's report stays one line. */
140
+ function describeRanges(numbers) {
141
+ const ranges = [];
142
+ let index = 0;
143
+ while (index < numbers.length) {
144
+ const start = numbers[index];
145
+ let end = start;
146
+ while (numbers[index + 1] === end + 1) {
147
+ index += 1;
148
+ end += 1;
149
+ }
150
+ ranges.push(start === end ? String(start) : `${start}–${end}`);
151
+ index += 1;
152
+ }
153
+ return ranges.join(", ");
154
+ }
155
+ /**
156
+ * Run work one at a time per key.
157
+ *
158
+ * Keyed twice: by session, because a call reads the manifest, decides and commits,
159
+ * and two interleaved calls would each commit a manifest missing the other's part;
160
+ * and by destination, because two sessions publishing one path must not both pass
161
+ * the ownership check before either installs its file.
162
+ */
163
+ const queues = new Map();
164
+ function serialised(key, work) {
165
+ const previous = queues.get(key) ?? Promise.resolve();
166
+ const next = previous.then(work, work);
167
+ const settled = next.catch(() => undefined);
168
+ queues.set(key, settled);
169
+ void settled.then(() => {
170
+ if (queues.get(key) === settled) {
171
+ queues.delete(key);
172
+ }
173
+ });
174
+ return next;
175
+ }
176
+ /**
177
+ * Remove sessions nobody has touched within the TTL. Best effort: never fails a call.
178
+ *
179
+ * Every call on a session touches its directory, so "untouched" means no call at
180
+ * all — a status check or an unchanged resend counts. A session with a call in
181
+ * flight is skipped whatever its age.
182
+ */
183
+ async function sweepExpired(config) {
184
+ const root = await resolveOutputPath(config, UPLOADS_DIRECTORY);
185
+ const names = await readdir(root).catch(() => []);
186
+ const now = Date.now();
187
+ await Promise.all(names
188
+ .filter(name => UPLOAD_ID.test(name) && !queues.has(`session:${name}`))
189
+ .map(async (name) => {
190
+ const directory = path.join(root, name);
191
+ const modified = await stat(directory).then(info => info.mtimeMs, () => now);
192
+ if (now - modified > SESSION_TTL_MS) {
193
+ await rm(directory, { recursive: true, force: true }).catch(() => undefined);
194
+ }
195
+ }));
196
+ }
197
+ function withoutPending(meta) {
198
+ const { pending, ...rest } = meta;
199
+ void pending;
200
+ return rest;
201
+ }
202
+ async function sha256Of(file) {
203
+ const hash = createHash("sha256");
204
+ for await (const chunk of createReadStream(file)) {
205
+ hash.update(chunk);
206
+ }
207
+ return hash.digest("hex");
208
+ }
209
+ /**
210
+ * Assemble parts 1…total into the destination, streaming, and install it atomically.
211
+ *
212
+ * @returns The manifest after publishing.
213
+ */
214
+ async function publish(config, session, meta) {
215
+ const target = await resolveOutputPath(config, meta.path);
216
+ return serialised(`target:${target}`, async () => {
217
+ // Re-checked here, not only when a part arrives: total may have grown to take in
218
+ // parts that were stored while it was smaller and so were never counted.
219
+ const size = includedSize(meta);
220
+ if (size > config.maxFileSize) {
221
+ throw toolError.invalidInput(`${outputDisplay(meta.path)} would be ${size} bytes, over the ${config.maxFileSize} byte limit`, "Lower total, replace large parts, or ask the user to raise --max-file-size.");
222
+ }
223
+ // Replace an existing file only if it is one this upload wrote.
224
+ const ours = [meta.published?.sha256, meta.pending?.sha256].filter((value) => value !== undefined);
225
+ let replace = meta.overwrite;
226
+ if (ours.length > 0 && (await exists(target))) {
227
+ if (!ours.includes(await sha256Of(target))) {
228
+ throw toolError.invalidInput(`${outputDisplay(meta.path)} was changed by something else after this upload published it`, "Nothing was overwritten. Start a new upload to a different path, or with overwrite: true to replace it.");
229
+ }
230
+ replace = true;
231
+ }
232
+ const files = [];
233
+ for (let part = 1; part <= meta.total; part += 1) {
234
+ files.push(await sessionFile(config, session.id, meta.parts[part].file));
235
+ }
236
+ let pending;
237
+ await writeWithPolicy(target, replace, async (temporary) => {
238
+ const hash = createHash("sha256");
239
+ const output = createWriteStream(temporary);
240
+ try {
241
+ for (const file of files) {
242
+ for await (const chunk of createReadStream(file)) {
243
+ hash.update(chunk);
244
+ if (!output.write(chunk)) {
245
+ await new Promise(resolve => output.once("drain", resolve));
246
+ }
247
+ }
248
+ }
249
+ }
250
+ catch (cause) {
251
+ output.destroy();
252
+ throw cause;
253
+ }
254
+ await new Promise((resolve, reject) => {
255
+ output.end((error) => (error ? reject(error) : resolve()));
256
+ });
257
+ // Recorded before the file is installed, so a crash straight after installing
258
+ // still leaves this upload able to recognise the file as its own.
259
+ pending = { revision: meta.revision, sha256: hash.digest("hex") };
260
+ await commit(config, session.id, { ...meta, pending });
261
+ });
262
+ const published = { ...withoutPending(meta), published: pending };
263
+ await commit(config, session.id, published);
264
+ return published;
265
+ });
266
+ }
267
+ export const textWriteTool = defineTool({
268
+ name: "text_write",
269
+ group: "core",
270
+ title: "Upload a text file in parts",
271
+ description: "Upload a text file (.md, .json, .csv, .mmd, .txt …) to @output/ in numbered parts, for content too long for one call — a full translation, a long report, large JSON or CSV. One call carrying all of it can exceed your output limit and be aborted before it is sent, so keep each part to a few thousand words. Start with path, total and part 1 (no upload); the reply gives an upload id — pass it with every later part. The file is published only when parts 1…total are all present. Resend a part to replace it; call with just upload to see what is missing or to retry a failed publish. Then pass the file by path: doc_write `from`, template_fill `dataFrom`, sheet_write `sheetsFrom`, sheet_edit `opsFrom`, form_fill `valuesFrom`, diagram_render `from`.",
272
+ inputSchema: {
273
+ upload: z
274
+ .string()
275
+ .optional()
276
+ .describe("Upload id returned by the first call. Omit only to start a new upload."),
277
+ path: z
278
+ .string()
279
+ .min(1)
280
+ .optional()
281
+ .describe('Starting only: destination below --output-root, e.g. "report.md"; returned as @output/<path>.'),
282
+ total: z
283
+ .number()
284
+ .int()
285
+ .min(1)
286
+ .max(MAX_PART)
287
+ .optional()
288
+ .describe("How many parts the file has. Required to start; may be changed later if the plan changes."),
289
+ part: z
290
+ .number()
291
+ .int()
292
+ .min(1)
293
+ .max(MAX_PART)
294
+ .optional()
295
+ .describe("This part's number, from 1 to total. Parts are joined in number order."),
296
+ text: z
297
+ .string()
298
+ .optional()
299
+ .describe("This part's content, joined to its neighbours exactly as sent — end a Markdown part with a blank line."),
300
+ overwrite: z
301
+ .boolean()
302
+ .optional()
303
+ .describe("Starting only: replace an existing file at path. Defaults to false.")
304
+ },
305
+ annotations: {
306
+ readOnlyHint: false,
307
+ destructiveHint: false,
308
+ // Not idempotent: a call without `upload` starts a new session every time.
309
+ idempotentHint: false,
310
+ openWorldHint: false
311
+ },
312
+ mutates: true,
313
+ handler: async (args, context) => {
314
+ const { config } = context;
315
+ assertWritable(config);
316
+ if ((args.part === undefined) !== (args.text === undefined)) {
317
+ throw toolError.invalidInput("`part` and `text` go together", "Send a part as { part, text }, or neither to only start a session or check its status.");
318
+ }
319
+ const session = args.upload === undefined ? await start(config, args) : await open(config, args);
320
+ return serialised(`session:${session.id}`, async () => {
321
+ // Read inside the queue: an earlier call may have committed since `open`.
322
+ let meta = await readMeta(config, session.id);
323
+ await utimes(session.directory, new Date(), new Date()).catch(() => undefined);
324
+ meta = await apply(config, session, meta, args);
325
+ const missing = missingParts(meta);
326
+ const size = includedSize(meta);
327
+ let state;
328
+ if (missing.length > 0) {
329
+ state = `**not published yet** — waiting for part(s) ${describeRanges(missing)}`;
330
+ }
331
+ else if (meta.published?.revision !== meta.revision) {
332
+ // Decided from the manifest, not from what this call did: a status call
333
+ // after a failed publish retries it. A failure is reported rather than
334
+ // thrown because the part is already committed — an error would read as
335
+ // "this part was lost" and invite a pointless resend.
336
+ try {
337
+ meta = await publish(config, session, meta);
338
+ state = `**published** ${outputDisplay(meta.path)} (${formatBytes(size)}) — pass it by path to the tool that uses it`;
339
+ }
340
+ catch (cause) {
341
+ state = `**not published — publishing failed**: ${formatToolError(cause)}\n- every part is stored; resolve that, then call { upload: "${session.id}" } to publish`;
342
+ }
343
+ }
344
+ else {
345
+ state = `published ${outputDisplay(meta.path)} (${formatBytes(size)}); up to date`;
346
+ }
347
+ const beyond = partNumbers(meta).filter(part => part > meta.total);
348
+ const included = partNumbers(meta).length - beyond.length;
349
+ return textResult(config, [
350
+ `Upload **${session.id}** → ${outputDisplay(meta.path)}: ${included} of ${meta.total} part(s) stored.`,
351
+ `- ${state}`,
352
+ ...(beyond.length > 0
353
+ ? [
354
+ `- part(s) ${describeRanges(beyond)} are beyond total ${meta.total} and are not included`
355
+ ]
356
+ : []),
357
+ ...(missing.length > 0 ? [`- continue with { upload: "${session.id}", part, text }`] : [])
358
+ ].join("\n"));
359
+ });
360
+ }
361
+ });
362
+ /**
363
+ * Apply one call's changes — a new total, a part, or both — as a single commit.
364
+ *
365
+ * Everything is validated against the state the call would produce before anything
366
+ * is written, so a rejected call changes nothing at all.
367
+ */
368
+ async function apply(config, session, meta, args) {
369
+ const total = args.total ?? meta.total;
370
+ let parts = meta.parts;
371
+ let replaced;
372
+ let changed = total !== meta.total;
373
+ if (args.part !== undefined && args.text !== undefined) {
374
+ if (args.part > total) {
375
+ throw toolError.invalidInput(`part ${args.part} is beyond total ${total}`, "Raise total in this same call if the file really has more parts.");
376
+ }
377
+ const bytes = Buffer.from(args.text, "utf8");
378
+ const previous = meta.parts[args.part];
379
+ const unchanged = previous !== undefined &&
380
+ previous.size === bytes.byteLength &&
381
+ (await readFile(await sessionFile(config, session.id, previous.file))).equals(bytes);
382
+ if (!unchanged) {
383
+ assertWithinLimit(config, {
384
+ ...meta,
385
+ total,
386
+ parts: { ...meta.parts, [args.part]: { file: "", size: bytes.byteLength } }
387
+ });
388
+ // A new file for every version, so the manifest still pointing at the old one
389
+ // stays true until the commit below replaces it.
390
+ const file = `${String(args.part).padStart(5, "0")}.${randomBytes(6).toString("hex")}`;
391
+ await writeFileAtomic(await sessionFile(config, session.id, file), bytes);
392
+ parts = { ...meta.parts, [args.part]: { file, size: bytes.byteLength } };
393
+ replaced = previous?.file;
394
+ changed = true;
395
+ }
396
+ }
397
+ // Checked for the state the call produces whatever it carried: a new total with an
398
+ // unchanged part, or with no part at all, can bring earlier parts back into range.
399
+ if (parts === meta.parts && total !== meta.total) {
400
+ assertWithinLimit(config, { ...meta, total });
401
+ }
402
+ if (!changed) {
403
+ return meta;
404
+ }
405
+ const next = { ...meta, total, parts, revision: meta.revision + 1 };
406
+ await commit(config, session.id, next);
407
+ if (replaced !== undefined) {
408
+ // Only after the commit: until then the old file is what the manifest names.
409
+ await unlink(await sessionFile(config, session.id, replaced)).catch(() => undefined);
410
+ }
411
+ return next;
412
+ }
413
+ /** Refuse a state whose published file would exceed the size limit. Writes nothing. */
414
+ function assertWithinLimit(config, meta) {
415
+ const size = includedSize(meta);
416
+ if (size > config.maxFileSize) {
417
+ throw toolError.invalidInput(`${outputDisplay(meta.path)} would be ${size} bytes, over the ${config.maxFileSize} byte limit`, "Nothing was changed. Lower total, replace large parts, or ask the user to raise --max-file-size.");
418
+ }
419
+ }
420
+ /** Begin a session: validate the destination now, so a doomed upload fails on part 1. */
421
+ async function start(config, args) {
422
+ if (args.path === undefined || args.total === undefined) {
423
+ throw toolError.invalidInput("starting an upload needs `path` and `total`", 'e.g. { path: "report.md", total: 6, part: 1, text: "…" }. To continue an upload, pass its `upload` id instead.');
424
+ }
425
+ const target = await resolveOutputPath(config, args.path);
426
+ if (args.overwrite !== true && (await exists(target))) {
427
+ throw toolError.invalidInput(`${outputDisplay(args.path)} already exists`, "Pass overwrite: true to replace it, or choose a different path.");
428
+ }
429
+ await sweepExpired(config);
430
+ const id = randomBytes(10).toString("hex");
431
+ const directory = await resolveOutputPath(config, sessionPath(id));
432
+ await mkdir(directory, { recursive: true });
433
+ await commit(config, id, {
434
+ version: 2,
435
+ path: args.path,
436
+ total: args.total,
437
+ overwrite: args.overwrite === true,
438
+ revision: 0,
439
+ parts: {}
440
+ });
441
+ return { id, directory };
442
+ }
443
+ /** Continue a session named by id. */
444
+ async function open(config, args) {
445
+ const id = args.upload;
446
+ if (!UPLOAD_ID.test(id)) {
447
+ throw toolError.invalidInput(`${JSON.stringify(id)} is not an upload id`, "Pass the id exactly as the first call returned it.");
448
+ }
449
+ const meta = await readMeta(config, id);
450
+ if (args.path !== undefined && args.path !== meta.path) {
451
+ throw toolError.invalidInput(`upload ${id} writes ${outputDisplay(meta.path)}, not ${outputDisplay(args.path)}`, "Omit path when continuing an upload, or start a new upload for a different file.");
452
+ }
453
+ return { id, directory: await resolveOutputPath(config, sessionPath(id)) };
454
+ }
455
+ //# sourceMappingURL=text-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-write.js","sourceRoot":"","sources":["../../src/tools/text-write.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@documonster/mcp",
3
- "version": "0.17.1",
3
+ "version": "0.18.0",
4
4
  "description": "Model Context Protocol server for documonster — lets AI assistants read, write and convert Excel, Word, PDF, CSV and ZIP documents.",
5
5
  "keywords": [
6
6
  "ai",
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@modelcontextprotocol/sdk": "^1.30.0",
52
- "documonster": "0.17.1",
52
+ "documonster": "0.18.0",
53
53
  "zod": "^4.4.3"
54
54
  },
55
55
  "devDependencies": {