Skip to main content
Glama
zipnative-mcp

zipnative-mcp

Scan forward (truncated / unseekable streams — NOT authoritative)

scan_zip_forward
Read-onlyIdempotent

Scan ZIP local headers in stream order with bounded memory to inventory truncated or mid-stream archives; use tolerateTruncation for partial forensic results when the central directory is missing.

Instructions

Walk LOCAL headers in stream order with bounded memory (zipnative's central-directory-less reader). The only tool that works on a truncated archive or a stream cut mid-way (it cannot skip an SFX prefix: the stream must start at a local header) — and the only one whose result is NOT authoritative: forward iteration trusts local headers ALONE, so a hostile archive can present different content here than inspect_zip / list_zip_entries report (the upload-scanner differential). Prefer those tools whenever the whole archive is available; use this one for forensics (tolerateTruncation:true returns the partial inventory + error). data 'none' skips payloads, 'verify' decompresses to check CRCs, 'include' returns them (inline caps). stoppedAt tells you whether a central directory was reached. Names are NOT sanitized — sanitizedPath shows what the extraction gate would use.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "scan_zip_forward"
  }
}

Input Schema

NameRequiredDescriptionDefault
dataNo'none' (default): skip payloads (a data-descriptor entry still costs a full decompress-and-discard); 'verify': decompress every kept entry so CRC and sizes are checked; 'include': also return the content as base64 (inline caps apply).none
fieldsNoDot-paths to keep, after verbosity (e.g. ['entryCount', 'entries.name']); unmatched ones are listed in _meta.unmatchedFields.
filterNoSelect entries: `names` (exact), `prefix`, `glob` (`*` in a segment, `**` across, `?`, `[a-z]`; no `/` = any depth, trailing `/` = subtree), ANDed; `includeDirectories` (default false).
limitsNoPer-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.
strictNoTurn the first engine diagnostic into a ZIP_STRICT_DIAGNOSTIC error.
zipPathNoArchive path relative to the ZIPNATIVE_MCP_OUTPUT_DIR sandbox (container extensions: .zip .jar .docx .epub …). Exclusive with zipBase64; saves re-sending bytes between calls.
verbosityNo'summary': scalar verdict fields only (the token-frugal form).full
zipBase64NoArchive bytes, base64 (≤ 128 MiB decoded). Exclusive with zipPath.
maxEntriesNoStop after this many local headers (bounded work on an unbounded stream). Default 10000, clamped to the operator ceiling ZIPNATIVE_MCP_MAX_ENTRIES; an explicit value above the ceiling is refused (LIMIT_CEILING_EXCEEDED).
tolerateTruncationNotrue: a truncated / corrupt stream ends the scan with `stoppedAt:"error"` and the partial inventory (forensics) instead of failing the call.

Output Schema

NameRequiredDescriptionDefault
errorNo
namesNosummary only: the kept entry names.
trustNoConstant reminder: nothing here was cross-checked against a central directory.
entriesNo
keptCountNo
stoppedAtNo'central-directory' is the normal end of a complete archive; 'eof' means the stream ended before any central directory (truncated or CD-less); 'max-entries' means more local headers remained.
truncatedNotrue when the stream ended without reaching a central directory.
entryCountNoLocal headers seen (before the filter).
inputBytesNo
maxEntriesNoThe header budget in force (after clamping to the operator ceiling).
diagnosticsNoNon-fatal engine concerns (de-duplicated by code + entry, ≤ 200; codes in describe_engine.diagnosticCodes). Empty for a clean archive.
bytesDeliveredNoBytes handed to the forward reader.
diagnosticCountNosummary only: number of distinct diagnostics.
diagnosticCountsNoOccurrences per code, duplicates included.
diagnosticsTruncatedNotrue when rows beyond 200 were dropped.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed25 schema fields changedv1.0.1
    • changedInput schema / properties / fields / description
      Previous value: -"Dot-path projection applied after verbosity (e.g. ['entryCount', 'entries.name']); array segments map over elements; unmatched paths are reported in _meta.unmatchedFields."New value: +"Dot-paths to keep, after verbosity (e.g. ['entryCount', 'entries.name']); unmatched ones are listed in _meta.unmatchedFields."
    • addedInput schema / properties / fields / items / pattern
      Added value: +"^(?!(?:[^.]*\\.)*(?:__proto__|constructor|prototype)(?:\\.|$)).+$"
    • changedInput schema / properties / filter / description
      Previous value: -"Select entries by name. `names` (exact, case-sensitive), `prefix` (path prefix) and `glob` (patterns: `*` within a segment, `**` across segments, `?` one character; a pattern without `/` matches at any depth, a trailing `/` matches a whole subtree) are ANDed when several are given; `includeDirectories` (default false) keeps explicit directory entries."New value: +"Select entries: `names` (exact), `prefix`, `glob` (`*` in a segment, `**` across, `?`, `[a-z]`; no `/` = any depth, trailing `/` = subtree), ANDed; `includeDirectories` (default false)."
    • changedInput schema / properties / filter / properties / glob / description
      Previous value: -"Glob patterns; an entry matching ANY pattern is kept (e.g. ['**/*.json', 'docs/'])."New value: +"Patterns (≤ 1024 characters); ANY match keeps the entry (e.g. ['**/*.json', 'docs/'])."
    • addedInput schema / properties / filter / properties / glob / items / maxLength
      Added value: +1024
    • changedInput schema / properties / limits / description
      Previous value: -"Override zipnative's named security bounds for this call (CWE-400 / CWE-409 guards). Every key is optional; absent keys keep the engine defaults (maxEntries 100000, maxEntryUncompressedSize 1 GiB, maxTotalUncompressedSize 8 GiB, maxCompressionRatio 1024, maxNameBytes 4096, maxExtraFieldBytes 65535, maxCommentBytes 65535, maxCentralDirectoryBytes 256 MiB). Values above the operator ceilings (ZIPNATIVE_MCP_MAX_UNCOMPRESSED_BYTES, ZIPNATIVE_MCP_MAX_ENTRIES) are refused with LIMIT_CEILING_EXCEEDED. Raise a bound for trusted input only."New value: +"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."
    • changedInput schema / properties / limits / properties / maxCentralDirectoryBytes / description
      Previous value: -"Maximum central-directory size in bytes."New value: +"Bytes."
    • changedInput schema / properties / limits / properties / maxCommentBytes / description
      Previous value: -"Maximum comment length in bytes."New value: +"Bytes."
    • changedInput schema / properties / limits / properties / maxCompressionRatio / description
      Previous value: -"Maximum declared uncompressed/compressed ratio for entries >= 1 KiB compressed (zip-bomb guard)."New value: +"Declared ratio (entries ≥ 1 KiB compressed)."
    • changedInput schema / properties / limits / properties / maxEntries / description
      Previous value: -"Maximum central-directory entry count."New value: +"Entries."
    • addedInput schema / properties / limits / properties / maxEntryCompressedSize
      Added value: +{
      +  "description": "Bytes, one compressed payload fetched by the byte-range reader (access range).",
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • changedInput schema / properties / limits / properties / maxEntryUncompressedSize / description
      Previous value: -"Maximum decompressed size of one entry, bytes."New value: +"Bytes, one entry decompressed."
    • changedInput schema / properties / limits / properties / maxExtraFieldBytes / description
      Previous value: -"Maximum extra-field block length in bytes."New value: +"Bytes."
    • changedInput schema / properties / limits / properties / maxNameBytes / description
      Previous value: -"Maximum entry-name length in bytes."New value: +"Bytes."
    • changedInput schema / properties / limits / properties / maxTotalUncompressedSize / description
      Previous value: -"Maximum total decompressed size across an extraction, bytes."New value: +"Bytes, all entries decompressed."
    • changedInput schema / properties / strict / description
      Previous value: -"Escalate the first engine diagnostic (prepended data, duplicate name, name mismatch, …) to a ZIP_STRICT_DIAGNOSTIC error instead of reporting it."New value: +"Turn the first engine diagnostic into a ZIP_STRICT_DIAGNOSTIC error."
    • changedInput schema / properties / verbosity / description
      Previous value: -"'summary' returns only the scalar verdict fields (drops arrays and payloads) — the token-frugal form."New value: +"'summary': scalar verdict fields only (the token-frugal form)."
    • changedInput schema / properties / zipBase64 / description
      Previous value: -"The archive bytes as base64 (exactly once; a data: URI prefix is tolerated). Exclusive with zipPath. Decoded size ≤ 128 MiB."New value: +"Archive bytes, base64 (≤ 128 MiB decoded). Exclusive with zipPath."
    • changedInput schema / properties / zipPath / description
      Previous value: -"Relative path of an archive inside the ZIPNATIVE_MCP_OUTPUT_DIR sandbox (no absolute paths, no '..'; container extensions only: .zip .jar .docx .epub …). Exclusive with zipBase64. Lets a create/modify → verify/extract chain avoid re-sending the bytes."New value: +"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."
    • changedOutput schema / properties / diagnosticCounts / description
      Previous value: -"Number of diagnostics received per code (counts every occurrence, including de-duplicated ones)."New value: +"Occurrences per code, duplicates included."
    • changedOutput schema / properties / diagnostics / description
      Previous value: -"Non-fatal conformance concerns the engine raised while parsing or writing (de-duplicated by code + entry, at most 200). Empty for a clean archive. Codes: ZIP_PREPENDED_DATA, ZIP_MULTIPLE_EOCD, ZIP_NAME_MISMATCH, ZIP_UNICODE_PATH_CONFLICT, ZIP_INVALID_UTF8_NAME, ZIP_DUPLICATE_NAME, ZIP_EXTRA_FIELD_MALFORMED, ZIP_ZIP64_EXTRA_IGNORED, ZIP_TIMESTAMP_NOT_PINNED, ZIP_NONDETERMINISTIC_CODEC, ZIP_DEAD_BYTES_RATIO."New value: +"Non-fatal engine concerns (de-duplicated by code + entry, ≤ 200; codes in describe_engine.diagnosticCodes). Empty for a clean archive."
    • changedOutput schema / properties / diagnosticsTruncated / description
      Previous value: -"Present (true) when more than 200 distinct diagnostics were dropped from `diagnostics`."New value: +"true when rows beyond 200 were dropped."
    • addedOutput schema / properties / entries / items / properties / extendedTimestamps
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "With includeExtendedTimestamps: modification / access / creation instants (ISO-8601, UTC) from the UT (0x5455) extra, else the NTFS (0x000a) extra, else the DOS fields (source names which); a missing one is null.",
      +  "properties": {
      +    "atime": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "ctime": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "mtime": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "source": {
      +      "enum": [
      +        "ut",
      +        "ntfs",
      +        "dos"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedOutput schema / properties / entries / items / properties / nameEncoding / enum
      Previous value: -[
      -  "utf-8",
      -  "cp437"
      -]New value: +[
      +  "utf-8",
      +  "cp437",
      +  "custom"
      +]
    • addedOutput schema / properties / entries / items / properties / unixIds
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "With includeUnixIds: the Unix owner uid / gid from the Info-ZIP ux (0x7875) extra; null when the archive carries none.",
      +  "properties": {
      +    "gid": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "uid": {
      +      "minimum": 0,
      +      "type": "integer"
      +    }
      +  },
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  2. First observedv1.0.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnly/idempotent/non-destructive; the description goes far beyond, disclosing bounded memory, that results are NOT authoritative, the hostile-archive differential versus the authoritative tools, and the `tolerateTruncation`/`stoppedAt` forensics behavior. It also warns names are unsanitized and `sanitizedPath` shows what the extraction gate would use.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the scoping constraint and the warning about non-authoritative results, and every sentence carries information that isn't in structured fields. It is dense—long em-dash-chained sentences—but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter tool with nested objects, an output schema, and full annotation coverage, the description supplies the missing decision-level context: why results differ from authoritative tools, truncation handling, and unsanitized names. Return-value detail is correctly delegated to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real semantics beyond the schema: the three `data` modes are explained in terms of cost and CRC checking, `tolerateTruncation:true` is tied to the partial inventory + `error`, and `stoppedAt` is explained as a central-directory-reached signal. Minor gap: `limits`/`strict`/`fields` are left entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('walk LOCAL headers in stream order') plus the distinguishing mechanism ('central-directory-less reader'). It explicitly names siblings inspect_zip and list_zip_entries and explains how the result differs from theirs, so an agent can tell it apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Prefer those tools whenever the whole archive is available; use this one for forensics' gives an explicit when-to-use and when-not-to-use rule with named alternatives. It also names the concrete precondition (stream must start at a local header; cannot skip an SFX prefix) that would disqualify it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.