Model or dataset
agarwalvishal/claude-chat-exporter avatar
agarwalvishal/claude-chat-exporter

claude-chat-exporter: pulling Claude.ai conversations out through the internal API

One-click, privacy-first exporter for Claude.ai chats — clean Markdown with artifacts and attachments, ready for Obsidian and RAG.

686 stars79 forksJavaScriptMIT

At a glance

What is it?
A browser bookmarklet that reads Claude's own chat_conversations endpoint and writes a single Markdown file with YAML frontmatter, artifacts and attachments included. Its whole value and its whole fragility come from the same decision: read the API, not the page.
Who is it for?
Adopt it if you want Claude.ai conversations as Markdown files in an Obsidian vault or a retrieval pipeline, and you are comfortable running a bookmarklet that calls Claude's internal API with your session cookie. Do not adopt it if you need a supported, versioned integration, or if you are exporting on behalf of someone else's account.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap between a rendered conversation and a retrievable file

Claude.ai is a chat surface, not a document store. A conversation that took an hour to build lives in a scrollable pane, and the copy button gives you one message at a time. That is fine for pasting a snippet into an editor and useless for building a corpus. Anyone who wants their Claude conversations inside Obsidian, or indexed by a retrieval pipeline, has to reassemble them by hand: scroll, copy, paste, repeat, then fix the ordering when a regenerated answer sits above the version that replaced it.

This project targets exactly that gap. It is a single JavaScript file, distributed primarily as a bookmarklet, that produces one Markdown document per conversation. The README frames the audience directly: the one-click path exists because it needs "no console, no copy-paste, works for non-developers too." The console path is offered for people who want to read or modify the script. Both paths end in the same artifact, a downloaded `.md` file named from the conversation title.

What makes it worth a separate look rather than a generic scraper is the stated reason for reading the API instead of the page. The README lists the failure modes of DOM-driven exporters: only the messages currently rendered get exported, human and Claude turns get paired by index so a regenerated branch can misalign them, and anything without a copy button (artifacts, created files, attachments) is unreachable. That is a real distinction, and it is the design decision the rest of the tool hangs on.

One fetch, then a tree walk from the active leaf

The mechanism is short enough to describe in full. The script calls `/api/organizations/{orgId}/chat_conversations/{conversationId}` on Claude's own backend, authenticated by the session cookie the browser already holds. The response carries the conversation title and every message. Nothing goes to a server belonging to this project, because there is no such server.

Ordering is the interesting part. Claude conversations are a tree, not a list, because regenerating a response creates a sibling branch. The exporter reconstructs the branch by walking from the current leaf up its parent chain. The README is explicit about the consequence: the export follows the branch Claude is currently showing, which is not necessarily the newest one. If you regenerated an answer and want the earlier version, you switch to it using the arrows on the regenerated message and run the exporter again. The README states the switch takes effect immediately, with no page reload.

After ordering, the script walks each message's content blocks in sequence. Text blocks are Claude's original source markdown, so there is no HTML parsing and no conversion step. Artifacts, created files, and charts or diagrams are rendered in position as fenced code blocks. Hidden and system messages are skipped. The output is a single file: YAML frontmatter with title, source, model and export date, then one `#`-level header per turn (`# Human` or `# Claude`), which is what lets Claude's own `##` and `###` headings nest underneath instead of colliding with the turn boundary.

Install paths: bookmarklet drag, or paste into the console

The primary install is a bookmarklet. You open the project's install page, drag the export button onto the bookmarks bar, open a conversation on claude.ai, and click the bookmark. The README describes the bookmarklet as the repository's script wrapped into a link, and notes it checks for updates and shows an "update available" notice when a newer version is published, so you re-drag to pick it up.

The console route is for people who want to run or edit the script themselves. You open the conversation, open developer tools (F12 or Ctrl+Shift+J on Chrome and Edge, Ctrl+Shift+K on Firefox, Cmd+Option+C on Safari after enabling the Develop menu), paste the contents of `claude-chat-exporter.js`, and press Enter. The README flags the one snag: Chrome, Edge and Firefox block pasting into the console as a safety measure, so on first use you type `allow pasting`, press Enter, then paste again. That is once per browser profile, and the bookmarklet path avoids it entirely.

The script then shows a small status indicator and downloads `{conversation-title}.md`. There are no config keys, no build step, no package install and no CLI flags documented. The only knob is which branch is active in the Claude UI when you run it, which is a UI state rather than a setting.

The maintenance model is the risk model

