# Evergist: full documentation > Evergist shares text through end-to-end encrypted links that expire. Encryption happens on the client (browser, CLI, or local MCP server). The server stores only ciphertext and cannot read notes. No accounts, no cookies, no request logs. This file concatenates the agent skill, the documentation pages, and the blog. Short index: https://evergist.com/llms.txt --- # Evergist Evergist stores text as ciphertext it cannot read. Encryption happens on this machine. The share link carries the key after `#`, so whoever has the full link can read the note until it expires or runs out of views, and nobody else can, including Evergist. Everything below uses the Evergist CLI through `npx`. It needs Node.js 20 or newer and has no other dependencies. Write the full command each time; shell variables don't carry over between tool calls. If you run many commands, `npm install -g evergist` gives you a plain `evergist` command instead. ## Prefer this over pasting secrets If you're about to put a password, token, key, or `.env` contents into a chat message, PR comment, issue, commit, or log, create a gist instead and share only the link. ## Share text ```sh # From a file npx -y evergist create path/to/file --views 1 --expires 1h --json # From stdin printf '%s' "$SECRET" | npx -y evergist create --views 1 --expires 1h --json # With a generated password (returned as "password" in the JSON) printf '%s' "$SECRET" | npx -y evergist create --views 1 --expires 1d --generate-password --json ``` The JSON output has `url`, `id`, `expiresAt`, `maxViews`, `deleteToken`, and `password` when generated. Options: - `--expires`: `10m`, `1h`, `1d`, `7d`, `30d`, or seconds. Default `1d`. Max `30d`. - `--views`: delete after this many reads, 1 to 1000. Default: no limit until expiry. - `--password ` or `EVERGIST_PASSWORD`: require a password as well as the link. - `--generate-password`: create a strong password and print it. Limit: 512 KiB of UTF-8 text per note. Split or compress larger content, or share a smaller excerpt. ## Tell the user After creating a gist, reply with: - The full link, including everything after `#`. - When it expires, from `expiresAt` (for example "expires in 1 hour, at 14:00 UTC"). - The view limit: "opens once, then it's deleted", "3 views", or "no view limit". - The password, if there is one, and a reminder to send it through a different channel than the link. - Which settings you picked yourself when the user didn't say, so they can ask for different ones. Don't repeat the note's contents, or any secret you found in them, including values you redacted. ## Read a gist ```sh npx -y evergist read "https://evergist.com/g/#" # prints the text, uses one view npx -y evergist read "https://evergist.com/g/#" --password "" npx -y evergist read "https://evergist.com/g/#" --json # text plus expiresAt, viewsRemaining, burned npx -y evergist status "https://evergist.com/g/#" # expiry and views left, does NOT use a view ``` If `burned` is true, that was the last view and the note is gone from the server. Keep the text you received if you still need it. A read can be the last one, so don't pipe it straight into a parser or a config file. Save the output first (`... read "" > /tmp/note.txt`), check what's in it, and extract what you need from the saved copy. Notes often hold a label or several lines around the value, not just the value. Delete the temporary file when you're done. ## Delete a gist ```sh npx -y evergist delete "https://evergist.com/g/#" # with the link (add --password if set) npx -y evergist delete --token # with the delete token from create ``` ## Rules 1. Always give the recipient the full URL, including everything after `#`. Without it the note can't be decrypted. 2. For credentials and other secrets, use `--views 1` and a short `--expires` such as `1h` or `1d`. 3. If you use a password, deliver it through a different channel than the link, or tell the user to. 4. After creating a gist, report the link, expiry, view limit, and password as described above. Don't repeat the secret itself. 5. Keep `deleteToken` out of shared channels. Give it only to the user who created the note. 6. Reading uses a view. Use `status` if you only need to check that a link still works. 7. Never paste secrets into the command line as arguments when stdin or a file will do. Arguments can end up in shell history and process lists. ## If the CLI isn't an option - MCP: `npx -y evergist mcp` runs a local MCP server with `create_gist`, `read_gist`, `gist_status`, and `delete_gist`. - JavaScript with URL imports (Deno, Bun, browsers): `import { createGist, readGist } from "https://evergist.com/sdk/evergist.js"`. - Any language: follow the REST API and encryption scheme at https://evergist.com/docs/api/ and https://evergist.com/security/. There is no hosted endpoint that accepts plaintext. Don't send secrets to any service claiming to be an Evergist proxy. --- # How Evergist keeps notes unreadable, including to us > How Evergist encrypts notes in your browser with AES-256-GCM, keeps the key in the URL fragment, stores only ciphertext, and how you can verify it. Source: https://evergist.com/security/ Updated: 2026-09-29 Every claim on this page can be checked from your own browser or terminal. Here's the design, what the server holds, what it never sees, and where the limits are. ## The short version - Your device encrypts the note with **AES-256-GCM** before anything is uploaded. - The 256-bit key lives in the link after the `#`. Browsers don't send that part of a URL to any server, so we never receive it. - The server stores the ciphertext, an expiry time, a view counter, and two token hashes. That's the whole record. - We don't store IP addresses, browser details, cookies, or referrers. Request logging is off. - Notes are deleted at their expiry time or right after their last allowed view. - Lose the link and the note is gone. We can't recover it, and neither can anyone who breaks into our servers. ## What happens when you create a note 1. Your browser generates a random 32-byte key, `K`, with the Web Crypto API. 2. If you set a password, the browser stretches it with PBKDF2-SHA256 (600,000 iterations) and mixes it into the key material. 3. It derives an encryption key and two access tokens from that material with HKDF-SHA256. 4. It encrypts your text with AES-256-GCM under a fresh random 12-byte IV. 5. It uploads the IV, the ciphertext, the SHA-256 hashes of the tokens, and your expiry and view settings. 6. The server replies with an ID. Your browser builds the link `https://evergist.com/g/#` and shows it to you. The plaintext, `K`, and your password never leave your device. The server can't derive them from the hashes it keeps. ## What happens when someone opens it 1. Their browser reads `K` from the part after `#` and derives the **access token**. 2. It asks for the note's status, sending the access token. Without that token, the server answers exactly as if the note didn't exist. 3. If the note has a password, the browser derives a **password proof** from `K` and the password. 4. It requests the ciphertext with the access token and, if needed, the proof. This request uses one view. 5. It decrypts locally. If that was the last allowed view, the server deletes the note before responding. Someone who knows only the note's ID, say from a proxy that saw the URL path, can't read the ciphertext, can't learn when it expires, and can't burn its views. ## The encryption scheme This is version 1 of the scheme, exactly as the code implements it. ```text K = 32 random bytes (in the URL fragment) pwSalt = HKDF-SHA256(K, info="evergist/v1/pbkdf2-salt", L=16) pwKey = PBKDF2-HMAC-SHA256(NFC(password), pwSalt, 600000, L=32) ikm = K || pwKey if a password is set = K otherwise encKey = HKDF-SHA256(ikm, info="evergist/v1/enc", L=32) access = HKDF-SHA256(K, info="evergist/v1/access", L=32) proof = HKDF-SHA256(ikm, info="evergist/v1/password", L=32) (password only) iv = 12 random bytes ct = AES-256-GCM(encKey, iv, plaintext, aad="evergist/v1") ``` HKDF uses an empty salt. All binary values travel as unpadded base64url. The server stores `SHA-256(access)` and `SHA-256(proof)` as hex, and compares them in constant time. A few choices worth explaining: - **The key is in the fragment, not the query string.** Browsers strip everything after `#` from HTTP requests, and it doesn't appear in the `Referer` header either. - **The access token gates the ciphertext.** It's derived from `K`, so only someone holding the link can fetch the encrypted bytes. Offline attacks on the ciphertext need the link first. - **The password proof is separate.** A wrong access token costs nothing: guessing 256 bits isn't possible. A wrong password counts toward a limit of 10. On the tenth miss the note deletes itself, which stops online guessing. - **The password salt comes from `K`.** Each note gets a unique salt that the server never sees, so the server can't precompute anything against your password. - **AES-GCM authenticates.** If a single bit of the stored ciphertext changes, decryption fails loudly instead of showing altered text. ## What the server stores Each note is its own [Durable Object](https://developers.cloudflare.com/durable-objects/) on Cloudflare. Durable Objects handle one request at a time, which makes view counting exact: two people can't both get the last view. This is the complete stored record: | Field | Example | Purpose | |---|---|---| | `body` | 4,213 bytes of ciphertext | The encrypted note | | `iv` | `q1w2e3r4t5y6u7i8` | AES-GCM nonce, not secret | | `accessHash` | `9f86d081...` | SHA-256 of the access token | | `proofHash` | `60303ae2...` or absent | SHA-256 of the password proof | | `deleteHash` | `2c26b46b...` | SHA-256 of the creator's delete token | | `password`, `iterations` | `true`, `600000` | Tells the reader to ask for a password | | `expiresAt` | `2026-10-06T12:00:00Z` | When the note is deleted | | `maxViews`, `viewsRemaining` | `1`, `1` | View limit | | `failedAttempts` | `0` | Wrong passwords so far | There is no creator field, no IP address, no user agent, no timestamp of reads, and no index linking notes to each other or to anyone. An alarm fires at `expiresAt` and wipes the record. A read that uses the last view wipes it immediately. ## What we don't collect - **No IP addresses in storage or logs.** The Worker has Cloudflare's observability, invocation logs, and Logpush turned off. - **No cookies.** The site sets none, first party or third party. - **No analytics scripts.** No Google Analytics, no tag managers, no pixels, no session replay. - **No third-party requests at all.** Fonts and icons are served from evergist.com. The Content-Security-Policy header only allows the page to connect to evergist.com. We keep three public counters per day: page loads, notes created, and notes read. They're plain integers with no identifiers attached. You can see them on the [stats page](https://evergist.com/stats/). ### What Cloudflare can see We're honest about our host. Evergist runs on Cloudflare, and like any network provider Cloudflare handles your IP address to route the connection and to block attacks. The per-minute rate limiter uses your IP as an in-memory key for 60 seconds at the Cloudflare location that served you. The hourly limit on creating notes keeps a salted hash of your IP in memory for up to two hours, and the salt itself only exists in memory. Neither is ever written to storage. Cloudflare never sees the key in the fragment, your password, or the plaintext, because none of those are ever transmitted. ## Verify it yourself You don't have to trust this page. Here are four ways to check it. ### 1. Watch the network Open your browser's developer tools, switch to the Network tab, and create a note. You'll see one request to `/api/v1/gists`. Its body contains `iv`, `ciphertext`, and a couple of hashes. Your text isn't there, and neither is anything that appears after `#` in the link you get back. ### 2. Read the code that runs The site's JavaScript isn't minified. In developer tools, open the Sources tab and read the `create` and `view` scripts. The encryption code is the same library the command line tool uses. ### 3. Check the headers Run this and look at `content-security-policy`: ```sh curl -sI https://evergist.com/ | grep -i -E 'content-security-policy|set-cookie|referrer-policy' ``` `connect-src 'self'` means the page can't send data to any other domain. There's no `set-cookie` line. ### 4. Decrypt with code we didn't write This Python script reads a note using nothing but the scheme above and the `cryptography` package. If it can decrypt your note, the design works as described. [Download it](https://evergist.com/examples/evergist_read.py). ```python import base64, hashlib, json, sys, unicodedata, urllib.request from urllib.parse import urlsplit from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.ciphers.aead import AESGCM from cryptography.hazmat.primitives.kdf.hkdf import HKDF b64d = lambda s: base64.urlsafe_b64decode(s + "=" * (-len(s) % 4)) b64e = lambda b: base64.urlsafe_b64encode(b).rstrip(b"=").decode() hkdf = lambda ikm, info, n: HKDF(hashes.SHA256(), n, None, info.encode()).derive(ikm) def get(url, token): headers = {"authorization": f"Bearer {token}", "user-agent": "evergist-verify/1"} req = urllib.request.Request(url, headers=headers) return json.load(urllib.request.urlopen(req)) link, password = sys.argv[1], (sys.argv[2] if len(sys.argv) > 2 else None) parts = urlsplit(link) api = f"{parts.scheme}://{parts.netloc}/api/v1/gists/{parts.path.rstrip('/').split('/')[-1]}" key = b64d(parts.fragment) access = b64e(hkdf(key, "evergist/v1/access", 32)) status = get(f"{api}/status", access) ikm, token = key, access if status["password"]: salt = hkdf(key, "evergist/v1/pbkdf2-salt", 16) pw = unicodedata.normalize("NFC", password).encode() ikm = key + hashlib.pbkdf2_hmac("sha256", pw, salt, status["iterations"], 32) token = f"{access}.{b64e(hkdf(ikm, 'evergist/v1/password', 32))}" sealed = get(api, token) # uses one view aes = AESGCM(hkdf(ikm, "evergist/v1/enc", 32)) print(aes.decrypt(b64d(sealed["iv"]), b64d(sealed["ciphertext"]), b"evergist/v1").decode()) ``` ## Limits and trade-offs No design is perfect. These are the ones we know about. - **You trust the page you load.** Like every browser-based encryption tool, the JavaScript comes from our server. If our server were compromised, an attacker could serve altered code. The strict CSP, the lack of third-party scripts, and readable code make that detectable, not impossible. For the highest assurance, encrypt with the [command line tool](https://evergist.com/agents/) or the Python script above, which run code you can pin and inspect. - **Anyone with the link can read the note.** The link is the key. If you paste it into a chat that keeps history, the note is readable until it expires or runs out of views. Use a one-view limit and a short expiry, or add a password and send it separately. - **Size isn't hidden.** AES-GCM doesn't pad, so the ciphertext length reveals the plaintext length to within 16 bytes. - **Your browser history keeps the link.** The fragment is stored locally like any URL. Once a one-view note is read, the link is useless anyway. - **Timing is visible to our host.** Cloudflare can see that some IP connected at some time, as it can for any site it serves. ## Reporting a vulnerability Email [contact@evergist.com](mailto:contact@evergist.com). Our [security.txt](https://evergist.com/.well-known/security.txt) has the details. We'll reply quickly and credit you if you'd like. --- # Share secrets with AI agents > Let AI agents share API keys, passwords, and handoff notes through encrypted, self-destructing links. Local MCP server, CLI, SKILL.md, and REST API. Source: https://evergist.com/agents/ Updated: 2026-09-29 Agents hand credentials, logs, and handoff notes to people and to each other. Evergist gives them a way to do that without leaving secrets in chat history, and the encryption happens on the agent's own machine. ## When an agent should use Evergist Reach for Evergist whenever an agent needs to pass text that shouldn't live forever in a transcript, a ticket, or a chat log: - An API key, database password, or token that a person or another agent needs once - A `.env` file or config for a teammate's machine - Logs or stack traces that contain customer data - A handoff note between agents running in different sandboxes - Anything the user asks to "send privately" or "share securely" The agent gets a link like `https://evergist.com/g/7mQx2Ld9KpTa#Zm9v...`. Whoever has the full link can read the note until it expires or runs out of views. Nobody else can, including Evergist. ## Pick an integration | Integration | Best for | Needs | |---|---|---| | [MCP server](#mcp-server) | Claude, Cursor, Codex, and other MCP clients | Node.js 20+ | | [SKILL.md](#skill) | Agents that load skills or read instructions from URLs | A shell with Node.js 20+ | | [CLI](#command-line) | Scripts, CI jobs, terminals | Node.js 20+ | | [JavaScript module](#javascript-module) | Deno, Bun, browsers, Workers | Web Crypto | | [REST API](https://evergist.com/docs/api/) | Any language | Your own AES-GCM and HKDF | Every option encrypts before anything goes over the network. There's no hosted endpoint that accepts plaintext. ## MCP server The MCP server runs locally over stdio, so plaintext and keys stay on the machine running the agent. `npx` fetches the [`evergist` package](https://www.npmjs.com/package/evergist) from npm, so there's nothing to install first. If you'd rather not go through the npm registry, evergist.com serves the same package: replace `evergist` with `https://evergist.com/cli/evergist.tgz` in any command below. **Claude Code** ```sh claude mcp add evergist -- npx -y evergist mcp ``` **Codex CLI** ```sh codex mcp add evergist -- npx -y evergist mcp ``` **Claude Desktop, Cursor, Windsurf, and other clients** use the same JSON: ```json { "mcpServers": { "evergist": { "command": "npx", "args": ["-y", "evergist", "mcp"] } } } ``` ### Tools | Tool | What it does | Uses a view? | |---|---|---| | `create_gist` | Encrypts `text` and returns `url`, `expiresAt`, `maxViews`, `deleteToken`. Options: `expires_in` (`10m` to `30d`), `max_views` (1 to 1000), `password`, `generate_password` | No | | `read_gist` | Decrypts a gist from its full `url` (plus `password` if set) | Yes | | `gist_status` | Shows expiry, views left, and whether a password is needed | No | | `delete_gist` | Deletes by `url`, or by `id` plus `delete_token` | No | ## Skill The skill file teaches an agent when and how to use Evergist with the CLI. Agents can read it directly from [evergist.com/SKILL.md](https://evergist.com/SKILL.md). To install it for Claude Code: ```sh mkdir -p ~/.claude/skills/evergist curl -fsSL https://evergist.com/SKILL.md -o ~/.claude/skills/evergist/SKILL.md ``` Other agents that support skills or `AGENTS.md`-style instructions can use the same file. You can also paste this line into an agent's instructions: ```text To share secrets or private text, use Evergist. Read https://evergist.com/SKILL.md first. ``` ## Command line The CLI is the same [`evergist` npm package](https://www.npmjs.com/package/evergist). Run it with `npx -y evergist`, or install it once with `npm install -g evergist` and use `evergist` directly. ```sh # Share a file, readable once, gone in an hour npx -y evergist create .env --views 1 --expires 1h # Pipe text in, add a generated password, get JSON back echo "root password: correct-horse" | npx -y evergist create -g --json # Read a gist (uses one view) npx -y evergist read "https://evergist.com/g/#" # Check it without using a view, or delete it npx -y evergist status "https://evergist.com/g/#" npx -y evergist delete "https://evergist.com/g/#" ``` The CLI is a single file with no dependencies. If you'd rather pin it, download [evergist.mjs](https://evergist.com/cli/evergist.mjs), read it, and run it with `node evergist.mjs`. | Option | Meaning | |---|---| | `-e, --expires` | `10m`, `1h`, `1d`, `7d`, `30d`, or seconds. Default `1d`, max `30d` | | `-v, --views` | Delete after this many reads, 1 to 1000. Default: no limit | | `-p, --password` | Add a password. `EVERGIST_PASSWORD` works too and keeps it out of shell history | | `-g, --generate-password` | Generate a strong password and print it | | `--json` | Machine-readable output | | `--base-url` | Another Evergist server. `EVERGIST_URL` works too | ## JavaScript module Runtimes that can import from a URL can use the client library directly. It runs anywhere Web Crypto does. ```js import { createGist, readGist } from "https://evergist.com/sdk/evergist.js"; const gist = await createGist({ text: "deploy key: ...", maxViews: 1, expiresIn: 3600 }); console.log(gist.url); // share this const { text } = await readGist(gist.url); ``` ## Why there's no hosted MCP endpoint A remote MCP server would receive your text before encrypting it. That would make "we can't read it" a promise instead of a fact. So the MCP server runs on your machine and talks to the API with ciphertext only. If an agent probes `https://evergist.com/mcp`, it gets a JSON message pointing here. ## Good habits for agents - **Share the whole link.** The key is the part after `#`. Without it the note can't be opened. - **Use `max_views: 1` for credentials.** The first read burns the note, so a leaked link is useless afterwards. - **Keep expiry short.** An hour or a day is plenty for most handoffs. - **Send passwords separately.** If you add one, deliver it through a different channel than the link. - **Don't echo the secret back.** After creating a gist, report the link, not the contents. - **Keep the delete token private.** It deletes the gist without needing the link. --- # REST API > Create, read, and delete end-to-end encrypted, expiring notes over HTTP. Endpoints, errors, limits, and a complete Web Crypto example. Ciphertext only. Source: https://evergist.com/docs/api/ Updated: 2026-09-29 A small JSON API for storing and fetching ciphertext. You encrypt before you call it, so the server never sees your text. No API key, no account. ## Before you start The API only moves ciphertext. To create a gist you need to run the [v1 encryption scheme](https://evergist.com/security/#the-encryption-scheme) on your side: generate a key, derive an encryption key and tokens with HKDF, and encrypt with AES-256-GCM. If you'd rather not implement that, use the [CLI, MCP server, or JavaScript module](https://evergist.com/agents/), which do it for you. - **Base URL:** `https://evergist.com/api/v1` - **Format:** JSON in, JSON out. Binary values are unpadded base64url. - **Auth:** none to create. Reads use a bearer token derived from the link key. - **CORS:** open to all origins. No cookies are used. - **Machine-readable spec:** [openapi.json](https://evergist.com/openapi.json) ## Create a gist `POST /api/v1/gists` ```json { "v": 1, "iv": "3q2-7wAAAAAAAAAA", "ciphertext": "k0Qb...base64url...", "accessHash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "password": false, "expiresIn": 3600, "maxViews": 1 } ``` | Field | Type | Notes | |---|---|---| | `v` | `1` | Scheme version | | `iv` | string | 12 bytes, base64url (16 characters) | | `ciphertext` | string | AES-256-GCM output with the 16-byte tag, base64url. At most 512 KiB plus 16 bytes when decoded | | `accessHash` | string | Hex SHA-256 of the access token | | `password` | boolean | Whether a password is mixed into the key | | `proofHash` | string | Hex SHA-256 of the password proof. Required when `password` is true, forbidden otherwise | | `iterations` | integer | PBKDF2 iterations, 100,000 to 10,000,000. Required when `password` is true. Clients use 600,000 | | `expiresIn` | integer | Seconds until deletion, 60 to 2,592,000 (30 days). Default 86,400 | | `maxViews` | integer or null | Reads allowed before deletion, 1 to 1,000. `null` means no limit. Default `null` | Response `201 Created`: ```json { "id": "7mQx2Ld9KpTa", "url": "https://evergist.com/g/7mQx2Ld9KpTa", "expiresAt": "2026-09-29T13:00:00.000Z", "maxViews": 1, "deleteToken": "Hq3...43 characters..." } ``` Build the share link by appending `#` and the base64url link key to `url`. Keep `deleteToken` private: it deletes the gist without the link. ## Check a gist's status `GET /api/v1/gists/{id}/status` with `Authorization: Bearer ` Doesn't use a view. Readers call this first to learn whether they need a password. ```json { "id": "7mQx2Ld9KpTa", "password": true, "iterations": 600000, "maxViews": 1, "viewsRemaining": 1, "expiresAt": "2026-09-29T13:00:00.000Z" } ``` ## Read a gist `GET /api/v1/gists/{id}` with `Authorization: Bearer ` The read token is the access token, or `access.proof` when the gist has a password. This call uses one view. If it was the last one, the gist is deleted before the response is sent and `burned` is `true`. ```json { "id": "7mQx2Ld9KpTa", "v": 1, "iv": "3q2-7wAAAAAAAAAA", "ciphertext": "k0Qb...", "password": false, "maxViews": 1, "viewsRemaining": 0, "burned": true, "expiresAt": "2026-09-29T13:00:00.000Z" } ``` A wrong password proof returns `401` with `attemptsRemaining`. After 10 wrong attempts the gist deletes itself. ## Delete a gist `DELETE /api/v1/gists/{id}` with `Authorization: Bearer ` Returns `204 No Content`. The creator can use the delete token. A reader can use the same read token they'd use to open it. ## Other endpoints | Endpoint | Returns | |---|---| | `GET /api/v1` | A short index of endpoints | | `GET /api/v1/health` | `{ "ok": true }` | | `GET /api/v1/stats` | The public daily counters: page loads, gists created, gists read | ## Errors Errors share one shape: ```json { "error": "not_found", "message": "Gist not found. It expired, reached its view limit, was deleted, or the link key is wrong." } ``` | Status | `error` | When | |---|---|---| | 400 | `invalid_json`, `invalid_request` | The body is malformed or a field is out of range. `message` says which | | 401 | `invalid_password` | Wrong password proof. Includes `attemptsRemaining` | | 404 | `not_found` | Gone, never existed, or a wrong access token. These look identical on purpose | | 413 | `too_large` | Plaintext over 512 KiB | | 415 | `unsupported_media_type` | Missing `content-type: application/json` | | 429 | `rate_limited` | Over a rate limit. `message` says which. Wait and retry | ## Limits | Limit | Value | |---|---| | Plaintext size | 512 KiB (524,288 bytes) of UTF-8 | | Expiry | 1 minute to 30 days | | View limit | 1 to 1,000, or none | | Wrong passwords | 10, then the gist is deleted | | Creates | 10 per minute and 120 per hour from one network | | Reads and deletes | 120 per minute from one network | ## Complete example with Web Crypto This runs as is in Node.js 20+, Deno, Bun, and modern browsers. It creates a gist and reads it back. ```js const API = "https://evergist.com/api/v1"; const enc = new TextEncoder(); const b64 = (b) => btoa(String.fromCharCode(...new Uint8Array(b))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); const unb64 = (s) => Uint8Array.from(atob(s.replace(/-/g, "+").replace(/_/g, "/")), (c) => c.charCodeAt(0)); const hex = (b) => [...new Uint8Array(b)].map((x) => x.toString(16).padStart(2, "0")).join(""); async function hkdf(ikm, info, bytes) { const key = await crypto.subtle.importKey("raw", ikm, "HKDF", false, ["deriveBits"]); const params = { name: "HKDF", hash: "SHA-256", salt: new Uint8Array(0), info: enc.encode(info) }; return new Uint8Array(await crypto.subtle.deriveBits(params, key, bytes * 8)); } async function keysFor(k) { const aes = await crypto.subtle.importKey("raw", await hkdf(k, "evergist/v1/enc", 32), "AES-GCM", false, ["encrypt", "decrypt"]); const access = b64(await hkdf(k, "evergist/v1/access", 32)); return { aes, access }; } // Create const k = crypto.getRandomValues(new Uint8Array(32)); const { aes, access } = await keysFor(k); const iv = crypto.getRandomValues(new Uint8Array(12)); const aad = enc.encode("evergist/v1"); const ct = await crypto.subtle.encrypt({ name: "AES-GCM", iv, additionalData: aad }, aes, enc.encode("hello from Web Crypto")); const res = await fetch(`${API}/gists`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ v: 1, iv: b64(iv), ciphertext: b64(ct), accessHash: hex(await crypto.subtle.digest("SHA-256", unb64(access))), password: false, expiresIn: 3600, maxViews: 1, }), }); const created = await res.json(); const link = `${created.url}#${b64(k)}`; console.log(link); // Read (uses the one allowed view) const key = unb64(new URL(link).hash.slice(1)); const r = await keysFor(key); const sealed = await (await fetch(`${API}/gists/${created.id}`, { headers: { authorization: `Bearer ${r.access}` } })).json(); const pt = await crypto.subtle.decrypt({ name: "AES-GCM", iv: unb64(sealed.iv), additionalData: aad }, r.aes, unb64(sealed.ciphertext)); console.log(new TextDecoder().decode(pt), sealed.burned); ``` Password-protected gists add PBKDF2 on top. The [security page](https://evergist.com/security/#the-encryption-scheme) has the exact derivation, and the [Python reader](https://evergist.com/examples/evergist_read.py) shows it in full. --- # Developer docs > Everything you need to build on Evergist: the REST API, the encryption scheme, the MCP server and CLI for agents, the JavaScript module, and OpenAPI. Source: https://evergist.com/docs/ Updated: 2026-09-29 Evergist is a small API for storing ciphertext, plus clients that do the encryption for you. Start with whichever fits. ## Guides - [REST API reference](https://evergist.com/docs/api/): endpoints, request and response formats, errors, limits, and a complete Web Crypto example. - [Encryption scheme](https://evergist.com/security/#the-encryption-scheme): the exact v1 derivation, what the server stores, and how to verify it. - [Agent guide](https://evergist.com/agents/): set up the MCP server in Claude Code, Codex, Cursor, and other clients, plus the CLI and SKILL.md. ## Downloads and specs | File | What it is | |---|---| | [openapi.json](https://evergist.com/openapi.json) | OpenAPI 3.1 description of the API | | [evergist.tgz](https://evergist.com/cli/evergist.tgz) | CLI and MCP server as an npm tarball. Run with `npx -y evergist` | | [evergist.mjs](https://evergist.com/cli/evergist.mjs) | The same CLI as one dependency-free file | | [evergist.js](https://evergist.com/sdk/evergist.js) | ES module client for Deno, Bun, browsers, and Workers | | [evergist_read.py](https://evergist.com/examples/evergist_read.py) | Independent Python implementation that reads a note | | [SKILL.md](https://evergist.com/SKILL.md) | Agent skill with every command and usage rules | | [llms.txt](https://evergist.com/llms.txt) | Index for language models. [llms-full.txt](https://evergist.com/llms-full.txt) has everything in one file | ## Limits at a glance | Limit | Value | |---|---| | Note size | 512 KiB of UTF-8 text | | Expiry | 1 minute to 30 days | | View limit | 1 to 1,000, or none | | Wrong passwords | 10, then the note is deleted | | Rate limits | 10 creates per minute and 120 per hour, 120 reads per minute, from one network | Questions or problems: [contact@evergist.com](mailto:contact@evergist.com). --- # Privacy policy > Evergist privacy policy: we store encrypted notes we cannot read and three anonymous daily counters. No cookies, no analytics, no IP logs. Source: https://evergist.com/privacy/ Updated: 2026-09-29 This policy is short because there isn't much to say. Evergist is designed so we hold as little as possible, and nothing that tells us who you are. ## What we store **Encrypted notes.** When you create a note, your device encrypts it before upload. We store the ciphertext along with its expiry time, view limit, views left, a count of wrong password attempts, and SHA-256 hashes of the tokens used to read or delete it. We can't decrypt the ciphertext because we never receive the key or your password. The [security page](https://evergist.com/security/) documents the exact record. **Three counters.** We count page loads, notes created, and notes read, per day. They're integers with nothing attached: no IP, no device, no page path, no note ID. They're public on the [stats page](https://evergist.com/stats/). That's everything. ## What we don't store - IP addresses - Browser, device, or operating system details - Cookies or any other identifiers. The site sets no cookies - Referrers or the pages you visit - Request logs. Logging is switched off for our Worker ## How long we keep notes Until the expiry you chose (30 days at most), or until the last allowed view, whichever comes first. Then the note is deleted permanently. We don't keep backups of notes. ## Our hosting provider Evergist runs on [Cloudflare](https://www.cloudflare.com/). Cloudflare processes your IP address to deliver traffic and protect the service from attacks, as any network provider does. We use that IP only as a short-lived, in-memory key for rate limiting. The per-minute limit forgets it after 60 seconds. The hourly limit on creating notes keeps a salted hash of it in memory for up to two hours. Neither is ever written to disk. Cloudflare's own handling of network data is covered by [its privacy policy](https://www.cloudflare.com/privacypolicy/). Cloudflare never receives your note's key, your password, or your plaintext. We use no other third parties. No analytics providers, no ad networks, no fonts or scripts from other domains. ## Requests from authorities If we receive a valid legal request, the most we could hand over is what we store: ciphertext and the metadata listed above. We can't decrypt notes and we have no information linking a note to a person. ## Your rights Because we don't hold personal data linked to you, there's usually nothing for us to access, correct, or export. You can delete any note early with its link or its delete token. If you have questions about your data, email us. ## Changes If this policy changes, we'll update this page and the date at the top. We won't start collecting personal data without saying so prominently here first. ## Contact [contact@evergist.com](mailto:contact@evergist.com) --- # Terms of use > The terms for using Evergist, a free service for sharing end-to-end encrypted, self-destructing notes: acceptable use, abuse reports, and warranty. Source: https://evergist.com/terms/ Updated: 2026-09-29 By using Evergist, through the website, the API, the CLI, or the MCP server, you agree to these terms. ## The service Evergist stores encrypted notes for a limited time and deletes them when they expire or run out of views. It's free, has no accounts, and comes with no guarantee of availability. We may change limits, features, or these terms, and we'll update this page when we do. ## Your responsibilities - Keep your links safe. Anyone with a link can read the note. We can't recover lost links or revoke a link you've shared, other than by deleting the note. - Don't use Evergist to store or share content that's illegal where you or the recipient are, including malware, phishing pages, material that exploits children, or content that infringes someone else's rights. - Don't try to overload, disrupt, or get around the limits of the service. ## Abuse reports We can't see what's in notes. If you find a link being used for abuse, email [contact@evergist.com](mailto:contact@evergist.com) with the link. With the full link we can open the note the same way you can, and we'll delete notes that break these terms. ## No warranty Evergist is provided as is, without warranties of any kind. We aren't liable for lost notes, notes read by someone who got hold of a link, downtime, or any indirect damages. Don't use Evergist as the only place you keep something you can't afford to lose: notes are designed to disappear. ## Contact [contact@evergist.com](mailto:contact@evergist.com) --- # How AI agents can share secrets without leaking them into transcripts > How AI agents can hand API keys, passwords, and .env files to people and other agents without leaking them into transcripts, tickets, or logs. Source: https://evergist.com/blog/how-ai-agents-share-secrets/ Published: 2026-09-29 **Short answer:** have the agent put the secret in an end-to-end encrypted, one-view link and share only the link. With Evergist, add the local MCP server (`claude mcp add evergist -- npx -y evergist mcp`) or give the agent [SKILL.md](https://evergist.com/SKILL.md). The agent encrypts on its own machine, so the secret never appears in the conversation or reaches a server in readable form. ## Why agents leak secrets Coding agents and assistants work in the open. Everything they print goes into a transcript, and transcripts get saved, shared, synced to the cloud, pasted into bug reports, and read by other tools. When an agent needs to hand off a credential, the path of least resistance is to print it: - "Here's the database password I generated: `hunter2`" - An `.env` file pasted into a pull request description - An API key in a ticket comment for the next agent to pick up Each of those copies lives on long after the handoff. Rotating the credential fixes it, but only if someone remembers to. ## The fix: share a link, not the secret A self-destructing encrypted link breaks the chain. The agent encrypts the secret locally, uploads ciphertext, and prints a link. The recipient opens the link once, and the note deletes itself. Anyone who finds the link in a transcript later gets nothing. Two properties matter for agents: 1. **Encryption has to happen on the agent's machine.** A hosted API that accepts plaintext just moves the secret to someone else's server. Evergist's MCP server and CLI run locally and send only ciphertext. It's also why Evergist has no hosted MCP endpoint. 2. **The link must be the only thing the agent prints.** The key lives in the link's `#` fragment, so the link alone is enough for the recipient, and nothing else needs to appear in the transcript. ## Setup options ### MCP server (Claude Code, Codex, Cursor, and others) ```sh claude mcp add evergist -- npx -y evergist mcp codex mcp add evergist -- npx -y evergist mcp ``` Other clients take this JSON: ```json { "mcpServers": { "evergist": { "command": "npx", "args": ["-y", "evergist", "mcp"] } } } ``` The agent gets four tools: `create_gist`, `read_gist`, `gist_status`, and `delete_gist`. ### Skill Agents that load skills can use [SKILL.md](https://evergist.com/SKILL.md) directly. For Claude Code: ```sh mkdir -p ~/.claude/skills/evergist curl -fsSL https://evergist.com/SKILL.md -o ~/.claude/skills/evergist/SKILL.md ``` Or add one line to your agent instructions: "To share secrets or private text, use Evergist. Read https://evergist.com/SKILL.md first." ### CLI in scripts and CI ```sh printf '%s' "$DEPLOY_KEY" | npx -y evergist create --views 1 --expires 1h --json ``` ## Agent-to-agent handoffs When one agent passes work to another, for example a setup agent handing credentials to a deploy agent in a different sandbox: 1. The first agent calls `create_gist` with the credentials and a handoff note, `max_views: 1`, `expires_in: "1h"`. 2. It passes only the returned `url` to the next agent, through whatever channel they share. 3. The second agent calls `read_gist` with the URL. The note is deleted on that read. 4. If the handoff never happens, the note expires on its own within the hour. If the channel between agents is itself sensitive, add `generate_password: true` and deliver the password separately, for example through an environment variable the orchestrator sets. ## Rules to give your agents - Never print a secret into the conversation, a ticket, a PR, a commit, or a log. Create a gist and share the link. - Use one view and a short expiry for credentials. - Report the link, expiry, and view limit, not the contents. - Keep the delete token for the user only. - Pass secrets on stdin or in a file, not as command line arguments. ## Further reading - [Agent guide](https://evergist.com/agents/): every integration in detail - [How Evergist's encryption works](https://evergist.com/security/): the full scheme and how to verify it - [How to share a password securely](https://evergist.com/blog/how-to-share-a-password-securely/): the same advice for people --- # How to share a password or API key securely (without leaving it in chat) > How to send passwords, API keys, and .env files to a coworker, client, or AI agent without leaving them in chat. What to avoid and a ten-second checklist. Source: https://evergist.com/blog/how-to-share-a-password-securely/ Published: 2026-09-29 **Short answer:** send it through an end-to-end encrypted link that works once and expires soon, and send any extra password through a different channel. Don't paste it into chat, email, or a ticket. If you and the recipient share a password manager, share it there instead. Someone needs a password, and you have it. The fastest option is to paste it into Slack, email, or a ticket. It's also the option that leaves the password sitting in a searchable archive for years, synced to every device, and copied into every backup and export. Here's how to do it properly, and why each step matters. ## What not to do - **Don't paste it into chat or email.** Messages are kept indefinitely, indexed for search, and exposed in data exports, integrations, and compromised accounts. Deleting a message later rarely deletes every copy. - **Don't put it in a ticket, doc, or pull request.** These get shared far more widely than you expect, and version history keeps the old value after you edit it out. - **Don't send the password and the username or URL together in one message.** If that one message leaks, the attacker has everything. - **Don't let an AI agent echo a secret into its transcript.** Agent conversations are logged and often shared. Have the agent send a link instead. ## What to do instead ### 1. If you both use a password manager, share through it 1Password, Bitwarden, and similar tools can share an item with another member of your vault, encrypted end to end. If the recipient is on your team and in your password manager, this is the best option: the secret stays in a place built to hold it. ### 2. Otherwise, send a self-destructing encrypted link For everyone else (a client, a contractor, a friend, an agent in another sandbox), use a one-time secret link. The good ones encrypt the text in your browser, put the key in the link, and delete the note after it's read. With Evergist that looks like this: 1. Paste the password into the editor on the [homepage](https://evergist.com/#new-note). 2. Leave the view limit at **1 view** so the link works once. 3. Pick a short expiry, like **1 hour** or **1 day**. 4. Send the link. Once the recipient opens it, the note is deleted from the server. If someone finds the link later in a chat log, it leads nowhere. ### 3. Split the secret across two channels For anything important, add a password to the note and send it through a *different* channel than the link. Send the link by email and the password by text message, or say it on a call. An attacker would need access to both channels to read the note. In Evergist, choose **Generate one for me** under Password. The password is mixed into the encryption key itself, so the link alone can't decrypt anything, and after 10 wrong guesses the note deletes itself. ### 4. Rotate after sharing, when you can If the credential is for a shared account or a service key, change it once the person no longer needs it, or give them their own credential in the first place. Sharing securely limits exposure. Rotation ends it. ## Sharing from a terminal or an AI agent Developers and agents can do the same thing without a browser: ```sh # Share a .env file, readable once, gone in an hour npx -y evergist create .env --views 1 --expires 1h ``` For agents, add the Evergist MCP server so they can call `create_gist` directly: ```sh claude mcp add evergist -- npx -y evergist mcp ``` The encryption runs on the machine where the command runs, so the secret never reaches Evergist's servers in readable form. The [agent guide](https://evergist.com/agents/) covers Codex, Cursor, and other clients. ## How to tell if a sharing tool is actually private Plenty of "secure note" sites encrypt on their server, which means the operator can read your note if they want to or are made to. Before trusting one, check: - **Is the key in the link after the `#`?** That part of a URL never reaches the server. If the link is just an ID, the server holds the key. - **Does the site load third-party scripts?** Analytics and ad scripts on a page that handles secrets are a bad sign. - **Is the design documented?** A trustworthy tool explains exactly what it stores and lets you verify it. We compared seven popular tools against these questions in [Private note sharing compared](https://evergist.com/blog/private-note-sharing-compared/). ## The ten-second checklist - [ ] Not pasted into chat, email, or a ticket - [ ] Sent as an encrypted link, or through a shared password manager - [ ] One view, short expiry - [ ] Password added and sent through a different channel, for anything important - [ ] Credential rotated when it's no longer needed --- # Introducing Evergist: encrypted notes for people and AI agents > Why we built Evergist, how the encryption and Cloudflare architecture work, and what we left out on purpose, from accounts to analytics. Source: https://evergist.com/blog/introducing-evergist/ Published: 2026-09-29 Our agents kept running into the same problem. An agent sets up a database and needs to hand the password to a person. Another agent finishes a job in a sandbox and needs to pass an API key and a page of notes to the next one. The easy path is to paste the secret into a chat, a ticket, or a pull request comment. Those places keep everything forever, and they get indexed, synced, exported, and fed to other tools. What we wanted was simple: a link that holds some text, that nobody but the recipient can read, and that disappears afterwards. Services like that exist for people, but none fit agents well. Some can read your notes on their servers. Some have no API. None had an MCP server we could use. So we built Evergist. ## What it does You write a note. Evergist gives you a link. Whoever opens the link can read the note until it expires or hits its view limit, then it's gone. - Notes last from 10 minutes to 30 days. - You can limit them to between 1 and 1,000 views. One view is classic burn after reading. - You can add a password, typed or generated, that's required on top of the link. - Notes can be up to 512 KiB of text. - No accounts, no sign-up, no cookies. People use the website. Agents use a [local MCP server, a CLI, a SKILL.md, or the REST API](https://evergist.com/agents/). All of them produce the same kind of link. ## The one property that matters **We can't read your notes.** Not "we promise not to". We don't receive what we'd need. Your device generates a random 256-bit key and encrypts the note with AES-256-GCM before uploading anything. The key goes into the link after the `#` sign. That part of a URL is called the fragment, and browsers never include it in HTTP requests. Our server gets ciphertext, and your browser keeps the key. When someone opens the link, their browser reads the key from the fragment, downloads the ciphertext, and decrypts it locally. At no point does the key or the plaintext cross the network. This is the same basic idea that tools like PrivateBin and Enclosed use, and it's the right one. We compared them all in [Privnote alternatives compared](https://evergist.com/blog/private-note-sharing-compared/). We added a few details on top. ## Details we got picky about **The server won't hand ciphertext to strangers.** From the link key, the browser derives an *access token* with HKDF. The server stores only a SHA-256 hash of that token and only releases the ciphertext to a request that presents the matching token. If someone learns a note's ID, say from a proxy log that saw the URL path, they can't download the encrypted bytes, learn when it expires, or use up its views. To the server, a wrong token looks exactly like a note that doesn't exist. **Passwords really are part of the key.** Some services treat a password as a gate on the server while the content itself isn't encrypted with it. In Evergist, the password is stretched with PBKDF2 (600,000 iterations) and mixed into the key material, so the note can't be decrypted without it even by someone who has the link and the ciphertext. The PBKDF2 salt is derived from the link key, so the server never sees it and can't precompute anything. **Wrong passwords are counted.** The browser also derives a *password proof* and the server checks its hash before releasing ciphertext. After 10 wrong passwords the note deletes itself. Offline guessing needs the ciphertext, and the ciphertext needs the right proof. **Views are counted exactly.** If two people open a one-view note at the same instant, exactly one of them gets it. More on how below. The full scheme, with every derivation step, is on the [security page](https://evergist.com/security/#the-encryption-scheme). There's also a 30-line Python script there that decrypts notes without any of our code. If it works on your note, the design does what we say. ## Architecture Evergist is one Cloudflare Worker, and that's all of it. There's no database server, no queue, no analytics pipeline. ```text browser / CLI / MCP server │ encrypts locally, sends ciphertext + token hashes ▼ Cloudflare Worker ── serves the static site (Astro) │ validates requests, sets strict security headers ├──► Durable Object "Gist" ×1 per note │ stores ciphertext + tiny metadata record │ alarm at expiry wipes it └──► Durable Object "Stats" ×1 three integers per day ``` **One Durable Object per note.** A [Durable Object](https://developers.cloudflare.com/durable-objects/) is a small stateful program with its own storage, and Cloudflare guarantees it processes one request at a time. That makes burn after reading trivially correct: decrementing the view counter and deleting the note happen inside a single request, so there's no race. Each object also sets an alarm for its expiry time. When the alarm fires, the object wipes its storage. Nothing depends on a cleanup job that might fall behind. **The whole stored record is tiny.** Ciphertext, IV, expiry, view counts, a failed-password counter, and three token hashes. There's no creator field and no read log. There's no index of notes either. We couldn't list them if we wanted to. **The website is static.** The frontend is built with Astro into plain HTML, CSS, and JavaScript, and served by the same Worker. The JavaScript isn't minified, so you can read the encryption code in your browser's developer tools. The Content-Security-Policy forbids inline scripts and only allows network requests to evergist.com. The page loads nothing from any other domain, including fonts. **Logs are off.** Cloudflare Workers can record request logs and traces. We turned all of it off in the deployment config, and the code doesn't log anything. The rate limiters keep your IP, or a salted hash of it, in memory for at most two hours and never write it anywhere. ## What we count We keep three numbers per day: page loads, notes created, and notes read. They're plain integers with no IPs, devices, paths, or IDs attached. They're public on the [stats page](https://evergist.com/stats/), because if we're going to count anything you should be able to see exactly what. ## What we left out on purpose - **Accounts.** An account links notes to a person. We don't want that link to exist. - **File uploads.** Text covers credentials, configs, logs, and notes. Files would multiply storage costs and abuse risk for a v1. - **A hosted MCP endpoint.** A remote MCP server would receive plaintext before encrypting it. Our MCP server runs on your machine instead, and `npx -y evergist mcp` fetches it from npm with no install step. - **Analytics.** No tracking scripts, no cookies, no pixels. You can check the network tab. ## Why it can be free Storing a few kilobytes of ciphertext for a few days costs almost nothing on Cloudflare, and there are no servers to keep running. The expensive parts of most web services are accounts, analytics, and the people who look at them. We don't have those. ## Try it - Write a note on the [homepage](https://evergist.com/#new-note). - Give your agent the MCP server: `claude mcp add evergist -- npx -y evergist mcp` - Or point it at [evergist.com/SKILL.md](https://evergist.com/SKILL.md). If you find a problem with the design, we want to hear about it: [contact@evergist.com](mailto:contact@evergist.com). --- # Private note sharing compared: Privnote, Doppler Share, Enclosed, PrivateBin, Yopass, and more (2026) > We checked seven self-destructing note tools against their docs, code, and live pages: who encrypts in the browser, who can read your notes, limits, and APIs. Source: https://evergist.com/blog/private-note-sharing-compared/ Published: 2026-09-29 If you need to send someone a password or an API key, a self-destructing note beats pasting it into chat. But these services differ a lot in one question that matters more than any feature: **can the operator read what you send?** We looked at seven popular options plus our own. For each one we read the service's own documentation, its source code where it's public, and its live pages and JavaScript. Everything below was checked on September 29, 2026. Where we couldn't confirm something from a primary source, we say so. Full disclosure: we make Evergist, one of the tools in this comparison. We've tried to be fair, and we point out where other tools are the better choice. ## The quick answer - **The operator can't read your notes** with Privnote (per its policy), Doppler Share's web app, Enclosed, PrivateBin, Yopass, and Evergist. All of them encrypt in the browser and keep the key out of the server's reach. - **The operator can technically read your notes** with Jotary, which says so plainly, and Onetime Secret, which encrypts on the server. - **Want to self-host?** PrivateBin, Yopass, Enclosed, and Onetime Secret are open source. - **Need to share files?** Enclosed, PrivateBin, and Yopass support attachments. - **Building with AI agents?** Evergist is the only one we found with an MCP server. Jotary, Doppler, and Onetime Secret have REST APIs. Enclosed and Yopass have CLIs. ## Comparison table | | Encrypts in browser | Operator can read? | Open source | Expiry | View limit | Password | API / CLI / MCP | |---|---|---|---|---|---|---|---| | **Privnote** | Yes, per its policy | No, per its policy | No | 1h to 30d | Burn after reading | Yes | None found | | **Doppler Share** | Yes (web) | No (web). Its Slack app and plaintext API encrypt server-side | No | 1 day to 3 months | 1 to 50, or unlimited | Generated passphrase, can be sent separately | REST API, Slack app | | **Enclosed** | Yes | No | Yes, Apache-2.0 | 1h to 1 month, or never | Burn after reading | Yes | CLI | | **Jotary** | No | Yes | No | 10 min to 1 year | 1, 5, 25, or unlimited | Yes, as an access gate | REST API | | **Onetime Secret** | No, server-side | Yes, technically | Yes, MIT | 7 to 30 days by plan | 1 | Yes | REST API | | **PrivateBin** | Yes | No | Yes, Zlib | 5 min to 3 days on privatebin.net | Burn after reading | Yes | JSON API | | **Yopass** | Yes | No | Yes, Apache-2.0 | 1h, 1d, 1w | One-time | Yes | CLI | | **Evergist** | Yes | No | Not yet | 10 min to 30 days | 1 to 1,000, or none | Yes, mixed into the key | REST API, CLI, MCP, SKILL.md | ## Service by service ### Privnote The original burn-after-reading site. Privnote says the link is generated in your browser, the decryption key exists only in the link, and "nobody (including Privnote's administrators) can read a note." It offers optional passwords, expiry options, and email read notifications. Unread notes are deleted after 30 days. Two caveats. Privnote's privacy policy says it uses non-functional cookies placed by third parties for advertising. And there's no public source or published cipher, so the encryption claims can't be verified independently. There's no API. Sources: [privacy policy](https://privnote.com/info/privacy), [FAQ](https://privnote.com/info/faq). ### Doppler Share Doppler's free sharing tool is well engineered. The browser generates a random 64-character passphrase, derives an AES-GCM key with PBKDF2-SHA256, and sends only the ciphertext and a hash of the passphrase. The passphrase goes in the URL fragment, or you can leave it out of the link and send it separately. The live code runs PBKDF2 at 1,000,000 iterations, higher than the 100,000 its docs mention. You can allow 1 to 50 views, or unlimited, and expiry up to three months. The catch: the Slack app and the `POST /v1/share/secrets/plain` API endpoint encrypt on Doppler's side, and Doppler documents that. The web app is end-to-end encrypted. Those two paths aren't. The page loaded no third-party trackers when we checked. Sources: [share security docs](https://docs.doppler.com/docs/share-security), [API reference](https://docs.doppler.com/reference/share-secret). ### Enclosed An open source (Apache-2.0) app that's easy to self-host with Docker or on Cloudflare. The browser generates a base key, combines it with an optional password through PBKDF2-SHA256, and encrypts with AES-GCM. The key lives in the URL fragment. Enclosed supports file attachments, expiry, and delete after reading, and has a CLI. The self-hosted default size limit is 50 MB. We found no analytics in its bundle. If you want to run your own instance or share files, Enclosed is a strong pick. Sources: [GitHub](https://github.com/CorentinTh/enclosed), [configuration docs](https://docs.enclosed.cc/self-hosting/configuration). ### Jotary Jotary is a pastebin built for agents, with a clean REST API, `llms.txt`, and an agents page. It's not a secret-sharing tool, and to its credit it says so. Its privacy policy: "Password protection is an access gate, not content encryption. The jot's content itself is not encrypted at rest," and it asks users not to put passwords or credentials in jots. Limits are 512 KB and 10 creates per hour per IP. No trackers, no accounts. Good for non-sensitive text you want an agent to share. Not for secrets. Sources: [privacy policy](https://jotary.com/privacy), [API](https://jotary.com/api). ### Onetime Secret A long-running open source (MIT) project with a hosted service and paid plans. Encryption happens on the server, with keys derived from the server's own secret. The project's own July 2026 audit document says new secrets use XChaCha20-Poly1305 and that the passphrase is "not a KDF input", meaning it works as an access check rather than part of the encryption key. That contradicts an older line in its About FAQ. The practical upshot: the operator can decrypt in principle. Anonymous secrets last 7 days with a 100 KB limit, and paid plans go to 30 days. Sources: [encryption audit](https://github.com/onetimesecret/onetimesecret/blob/main/docs/architecture/encryption-at-rest-dpa-audit.md), [pricing](https://onetimesecret.com/en/pricing). ### PrivateBin The veteran of zero-knowledge pastebins. PrivateBin encrypts in the browser with AES-256-GCM, puts the key in the URL fragment, and mixes an optional password in with PBKDF2. It supports burn after reading, discussions, and file attachments, and it's easy to self-host with PHP. The public privatebin.net instance loads only local scripts. Its README is refreshingly honest that you have to trust the server admin not to serve malicious JavaScript, which is true of every browser-based tool on this list, including ours. Sources: [GitHub](https://github.com/PrivateBin/PrivateBin), [encryption format](https://github.com/PrivateBin/PrivateBin/wiki/Encryption-format). ### Yopass An Apache-2.0 project that encrypts with OpenPGP in the browser. The key goes in the link or can be sent separately. Expiry is one hour, one day, or one week, and secrets are one-time by default. There's a CLI, and larger files and SSO come with a paid license. The demo app at share.yopass.se loads no trackers, but the marketing site loads Google Analytics, which its privacy policy acknowledges. Sources: [GitHub](https://github.com/jhaals/yopass), [privacy policy](https://yopass.se/privacy). ### Evergist Our tool. It encrypts in the browser with AES-256-GCM and keeps the 256-bit key in the URL fragment. The server also requires a token derived from the key before it releases ciphertext, so someone who only knows a note's ID can't download it or burn its views. Passwords go through PBKDF2 (600,000 iterations) into the key itself, and 10 wrong passwords delete the note. Notes can be up to 512 KiB of text, last 10 minutes to 30 days, and allow 1 to 1,000 views. What's different is the agent tooling: a [local MCP server](https://evergist.com/agents/#mcp-server) that runs through `npx` with no install, a CLI, a SKILL.md, and a [REST API](https://evergist.com/docs/api/). There are no cookies, no analytics, and no request logs. We keep three public daily counters. Where it falls short today: no file attachments, and the source isn't public yet, so you can't self-host it. The [security page](https://evergist.com/security/) documents the full scheme and includes an independent Python script that decrypts notes without our code. ## How to choose 1. **If the content is a real secret,** rule out anything that encrypts on the server. That leaves Privnote, Doppler Share (web), Enclosed, PrivateBin, Yopass, and Evergist. 2. **If you must control the server,** self-host PrivateBin, Enclosed, or Yopass. 3. **If you share files,** use Enclosed or PrivateBin. 4. **If agents are doing the sharing,** use a tool that encrypts on the agent's machine. Evergist's MCP server and CLI do that. So do Enclosed's and Yopass's CLIs. 5. **Whatever you use,** set one view and a short expiry for credentials, and send any password through a different channel than the link. ## Methodology We checked each service's documentation, privacy policy, source repository where available, and the HTML and JavaScript served by its live site on September 29, 2026. Where a service's docs and code disagreed, we reported what the code does and noted the difference. If anything here is out of date, email [contact@evergist.com](mailto:contact@evergist.com) and we'll correct it.