Modify archive (incremental, no recompression)
modify_zipEdit existing ZIP archives without recompression to add, replace, remove, rename entries, or set comments; choose append for byte-preserving saves or compact to drop removed data.
Instructions
Edit an existing archive without recompressing anything: operations add / replace / remove / rename / setComment applied in order. mode 'append' (default) = save(): the original bytes stay verbatim and edits are appended — fast and byte-preserving, BUT removed or replaced payloads REMAIN in the file (data remanence: recoverable by anyone; a ZIP_DEAD_BYTES_RATIO diagnostic fires past 50 % dead bytes, and 7-Zip is known to read the stale payload). mode 'compact' = saveCompact(): a rewrite without the dead bytes, entries SORTED by raw name bytes (an insertion-ordered layout — EPUB mimetype first, JAR manifest first — is not kept; 'append' keeps it), still no recompression, removed data truly gone, SFX prefix dropped; add canonical: {…} for the canonical deterministic form (zipnative 1.1.0, the canonicalize_zip rules applied after the edits). No edits and an unchanged comment return the same bytes (summary.noOp). The input is opened eagerly and, in 'append' mode, every entry is cross-checked against its local header and declared sizes before its bytes are re-emitted (ZIP_ENTRY_OVERLAP / ZIP_CD_LFH_MISMATCH / ZIP_LIMIT_EXCEEDED). Entry names travel verbatim (an unsafe name stays unsafe — extract_zip sanitises on the way out). Archives with duplicate entry names are refused — prefer create_zip for a full rebuild or when the source has duplicate names. Output base64 or a sandbox file.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"operations": "<operations>"
},
"name": "modify_zip"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | 'append' (default): save() — original bytes verbatim + appended entries + new central directory; removed/replaced payloads REMAIN in the file (data remanence). 'compact': saveCompact() — a rewrite without recompression, entries sorted by raw name bytes, removed data truly gone, SFX prefix dropped (add `canonical` for the canonical deterministic form). | append |
| limits | No | Per-call override of zipnative's security bounds (CWE-400/409); absent keys keep the engine defaults (describe_engine.defaultLimits). A value above its operator ceiling is LIMIT_CEILING_EXCEEDED. Raise only for trusted input. | |
| strict | No | Turn the first engine diagnostic into a ZIP_STRICT_DIAGNOSTIC error. | |
| zipPath | No | Archive path relative to the ZIPNATIVE_MCP_OUTPUT_DIR sandbox (container extensions: .zip .jar .docx .epub …). Exclusive with zipBase64; saves re-sending bytes between calls. | |
| canonical | No | mode 'compact' only (zipnative 1.1.0 saveCompact({ canonical })): after the edits, rewrite every entry into the canonical deterministic form — sorted by raw name bytes, one timestamp, UTF-8 flags, Zip64-only extras, version-made-by 0x032D — still without recompression. `{}` takes the defaults. The same rules as canonicalize_zip. | |
| zipBase64 | No | Archive bytes, base64 (≤ 128 MiB decoded). Exclusive with zipPath. | |
| operations | Yes | Edits applied in order. add: new entry (ZIP_ENTRY_EXISTS if present); replace: existing entry (ZIP_ENTRY_NOT_FOUND otherwise); remove; rename (never overwrites: remove the target first); setComment. | |
| outputMode | No | 'base64' (default): inline embedded resource (≤ 50 MiB; the bytes appear in both its data: uri and its blob). 'file': written into the sandbox (never overwrites; ≤ ZIPNATIVE_MCP_MAX_FILE_OUTPUT_BYTES, default 4 GiB) and returned as a resource_link — far fewer tokens. | base64 |
| outputPath | No | Relative path inside the sandbox (only when outputMode='file'); must end in a container extension (.zip recommended). | |
| compression | No | Compression settings. `method` 'deflate' (default) or 'store'; `level` 0–9 (default 6); `deterministic: true` pins the pure-TS encoder so the bytes are identical on every runtime (slower). | |
| defaultDate | No | Timestamp for entries that set no `date`: an ISO-8601 instant (1980-01-01 … 2107-12-31, 2-second DOS granularity) or 'now' (wall clock — emits the ZIP_TIMESTAMP_NOT_PINNED diagnostic and makes the bytes non-reproducible). Omitted: the DOS epoch 1980-01-01T00:00:00 (reproducible). | |
| includeSha256 | No | Add `summary.sha256` of the produced bytes. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | ||
| summary | Yes | modify_zip summary. | |
| filePath | No | Sandboxed absolute path (file mode). | |
| sizeBytes | Yes | ||
| diagnostics | Yes | Non-fatal engine concerns (de-duplicated by code + entry, ≤ 200; codes in describe_engine.diagnosticCodes). Empty for a clean archive. | |
| diagnosticCounts | No | Occurrences per code, duplicates included. | |
| diagnosticsTruncated | No | true when rows beyond 200 were dropped. |