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.
The Evergist team · · 5 min read
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. 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. 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. 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.
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 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, 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 mcpfetches 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.
- Give your agent the MCP server:
claude mcp add evergist -- npx -y evergist mcp - Or point it at evergist.com/SKILL.md.
If you find a problem with the design, we want to hear about it: contact@evergist.com.