Batch-export your entire chatgpt.com history to Obsidian-friendly Markdown — one click, in the page, fully local.
An inkstone grinds raw pigment into ink for writing. Inkstone helps you grind GPT's raw output into ink for your notes.
English · 简体中文
① Install Tampermonkey → ② Install Inkstone → ③ Open chatgpt.com, hit ⤓
Your ChatGPT history holds real work, but getting it into a vault is painful. The official export is a raw JSON dump: tool and system messages are stripped (Canvas and code-interpreter output simply aren't there), some attachments have already expired server-side, math arrives in \( \) delimiters Obsidian won't render, and web-search citations turn into private-use Unicode garbage. Copy-pasting by hand doesn't scale past ten conversations, let alone a thousand.
Inkstone runs inside chatgpt.com and fetches conversations through the same backend API the app itself uses, then converts everything locally in your browser — nothing ever leaves the page. The result is Markdown that reads natively in Obsidian: real headings per turn, $ / $$ math, resolved citations, downloaded images, clean frontmatter.
| Panel UI | Advanced settings |
|---|---|
![]() |
![]() |
| Batch export all | Multi-select export |
|---|---|
![]() |
![]() |
| Export directly to Obsidian | Keep thoughts / tool traces |
|---|---|
![]() |
![]() |
| Keep math & links | Keep attachments & images |
|---|---|
![]() |
![]() |
# User/# ChatGPTtop-level headings separate turns; headings inside messages are demoted one level (H1–H6)\( \)/\[ \]→$/$$math-delimiter conversion (code-block aware); currency$escaped- Citations restored: web-search citations become inline
[source](url)links plus a# Sourcessection at the end; file citations become filename notes; anything unresolvable is stripped — no garbled markers, ever - Chain-of-thought and tool traces (code-interpreter code, search queries, run output) are wrapped in collapsed callouts and not written by default — opt in via advanced settings ("write thoughts" / "write tool traces"), or
--thoughts/--tool-tracesin the CLI - Unknown content types are preserved verbatim inside collapsed callouts — nothing is ever silently dropped
- Frontmatter:
title / chat_id / url / created / updated / model / tags
- Every image in a conversation is downloaded into an attachments subfolder next to the notes (default
conversations/attachments/, inlined with Obsidian![[wikilink]]) - User-uploaded files ≤ 2 MB are downloaded and linked; larger ones get a placeholder note
- Folder layout is customizable in settings: the notes subfolder (default
conversations, nestable asa/b, empty = vault root) and the attachments subfolder (defaultattachments, relative to the notes folder, empty = same level as notes). Attachment links are strict relative paths, so GitHub and VS Code previews work too - A "download attachments" toggle: turn it off for text-only export with drastically fewer requests
A watermark records each conversation's update_time, so re-exports only fetch what changed (can be disabled; the panel has a "reset incremental state" button). The heavy full grab only ever happens once.
Besides Markdown, Inkstone exports a raw JSON zip — data insurance, and the source of converter fixtures.
- Install Tampermonkey
- Click the latest inkstone.user.js — the script header carries an update URL, so future releases auto-update
Or GreasyFork: inkstone
Or build from source:
bun install
bun run build # → dist/inkstone.user.js, drag it into TampermonkeyOpen chatgpt.com (logged in) → click the ⤓ button left of the Share button in the top bar → pick Markdown zip or raw JSON zip → unzip into your Obsidian vault.
- The button position is switchable (panel → advanced settings): next to Share in the top bar, or a glass button beside the input box
- The UI follows ChatGPT's appearance settings automatically (light/dark + accent color)
- Exports are cancelable; a single failed conversation never aborts the run — failures are summarized in
_failures.json
The zero-risk alternative: convert ChatGPT's official export zip entirely offline — it never touches the backend API.
bun run offline <export.zip | extracted-dir> [-o outdir]
[--thoughts] [--tool-traces] [--no-assets]
[--link-style wikilink|markdown] [--heading-mode demote|strip]
[--notes-dir <name>] [--attachments-dir <name>]The output layout matches the userscript's. Caveat: the official zip only contains visible user/assistant messages — tool/system payloads (Canvas, code interpreter) are stripped by OpenAI, and some referenced attachments are already expired server-side (placeholders are left in their place).
bun install
bun run dev # vite-plugin-monkey prints a one-time install URL; edits hot-reload
bun test # converter unit tests (pure TS, no browser needed)
bun run typecheck
bun run buildMV3 browser extension (no Tampermonkey, store release) and Claude / Gemini support. Already done: incremental sync, direct-write to an Obsidian vault, settings panel, Canvas patch replay, and the offline CLI. Details in PLAN.md (Chinese).







