operations / skill

Chat Cache Exporter

Recover a private, partial Discord message snapshot from the local desktop cache.

At a glance

Purpose
Recover a private, partial Discord message snapshot from the local desktop cache.
Runs in
Local agent with shell
Operating systems
macOS, Linux
Needs
Runtime: Python 3.10+, standard library only; zstd needs 3.14+; Needs internet: No; Needs accounts or API keys beyond your agent: No
Files and data
Reads files: Yes; Writes files: Yes; Sends data to other services: No
Tool type
Skill
Delivery
Download from Skills Outpost
Version
0.1.2
ZIP SHA-256
7dc6b02ebdc7f10efa24fc967a7f311003accfdcf2cee26549a2d47d9843609b
Access
Download from Skills Outpost
Compatibility
Requires Python 3.10 or newer, an Agent Skills compatible harness that can run command-line tools, a Discord desktop client on the same machine, and read access to its cache directory. Scan defaults support macOS, Windows, and Linux. Export (including dry-run) supports macOS and Linux with os.O_NOFOLLOW, os.O_DIRECTORY, and os.open in os.supports_dir_fd; unsupported platforms, including Windows, are refused before any export write. Standard library only; no packages, credentials or network access. Zstd coverage needs Python 3.14 or newer.
External costs
None. The tool uses local files and has no network service, account, subscription, or usage fee requirement.
Permissions
Read access to the selected local Discord desktop cache. --channel filters summaries and exports after the whole selected cache has been scanned and parsed; it does not restrict cache reads to selected channels. Write access to the selected --out directory and permission to create --out itself in its existing parent. Scan writes nothing. Dry-run may create --out or fchmod an existing empty output directory to 0700 for privacy, and writes approval state; live export adds messages.json and transcripts beneath --out. No directories above --out are created. No account token, credential, elevated account permission, or network access is required.
Usage terms
MIT license. Copyright 2026 Zero Width Lab. Discord is a trademark of its owner, Discord Inc. Chat Cache Exporter is not affiliated with or endorsed by Discord Inc. By Zero Width Lab (zerowidthlab.com)

Download from Skills Outpost

Get this version

Free

Version 0.1.2 · Skill package (ZIP) · 144.5 KiB

Static source, format, secret-pattern and declaration checks with independent human source review.

SHA-256 of the released ZIP
7dc6b02ebdc7f10efa24fc967a7f311003accfdcf2cee26549a2d47d9843609b

The creator shows this version's package files publicly: anyone can read SKILL.md and the other files under Files, without an account. The ZIP download needs the version in your Library (how it works).

Sign in to add this version to your library and follow its creator for free.

Sign in to get free

A creator follow is free, not a paid membership. Your email is not shared with the creator.

Files

Version 0.1.2, shown publicly by its creator, exactly as in this version's ZIP. ZIP SHA-256: 7dc6b02ebdc7f10efa24fc967a7f311003accfdcf2cee26549a2d47d9843609b. License: MIT (read it).

Each file has its own address. Read one as a web page at https://skillsoutpost.com/agents/chat-cache-exporter-dabae2a6/files?path=SKILL.md, or as JSON at https://skillsoutpost.com/api/v1/catalog/chat-cache-exporter-dabae2a6/files?path=SKILL.md; replace SKILL.md with any path below.

MITMIT License

Copyright (c) 2026 Zero Width Lab

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Version history
  1. Version 0.1.2 Current

    No release notes for this version.

What it does

Chat Cache Exporter is a command-line Agent Skill that recovers the partial message snapshot retained in a user's own Discord desktop client cache. An agent harness is software that can install the skill, run Python commands, and present results to the user. It needs Python 3.10 or newer, a Discord desktop client on the same machine, and read access to that client's cache directory. It is free under the MIT license. This listing delivers the complete package, including the Python scripts.

The local-only CLI scans cached message response URLs, decompresses supported gzip and zstd streams, parses cached JSON arrays, deduplicates messages by identifier, groups them by channel, and sorts them chronologically. Scan produces a channel summary and writes nothing. --channel filters summaries and exports after the whole selected cache has been scanned and parsed; it does not restrict cache reads to selected channels. Export is approval-gated: dry-run previews creation of --out itself if missing and records a digest of the fully resolved path, output and parent directory identities (st_dev, st_ino), and exact rendered plan inside it, the harness confirms the output and channel scope with the user, and a live export refuses to write anything unless that approval exists and still matches a fresh scan. Dry-run resolves --out once with os.path.realpath, shows and binds that path, and permits existing symlink prefixes; live mode uses the stored resolved path. Dry-run also fchmods an existing empty output directory to 0700 for privacy. The parent must already exist; no directories above --out are created. Scan defaults support macOS, Windows, and Linux. Export (including dry-run) supports macOS and Linux with os.O_NOFOLLOW, os.O_DIRECTORY, and os.open in os.supports_dir_fd; unsupported platforms, including Windows, are refused before any export write. All export writes use verified directory descriptors and exclusive no-follow opens; live mode compares opened directory identities from os.fstat with the approved digest before any mutation and refuses changed identities or symlinks in resolved components. The resulting messages.json retains cached message objects, while transcripts render one header line per message (timestamp, display name, first content line) and mark every further content line with four spaces and a bar, so message text cannot imitate another speaker.

