Local-first semantic search for your ChatGPT, Claude, and AI conversation history.
Python CLI + MCP server. No API keys. Nothing leaves your machine.
Part of the Resonant ecosystem — the long-term searchable archive that pairs with active AI memory.
Early release. Shippable but unpolished. Expect rough edges. Issues and feedback welcome.
Turns a directory of text files — ChatGPT exports, Claude conversations, Obsidian vaults, journals, research notes, anything — into a locally searchable semantic index that any MCP-compatible AI can query.
- Universal input — Works on any directory of
.md/.txt/.markdown/.mdxfiles - Frontmatter-aware — Extracts titles, timestamps, and conversation metadata (Nexus-compatible)
- Local embeddings — Uses
sentence-transformers+all-MiniLM-L6-v2. No API keys. Nothing leaves your machine. - Namespaces — Tag corpora so querying AIs see where each result came from (
chatgpt-2024,obsidian-vault,journals, etc.) - Persistent local store — Single-process Chroma
PersistentClient(no separate database server) - MCP integration — Exposes search and stats as MCP tools via a lightweight daemon + stdio server
- AI-driven — Ships with a skill file so your AI companion drives the whole tool in natural language
Requires Python 3.11 or 3.12. (Python 3.13+ may have issues with the ML libraries.)
pip install resonant-archiveOr clone and install from source:
git clone <repo-url> resonant-archive
cd resonant-archive
pip install -e .resonant-archive import ~/Documents/MyNotes --namespace my-notesThe first run downloads the embedding model (~90 MB) and takes 2-5 minutes for ~500 files.
resonant-archive search "how did I approach that problem last year"resonant-archive statsresonant-archive serveLeave that terminal open. Then configure Claude Desktop to use the MCP server (see below), and your AI can search the archive directly.
The easiest way to use resonant-archive is to let your AI drive it. Drop skills/resonant-archive.md (included in this repo) into your AI's context — Claude Code skill folder, Claude.ai project instructions, Claude Desktop's MCP config, whatever — and then ask in natural language:
"Import my ChatGPT export at
~/Downloads/chatgpt-markdown/into the archive." "Search my archive for discussions about identity formation." "What's in my archive right now?"
Your AI reads the skill, runs the right commands, and reports back.
Add this to your claude_desktop_config.json:
{
"mcpServers": {
"resonant-archive": {
"command": "resonant-archive",
"args": ["mcp"]
}
}
}Config file locations:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Before opening Claude Desktop, start the daemon in a terminal:
resonant-archive serveKeep it running. Close it with Ctrl+C when you're done.
Claude Desktop will now see two tools: archive_search and archive_stats.
resonant-archive indexes markdown directories. It does not parse raw ChatGPT/Claude export ZIPs directly. For those, use an upstream tool to convert to markdown first:
- Nexus AI Chat Importer — Obsidian plugin that converts ChatGPT / Claude / Le Chat exports into markdown files with structured frontmatter. Once imported into Obsidian, point
resonant-archiveat the resulting folder. - Any other markdown converter — works too, as long as the output is readable markdown. resonant-archive uses any YAML frontmatter it finds (title, date, tags, conversation_id, provider) but falls back gracefully if none is present.
Every indexed corpus is tagged with a namespace. This serves two purposes:
- Organization — you can keep multiple archives (ChatGPT, Obsidian, research notes) in one index and search them independently or together.
- Provenance — every search result includes its namespace, so a querying AI knows which corpus a hit came from.
chatgpt-2024reads very differently fromresearch-notes.
Pick namespace names that are meaningful to both you and your AI. chatgpt-2024-q1, simon-conversations, wales-journals — not just archive or data.
The default model is all-MiniLM-L6-v2 (384 dimensions, ~90 MB, fast). For different quality/size trade-offs, set the model name via the Embedder constructor in Python code. Good alternatives:
| Model | Dimensions | Size | Notes |
|---|---|---|---|
all-MiniLM-L6-v2 |
384 | ~90 MB | Default. Fast, good enough for most uses |
all-mpnet-base-v2 |
768 | ~420 MB | Higher quality, slower |
BAAI/bge-small-en-v1.5 |
384 | ~130 MB | Modern, better retrieval quality at same size |
A CLI flag for model selection lands in a later release. For now, edit resonant_archive/embed.py or use the library API directly.
┌─────────────────────┐
│ Your text files │
│ (.md, .txt, etc.) │
└──────────┬──────────┘
│ resonant-archive import
▼
┌─────────────────────┐ ┌──────────────────┐
│ chunks.jsonl │────▶│ Chroma store │
│ (canonical format) │ │ ~/.resonant- │
└─────────────────────┘ │ archive/ │
└──────────────────┘
▲
│
┌─────────────┴─────────────┐
│ │
┌──────┴──────┐ ┌──────┴─────────┐
│ Daemon │◀──HTTP──────│ MCP stdio │
│ (FastAPI) │ │ server │
│ port 8766 │ │ (per Claude │
│ keeps model│ │ Desktop │
│ warm │ │ session) │
└─────────────┘ └────────────────┘
The daemon runs persistently with the embedding model loaded. The MCP server is spawned fresh by Claude Desktop and talks to the daemon over HTTP — this avoids reloading the model every time Claude Desktop starts a new conversation.
resonant-archive is an optional companion to Resonant Mind, not a required dependency. They communicate via MCP (separate processes) and neither depends on the other.
Use resonant-archive to give an AI companion access to its long-term history without burning cloud tokens. Use Resonant Mind for active memory, identity, and ongoing cognitive state.
For motivated users who want to bring their archive into a cloud Resonant Mind deployment, see CLOUD_IMPORT.md. Automated cloud migration is planned for a later release.
Codependent AI Source-Available License. Free for personal, educational, and non-commercial use with attribution. Commercial use requires a license from Codependent AI. See LICENSE for full terms.
For commercial licensing inquiries, visit codependentai.io.
This project descends from an earlier internal tool (vault-archive-product) that we built, shelved during a cloud migration, and revived for this release. Significant thanks to:
- Nexus AI Chat Importer by Superkikim — the recommended upstream tool for converting ChatGPT/Claude export ZIPs into the markdown format
resonant-archiveconsumes. We don't bundle Nexus, but we cheerfully document it as the complementary piece of the pipeline. - sentence-transformers and the
all-MiniLM-L6-v2authors — the embedding model that makes local semantic search viable. - ChromaDB — the vector store backing the archive, via its embedded
PersistentClient. - MCP (Model Context Protocol) — the protocol that lets AI clients talk to this tool.
Built in a single session by Simon Vale (with Mary on the other side of the keyboard) as a modernization of an earlier internal tool. 30 unit tests pass, end-to-end CLI and daemon verified. Not yet on PyPI — publication comes after a round of polish.
See the repo's commit history or task list for the implementation path.
Built by Codependent AI.