A /export-md slash command for Claude Code that saves the current session as a clean, readable markdown file.
What's inside
FAQ
export-md is a Claude Code plugin with hand-picked skills for documentation work, indexed on Flowy. Install it with the command on its page. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Repo: yussufs/export-md
A /export-md slash command for Claude Code that saves the
current session as a clean, readable markdown file.
I kept wanting to copy paste stuff from claude code โ a debugging trail, some text, but Claude Code (in the CLI) is so annoying when working with text.
My only option was selecting text in the terminal and copy-pasting it somewhere, which mangles the wrapping, loses the code blocks, or adds strange characters.
Claude Code ships a built-in /export, but it hands you the raw conversation in a txt. I wanted
something I could paste straight into notes, a PR description, or a docs page: proper
headings per turn, code fences intact, tool noise collapsed down to one line, and my own
choice of filename and folder.
So this reads the session transcript Claude Code already writes to disk and renders it as markdown instead so you can copy paste easily.
Requires python3 (3.6+, already present on macOS and most Linux distros).
For all your projects:
Replace OWNER with the repository owner.
git clone https://github.com/OWNER/export-md.git
cd export-md
./install.sh
For one repo (checks in alongside your code, so your whole team gets it):
./install.sh --project /path/to/your/repo
Then start a new Claude Code session and type /export-md.
To remove it: ./install.sh --uninstall (add --project PATH to scope it).
Copy two files and fix one path.
scripts/export-md.py โ ~/.claude/scripts/export-md.pycommands/export-md.md โ ~/.claude/commands/export-md.md__SCRIPT_PATH__ with the real,
absolute path to the script โ e.g. /path/to/.claude/scripts/export-md.py.Slash commands don't expand ~ or $HOME inside allowed-tools, which is why step 3
needs a literal path. For a project-scoped install, put the files under .claude/ in the
repo instead and use the relative path .claude/scripts/export-md.py, which stays portable
for anyone who clones it.
/export-md # โ ./2026-01-15-0812-a1b2c3d4.md
/export-md thread.md # โ ./thread.md
/export-md notes/deep/x.md # nested dirs are created for you
/export-md ~/Desktop/chat.md # absolute and ~ paths both work
/export-md mythread # .md is appended if you leave it off
/export-md --last 10 # only the last 10 turns
/export-md recent.md --last 4 # combine with a path
Paths are relative to whatever directory you're working in.
| Flag | Effect |
|---|---|
--last N | Only the last N turns, newest end of the conversation |
--with-thinking | Include Claude's reasoning blocks, in collapsed <details> |
--full-tools | Full tool inputs plus an excerpt of each result |
--no-tools | Prose only โ no tool calls at all |
A turn is one ## User or ## Claude heading, so --last 4 gives you roughly the last two
exchanges, each with its tool calls attached. When the export is trimmed, the header records
it (- **Scope**: last 4 of 37 turns). Asking for more turns than exist just exports
everything.
By default you get one compact line per tool call (> ๐ง **Bash** โ \{...}``) and no
results, which keeps the transcript readable without pretending the work didn't happen.
The script also runs standalone, which is how you reach conversations that have already ended:
python3 ~/.claude/scripts/export-md.py --list
# 2026-01-15 08:08 a1b2c3d4-0000-4000-8000-000000000000 (175 KB)
# 2026-01-14 16:38 e5f6a7b8-0000-4000-8000-000000000000 (4570 KB)
python3 ~/.claude/scripts/export-md.py --session a1b2c3d4-0000-4000-8000-000000000000 out.md
# Session a1b2c3d4
- **Date**: 2026-01-15 08:12
- **Project**: `/path/to/my-app`
- **Branch**: `main`
- **Model**: `claude-opus-5`
- **Session**: `a1b2c3d4-0000-4000-8000-000000000000`
---
## User <sub>07:31</sub>
Can you fix the failing test in auth.spec.ts?
---
## Claude <sub>07:31</sub>
> ๐ง **Read** โ `{"file_path": "src/auth.spec.ts"}`
The assertion expects a 401, but the middleware now returns 403 ...
Claude Code already records every session as JSONL under
~/.claude/projects/<slugified-cwd>/<session-id>.jsonl. The script finds the transcript
for your current directory, takes the most recently modified one, and renders the user and
assistant turns as markdown.
Along the way it drops the things you didn't write and don't want in a document: injected
<system-reminder> blocks, sub-agent side transcripts, and internal metadata records.
Nothing is sent anywhere. It reads local files and writes a local file.
--session, it picks the most recently modified
transcript for the current directory. If you have two Claude Code windows open on the
same repo, the other one's writes can make it the newest. Use --list and --session
when that matters.MIT โ see LICENSE.
.gitignore commands/ export-md.md install.sh LICENSE README.md scripts/ export-md.py
ยฉ 2026 Flowy ยท Free and open source
Built for Claude Code ยท Not affiliated with Anthropic