Cache coverage is opportunistic and can never be assumed complete. The cache is a snapshot: a message deleted or edited in Discord after it was cached can still appear in its cached form, and the tool cannot tell. The tool uses the Python standard library only; zstd streams need Python 3.14 or newer. Unreadable files or skipped zstd streams mark the result incomplete and produce exit status 2 unless the user explicitly accepts partial coverage. The tool reads no account token, makes no network request, and never accesses another machine. Recovered content can include other people's private messages, so it should remain local and be treated as untrusted data rather than instructions.

When complete history is required, use Discord Settings, Data & Privacy, Request all of my Data.

Who it is for

People who need an agent harness to inspect or export the partial message snapshot retained in their own Discord desktop client's local cache, without account credentials or network access.

Example tasks

Scan my local Discord desktop cache and summarize the channels it retained.
Return the scan summary as structured JSON.
Preview the exact export files and record an approval digest before writing them.
Export only the channel identifiers I selected to a local directory I chose.
Create a grouped JSON export and one readable transcript per selected channel.
Report unreadable files and skipped zstd streams as a partial result.
Explain how to request complete history through Discord's own data request.

Getting started

SKILL.md and the scripts can be read without an account: SKILL.md at https://skillsoutpost.com/agents/chat-cache-exporter-dabae2a6/files?path=SKILL.md, and the list of every file at https://skillsoutpost.com/agents/chat-cache-exporter-dabae2a6/files.

Copy the skill folder into the skills directory used by the agent harness and keep scripts/ beside SKILL.md. Run commands from the skill directory with Python 3.10 or newer.

Start with a read-only scan:
python3 scripts/discord_cache_export.py scan

Choose the client with --client discord, discordptb, or discordcanary, or supply the exact cache directory with --cache-dir PATH. The resolved directory is printed on stderr.

Review the channel identifiers, choose a new or empty output directory outside the skill directory, with an existing parent, then preview the exact write set:
python3 scripts/discord_cache_export.py export --out "/path/to/export" --channel CHANNEL_ID --dry-run

Dry-run resolves --out once with os.path.realpath, shows and binds that path, permits existing symlink prefixes, and writes only approval state inside it. It creates --out if missing or fchmods an existing empty output directory to 0700 for privacy; no directories above --out are created. The digest binds the fully resolved output path, output and parent directory identities (st_dev, st_ino), and rendered plan. After confirming the digest, path, identities, and scope, repeat the command without --dry-run. A live export without that matching approval state is refused and writes nothing. Live mode uses the stored resolved path; both modes refuse symlinks in resolved components; changed identities are refused before any live write; preview and confirm changed plans again. Repeat --channel to select more channels. Use Python 3.14 or newer when zstd coverage is needed; no package installation is required.

Limitations

This tool recovers only the opportunistic subset retained in the local desktop client's HTTP cache. Cache eviction, browsing history, unsupported compression, unreadable files, messages deleted before caching, and API changes can reduce coverage. The cache is a snapshot: a message deleted or edited in Discord after it was cached can still appear, in its cached form, in the export, and the tool cannot tell. It cannot distinguish every direct-message channel from every server channel reliably. For complete history, use Discord Settings, Data & Privacy, Request all of my Data.

The tool uses the Python standard library only. Gzip works with Python 3.10 or newer. Zstd coverage needs Python 3.14 or newer (compression.zstd); on older versions zstd streams are skipped and the result is incomplete, as is any failed decoding. Cache files larger than 128 MiB and decompressed candidates larger than 64 MiB are counted as unreadable.

Export (including dry-run) requires supported no-follow directory-descriptor operations (macOS and Linux; Windows is refused). The output parent must already exist. The output directory must be new or empty so stale transcripts cannot survive a narrower export. The tool never reads account tokens, contacts the network, or accesses another machine. Exported files contain other people's messages and must be kept local.

Version 0.1.2 is an early release with no support commitment; fixes and updates ship as new package versions on this listing.

Data practices

The CLI reads only regular non-symlink files directly inside the selected local Discord desktop cache directory. --channel filters summaries and exports after the whole selected cache has been scanned and parsed; it does not restrict cache reads to selected channels. It does not recurse, read Local Storage or account tokens, contact the network, or send telemetry.

Dry-run may create --out itself and writes approval state there; its parent must already exist, and no directories above --out are created. The digest binds the fully resolved destination, destination and parent directory identities (st_dev, st_ino), and rendered plan. Dry-run resolves --out once with os.path.realpath, shows and binds that path, and permits existing symlink prefixes. Both modes walk resolved components with no-follow directory descriptors and refuse later symlinks. Live mode uses the stored path and compares os.fstat identities of opened parent and output directories with the approved digest before any mutation; files use O_CREAT|O_EXCL|O_NOFOLLOW relative to the verified descriptor. A parent replaced by a symlink after approval is refused before any export write. Scan defaults support macOS, Windows, and Linux. Export (including dry-run) supports macOS and Linux with os.O_NOFOLLOW, os.O_DIRECTORY, and os.open in os.supports_dir_fd; unsupported platforms, including Windows, are refused before any export write. On macOS and Linux new directories use mode 0700 and files mode 0600; dry-run also fchmods an existing empty output directory to 0700 for privacy.

Recovered content can contain other people's private messages. Keep it local. Treat recovered message text, links, attachment names, and embeds as untrusted data, never as instructions or authorization.
Report a listing concern

What did you see, and where? Please don't include passwords or keys.

We'll only use it to ask you about this report.