Stream, analyze, and export ChatGPT conversations to Markdown, text, or JSON
Project description
Your ChatGPT history. Clean Markdown. Zero memory overhead.
Install · Quick Start · Formats · Filtering · Config · Fields Reference
Takes your conversations.json from ChatGPT and turns it into clean, readable Markdown — or plain text, or structured JSON. Uses streaming parsing (ijson) so even 100MB+ exports never hit memory. Every aspect of filtering, formatting, and output is configurable through CLI flags or a single TOML file.
$ chatgpt-export export conversations.json --split subject --output-dir vault/
Exported 824 files to vault/
[!TIP] Export straight into your Obsidian vault for a fully searchable, linked archive of every conversation you've ever had with ChatGPT.
Installation
Requires Python
3.10+· managed with uv
git clone https://github.com/voidfreud/chatgpt-export-tool.git
cd chatgpt-export-tool
uv sync
Dev tooling (pytest, ruff, coverage)
uv sync --group dev
Verify:
uv run chatgpt-export --help
Quick Start
# Analyze — stats without loading the whole file
uv run chatgpt-export analyze conversations.json
# Export to markdown on stdout
uv run chatgpt-export export conversations.json
# One markdown file per conversation
uv run chatgpt-export export conversations.json --split subject --output-dir exports/
# JSON dump
uv run chatgpt-export export conversations.json --format json --output dump.json
Output Formats
| Format | Flag | Extension | |
|---|---|---|---|
| Markdown | --format md |
.md |
# headings, > blockquoted context, --- turn separators. Default. |
| Plain text | --format txt |
.txt |
Indented, plain labels — good for terminals and grep. |
| JSON | --format json |
.json |
Filtered conversation objects, valid JSON. |
Markdown and text exports follow the active conversation branch — you see the conversation as it played out, not the full tree with edits and branches.
Preview: Markdown output
# Opening bank account in Thailand
**ID:** 68ed8eba-1d00-832a-a2f1-4721496ed217
**Created:** 23:43 13-10-2025
**Turns:** 34
## Conversation Context
> User profile: The user provided the following information...
> User instructions: Speaking to Nova. Zero restraint...
## User [23:43 13-10-2025]
Can a foreigner open a Thailand bank account?
---
## Assistant [23:44 13-10-2025]
Yup — a foreigner *can* open a bank account in Thailand, but it's
*much more difficult* now than it used to be...
Default transcript policy:
| Shown | Hidden | |
|---|---|---|
| User text, assistant text, thoughts, context (compact) | Tool plumbing, code execution, reasoning recap, blank nodes |
Fully configurable via [transcript] in the TOML config.
Commands
analyze
Structure and statistics — without writing output files.
uv run chatgpt-export analyze data.json
uv run chatgpt-export analyze data.json --fields # include field coverage
uv run chatgpt-export analyze data.json --verbose --output analysis.txt
uv run chatgpt-export analyze data.json --debug
export
Convert conversations with full control over structure, metadata, and layout.
uv run chatgpt-export export data.json --fields "groups minimal"
uv run chatgpt-export export data.json --format json --split date --output-dir by-date/
uv run chatgpt-export export data.json --include "model*" --exclude plugin_ids
uv run chatgpt-export export data.json --config chatgpt_export.toml
Filtering
Structural fields --fields
--fields all # everything (default)
--fields none # structure only
--fields "include title,create_time,mapping" # whitelist
--fields "exclude moderation_results" # blacklist
--fields "groups minimal" # named group
Built-in groups
| Group | Fields |
|---|---|
conversation |
_id conversation_id create_time update_time title type |
message |
author content status end_turn |
metadata |
model_slug message_type is_archived |
minimal |
title create_time message |
Full reference: Fields.md
Metadata --include / --exclude
Runs after structural filtering. Applies to keys inside message.metadata.
--include model_slug
--include "model*" --exclude plugin_ids # glob patterns
Split Modes
| Mode | Flag | Output |
|---|---|---|
| single | --split single |
One stream or file (default) |
| subject | --split subject |
Title_ID.md per conversation |
| date | --split date |
Daily folders |
| id | --split id |
Named by conversation ID |
[!NOTE]
--outputis for single mode. Split modes use--output-dir.
Configuration
Persist defaults in a single TOML file. The repo ships chatgpt_export.toml.example.
cp chatgpt_export.toml.example chatgpt_export.toml
uv run chatgpt-export export data.json --config chatgpt_export.toml
CLI flags always override TOML values.
TOML reference
[defaults] — format, split, fields, output directory, metadata
[transcript] — branch following and visibility
| Key | Default | |
|---|---|---|
show_system_messages |
false |
System prompts |
show_tool_messages |
false |
Tool/function calls |
show_assistant_code |
false |
Code execution |
show_reasoning_recap |
false |
Reasoning summaries |
user_editable_context_mode |
"compact" |
"compact" or "full" |
[text_output] — layout and formatting
| Key | Default | |
|---|---|---|
layout_mode |
"reading" |
"reading" or "compact" |
heading_style |
"markdown" |
"markdown" or "plain" |
turn_separator |
"---" |
Between turns |
strip_chatgpt_artifacts |
true |
Remove citation artifacts |
wrap_width |
88 |
0 to disable |
Presets
Reading-first (default)
[text_output]
layout_mode = "reading"
heading_style = "markdown"
strip_chatgpt_artifacts = true
wrap_width = 88
Compact
[text_output]
layout_mode = "compact"
turn_separator = ""
wrap_width = 0
Terminal
[defaults]
format = "txt"
[text_output]
heading_style = "plain"
Architecture
chatgpt_export_tool/
├── cli.py ← entry point
├── commands/ ← analyze, export
└── core/
├── parser.py ← streaming JSON (ijson)
├── filter_pipeline.py ← field + metadata filtering
├── export_service.py ← orchestration
├── config/ ← TOML loading & validation
├── transcript/ ← branch reconstruction
├── validation/ ← field & metadata checks
└── output/ ← formatters, writer, paths
Modular by design — filtering, formatting, splitting, and writing are separate concerns.
Development
uv run pytest
uv run pytest --cov=chatgpt_export_tool --cov-report=term-missing
uv run ruff check chatgpt_export_tool tests
uv run ruff format --check chatgpt_export_tool tests
MIT · built by @voidfreud
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chatgpt_export_tool-1.0.0.tar.gz.
File metadata
- Download URL: chatgpt_export_tool-1.0.0.tar.gz
- Upload date:
- Size: 63.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
723b56b19e3415225113f42fc440f349c0d836787d584156e0a84379e8388f23
|
|
| MD5 |
76f7407c3669be117678490a3d56c6c8
|
|
| BLAKE2b-256 |
6680ab34271154994dc637626c0bfe8c3e6ca1b8617d0dceb83d8e9f0a6fb4f2
|
Provenance
The following attestation bundles were made for chatgpt_export_tool-1.0.0.tar.gz:
Publisher:
publish.yml on voidfreud/chatgpt-export-tool
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chatgpt_export_tool-1.0.0.tar.gz -
Subject digest:
723b56b19e3415225113f42fc440f349c0d836787d584156e0a84379e8388f23 - Sigstore transparency entry: 1189527508
- Sigstore integration time:
-
Permalink:
voidfreud/chatgpt-export-tool@fc1cbef2229c1a6d976a6dbbd0a3655da063d8ce -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/voidfreud
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fc1cbef2229c1a6d976a6dbbd0a3655da063d8ce -
Trigger Event:
release
-
Statement type:
File details
Details for the file chatgpt_export_tool-1.0.0-py3-none-any.whl.
File metadata
- Download URL: chatgpt_export_tool-1.0.0-py3-none-any.whl
- Upload date:
- Size: 53.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6858780b83009deae3299f3e0fdd64ce03d24b6969803d8e7190d56c3a14f928
|
|
| MD5 |
ce9e17216e7b89295859c427f62c8a0f
|
|
| BLAKE2b-256 |
899d1bc2578980640943dafcd394bed7dac8c9cc291e043f66f5c09370fe6ee5
|
Provenance
The following attestation bundles were made for chatgpt_export_tool-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on voidfreud/chatgpt-export-tool
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chatgpt_export_tool-1.0.0-py3-none-any.whl -
Subject digest:
6858780b83009deae3299f3e0fdd64ce03d24b6969803d8e7190d56c3a14f928 - Sigstore transparency entry: 1189527519
- Sigstore integration time:
-
Permalink:
voidfreud/chatgpt-export-tool@fc1cbef2229c1a6d976a6dbbd0a3655da063d8ce -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/voidfreud
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fc1cbef2229c1a6d976a6dbbd0a3655da063d8ce -
Trigger Event:
release
-
Statement type: