When Email Becomes Your API: Archiving Claude Code to Evernote | Blog Skip to main content
Cover image for When Email Becomes Your API: Archiving Claude Code to Evernote

When Email Becomes Your API: Archiving Claude Code to Evernote

Published on 9 min read

I’ve been using Claude Code as my primary coding agent for months now that I can do so safely. It’s good. Suspiciously good. And I’m addicted to using it. It writes code that compiles, finds bugs I’d missed, and on a good day handles refactors that I’d otherwise put off for weeks.

But here’s the thing nobody warns you about with agentic coding tools: you generate an enormous amount of valuable context that gets stuck inside the agent’s local files.

Every Claude Code conversation lives as a JSONL file under ~/.claude/projects/<encoded-path>/<session-id>.jsonl. The encoded path is whatever directory you ran Claude in, with /, ., and _ all mashed into -. The session ID is a UUID. The filename tells you nothing useful. There is no export button.

I’d been copy-pasting conversations into Evernote manually whenever a session produced something worth keeping — an architecture decision, a debugging breakthrough, a particularly clever workaround. This worked, in the sense that any process where the human is doing the routing technically works. It also meant that for every useful conversation, three other ones — the ones I forgot to copy at the time — vanished the moment I closed the terminal tab.

Why Evernote, when the cool kids have long since moved on to Obsidian or Notion? Habit, mostly — the decade-plus kind. My grad school colleague talked me into it back when I was generating more data and sitting in more meetings than my brain could possibly retain. Today my account holds 5,950 notes across 71 notebooks, 40,155 attachments, and 13 GB of storage synced to 8 devices. The newer tools solve real problems, but the switching cost on a corpus that size has never penciled out. Maybe AI agents will eventually make that migration painless; until then, the archive stays where the archive is.

I wanted this automated.


The Plot Twist: Evernote Pulled the API

The obvious solution is just use the API. Evernote has had a REST/Thrift API for over a decade. Generate a personal developer token, point a script at it, done.

Except: in January 2026, Evernote quietly suspended new developer-token issuance while they “complete some maintenance on the platform.” Their support team confirmed this directly when I requested a key:

“At this time, we’re no longer issuing new Evernote API keys. However, we’re actively working on a new MCP (Model Context Protocol) integration that will provide a more modern way to connect Evernote with AI tools and workflows.”

You can register interest in the forthcoming MCP integration, but as of writing it doesn’t exist yet. And the existing community MCP servers all require you to supply your own Consumer Key, which Evernote can’t issue you, because the program is shut down. It’s a Catch-22.

I also briefly considered AppleScript. Evernote dropped AppleScript support entirely in version 10, back in 2020. The modern Bending Spoons–era app has no Mac scripting hook. Dead end.

So my remaining options were roughly:

  1. Wait indefinitely for Evernote to reopen the API
  2. Route my private conversations through a third-party automation platform (Make, Zapier, Flozic)
  3. Get creative

I picked option 3.


The Pivot: Email Is the Last Working API

Here’s the move: Evernote still supports email-to-note. Every account has a secret address like username.xxx@m.evernote.com. Emails sent to that address become notes. The feature has existed since basically forever and works on every paid tier — and the current free tier too.

More importantly, Evernote’s email-to-note syntax supports two non-obvious tricks in the subject line:

  • @notebookname — route the note to a specific notebook
  • A trailing + — append the email body to the most recent existing note with a matching title, instead of creating a new one

Stitch those together and you have: a write-only API that can target a specific notebook, create-or-append to existing notes by title, and requires no developer credentials. Just SMTP and Evernote’s existing inbox infrastructure.

(Fair question: doesn’t this just route my private conversations through Google instead? It does — but my mail already lives in Gmail, so unlike option 2, this adds zero new parties to the trust list. If your mail lives elsewhere, weigh accordingly.)

The full system, claude-evernote-sync, runs once an hour via launchd and does this:

  1. Scan ~/.claude/projects/**/*.jsonl for sessions modified in the last two days
  2. Parse each JSONL — keep user prompts, assistant text, and a compact, foldable list of the tool calls the agent made; strip thinking blocks (signal-to-noise matters when you’re archiving thousands of messages, but “what did it actually do” turns out to be worth keeping)
  3. Give each session a bucket — by default the git repo root’s basename, so a session in ~/Documents/git/myrepo/some/subdir/ files under myrepo
  4. For each session, check a local state file for which message UUIDs have already been emailed
  5. If the session is new: send a creation email with the full content so far (Subject: Fix flaky auth tests - myrepo - 3f2a9c1b @convos_myrepo) — the title comes from Claude Code’s own session summary, with a short-id suffix for uniqueness
  6. If the session has grown: send an append email with only the new messages — same subject, plus a trailing +
  7. Record the synced UUIDs and exit

