Migrate your entire ChatGPT history to Gemini-optimized Markdown β in seconds. Now with a full-stack React dashboard, FastAPI backend, and direct NotebookLM integration.
Your conversation history is a goldmine. Whether you just want a quick backup to throw into NotebookLM or you want to build a fully searchable local knowledge base, byeGPT has you covered. It converts your raw, messy ChatGPT data export into perfectly-sized Markdown files.
| Problem | byeGPT Solution |
|---|---|
| Gemini/NotebookLM has file size limits | Auto-splits into perfectly-sized chunks (e.g., ~7MB) |
| ChatGPT exports are raw JSON blobs | Converts to clean, readable Markdown |
| Finding old conversations is impossible | Optional Semantic Search with local vector indexing |
| Hard to visualize your knowledge | Interactive Mind Map rendered directly in the browser |
| Thinking blocks (O1/GPT-5) clutter the output | Collapsed Obsidian callouts keep it clean |
| Attachments are scattered | Extracted & linked with proper relative paths |
| You want AI to "know you" instantly | Digital Passport β one click to copy your AI persona to clipboard |
| Managing notebooks is tedious | Studio Dashboard batch-uploads to NotebookLM automatically |
| Audio Overviews are hard to find | Built-in Podcast Player with play/pause controls |
| Slides need iteration | Slide Editor with per-slide AI revision prompts |
You just want your chat history in a format that NotebookLM or Gemini Advanced can easily read without hitting file-size limits.
- Run
byegpt convertand it instantly turns your.zipexport into clean Markdown chunks in./gemini_history/. - Upload the folder directly to NotebookLM as a source.
- Automatically get a
digital_passport.mdto give Gemini or NotebookLM instant context on who you are.
You want to build a local, searchable "second brain" out of your AI conversations.
- Run
byegpt convert --organizeto interactively sort your history into topic subfolders. - byeGPT generates Maps of Content (
_map.md) so you can visually click through your history in Obsidian. - Run
byegpt indexto embed your history locally using ChromaDB. - Run
byegpt query "What did we discuss about python decorators?"to instantly find answers from your past.
You want a point-and-click interface that handles everything β conversion, NotebookLM upload, and AI artifact generation β without touching the terminal.
- Start the Studio with
docker compose upand openhttp://127.0.0.1:5173(usehttp://localhost:5173only if it resolves correctly on your machine). - By default the Docker stack runs in demo mode for easy local testing.
- For real NotebookLM mode, start the stack with
BYEGPT_DEMO_MODE=false docker compose up. - Drag-and-drop your
.zipexport onto the Ingestion Dropzone β conversion starts immediately. - Click Generate Digital Passport to synthesize your AI persona, then copy it to the clipboard with one click.
- Use the Studio Controls sidebar to batch-upload your Markdown files to NotebookLM, then generate a mind map, audio overview, or slide deck directly from the dashboard.
# Clone the repository
git clone https://github.com/damie/byegpt.git
cd byegpt
# Install (editable mode)
pip install -e .
# Optional: Install Intelligence Layer dependencies (for RAG/Search)
pip install chromadb==0.4.15 sentence-transformers transformers
# Convert instantly β byeGPT auto-detects your export .zip!
byegpt convert
# Generate your Digital Passport
byegpt personaYour files land in ./gemini_history/, ready for NotebookLM, Gemini, or Obsidian.
git clone https://github.com/damie/byegpt.git
cd byegpt
docker compose up --build| Service | URL |
|---|---|
| Studio Dashboard (React) | http://127.0.0.1:5173 |
| Backend API + Swagger docs | http://127.0.0.1:8000/docs |
- π¦ ZIP & JSON support β Feed it
.ziporconversations.jsondirectly - β¨ Zero-config auto-detect β Automatically finds your export file in the current folder
- π Smart splitting β Files respect Gemini's ~7MB context window (configurable)
- π Attachment extraction β Images extracted to
assets/with relative Markdown links - π Thinking blocks β GPT-5/O1 reasoning rendered as collapsed Obsidian callouts
- π YAML frontmatter β Title, date, model, tags β searchable in Obsidian/Logseq
- 𧬠Code blocks β Properly fenced with language tags
- π Digital Passport β AI profile document capturing your communication style
- π¨ Beautiful CLI β Rich progress bars, spinners, and colorful output
- π§ Knowledge Graph β Automatically generates Map of Content (MOC) files for Obsidian
- π Semantic Search β Local vector indexing with ChromaDB for natural language retrieval
- π Topic Organizer β Interactively categorize history into topic subfolders
- π±οΈ Drag-and-drop ingestion β Drop your
.zipdirectly; real-time conversion stats appear instantly - π Digital Passport card β One-click AI persona generation with clipboard copy
- π Converted file gallery β Scrollable grid of every generated Markdown file
- βοΈ NotebookLM batch uploader β Auto-chunks files into 50-source batches and creates notebooks
- π§ Interactive Mind Map β Force-directed graph (powered by
react-force-graph-2d) visualises your knowledge connections; node labels and group colours update in real time - ποΈ Podcast Player β Built-in audio player with play/pause for NotebookLM Audio Overviews
- π Slide Editor β Expandable slide list where each slide has an AI revision prompt input β type a prompt and press Enter (or click Send) to regenerate that slide via the Gemini API
byegpt convert [OPTIONS]| Option | Default | Description |
|---|---|---|
--input, -i |
(auto) | Path to .zip or conversations.json |
--output, -o |
./gemini_history |
Output folder for Markdown files |
--organize |
false |
Interactively organize into topic subfolders |
--split-size, -s |
7MB |
Max file size per Markdown file |
--no-thinking |
false |
Exclude thinking/reasoning blocks |
--no-attachments |
false |
Skip attachment extraction |
byegpt persona [OPTIONS]| Option | Default | Description |
|---|---|---|
--input, -i |
(required) | Path to .zip or conversations.json |
--output, -o |
./digital_passport.md |
Output file path |
Index your Markdown history for semantic search.
byegpt index [OPTIONS]| Option | Default | Description |
|---|---|---|
--input, -i |
./gemini_history |
Folder containing Markdown files to index |
--db, -d |
.byegpt/index |
Path to store the vector database index |
--limit, -l |
None |
Limit indexing to the first N files (for quick testing) |
--batch-size, -b |
200 |
Number of conversations to batch per database addition |
Tip
You can index a specific topic by pointing --input to a subfolder:
byegpt index --input ./gemini_history/Python
Perform a semantic search across your indexed history.
byegpt query [TEXT] [OPTIONS]| Option | Default | Description |
|---|---|---|
--db, -d |
.byegpt/index |
Path to the vector database index |
--results, -n |
5 |
Number of results to return |
byegpt --version # Show version
byegpt --help # Show helpgraph TD
A["π¦ ChatGPT Export<br/>.zip / .json"] --> B["π Parser<br/>parser.py"]
B --> C["π Attachment<br/>Extractor"]
B --> D["π³ Message Tree<br/>Builder"]
C --> E["π assets/"]
D --> F["βοΈ Formatter<br/>formatter.py"]
F --> G["π Markdown Files<br/>β€ 7MB each"]
G --> G1["π§ Knowledge Graph<br/>_map.md files"]
G --> G2["π Vector Index<br/>ChromaDB"]
G2 --> G3["π¬ Semantic Search<br/>byegpt query"]
F --> H["π Thinking<br/>Callouts"]
F --> I["π YAML<br/>Frontmatter"]
B --> J["π Persona<br/>persona.py"]
J --> K["π Digital<br/>Passport"]
graph LR
subgraph Browser["π₯οΈ Studio Dashboard (React)"]
DZ["π±οΈ Ingestion<br/>Dropzone"]
PC["π Passport<br/>Card"]
CG["π Chat<br/>Gallery"]
SC["βοΈ Studio<br/>Controls"]
AG["π¨ Artifact<br/>Gallery"]
MM["π§ Mind Map<br/>(Force Graph)"]
PP["ποΈ Podcast<br/>Player"]
SE["π Slide<br/>Editor"]
end
subgraph API["β‘ FastAPI Backend"]
CV["/convert"]
PS["/persona"]
NB["/notebooks/upload"]
MMA["/notebooks/{id}/mindmap"]
AUD["/notebooks/{id}/audio"]
SLD["/notebooks/{id}/slides"]
end
subgraph NLM["βοΈ NotebookLM (Google)"]
NB2["Notebook<br/>Sources"]
ART["AI Artifacts"]
end
DZ -->|"POST .zip"| CV
CV -->|"Markdown files"| CG
PC -->|"POST .zip"| PS
SC -->|"Upload batch"| NB
NB --> NB2
SC -->|"Generate"| MMA & AUD & SLD
MMA & AUD & SLD --> ART
ART --> MM & PP & SE
AG --> MM & PP & SE
The Studio Dashboard is a dark-themed React application (Tailwind + Vite) that guides you through a 4-step workflow using a two-column layout:
ββββββββββββββββββββββββββββ byeGPT Studio ββββββββββββββββββββββββββββββββ
β β
β βββββββββββββββ Main (2/3 width) βββββββββββββββ βββ Sidebar (1/3) ββββ
β β β β ββ
β β β Import your ChatGPT export β β Studio Controls ββ
β β βββββββββββββββββββββββββββββββββββββββββββ β β βββββββββββββββ ββ
β β β π¦ Drop your ChatGPT export here β β β β 1 Β· Upload β ββ
β β β Accepts .zip or conversations.json β β β β to NLM β ββ
β β βββββββββββββββββββββββββββββββββββββββββββ β β βββββββββββββββ ββ
β β β β βββββββββββββββ ββ
β β β‘ Digital Passport β β β 2 Β· Generateβ ββ
β β βββββββββββββββββββββββββββββββββββββββββββ β β β Artifacts β ββ
β β β π€ Generate Digital Passport β β β β π§ Mind Mapβ ββ
β β β [ Sync Persona as Global Context π ] β β β β ποΈ Audio β ββ
β β βββββββββββββββββββββββββββββββββββββββββββ β β β π Slides β ββ
β β β β βββββββββββββββ ββ
β β β’ Converted Files β β ββ
β β ββββββββ ββββββββ ββββββββ ββββββββ β β ββ
β β β π β β π β β π β β π β β¦ β β ββ
β β ββββββββ ββββββββ ββββββββ ββββββββ β β ββ
β β β β ββ
β β β£ Artifacts β β ββ
β β βββββββββββββββββββββββββββββββββββββββββββ β β ββ
β β β π§ Mind Map [force-directed graph] β β β ββ
β β β ποΈ Audio Overview [βΆ player bar] β β β ββ
β β β π Slides [expandable list + prompts] β β β ββ
β β βββββββββββββββββββββββββββββββββββββββββββ β β ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The entry point of the Studio. Drop your ChatGPT .zip or conversations.json directly onto the dropzone β or click to open a file picker.
- Idle state: shows a file-archive icon with a dashed border that glows teal on hover/drag-over
- Converting state: border dims, a pulsing progress bar appears, and the label changes to "Convertingβ¦"
- Done state: a green checkmark appears alongside three stat tiles showing the number of Conversations, Files created, and Attachments extracted
- Error state: a red alert icon with the error message from the backend
Triggered after your file is uploaded. Click Generate Digital Passport to call the /persona API β the backend analyses all your user messages and returns a structured Markdown document.
- The first ~600 characters of the passport are previewed in a scrollable code block
- A "Sync Persona as Global Context" button copies the full Markdown to your clipboard so you can paste it into any AI assistant (Gemini, ChatGPT, Claudeβ¦)
- The button briefly shows a green checkmark and "Copied!" confirmation
A scrollable 2-column grid of every .md file produced by the conversion. Each card shows the filename with a document icon, truncated to fit. Lets you quickly see the scope of your archive at a glance.
A sticky sidebar panel divided into two sections:
Section 1 β Upload to NotebookLM
- A text input to name the notebook (defaults to
"byeGPT Archive") - An Upload to NotebookLM button that posts the output directory to
/notebooks/upload; the backend automatically splits files into batches of 50 (NotebookLM's source limit) and creates one notebook per batch - A confirmation badge showing how many notebooks were created
Section 2 β Generate Artifacts (appears once notebooks exist)
- If multiple notebooks were created, a dropdown lets you select which one to target
- Three action buttons, each with a loading spinner while the request is in-flight:
- π§ Generate Mind Map β triggers
/notebooks/{id}/mindmap - ποΈ Generate Audio Overview β triggers
/notebooks/{id}/audio - π Generate Slides β triggers
/notebooks/{id}/slides
- π§ Generate Mind Map β triggers
An interactive, physics-based force graph powered by react-force-graph-2d (rendered on an HTML canvas).
- Nodes represent knowledge concepts; edges represent connections between them
- Node labels are rendered in teal (
#14b8a6) on a near-black canvas (#03050a) - The graph is fully interactive: nodes can be dragged, and the simulation settles automatically
- A header bar shows the node count and link count
- Graceful fallback: if
react-force-graph-2dfails to load (e.g., in SSR), a plain accessible table listing all nodes and their groups is shown instead
A minimal audio player for NotebookLM's "Audio Overview" MP3 feature, embedded directly inside the Artifact Gallery.
- A circular play/pause button (teal background, white icon) toggles playback
- A thin progress track shows the playback position (updating via the
<audio>element) - The
onEndedevent resets the button back to the play state automatically
An expandable accordion list of the AI-generated presentation slides.
- Each slide row shows the slide number and title; clicking it toggles the content panel open/closed using a chevron icon
- The expanded panel shows the slide body text and a revision prompt input:
- Type a prompt (e.g., "Make this slide about Python decorators more visual")
- Press Enter or click the Send button (β) to call
PATCH /notebooks/{id}/slides/{index}and update that individual slide in place
- The slide list updates reactively as revisions come back from the API
The persona command (and the Digital Passport Card in the Studio) analyses your entire ChatGPT history and generates a structured document capturing:
- π Profile Summary β Total conversations, messages, date range
- π·οΈ Top Topics β Your most discussed subjects
- π€ Models Used β Which AI models you've used
- π Activity Timeline β Monthly conversation frequency
- π¬ Communication Style β Message length, question ratio, style primer
In the Studio Dashboard the passport is previewed directly in the card and can be copied to the clipboard with a single click. On the CLI it writes to ./digital_passport.md.
Share this document with any AI assistant and it'll understand your preferences and communication style instantly!
Each generated Markdown file includes:
---
title: "My Conversation Title"
date: 2024-03-10
model: gpt-4o
tags: [chatgpt-export, archive]
---
# My Conversation Title (2024-03-10)
**USER:**
What is the meaning of life?
**ASSISTANT:**
The meaning of life is a philosophical question...
> [!abstract]- π Thinking Process
> Let me consider this from multiple angles...
> First, from a philosophical standpoint...Context Anchor comments (injected by the Studio backend for NotebookLM citation) appear at the very top of each file:
<!-- source: https://chatgpt.com/c/abc123def456 -->
---
title: "My Conversation Title"
...byegpt/
βββ .byegpt/ # Local cache & session storage
βββ assets/ # Extracted images from ChatGPT
βββ backend/ # FastAPI & NotebookLM integration
β βββ app/
β β βββ main.py # Entry point & 10 API routes
β β βββ cloud.py # notebooklm-py batch uploader + artifact wrappers
β β βββ parser.py # Markdown conversion + Context Anchor injection
β β βββ auth_manager.py # Playwright headless login & cookie persistence
β βββ requirements.txt
β βββ Dockerfile # python:3.11-slim + Playwright/Chromium
βββ frontend/ # React 18 + Tailwind CSS + Vite
β βββ src/
β β βββ components/
β β β βββ IngestionDropzone.tsx # Drag-and-drop upload + live stats
β β β βββ PassportCard.tsx # Persona preview + clipboard sync
β β β βββ ChatGallery.tsx # Converted file grid
β β β βββ StudioControls.tsx # NotebookLM action sidebar
β β β βββ MindMap.tsx # Force-graph canvas (react-force-graph-2d)
β β β βββ ArtifactGallery.tsx # MindMap + PodcastPlayer + SlideEditor
β β βββ hooks/
β β β βββ useNotebook.ts # API calls: upload, mindmap, audio, slides
β β βββ App.tsx # 4-step layout (2-column grid)
β βββ package.json
β βββ tailwind.config.js
βββ core/ # Shared CLI logic (dependency-free wrappers)
β βββ converter.py # convert_conversations() β no Typer/Rich coupling
β βββ persona.py # build_passport()
βββ skill.json # Claude / Codex agent integration descriptor
βββ docker-compose.yml # Backend + Frontend + named node_modules volume
βββ README.md
Backend:
cd backend
pip install -r requirements.txt
playwright install chromium
uvicorn app.main:app --reload
# API docs β http://localhost:8000/docsFrontend:
cd frontend
npm install
npm run dev
# Studio β http://localhost:5173Vite proxies /api/* β http://localhost:8000 so the React dev-server and the FastAPI backend talk to each other without CORS issues.
The Studio requires a Google account to use the NotebookLM features. On first launch:
- Call
POST /auth/login(or click the login button in the UI once implemented) - A headed Chromium window opens β complete the Google sign-in
- The session cookies are saved to
.byegpt/storage.jsonand reused on all future requests GET /auth/statusreturns{"authenticated": true}once cookies are stored
The included skill.json lets Claude Code or Codex talk directly to your byeGPT PowerApp:
"Claude, ask my byeGPT archive about that recipe I saved in 2023."
Load the skill in Claude Code:
claude skill add ./skill.json| Method | Path | What the Studio uses it for |
|---|---|---|
GET |
/health |
Liveness probe |
GET |
/auth/status |
Check if Google session cookie exists |
POST |
/auth/login |
Start headless Playwright Google login |
POST |
/convert |
IngestionDropzone β Markdown + Context Anchors |
POST |
/persona |
PassportCard β Digital Passport Markdown |
POST |
/notebooks/upload |
StudioControls β batch upload to NotebookLM |
GET |
/notebooks/{id}/mindmap |
StudioControls β force-graph JSON for MindMap |
GET |
/notebooks/{id}/audio |
StudioControls β MP3 for PodcastPlayer |
GET |
/notebooks/{id}/slides |
StudioControls β slide list for SlideEditor |
PATCH |
/notebooks/{id}/slides/{i} |
SlideEditor revision prompt β updated slide |
# Install CLI with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run with coverage
pytest tests/ -v --cov=byegpt --cov-report=term-missingContributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Run tests (
pytest tests/ -v) - Commit your changes
- Open a Pull Request
MIT β see LICENSE for details.
Made with β€οΈ for everyone building a personal AI knowledge base
byeGPT v3.0.0 "Studio"
The Docker stack defaults to demo mode because interactive Google login from inside a Linux container is unreliable on non-X11 hosts.
To use real NotebookLM:
BYEGPT_DEMO_MODE=false docker compose up --buildThen use one of these two paths:
- Recommended: place a valid Playwright session file at
.byegpt/storage.jsonbefore opening the dashboard. - Alternative: run the backend on the host OS instead of Docker, complete
/auth/loginthere, and let it write.byegpt/storage.json.
If you run in real mode without a valid session file, NotebookLM actions will return:
Interactive NotebookLM login is unavailable in Docker without an X server.
That is expected in containerized mode on many Windows/macOS setups.
If you want a real NotebookLM session without fighting the Docker browser limitation, run the backend on the host once:
Windows:
.\scripts\start_host_backend.ps1Or:
scripts\start_host_backend.cmdmacOS / Linux / WSL:
./scripts/start_host_backend.shWhat the script does:
- Creates
.venv-backend - Installs
backend/requirements.txt - Installs Playwright Chromium
- Starts the backend in real mode on
http://127.0.0.1:8000
Then:
- Open
http://127.0.0.1:8000/docs - Run
POST /auth/login - Complete the Google / NotebookLM sign-in in the browser window
- Confirm
.byegpt/storage.jsonnow exists - Stop the host backend
- Start Docker in real mode:
BYEGPT_DEMO_MODE=false docker compose up --buildThe Docker backend will reuse .byegpt/storage.json.
Google may reject even a real Chrome instance when Playwright launches it.
If that happens, use Chrome manually and capture the session instead:
- Start Chrome with remote debugging:
.\scripts\start_chrome_debug.ps1- In that Chrome window, sign in to NotebookLM manually and make sure it works.
- In a second terminal, capture the session into
.byegpt/storage.json:
.\scripts\capture_chrome_session.ps1- Press Enter in the capture terminal after NotebookLM is open in Chrome.
- Start Docker in real mode:
BYEGPT_DEMO_MODE=false docker compose up --buildThis path avoids automating the Google sign-in itself.