v0.5.0 · MIT · Rust

Archives are file trees. Stop extracting to look inside.

A unified archive access layer for AI agents and humans. Inspect and stream archive contents before choosing to extract them.

12 format families · schema_version "1" · macOS + Linux CI

~/datasets — zsh
$ arcthis inspect dataset.zip archive: dataset.zip format: zip compression: mixed entries: 7 compressed size: 201315 uncompressed size: 200124 random access: true $ arcthis tree dataset.zip dataset.zip └── dataset ├── README.md ├── docs │ └── notes.md └── train ├── data.csv └── labels.csv $ arcthis read dataset.zip dataset/train/labels.csv id,label 1,cat 2,dog 3,bird
01 — Quickstart

From clone to first inspect in three commands.

v0.5 ships as source — no crates.io package or prebuilt binaries yet. RAR support statically links libarchive; see Download for platform dependencies.

install — zsh
$ git clone https://github.com/mkynyd/arcthis.git $ cd arcthis $ cargo build --release --locked $ ./target/release/arcthis --version arcthis 0.5.0
02 — Signature moves

One grammar. Every format. Nothing extracted by default.

The same arcthis <command> <archive> [entry] shape works across ZIP, 7z, RAR, TAR and the single-stream codecs. Every session below is real output from Arcthis 0.5.0.

move / 01

Query entries without decoding

find applies glob filters to normalized entry metadata. Content is never decoded, so path discovery stays cheap even on multi-gigabyte archives.

find
$ arcthis find dataset.zip --glob '**/*.csv' dataset/train/labels.csv dataset/train/data.csv
move / 02

Search contents in place

grep streams regular files with entry-size, line, match-count and binary bounds. Nothing is written to disk while you search.

grep
$ arcthis grep dataset.zip TODO --glob '**/*.md' dataset/docs/notes.md:1:TODO: fill in preprocessing notes dataset/README.md:3:Sample training bundle. TODO: document the schema.
move / 03

Integrity as a stream

hash pipes one entry through SHA-256 or SHA-512; verify checks the structure and every readable entry in a single full-stream pass.

hash · verify
$ arcthis hash dataset.zip dataset/train/data.csv 3307d48518fd5bc59980caee9f4833a1aef4a3ae7f16ef4102a132b719d947c2 dataset/train/data.csv $ arcthis verify dataset.zip verified 7 entries (200124 bytes)
move / 04

Writes are planned transactions

pack, extract and convert emit typed --dry-run plans, stage into a sibling location, verify, and only then commit.

pack --dry-run
$ arcthis pack ./dataset --output dataset.tar.zst --dry-run dry-run pack plan source: ~/demo/dataset destination: dataset.tar.zst format: tar_zstd entries: 7 estimated bytes: 200124 collision: false will skip: false delete source after success: false
move / 05

Archives inside archives

Repeatable --within descends through inner archives as bounded in-memory sources — up to 8 levels, no named temporary file ever created.

tree --within
$ arcthis tree backup.zip --within project.tar.gz backup.zip::project.tar.gz └── dataset ├── README.md ├── docs │ └── notes.md └── train ├── data.csv └── labels.csv
move / 06

Structured by default, for agents

Every query command speaks schema-versioned JSON on --json: stable fields, typed errors on stderr, deterministic exit codes.

stat --json
$ arcthis stat dataset.zip dataset/train/labels.csv --json {"schema_version":"1","archive":{"path":"dataset.zip","path_lossy":false,"format":"zip"},"entry":{"archive_index":5,"path":"dataset/train/labels.csv","path_encoding":"utf8","kind":"file","size":28,"compressed_size":28,"modified_time":"2026-08-30T01:05:30","encrypted":false,"executable":false,"symlink_target":null,"crc32":"9e6ad3e5","mime_guess":"text/csv"}}
03 — Formats

Twelve families, one archive model.

Detection is content-first: misleading extensions never override valid signatures. Backends own format quirks; commands see one uniform model with honest capability flags.

FormatAccess / extractCreateAccess model
zipStored/Deflate, including ZipCrypto/AES decryptionDeflate, unencryptedRandom entry access
7zYes, including AES decryptionLZMA2, unencryptedBlock/solid dependent
rar / rar5Read/extract through libarchiveread-onlySequential
tarYesyesSequential
tar.gz / tgzYesyesSequential decompression
tar.bz2 / tbz2YesyesSequential decompression
tar.xz / txzYesyesSequential decompression
tar.zst / tzstYesyesSequential decompression
gzipOne implicit entryyesSequential
bzip2One implicit entryyesSequential
xzOne implicit entryyesSequential
zstdOne implicit entryyesSequential
04 — Agent interface

JSON is the contract. Stable fields, versioned schema.

  • Real structured output. Every successful response is one JSON document with schema_version: "1". Field names and types are a public, versioned interface.
  • Strict stream separation. Results on stdout; diagnostics, warnings and errors on stderr. read emits raw entry bytes and rejects --json.
  • Typed failures. Machine errors are JSON with stable codes, mapped to deterministic process exit codes.
  • Honest costs. inspect reports capabilities like random_access and solid, so an agent can reason about what an operation will cost.
response envelope — schema_version "1"
{
  "schema_version": "1",
  "archive": {
    "path": "dataset.zip",
    "path_lossy": false,
    "format": "zip"
  }
}
unsupported_format invalid_archive corrupted_archive entry_not_found unsafe_path resource_limit password_required wrong_password collision verification_failed partial_failure io_error
05 — Safety model

Safe before convenient, by default.

Untrusted archives are hostile input. Every write path is conservative, validated and transactional — convenience flags exist, but they are always explicit.

paths

Unified path sanitizer

Extraction rejects .., absolute paths, Windows drive/UNC prefixes, NUL bytes, and links that could escape the destination.

writes

Staging then commit

Output lands in a sibling staging location and commits only after every entry succeeds. A failure never leaves a partial result posing as success.

collisions

Refuse by default

Existing destinations are refused unless you pass exactly one explicit policy: --overwrite, --skip-existing or --rename.

deletion

Source deleted last

--delete-source runs only after perform → finalize → verify → commit. Any error, interrupt or failed verification keeps the source.

06 — MCP

The same semantics, straight into your agent runtime.

  • Bounded stdio server. Optional feature-gated MCP frontend, pinned to revision 2025-06-18, with strict stdout separation.
  • Nine read-only tools for inspect, list, tree, stat, read, find, grep, hash and verify — always available under an explicit --allow-root.
  • Six mutation tools (extract/pack/convert plan + execute) appear only with an --allow-output-root policy.
  • Stale plans fail closed. A SHA-256 plan digest is invalidated when source or destination state changes before execution.
mcp — zsh
$ cargo build --release --locked --features mcp $ arcthis mcp --allow-root ./archives # read-only tools only $ arcthis mcp --allow-root ./archives --allow-output-root ./outputs # plan/execute mutation tools become visible

Access before extraction.

Build v0.5.0 from source and inspect your first archive in under a minute.

$ cargo install --path . --locked