A four-hour conversation that spans multiple hourly syncs lands in one note that grows incrementally — not four duplicate notes, not a wall of repeated content. The title gets locked in the state file at first sync, and the + operator handles the append. Idempotent, no race conditions, and the entire correctness model fits on a Post-it.

Notebook routing rides along in the subject line: with notebook_prefix = "convos_" in the config, every project gets its own notebook (convos_myrepo, convos_blog, …), which Evernote will happily stack in the sidebar. A notebook_overrides map handles the exceptions — say, a client repo that shouldn’t share a prefix with my hobby stuff.

Sub-agent transcripts — the side conversations Claude Code spawns for delegated tasks — get their own notes too, titled from the task description the sub-agent was given. If that’s more archive than you want, one config line suppresses them.

Here’s what actually lands in Evernote:


The Architecture Bit

The interesting design decision was making the destination pluggable. There’s a Destination protocol with one method:

class Destination(Protocol):
    """A sync target. Returns the set of newly-synced message UUIDs."""

    def sync_session(self, ctx: SyncContext) -> set[str]: ...

Two implementations exist today:

  • EmailDestination — the one that actually works. Uses SMTP + state tracking.
  • ApiDestination — uses the Evernote NoteStore API, full upsert semantics, currently dormant because nobody can get a token.

When Evernote ships their promised MCP integration, a third implementation will slot in. The parser, the grouping logic, the formatter, and the orchestration are all destination-agnostic. Only the final “how do bytes leave this script” step changes.

This kind of forward-compatibility doesn’t cost much when you set it up early. It costs a lot when you retrofit it later.

The stack itself is deliberately boring — Python, stdlib smtplib, launchd — and the interesting choices are the guardrails: 202 pytest tests at ~93% branch coverage, strict mypy, and gitleaks scanning every commit, because the one thing worse than no archive is an archive that leaks credentials.


Why Bother?

It would be entirely reasonable to keep copy-pasting and call it a day. So why automate?

Searchability. Evernote’s search across thousands of notes is decent. Searching for “that thing we figured out about polars groupby last month” inside Evernote is feasible. Searching for it inside ~/.claude/projects/<encoded-mess>/<uuid>.jsonl is a nonstarter.

Continuity. Claude Code conversations are ephemeral by default — the next session has no memory of the previous one unless you tell it to. Having a searchable archive of past conversations lets me say things like “look in my notes for how we solved the auth flow in repo X last week” — and that becomes context for the new session.

Evernote grew an AI layer. The current app ships an AI assistant that works across your notes. Once your Claude Code sessions are syncing, you can ask it to summarize everything you did in a repo over the past two weeks — which turns out to be excellent prep for a 1:1 with your manager or collaborators: recent efforts, pain points, what’s stuck.

The cost of forgetting is going up. As Cengizhan Demirci argued recently, AI conversations are accumulating a kind of personal corpus that’s both valuable and silently disappearing. The longer you use these tools, the more painful the gap becomes between “stuff the AI helped me figure out” and “stuff I can find again.”

The cost of building this once: roughly a Saturday. The cost of not building it: small per day, large in aggregate.


Should You Use It?

The repo is MIT-licensed. If you:

  • Use Claude Code regularly
  • Keep notes in Evernote
  • Have a Gmail account (or any SMTP-capable mail provider — Gmail just happens to be the easy default)
  • Are on macOS (other Unix-likes should mostly work, but launchd is Mac-specific)

…then you can be up and running in roughly fifteen minutes. The README walks through it: generate a Gmail App Password, drop your Evernote email-to-note address into a chmod 600 credentials file, run a one-shot --backfill, and install the LaunchAgent with the included script.

If Evernote ever reopens API access — or the MCP integration ships — both paths are already wired in. You’ll edit one line in config.toml (backend = "email"backend = "api", or eventually "mcp"), and the rest of the system carries on unchanged.

In the meantime: the cleanest way to talk to a vendor that’s ghosting your API turns out to be, of all things, to email them 🙃.


The project:

Evernote API situation:

Tooling:

Adjacent reading:

  • Cengizhan Demirci — Building a Permanent Archive of Every AI Conversation: cengizhan.com
  • Teaching AI Agents to YOLO Responsibly (my prior post on AI agent security): bubbabrooks.info

Tags:

← Back to Blog