export conversations into markdown
Sync, tag, and cross-link your ChatGPT & Claude conversation exports into an Obsidian vault — powered entirely by a local LLM running on your own machine. No API keys, no cloud, no costs, full privacy.
⚠️ This project uses a local LLM for tagging. You need to run an LLM server on your own machine (or network). Brain Sync does not use OpenAI, Anthropic, or any cloud API. Your data never leaves your computer.
You export your conversation history from Claude or ChatGPT as a ZIP file. You drop that ZIP into a folder. Brain Sync does the rest:
- Parses the export — auto-detects Claude vs ChatGPT format.
- Sends a snippet to your local LLM to generate tags, a summary, and a category.
- Creates a clean Markdown file with Obsidian-compatible frontmatter and wikilinks.
- Cross-links related conversations across your vault automatically.
If your LLM server is offline when you drop the file, Brain Sync still saves the conversation — it queues the tagging for later.
| Requirement | Details |
|---|---|
| Python | 3.8 or newer |
| Obsidian | Any recent version |
| A local LLM server | Any server with an OpenAI-compatible /v1/chat/completions endpoint (LM Studio, Ollama, text-generation-webui, LocalAI, etc.) |
| A model | Any instruction-tuned model (7B+ recommended for best results) |
💡 Recommended: LM Studio is the easiest way to get started. It has a simple UI, runs on Windows/Mac/Linux, and starts a local server with one click — no terminal commands needed.
git clone https://github.com/YOUR_USERNAME/BrainSync.git
cd BrainSync
python scripts/setup.pyThe setup script:
- Creates the folder structure (
incoming/,vault/claude/,vault/chatgpt/) - Installs Python dependencies (
watchdog,requests) - Warns you if
config.jsonstill has placeholder values
Open config.json in the project root and replace the placeholders with your LLM server details:
{
"base_dir": ".",
"llm_url": "http://YOUR_HOST:YOUR_PORT/v1/chat/completions",
"llm_model": "YOUR_MODEL_NAME",
"llm_health_url": "http://YOUR_HOST:YOUR_PORT/v1/models"
}| Field | What to Set |
|---|---|
base_dir |
Where Brain Sync stores everything. Default "." uses the project root (wherever you cloned the repo). You can set an absolute path like ~/MyVault to store data elsewhere. |
llm_url |
The full URL to your LLM server's chat completions endpoint. Replace YOUR_HOST:YOUR_PORT with your server's address and port. The path /v1/chat/completions is the standard OpenAI-compatible endpoint that most local LLM servers expose. |
llm_model |
The exact model name your server expects. Check your LLM server's model list for the correct name. |
llm_health_url |
(Optional) URL to check if your server is online. If left empty, Brain Sync derives it from llm_url automatically. |
Start your local LLM server and load a model. Make sure it's listening on the host/port you configured.
- Open Obsidian.
- Click Open folder as vault.
- Select the
vault/folder inside your BrainSync directory.
python scripts/brain_sync.pyLeave this terminal open. Brain Sync is now watching for ZIP drops.
| Platform | How to Export |
|---|---|
| Claude | claude.ai → Profile icon → Settings → Privacy → Export Data |
| ChatGPT | chatgpt.com → Profile icon → Settings → Data Controls → Export |
Both platforms email you a download link. Download the ZIP.
Drag the downloaded .zip into your incoming/ folder.
Brain Sync detects the file, parses every conversation, tags them with your local LLM, and saves Markdown files into your Obsidian vault — complete with tags, summaries, and cross-links.
---
title: "How to learn Python fast"
date: 2026-05-21
source: claude
category: learning
tagged: true
tags:
- "python"
- "programming"
- "beginner"
---
> A conversation about the fastest path to learning Python as a beginner.
[[python]] [[programming]] [[beginner]]
---
**User:** How do I learn Python fast?
**Assistant:** Start with the basics...Every file includes:
- Frontmatter — title, date, source, category, tags (works with Dataview and other Obsidian plugins)
- Summary — one-sentence description generated by your LLM
- Wikilinks —
[[tag]]links for Obsidian's Graph View - Full transcript — the complete conversation with tool use and attachments annotated
- Cross-links — auto-generated section linking to related conversations
python scripts/brain_sync.pyStarts the folder watcher. Processes existing ZIPs, checks pending tags, then waits for new drops.
python scripts/brain_sync.py --retagRe-runs your LLM on every conversation and regenerates all tags/summaries/categories. Use this when you switch to a better model.
python scripts/brain_sync.py --reprocessWipes state files and reimports everything from scratch. Use this if your vault state gets corrupted.
ZIP dropped into incoming/
↓
Auto-detect format (Claude or ChatGPT)
↓
Parse each conversation from the JSON
↓
Check state — new, updated, or duplicate?
↓
┌─ New/Updated ──────────────────────────────────┐
│ Is local LLM online? │
│ ├─ Yes → Tag with LLM → Save Markdown │
│ └─ No → Save untagged → Queue for later │
└─────────────────────────────────────────────────┘
┌─ Duplicate ────────────────────────────────────┐
│ Skip — nothing to do │
└─────────────────────────────────────────────────┘
↓
Cross-link all notes by tag similarity
↓
Done ✅
Every conversation is tracked by its unique ID and message count. Re-exporting the same data? Duplicates are skipped. Continued a conversation and re-exported? Brain Sync detects the new messages and updates the file.
If your LLM server isn't running, conversations are saved immediately as clean Markdown (tagged untagged). Next time Brain Sync starts with your LLM online, the queue is processed automatically.
After every sync, notes are scored against each other:
- +3 points per exact tag match
- +1 point per shared word in tags (fuzzy)
- +1 point for same category
Top 5 related notes are appended to each file as wikilinks.
Edit the prompt in scripts/brain_sync.py inside the tag_conversation function:
"category": exactly one of: coding, writing, research, planning, learning, personal, work, creative, otherAdd or remove categories as you like.
Any instruction-tuned model ≥ 3B parameters works. Bigger = better tags but slower.
| Model | Size | Speed | Tag Quality |
|---|---|---|---|
| Qwen 2.5 7B Instruct | 7B | Fast | Great |
| Llama 3.1 8B Instruct | 8B | Fast | Great |
| Mistral 7B Instruct | 7B | Fast | Good |
| Phi-3 Mini | 3.8B | Very fast | Good |
| Llama 3.1 70B | 70B | Slow | Excellent |
| Plugin | Why |
|---|---|
| Graph View (built-in) | Visualize connections between conversations (Ctrl+G) |
| Dataview | Query your vault like a database |
| Quick Switcher | Fast-search across all notes |
Create a note called Dashboard.md in your vault:
TABLE category, tags, date
FROM "claude" OR "chatgpt"
SORT date DESC
LIMIT 20
Make sure config.json is in the project root (it comes with the repo). Open it and fill in your LLM server URL and model name.
Your LLM server isn't running or the URL in config.json is wrong.
- Make sure your LLM server is started and accepting requests.
- Verify
llm_urlandllm_health_urlinconfig.json. - On Windows, use
127.0.0.1instead oflocalhost.
Normal when your LLM is offline. Start your LLM server, run Brain Sync again — it tags the queued conversations automatically.
Use Windows Terminal instead of old CMD/PowerShell.
The ZIP is still being written. Find time.sleep(1) in the ZipDropHandler._handle method in brain_sync.py and change it to time.sleep(3).
| Action | Command |
|---|---|
| First-time setup | python scripts/setup.py |
| Start watching | python scripts/brain_sync.py |
| Re-tag with new model | python scripts/brain_sync.py --retag |
| Rebuild from scratch | python scripts/brain_sync.py --reprocess |
| Config Field | What It Does |
|---|---|
base_dir |
Root directory for everything (default: . = project root) |
llm_url |
Your LLM server's chat completions endpoint |
llm_model |
Model name your server expects |
llm_health_url |
(Optional) URL to check if server is online |
Brain Sync runs entirely on your machine. No cloud APIs, no API keys, no subscriptions. Your conversations stay yours.