Skip to content

zsnoop-mcp

Ask your AI assistant things like:

  • โช "Recover my .zshrc from before I committed the rewrite three weeks ago."
  • ๐Ÿงน "Which snapshots older than 6 months are wasting the most space?"
  • ๐Ÿ”Ž "When did the directory /srv/backups first appear on this host?"
  • โŒ› "Find everything deleted under /home/youruser in the last week, and show me when each thing was last present."
  • ๐Ÿฅ "Are any of my pools throwing disk errors? When was the last scrub?"

An MCP server for read-only exploration of ZFS snapshots on remote hosts.

Browse, diff, search, and read files from any snapshot on any of your ZFS hosts through your AI assistant, over a single persistent SSH connection per host. No mutation operations are ever exposed.

What lives in these docs

  • Onboarding tutorial

    A guided walk through the codebase, from "what's MCP?" all the way to "here's how to add a new tool end-to-end". Targeted at developers new to the project โ€” every section is structured what / why / how with real code excerpts.

  • Install & configure

    Get the server running locally, decide on user-mode vs sudo-mode per host, set up ZFS delegation, and wire into Claude Code.

  • Usage examples

    Concrete LLM prompts grouped by workflow: file recovery, config drift audits, forensic dives.

  • Security model

    Threat model, the six guarantees, where each is enforced in code, and the test that asserts it.

  • Publishing

    PyPI release flow โ€” manual via uv publish or trusted publishing via CI.

Architecture in 30 seconds

MCP client (Claude Code, โ€ฆ)
        โ”‚
        โ”‚  MCP (stdio: JSON-RPC + content blocks)
        โ–ผ
zsnoop-mcp server (local, async Python)
        โ”‚
        โ”‚  one persistent subprocess per host,
        โ”‚  carrying line-delimited JSON-RPC over its stdio
        โ–ผ
zfs-snoop-agent (remote, stdlib-only Python)
        โ”‚
        โ”‚  zfs / zpool subprocess; POSIX walks under .zfs/snapshot/
        โ–ผ
ZFS pool on the host

Three layers. The agent and the server share nothing but a JSON-RPC wire protocol, which is what makes the transport pluggable (SSH today, local process today, in principle anything that gives you a bidirectional byte-stream).