The README says it plainly in the sponsorship note: Claude's internal API changes without notice, and someone has to keep up. That sentence is the honest version of this project's limitation. The exporter deliberately trades selector fragility for endpoint fragility. CSS classes change and break DOM scrapers; an internal endpoint can change shape, gain a field, move, or start requiring something the session cookie alone does not satisfy, and when that happens the script stops producing output until the author ships a fix.

The update-check notice is the mitigation, and it is a reasonable one, but it only works if you notice it and re-drag the bookmark. A user who installed the bookmarklet six months ago and never re-dragged is running whatever version they installed. There is no version pinning, no changelog in the supplied material, and the repository shows no retrieved releases, so there is no release feed to subscribe to for a stable artifact. The console path at least makes the version visible: you are pasting a specific file you can read.

The second limitation is authentication scope. The fetch runs over your existing claude.ai session cookie. That is what makes the privacy claim credible, and it also means the tool is tied to a logged-in browser session. It is not a script you point at an archive, a shared workspace, or someone else's account. The README does not describe any batch or multi-conversation mode; every export starts from a conversation you have open.

What the API route buys, and what it still cannot reach

The fidelity claim rests on reading Claude's source markdown rather than reconstructing it from rendered HTML. Tables, math and code arrive as they were generated, not as they were styled. Artifacts come out as their final version, in place and in order, as fenced code blocks. Attachments are handled by type: uploaded images embedded, documents linked, text files inlined. Whether those choices suit you depends on what you do next. An inlined text file makes the export self-contained; an embedded image makes the file larger; a linked document means the export is only as durable as the link.

The branch behaviour deserves a second mention because it is the most likely source of a wrong export. Regeneration is common, and the exporter follows the active leaf. If you regenerated a response three turns back and never switched back to the version you preferred, the file you get is the version Claude is showing, not the version you remember. The README's instruction to switch branches first is the whole remedy, and it is a manual step that is easy to forget in a long conversation.

One thing the material does not establish: what happens when the API call fails, returns a different shape, or the session has expired. The README describes a status indicator but does not document error output. Treat that as unverified rather than assume it is handled gracefully.

How it differs from Claude's own export and from DOM scrapers

Two alternatives are worth naming, and they differ in approach rather than in polish.

The first is Claude's built-in data export, which produces an archive of your account data. That route is account-wide and supported, and it is not tied to an internal endpoint that can change shape. The difference is granularity and shape: an account archive is not a per-conversation Markdown file with YAML frontmatter and one heading per turn, and it is not something you trigger from an open conversation. If you want a vault-ready note per chat, the archive gives you a different starting format to convert. If you want a complete, supported copy of everything, the archive is the safer primary and this exporter is the convenience layer.

The second is the DOM-scraping exporter, which drives the page and clicks copy buttons. That approach survives API changes better in one sense, because it depends on what the user sees, but the README's own list of its failure modes is concrete: partial exports of long conversations, index-based turn pairing that misaligns after a regeneration, and no access to artifacts, files or attachments at all. The trade is legibility against completeness. A DOM scraper exports what is on screen; this tool exports what the API returns for the active branch, including elements with no copy button.

Licence, cost and what you are actually maintaining

The project is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That covers the script itself. It does not cover anything about Claude's API, and the README's own note that the endpoint changes without notice is the practical constraint: MIT gives you the right to fork and patch, and the maintenance burden of patching is yours if the author stops.

The project asks for sponsorship on the stated grounds that keeping up with the internal API is the ongoing cost. Whether you pay is a judgement call, but the framing is accurate about where the effort sits. There is no dependency tree to audit, no server to run, no database and no telemetry, so operational cost is close to zero. The recurring cost is the re-drag after an update notice, plus the risk that a breaking API change lands between releases and you discover it mid-export.

Because the tool runs in your browser over your session, the licence question that matters most is not the MIT text but your own handling of the output. Exported conversations can contain anything you typed into Claude, and the tool makes it easy to accumulate those files in a vault or a retrieval index. The README's privacy claim is about the tool's behaviour, not about what you do with the resulting Markdown.

Editorial conclusion

Adopt it if you want Claude.ai conversations as Markdown files in an Obsidian vault or a retrieval pipeline, and you are comfortable running a bookmarklet that calls Claude's internal API with your session cookie. Do not adopt it if you need a supported, versioned integration, or if you are exporting on behalf of someone else's account. Before relying on it, export one long conversation that contains a regenerated response and a file attachment, and check three things in the output: that the branch matches what is on screen, that the attachment is present, and that the frontmatter title matches the conversation. Then re-drag the bookmarklet from the install page after any update notice, because the endpoint it calls is not a public contract.

Official sources

  1. agarwalvishal/claude-chat-exporter on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Community notes

Community notes