{
  "markdown": "<!-- mcp-name: io.github.dioniipereyraa/memex -->\n\n# Memex\n\n[![CI](https://github.com/dioniipereyraa/memex/actions/workflows/ci.yml/badge.svg)](https://github.com/dioniipereyraa/memex/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)\n\n**Your Claude.ai chats and your Claude Code sessions live in two worlds that never talk. Memex makes them one memory you can search from both.**\n\nLocal-first MCP server that indexes your Claude.ai chat history and your local Claude Code / terminal sessions, and exposes them to Claude Code (stdio) and Claude.ai (remote MCP connector).\n\n**Status:** alpha, `0.3.1` on PyPI. Phases 0 to 7 closed, security-audited (plus four adversarial red-team rounds). Shipped: hybrid search, live capture, auto-summaries, chat ↔ repo association, the Claude.ai remote connector (GitHub OAuth), Claude Code / terminal ingestion with secret redaction, one-command setup, cross-platform autostart, and one-click claude.ai history backfill.\n\n![Memex recalling a claude.ai chat from Claude Code](docs/screenshots/demo.gif)\n\n*End-to-end demo: from Claude Code, you ask about something you discussed on claude.ai. Memex searches your chat history (`search_chats`) and Claude answers from the real conversation. No copy-paste, no manual context handoff.*\n\n## Install\n\nOne command installs uv + Memex and runs `memex setup` (registers the MCP server, installs the always-on capture service, indexes your local sessions, prints the pairing token):\n\n```bash\n# macOS / Linux\ncurl -LsSf https://raw.githubusercontent.com/dioniipereyraa/memex/main/scripts/install-pypi.sh | sh\n```\n\n```powershell\n# Windows (PowerShell)\npowershell -ExecutionPolicy ByPass -c \"irm https://raw.githubusercontent.com/dioniipereyraa/memex/main/scripts/install-pypi.ps1 | iex\"\n```\n\nThen the one browser step a terminal cannot do: install the [Chrome extension](#live-capture-phase-2), paste the token it printed, and click \"Backfill claude.ai history\". Other paths (pipx, `uv tool install`, from source) are under [Installation](#installation).\n\n## The problem\n\nBrainstorming and planning happen in Claude.ai. Execution happens in Claude Code. The two worlds do not talk to each other: Claude Code cannot read a chat of yours from Claude.ai, not even the one that originated the task it is currently working on. The memory Anthropic shipped on Claude.ai (March 2026) is curated, not full history, and lives isolated inside Claude.ai.\n\nMemex fills that gap: runs locally, indexes the entire corpus of your chats, and exposes them as MCP tools so Claude can search and pull past context whenever it needs to.\n\n## How it works\n\n```\n[Claude.ai]\n    ↓  (official JSON export / Chrome ext)\n[Ingestor]  →  [SQLite + sqlite-vec]  →  [local embeddings (fastembed / Ollama)]\n                                    ↓\n                          [core: storage + retrieval]\n                                    ↓\n                  [MCP stdio]  ───→  Claude Code, Claude Desktop\n                  [MCP Streamable HTTP] ─→ Claude.ai connector\n```\n\nDesign: pure core (storage, ingest, embeddings, retrieval) decoupled from transport. The same engine serves both stdio and remote MCP without a rewrite.\n\n## Installation\n\n### Quick install (one command)\n\nInstalls [uv](https://docs.astral.sh/uv/) if needed (it brings the right\nPython), installs Memex from PyPI, and runs `memex setup` to wire it into Claude\nCode (MCP server + always-on capture service + local session indexing + the\npairing token). No git clone required.\n\n```bash\n# macOS / Linux\ncurl -LsSf https://raw.githubusercontent.com/dioniipereyraa/memex/main/scripts/install-pypi.sh | sh\n```\n\n```powershell\n# Windows (PowerShell)\npowershell -ExecutionPolicy ByPass -c \"irm https://raw.githubusercontent.com/dioniipereyraa/memex/main/scripts/install-pypi.ps1 | iex\"\n```\n\nThe only step a terminal cannot do is the browser one: install the\n[Chrome extension](#live-capture-phase-2), paste the token the installer prints,\nand click \"Backfill claude.ai history\" to import your history. Embeddings work\nout of the box (a quantized 130 MB [fastembed](https://github.com/qdrant/fastembed)\nmodel downloads on first ingest; no Ollama, no API key).\n\n> A plain `pipx install memex-chats` (or `uv tool install memex-chats`) followed\n> by `memex setup` does the same thing in two steps. The autostart service is\n> generated for the wheel install too (launchd / systemd / a logon Scheduled\n> Task), so no clone is needed for it.\n\n### From source (for development)\n\nClone the repo to get an editable install plus the extension source and service\ntemplates. You need [git](https://git-scm.com/downloads); the script installs uv\nand the pinned Python for you.\n\n### macOS / Linux\n\n```bash\ngit clone https://github.com/dioniipereyraa/memex\ncd memex\n./scripts/install.sh\n```\n\n`install.sh` installs uv if you do not have it, runs `uv sync`, and verifies\nthe install with `memex doctor`. That is the whole setup.\n\n### Windows (PowerShell)\n\n```powershell\ngit clone https://github.com/dioniipereyraa/memex\ncd memex\npowershell -ExecutionPolicy Bypass -File .\\scripts\\install.ps1\n```\n\nSame three steps as the macOS script (install uv, sync, verify). If git is\nnot installed, get it from [git-scm.com](https://git-scm.com/downloads) first.\n\n### Manual (any OS, if you prefer explicit steps)\n\n```bash\n# 1. Install uv (skip if you already have it):\n#    macOS/Linux:  curl -LsSf https://astral.sh/uv/install.sh | sh\n#    Windows:      powershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\ngit clone https://github.com/dioniipereyraa/memex\ncd memex\nuv sync               # installs Python 3.13 + dependencies into .venv\nuv run memex doctor   # verify\n```\n\n### Upgrading (already have memex)\n\nUpgrade with the **same tool that installed it**, or the new version will not land\non your PATH. A previous install owns the `memex` executable, so installing again\nwith a different manager fails with \"Executables already exist\" and `memex` keeps\nrunning the old version. (This is the usual reason `memex sync` seems to \"not\nexist\" after an upgrade: an old pipx-owned `memex` shadowed a newer `uv tool`\ninstall.)\n\n```bash\n# 1. Find which tool owns it:\nwhich memex            # macOS / Linux\nGet-Command memex      # Windows (PowerShell)\n\n# 2. Upgrade with that tool:\npipx upgrade memex-chats        # if pipx owns it\nuv tool upgrade memex-chats     # if uv owns it\n```\n\nIf you want to switch managers, uninstall the old one first (`pipx uninstall\nmemex-chats` or `uv tool uninstall memex-chats`), then reinstall. After upgrading,\n`memex --version` shows the new version and `memex doctor` should pass.\n\n### Multi-device (optional)\n\nTo make Claude one memory across several machines, install\n[Tailscale](https://tailscale.com) **first** (so each device has a stable private\naddress), then opt in once per device:\n\n```bash\nmemex setup --sync     # opt-in, persisted: the always-on service is sync-reachable\n```\n\nIt prints the single `memex sync connect ...` line to run on your other devices.\nThe choice is saved, so the service stays sync-reachable across reboots without\nre-running anything. Full flow, security model, and the manual one-shot\nalternative are in [Syncing across your devices](#syncing-across-your-devices).\n\nFor a **dual-boot machine** (Linux and Windows that are never on at the same time),\nuse file-based sync instead: `memex setup --sync-dir <shared-folder>` on each OS,\npointed at the same folder. No Tailscale, no two devices online at once. See\n[Dual-boot or never-online-together](#dual-boot-or-never-online-together-file-based-sync).\n\n## First run\n\nThe fast path is one command:\n\n```bash\nuv run memex setup\n```\n\n`memex setup` wires everything end to end and is safe to re-run: it registers\nthe MCP server with Claude Code (`claude mcp add`), installs the always-on\nlive-capture service (launchd on macOS, systemd on Linux, a Scheduled Task on\nWindows), indexes your local Claude Code sessions, and prints the access token\nto paste into the Chrome extension. Each step degrades to a warning instead of\naborting the rest. Flags: `--no-mcp`, `--no-autostart`, `--no-ingest`,\n`--remote` (also install the claude.ai connector agent), `-y` (no prompt).\n\nAfter that, the only manual step left is installing the\n[Chrome extension](#live-capture-phase-2) and pasting the token, so new chats\nare captured as you go.\n\n### Manual steps (if you prefer to run them yourself)\n\n```bash\n# 1. Request your official Claude.ai export (Settings → Privacy → Export data),\n#    then ingest it (first run downloads the embedding model, ~30s):\nuv run memex ingest /path/to/your-export.zip\n\n# 2. Optionally index your local Claude Code / terminal sessions:\nuv run memex ingest-claude-code\n\n# 3. Search, or wire it into Claude Code (see \"Wiring it into Claude Code\"):\nuv run memex search \"your query\" -n 5\nuv run memex stats\n```\n\n(If you installed with a script, the commands above work as written. If you\ninstalled the published PyPI package instead, drop the `uv run` prefix.)\n\n> **Where your data lives.** From a cloned repo, the database and exports stay\n> in `<repo>/data`. From a `uvx`/`pip` install, they go to your OS data\n> directory (`~/Library/Application Support/memex` on macOS,\n> `%LOCALAPPDATA%\\memex` on Windows, `~/.local/share/memex` elsewhere). Override\n> with `MEMEX_DB_PATH` / `MEMEX_EXPORTS_DIR`. `memex doctor` prints the resolved\n> path.\n\n## Using Memex (after setup)\n\nOnce `memex setup` finishes, nothing else needs launching: the capture server and\nthe indexers run in the background. You use Memex three ways.\n\n**1. From Claude Code (the main way).** Setup registers the MCP server, so Claude\nCode can search your whole history and keep it fresh through these tools:\n\n| Tool | What it does |\n|---|---|\n| `search_chats` | Semantic + keyword search across your claude.ai chats AND Claude Code sessions |\n| `get_chat` | Fetch a full conversation by id |\n| `list_recent_chats` | Your most recent conversations |\n| `find_related` | Conversations related to a topic or snippet |\n| `index_terminal_sessions` | Index your local Claude Code sessions now (so the current one becomes searchable) |\n| `sync_now` | Sync with your other devices now (paired peers + the dual-boot shared folder) |\n\nJust ask Claude Code naturally (\"what did we decide about X in my claude.ai\nchats?\", \"index this session\", \"sync this to my other devices\") and it calls\nthese. `index_terminal_sessions` and `sync_now` are local-only (never exposed to\nthe remote claude.ai connector). Note `sync_now` sends what is already indexed, so\nto include the session you are in, ask Claude to `index_terminal_sessions` first. To have context injected automatically at the start\nof a session, add the optional [SessionStart hook](#proactive-context-injection-sessionstart-hook).\n\n**2. From the terminal.** `memex search \"...\"`, `memex stats`, `memex doctor`,\n`memex token` (re-print the extension pairing token), `memex --version`.\n\n**3. Capture (automatic, you run nothing).** The Chrome extension indexes a\nclaude.ai chat as you open or reload it (and its \"Backfill\" button imports your old\nhistory once); your Claude Code sessions are indexed when a session ends, plus a\n15-minute backstop.\n\n### How fresh is the data (real-time)?\n\n| Path | Latency |\n|---|---|\n| A claude.ai chat into your local index | Near-instant: captured as you open/reload the chat (embedded in seconds) |\n| A Claude Code session into your local index | At session end, plus a 15-minute backstop |\n| Available to Claude Code on the **same** machine | Immediate (it reads the same local DB the capture writes) |\n| **Across devices** | **Not live.** Periodic + overlap: see below |\n\nSame-machine is essentially real-time. **Cross-device is not a live relay** (it is\npeer-to-peer with no cloud): paired devices auto-reconcile every 15 minutes while\nboth are online, and you can force it immediately with **`memex sync now`**. A\nclaude.ai chat is captured by the extension on open/reload, so to sync the latest\nturns of an in-progress chat, reload it (so the extension re-captures it), then run\n`memex sync now`. The terminal cannot read claude.ai directly, so the extension is\nalways what captures; sync only propagates what is already indexed locally.\n\n## Embeddings backend\n\nDefault is fastembed (zero-config). To route through a local Ollama instead\n(e.g. you already run it for other models):\n\n```bash\nexport MEMEX_EMBED_BACKEND=ollama\nollama pull nomic-embed-text          # install Ollama first: https://ollama.com/download\n```\n\nOn Windows, install Ollama from [ollama.com/download](https://ollama.com/download)\nbefore setting `MEMEX_EMBED_BACKEND=ollama`. This is optional; fastembed needs\nnone of it.\n\n## Diagnostics\n\nRun `memex doctor` any time something is not working. It checks Python version, database, embedder, live-capture server, summarizer config, registered repos, and indexed corpus. Reports OK / WARN / FAIL per check.\n\n## Troubleshooting\n\nStart with `memex doctor` (above): most of the issues below also surface there.\n\n**`memex: command not found` right after installing.** The `memex` executable lives in the tool's bin directory, which may not be on your `PATH` in the current shell yet. Open a new terminal, or add it now:\n- macOS / Linux: `export PATH=\"$HOME/.local/bin:$PATH\"`\n- Windows: re-open the terminal so the installer's PATH change takes effect (the bin dir is `%USERPROFILE%\\.local\\bin` for `uv tool`, or the pipx Scripts dir).\n\nThen confirm the right binary: `which memex` (macOS/Linux) or `where memex` (Windows). It should point at the uv-tool / pipx install, not an old clone.\n\n**The extension shows the server as not responding, or ingest returns `401`.**\n- Is the server up? `curl -s http://127.0.0.1:5777/health` should return JSON. If it does not, start it (`memex serve`) or check the autostart service below.\n- `401` means the pairing token is missing or stale: run `memex token`, copy the value, paste it into the extension popup, and click **Save token**.\n\n**The autostart service did not come up.** Check its status, then read its log:\n- **Linux**: `systemctl --user status memex-serve`; log at `~/.local/share/memex/serve.log`. `Failed to connect to bus` means there is no user systemd manager for this session (common over plain SSH): run `loginctl enable-linger \"$USER\"`, make sure `XDG_RUNTIME_DIR=/run/user/$(id -u)` is set, then re-run `memex install-service`.\n- **macOS**: `launchctl list | grep memex`; log in the data dir (`~/Library/Application Support/memex/com.memex.serve.log` on a PyPI install, `<repo>/data/serve.log` from source).\n- **Windows**: Task Scheduler, or `schtasks /Query /TN MemexServe /V`; log at `%LOCALAPPDATA%\\memex\\serve.log`. If an older install left a task with the same name, it can silently mask the new one: delete it (`schtasks /Delete /TN MemexServe /F`) and re-run `memex install-service`.\n\n**Autostart does not survive logout or reboot (Linux).** A systemd *user* unit is torn down when your session ends unless lingering is enabled: `loginctl enable-linger \"$USER\"`.\n\n**The one-command installer fails with a shell error.** The installer is POSIX `sh`. If you are on a very old or unusual shell and the pipe fails, fetch and run it with bash instead: `curl -LsSf <url>/install-pypi.sh | bash`.\n\n**Windows: `uv tool install` fails with \"Acceso denegado (os error 5)\" copying `memex-mcp.exe`.** Two causes, usually together:\n- **Claude Code / Claude Desktop is running** and its MCP child process holds the running `.exe`. Close Claude Code and Claude Desktop, then retry.\n- **Windows Defender blocks writing a brand-new `.exe`** even when nothing holds it. The tell: the destination file does not exist yet (`Test-Path \"$env:USERPROFILE\\.local\\bin\\memex-mcp.exe\"` is `False`) but the copy still fails. Add a Defender exclusion for `%USERPROFILE%\\.local\\bin` and `%APPDATA%\\uv`.\n\nThen re-run with `uv tool install --force memex-chats` (or `uv tool install --reinstall --refresh <spec>` when updating from a branch).\n\n**Windows: a paired device times out reaching your sync port (5777).** In sync-reachable mode the always-on server binds `0.0.0.0:5777`, but Windows Firewall silently drops inbound connections (the peer just times out, never \"connection refused\") until a rule allows the port. `memex setup --sync` adds it for you (idempotent, best-effort); if setup was not elevated it prints the one-time admin command to run yourself: `New-NetFirewallRule -DisplayName \"Memex sync 5777\" -Direction Inbound -Protocol TCP -LocalPort 5777 -Action Allow`.\n\n**Sync times out even though `tailscale ping` works.** If `tailscale ping <peer>` succeeds but regular ping/TCP (and memex sync) time out in BOTH directions, the problem is a local TUN/routing conflict on one of the machines, not memex and not the firewall rule: another VPN-style adapter (Hamachi, another VPN, a virtual switch) is swallowing the OS traffic that should ride the Tailscale interface. Disable or remove the other adapter and restart the Tailscale service. (Seen live: a Hamachi adapter installed for game hosting broke a Windows box's Tailscale traffic while `tailscale ping` kept working.)\n\n**The first backfill (or first ingest) is slow.** The first embed downloads a ~130 MB quantized model; that is one-time, later runs are fast. The backfill is incremental and safe to re-run, so a slow or interrupted first pass simply resumes where it left off.\n\n**Ingest uses too much memory.** Peak RAM scales with the embed batch size. Lower it: set `MEMEX_EMBED_BATCH_SIZE=1` (about 0.67 GB peak) in your environment or `.env`.\n\n**Where is my data?** `memex doctor` prints the DB path. By default it is `~/.local/share/memex` (Linux), `~/Library/Application Support/memex` (macOS), or `%LOCALAPPDATA%\\memex` (Windows) for a PyPI install, or `<repo>/data` from a clone. Override with `MEMEX_DB_PATH` / `MEMEX_EXPORTS_DIR`.\n\n## MCP server tools (v1)\n\n- `search_chats(query, limit=5, source?, mode=\"hybrid\", repo?)` searches the corpus. Modes: `hybrid` (default, combines vector search + FTS5 BM25 via Reciprocal Rank Fusion), `semantic` (vectors only), `lexical` (FTS5 only, ideal for proper nouns or exact terms). `source` filters by origin (`conversations`, `design_chat`, `memory`). `repo` boosts results associated to a registered repo (see \"Repo associations\" below). Deduplicated per conversation.\n- `get_chat(uuid, messages_limit=10, messages_offset=0)` fetches a conversation with its messages, paginated. `raw_content` is omitted; each message is truncated to 1500 chars to stay inside the client's token budget (worst-case response ~17k chars). Long chats are paginated with `messages_offset`; max `messages_limit` is 100.\n- `list_recent_chats(limit=10, source?)` lists the latest chats ordered by last update.\n- `find_related(context, limit=5, repo?)` takes free-form text (a paragraph, a file contents, the current discussion) and returns chats that are semantically related. Pure vector search, no FTS, capped at 4000 input chars. Useful when you want \"more like this\" without typing a keyword query.\n\nThe stdio server (`memex-mcp`, used by Claude Code) also exposes two **write/maintenance** tools, so you can ask Claude to keep your memory fresh instead of dropping to a terminal. They are **local-only**: never registered on the remote claude.ai connector (they mutate the store and reach the network).\n- `index_terminal_sessions()` runs the incremental `ingest-claude-code` scan (indexes new/changed local Claude Code sessions, including the current one up to what is flushed to its transcript). Shares the single-flight ingest lock; returns counts.\n- `sync_now()` runs an immediate two-way reconcile with every paired device and, if a shared folder is configured, a file sync. Requires sync enabled. It propagates what is ALREADY indexed, so to include the current session call `index_terminal_sessions` first.\n\nSearch is also reachable from the CLI with `memex search \"query\" --mode {hybrid|semantic|lexical}`. For databases created before the hybrid FTS5 work, run `memex reindex-fts` once to populate the lexical index.\n\n## Wiring it into Claude Code\n\nOnce your local database is populated (`memex ingest`), start the MCP server with `uv run memex-mcp`. For Claude Code to discover it automatically, add a `.mcp.json` file at the root of your project (or a user-level server in `~/.claude.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"memex\": {\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"memex-mcp\"],\n      \"cwd\": \"/absolute/path/to/the/memex/repo\"\n    }\n  }\n}\n```\n\nSet `cwd` to the absolute path where you cloned Memex (where `pyproject.toml` lives). Restart Claude Code and the tools `search_chats`, `get_chat`, `list_recent_chats` will show up in the session.\n\nThe same searches are also available from the CLI via `uv run memex search \"...\"` if you prefer them outside Claude Code.\n\n## Connecting from claude.ai (remote MCP, Phase 4)\n\n`memex serve-remote` exposes the same 4 tools as a [custom connector](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp) for claude.ai. One connector works across claude.ai web, Claude Desktop, and the mobile apps: the connection is brokered by your Claude account and always originates from Anthropic's cloud, never from your device. That has two consequences:\n\n1. The server must be reachable on a **public HTTPS URL** (a hostname with a public IPv4 `A` record; `localhost` and private IPs are rejected by design). The intended setup is a tunnel that terminates TLS and proxies to Memex on loopback.\n2. Auth is either *none* or *full OAuth 2.0* (claude.ai has no field to paste a token). Memex uses OAuth backed by a GitHub OAuth App, restricted to an allow-list of GitHub usernames: anyone else who completes the OAuth dance still gets a 401 on every request. Your machine must be on (and the tunnel up) for the connector to respond.\n\n### 1. Publish a URL with Tailscale Funnel\n\nInstall [Tailscale](https://tailscale.com/download), log in, then:\n\n```bash\ntailscale funnel --bg 8377\n```\n\nThis prints your public URL, e.g. `https://my-mac.my-tailnet.ts.net`, TLS included. Any other tunnel works the same way (ngrok, Cloudflare Tunnel); Memex only needs the resulting `https://` URL.\n\n### 2. Create a GitHub OAuth App\n\nAt [github.com/settings/developers](https://github.com/settings/developers) > OAuth Apps > New OAuth App:\n\n- Homepage URL: your funnel URL.\n- Authorization callback URL: `<funnel URL>/auth/callback`.\n\nCopy the Client ID and generate a Client Secret.\n\n### 3. Configure and run\n\nIn `.env` (see `.env.example`):\n\n```bash\nMEMEX_REMOTE_BASE_URL=https://my-mac.my-tailnet.ts.net\nMEMEX_GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxx\nMEMEX_GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxx\nMEMEX_REMOTE_ALLOWED_GITHUB_LOGINS=your-github-username\n```\n\n```bash\nuv run memex serve-remote   # listens on 127.0.0.1:8377, endpoint at /mcp\n```\n\nThe server refuses to start with incomplete config (no insecure defaults: an empty allow-list would expose your whole chat history to any GitHub account).\n\n### 4. Add the connector in claude.ai\n\nSettings > Connectors > Add custom connector, with URL `https://my-mac.my-tailnet.ts.net/mcp`. claude.ai registers itself via dynamic client registration, sends you through the GitHub authorization, and the tools appear in your chats. OAuth state is persisted encrypted on disk, so restarting `serve-remote` does not break the connection.\n\nSecurity model in short: loopback bind + tunnel, OAuth proxy over GitHub with a username allow-list enforced on **every** request (revoking the app on GitHub locks it out immediately), `TrustedHostMiddleware` pinned to the public hostname, and the same indirect-prompt-injection envelope on tool results as the stdio transport.\n\n## Indexing Claude Code / terminal sessions (Phase 6)\n\nMemex also indexes your local Claude Code and terminal sessions, so a single search covers both halves of your history: what you discussed on claude.ai and what you built with Claude Code. Claude Code records each session as a JSONL file under `~/.claude/projects/`; Memex reads them directly (no extension, no network). This covers Claude Code wherever it runs, the terminal CLI and the VS Code / JetBrains extensions alike: they all write the same transcripts.\n\n```bash\nuv run memex ingest-claude-code        # scans ~/.claude/projects/**/*.jsonl\nuv run memex ingest-claude-code --path /custom/path   # alternate root\n```\n\nThese sessions are stored under the `claude_code` source, searchable like any other chat (and filterable with `source=\"claude_code\"`). Details:\n\n- **Incremental.** Unchanged sessions are skipped (by content hash), so re-running after more work is cheap. Sessions grow append-only, so a re-scan picks up new turns and new sessions. Re-run it whenever you want to refresh, or wire it to a schedule.\n- **Repo-aware for free.** Every session carries its working directory, so each is auto-associated with the registered repo of that `cwd` (run `memex repos add <path>` first). `search_chats(repo=...)` then boosts the sessions where you worked on that project.\n- **What is indexed:** your prompts, the assistant replies, and tool calls as `[tool_use: ...]` / `[result]` markers. Excluded: assistant internal reasoning (`thinking`), parallel sub-agent side threads, and CLI plumbing (slash-command echoes, bash wrappers). Everything stays in the local SQLite DB.\n- **Secret redaction.** Session logs capture real terminal output and file contents, which often contain credentials. Before storing, Memex masks common secret shapes (API keys, bearer/JWT tokens, PEM private keys, `KEY=`/`SECRET=` assignments, URLs with embedded passwords) as `[REDACTED:...]`, and does not persist the raw block content for this source. Best-effort, not a guarantee: it catches well-known formats so third-party credentials that were never really part of a conversation stay out of the index (this matters because the remote connector can surface indexed text to claude.ai).\n\n### Getting a Claude Code session indexed\n\nA session becomes searchable once its transcript is scanned. Day to day there are three ways to trigger that yourself:\n\n- **Ask Claude.** Say \"index this session\" and Claude calls the `index_terminal_sessions` MCP tool (the current conversation is captured up to what Claude Code has flushed to its transcript at that point). Follow with \"sync my devices\" (`sync_now`) if you want it on your other machines right away.\n- **Close the conversation.** With the SessionEnd hook below installed, ending the Claude Code chat (just the conversation, not the whole terminal) ingests that session the moment it closes.\n- **Run the command.** `memex ingest-claude-code` scans everything new right now.\n\nEven if you do none of these, the periodic backstop below picks up new and grown sessions within about 15 minutes of their last write. The two automatic mechanisms complement each other (both run in the background at low priority, and the embedding model only loads when there is something new, so they barely cost anything):\n\n1. **SessionEnd hook** — ingests a session the moment it closes (no delay, nothing lost). Add to `~/.claude/settings.json`:\n   ```json\n   {\n     \"hooks\": {\n       \"SessionEnd\": [\n         { \"matcher\": \"*\", \"hooks\": [\n           { \"type\": \"command\", \"command\": \"/absolute/path/to/memex/scripts/session-end-hook.sh\" }\n         ] }\n       ]\n     }\n   }\n   ```\n   The hook reads the closed session's `transcript_path` and ingests just that one session, detached, returning immediately (SessionEnd hooks cannot block Claude Code).\n\n2. **Periodic backstop** — a scheduled scan that catches anything the hook missed (e.g. a crash). On macOS, with launchd:\n   ```bash\n   sed \"s|__REPO__|$(pwd)|g\" scripts/com.memex.ingest-claude-code.plist.template \\\n     > ~/Library/LaunchAgents/com.memex.ingest-claude-code.plist\n   launchctl load ~/Library/LaunchAgents/com.memex.ingest-claude-code.plist\n   ```\n   It runs `scripts/scheduled-ingest.sh` every 15 minutes as a low-priority background job. A PyPI install does not need these manual steps on macOS or Windows: `memex setup` (or `memex install-service`) already schedules the backstop there (the `com.memex.ingest-claude-code` launchd agent / the `MemexIngest` Scheduled Task). On Linux the installer sets up only the serve, so wire the backstop yourself with a systemd user timer or cron running `memex ingest-claude-code`.\n\n   Per-OS state of the two mechanisms: the SessionEnd hook script is bash, so it works on macOS and Linux; on Windows it needs a PowerShell equivalent of `session-end-hook.sh`, not yet included, so there the ways in are the backstop task, asking Claude, or the manual command.\n\n## Syncing across your devices\n\nIf you run memex on more than one machine (say a laptop and a desktop), `memex\nsync` makes Claude one memory across them: index a chat on one device and search\nit from the other. Each device keeps its own local store and they sync\npeer-to-peer, with no central server and nothing leaving your hardware. The sync\nneeds both devices powered on and reachable at the same time (it is overlap\nsync, not a cloud relay). It ships in memex `0.4.0`+; on an older install,\nupgrade first (`uv tool upgrade memex-chats`).\n\nThe whole feature is **off by default** and exposes nothing until you turn it on.\nWhile it is off, the sync endpoints return 404 and the sync commands refuse, so a\nnormal single-device install has no extra surface.\n\n### Set it up once (recommended)\n\nInstall [Tailscale](https://tailscale.com) on each device first, then opt in once:\n\n```bash\nmemex setup --sync\n```\n\nThis is the normal setup plus one thing: it turns sync on and makes your\n**always-on capture service** sync-reachable on this device's Tailscale address\n(it binds `0.0.0.0` so one server still answers the local extension, with the Host\nallow-list pinned to loopback + your Tailscale IP, resolved at startup, and the\nper-install token gating access). The choice is **persisted**: set it once and the\nservice comes up sync-reachable on every reboot, so you never hand-run a serve\ncommand. It prints the single line to run on each other device:\n\n```bash\nmemex sync connect --url http://100.x.y.z:5777 --token <TOKEN> --name my-mac\n```\n\n`connect` turns sync on there, pairs, and runs a two-way reconcile, so that device\nis set up and caught up in one step.\n\n**Set-and-forget:** `memex setup --sync` also enables **auto-sync**, so paired\ndevices reconcile by themselves every 15 minutes while both are online (no env var,\nno cron). It is overlap sync, not a cloud relay: if the other device is off, that\ntick is skipped and catches up next time both are on. On top of the timer, a\ncapture also **triggers a sync a few seconds after it lands**: when the Chrome\nextension captures a chat and Memex indexes it, that new conversation is pushed to\nyour other devices right away (no need to run anything). A burst of captures (a\nbackfill, several open tabs) is coalesced into one sync once it settles, and it\nonly fires while both devices are on (for a dual-boot the other OS just picks up\nthe change on its next boot). Turn just this off with `MEMEX_SYNC_ON_CAPTURE=false`;\ntune the coalescing window with `MEMEX_SYNC_ON_CAPTURE_DEBOUNCE_SECONDS` (default\n10). You can still sync immediately by hand between ticks (e.g. to push the chat\nyou are having right now), with:\n\n```bash\nmemex sync now          # immediate two-way reconcile with every paired device\n```\n\n`memex sync now` propagates what is already indexed locally; a claude.ai chat is\nindexed when the extension captures it (on open/reload), so reload an in-progress\nchat first if you want its latest turns included. `memex sync status` shows what is\npaired and the last sync; `memex sync reconcile` is the same as `now`. Turn the\nwhole thing back off (loopback-only, sync + auto-sync off) with `memex setup\n--no-sync`. Tune the interval with `MEMEX_SYNC_INTERVAL_SECONDS` (default 900).\n\n### One-shot (without changing your setup)\n\nIf you would rather not make the service permanently reachable, start a temporary\nendpoint on the device that has the conversations:\n\n```bash\n# SOURCE device:\nmemex sync serve\n# -> Memex sync serve reachable at http://100.x.y.z:5777\n#    On the other device, run this one command:\n#      memex sync connect --url http://100.x.y.z:5777 --token <TOKEN> --name my-mac\n```\n\n`memex sync serve` works the same on macOS, Linux, and Windows (it uses your\nTailscale address, so there is no per-OS network setup and no `--host`/allow-list\njuggling). If you are not on Tailscale, pass `--host <address the other device can\nreach>`. It binds to that address only and runs alongside your loopback capture\nserver without a port clash; keep it up while the other device connects, then stop\nit with Ctrl+C. Afterwards, `memex sync reconcile` re-syncs an already-paired device.\n\n`reconcile` is the usual command: it syncs both ways and converges the two\ndevices, keeping the newer copy of anything that exists on both (last writer wins\nby update time). If the same conversation was edited on both devices with the\nexact same timestamp, that is a conflict: `reconcile` leaves both copies\nuntouched and reports it, and you pick a winner with a one-directional `memex sync\npull --peer mac` (take the peer's) or `push --peer mac` (send yours).\n\nEvery sync only transfers conversations that are new or changed, brings their\nembeddings along so your machine never re-embeds, and is idempotent (re-running\nmoves nothing new). A large history transfers in size-bounded batches\nautomatically, so it works no matter how many conversations you have (tune the\ntarget with `MEMEX_SYNC_MAX_BATCH_BYTES`, default 8 MB; a single conversation\nlarger than the peer's `MEMEX_INGEST_MAX_BODY_BYTES` is skipped with a clear\nmessage). Both devices must use the same embedding model (the sync refuses on a\nmismatch). The peer's token is stored user-only (0600) next to the DB. Pairing is\na trust decision (it shares an access token), so only pair devices you control.\nNever sync the SQLite file itself with a folder-sync tool; always use `memex\nsync`, which is consistent at the conversation level.\n\nAuto-sync (the every-15-minutes reconcile) is turned on for you by `memex setup\n--sync`; you do not need an env var. Under the hood it reconciles with each paired\npeer on startup and every `MEMEX_SYNC_INTERVAL_SECONDS` (default 900), skipping a\npeer that is offline and backing off while an ingest is running. If you did not use\n`setup --sync` (e.g. a manual/dev setup) you can still enable it with\n`MEMEX_SYNC_AUTO=true` before `memex serve`; either the persisted flag or the env\nvar starts the loop. It only runs while sync is enabled; turn the whole feature\nback off with `memex sync disable` (or `memex setup --no-sync`).\n\n### Dual-boot or never-online-together (file-based sync)\n\nNetwork sync needs both devices online at the same time. That never happens on a\n**dual-boot machine** (Linux and Windows on the same disk, only one running at a\ntime), and is awkward for any pair of devices that are rarely on together. For\nthat, memex has a second sync mode that uses a **shared folder** instead of a live\nconnection: each OS exports a snapshot of its store to the folder and imports the\nothers'. No server, no port, no token, no third device. It ships in memex `0.4.4`+.\n\nPoint every OS at the **same** shared folder (one command per OS):\n\n```bash\n# On Linux (the Windows partition mounted at, e.g., /mnt/windows):\nmemex setup --sync-dir /mnt/windows/memex-sync --device-name linux\n\n# On Windows (the SAME physical folder, its path there):\nmemex setup --sync-dir C:\\memex-sync --device-name windows\n```\n\nThat is it. From then on each OS, when it boots, auto-syncs through the folder\n(every 15 minutes while running), and `memex sync now` syncs immediately. The\nfolder is created for you if it does not exist, and the choice is persisted, so\nyou set it up once.\n\nWhere to put the folder on a dual-boot: it must be readable from **both** OSes, so\nput it on the **Windows / NTFS partition**. Linux reads and writes NTFS out of the\nbox; Windows cannot read Linux's ext4. (For two separate machines that are rarely\non together, any shared location works: a USB drive, or a cloud-synced folder like\nDropbox.)\n\nDual-boot gotcha: Windows **Fast Startup** (and hibernation) leaves the NTFS\npartition dirty, so Linux mounts it **read-only**, and file sync needs to write\nits snapshot there (the initial export fails loudly if it cannot). If the folder\nmounts read-only on Linux, disable Fast Startup on Windows (or `powercfg /h off`)\nand shut Windows down fully once.\n\nHow it converges: a device only ever writes its own `<device>.memexsync.gz` and\nreads the others', so they never clash. Sync is last-writer-wins by update time,\nexactly like the network mode, and a same-timestamp conflict (a fork) is left\nuntouched and reported. The other OS's newer conversations land on your next boot\n(it left its snapshot on disk), and yours reach it on its next boot. Give the two\nOSes **distinct `--device-name` values** if their hostnames are the same, or they\nwould overwrite each other's snapshot. The snapshot carries your conversation text\nand vectors, so keep the shared folder somewhere only you can read (the same \"only\nshare what you control\" rule as pairing a peer). The two modes are independent: you\ncan use file sync, network sync, or both.\n\n### Rotating a token\n\nEach device has one access token (the `ingest_token` file next to its database;\n`memex doctor` shows the folder). Rotate it whenever it was pasted somewhere it\nshould not live: a chat, a screenshot, a ticket. There is no rotate command yet,\nand the running server reads the file only once, so the **order matters**:\n\n1. Delete the token file (`rm <data-dir>/ingest_token`; PowerShell:\n   `Remove-Item -Force $env:LOCALAPPDATA\\memex\\ingest_token`).\n2. **Restart the always-on serve** (macOS: `launchctl unload` then `load` on\n   `com.memex.serve`; Linux: `systemctl --user restart memex-serve`; Windows:\n   `schtasks /End /TN MemexServe` then `schtasks /Run /TN MemexServe`). Skipping\n   this leaves the OLD token accepted (it is cached in memory) and the new file\n   ignored.\n3. Run `memex token` to see the new value. Re-paste it into that machine's Chrome\n   extension popup, and **re-pair every device that dials this one**:\n   `memex sync connect --url http://<this-device>:5777 --name <name> --token \"...\"`\n   (passing `--token` avoids the hidden prompt, which is easy to mistype).\n\n## Running always-on\n\n`memex serve` (claude.ai capture) is a long-lived server, and the Claude Code\ningest backstop runs on a schedule. To have them start on login and stay up\n(restarting if they crash), let `memex setup` install the service, or call it\ndirectly on any OS:\n\n```bash\nmemex install-service            # install (launchd / systemd / Scheduled Task)\nmemex install-service status     # show what is registered\nmemex install-service uninstall  # remove it\n```\n\nThis is cross-platform: launchd agents on macOS, a systemd user unit on Linux,\na Scheduled Task on Windows. By default it manages the live-capture server plus\nthe 15-minute Claude Code ingest backstop. Idle cost is low: neither loads the\nembedding model until there is real work. It works the same from a PyPI / pipx /\n`uv tool` install (a self-contained launchd / systemd / Scheduled Task that runs\nthe installed `memex serve` directly) and from a cloned repo. Use a persistent\ninstall (`pipx` or `uv tool`), not transient `uvx`, so the service has a stable\ninterpreter to launch at boot.\n\nTo also run the claude.ai remote connector as a service, pass `--remote`\n(macOS): `memex install-service --remote`. It only makes sense once the\n`MEMEX_REMOTE_*` config is in `.env` and the Tailscale Funnel is up on the same\nport (`tailscale funnel --bg 8377`), otherwise the agent crash-loops; that is\nwhy it is opt-in.\n\n<details>\n<summary>Manual launchd setup (macOS, if you prefer explicit steps)</summary>\n\n```bash\ncd /path/to/memex\nfor svc in serve ingest-claude-code; do\n  sed \"s|__REPO__|$(pwd)|g\" \"scripts/com.memex.$svc.plist.template\" \\\n    > ~/Library/LaunchAgents/com.memex.$svc.plist\n  launchctl load ~/Library/LaunchAgents/com.memex.$svc.plist\ndone\nlaunchctl list | grep memex\n```\n\nTo stop a service: `launchctl unload ~/Library/LaunchAgents/com.memex.<name>.plist`.\n</details>\n\n## Auto-summaries (Phase 3, optional)\n\nWhen `search_chats` returns a chat that does not have a summary yet, Memex can generate one on-the-fly using Claude Haiku. The summary is persisted, so the next search of the same chat hits cache and does not pay the API again. This way you only pay for chats you actually look at, not for the whole corpus.\n\nOpt-in. Off by default. Cap: at most 3 summaries generated per `search_chats` call (parallel), to bound latency and per-query cost.\n\n1. Install the extra (adds the `anthropic` SDK):\n   ```bash\n   uv sync --extra summaries\n   ```\n2. In your `.env` (or as env vars), set:\n   ```bash\n   ANTHROPIC_API_KEY=sk-ant-...\n   MEMEX_SUMMARY_ENABLED=true\n   ```\n3. Use `search_chats` from Claude Code as usual. The first time a chat appears in results without a cached summary, Memex generates one. Subsequent searches return the cached summary instantly.\n\nConfigurable via env: `MEMEX_SUMMARY_MODEL` (default `claude-haiku-4-5-20251001`), `MEMEX_SUMMARY_MAX_TOKENS` (default 200). If the API fails for a particular chat (no key, rate limit, network), that one result comes back without a summary, the search itself never aborts, and the warning is logged.\n\nCost model: bulk ingest of an export with 74 chats costs $0 (no summaries are generated at ingest time). Each unique chat you actually open in a search costs roughly $0.01 (Haiku, ~5-10k input + ~200 output tokens). $5 of API credits comfortably covers months of use.\n\n## Repo associations (Phase 3)\n\nMemex can associate each chat with the local code repos it touches, and boost those chats when `search_chats` is invoked from inside a repo. So when you ask Claude Code something like \"remember the auth refactor we discussed?\", chats that touched the *current* repo rank higher than unrelated chats with the same keywords.\n\nHow it works:\n\n1. Register a repo:\n   ```bash\n   uv run memex repos add /path/to/your/repo\n   ```\n   Memex reads `.git/config` (origin URL), and `pyproject.toml` / `package.json` / `Cargo.toml` (package name). The canonical key prefers the git remote (stable across clones) over the path.\n\n2. Run a one-time scan over chats you already ingested:\n   ```bash\n   uv run memex repos scan\n   ```\n   Each chat gets matched against every registered repo. The matcher uses 4 signals (highest wins): remote URL literal in chat text (confidence 1.0), absolute path literal (0.9), manifest name word-bounded (0.8), display name word-bounded (0.5). Anything below 0.5 is dropped. New chats ingested after registering the repo are auto-scanned at ingest time.\n\n3. From Claude Code, search with the repo argument:\n   ```text\n   search_chats(query=\"auth refactor\", repo=\"d:/dionisio/memex\")\n   ```\n   Or pass the git remote URL, or the canonical key from `memex repos list`. Chats associated to the repo get their distance reduced by `0.3 * confidence`. Chats outside the repo still appear lower down (it is a boost, not a filter).\n\nCLI helpers:\n\n```bash\nuv run memex repos list           # show registered repos\nuv run memex repos remove <key>   # unregister + cascade-remove associations\nuv run memex tag <chat-uuid> <repo-key>    # manual override (sticky vs auto-scan)\nuv run memex untag <chat-uuid> <repo-key>  # remove an association\n```\n\nA `manual` tag survives subsequent auto-scans: once you tag a chat by hand, the matcher will not overwrite it.\n\n### Proactive context injection (`SessionStart` hook)\n\nClaude Code supports hooks that run shell commands at session boundaries. Memex ships `memex session-context`, designed to be wired into the `SessionStart` hook so every new Claude Code session in a registered repo starts with a Markdown blob listing the most relevant past chats. No query needed.\n\nTo enable it, add to your `.claude/settings.json` (project-local) or `~/.claude/settings.json` (user-global):\n\n```json\n{\n  \"hooks\": {\n    \"SessionStart\": [{\n      \"command\": \"uv run memex session-context\"\n    }]\n  }\n}\n```\n\nThe command auto-detects the active repo by walking up from `cwd` until it finds `.git`. If the repo is registered in Memex and has associated chats, it prints a short Markdown blob with the top N (default 5) chats, ordered by `manual` first, then `auto` by confidence. If anything fails (no `.git`, repo not registered, no associations), it prints nothing on stdout (only diagnostics on stderr), so the hook is a silent no-op in that case.\n\nYou can also run the command by hand to debug: `uv run memex session-context [--repo <path>] [--limit N]`.\n\n## Live capture (Phase 2)\n\nSo that new Claude.ai chats land in Memex without asking for a manual export:\n\n1. **Start the local HTTP server** in a terminal:\n   ```powershell\n   uv run memex serve\n   ```\n   Listens on `127.0.0.1:5777` by default. Keep it running while you browse claude.ai. On start it prints an **access token**; the extension must send it (the loopback Origin check alone does not authenticate other local processes). Reprint it any time with `uv run memex token`.\n\n2. **Load the Chrome extension**:\n   - Soon: install from the [Chrome Web Store](https://chrome.google.com/webstore/devconsole) (in review for the alpha).\n   - For now (unpacked load):\n     - Open `chrome://extensions/`\n     - Enable **Developer mode**\n     - **Load unpacked** → pick `chrome-extension/` from the repo\n     - Click the Memex icon and confirm the \"Server\" chip says **responding** (green).\n\n3. **Pair the extension with the access token.** Run `uv run memex token`, copy the value, paste it into the extension popup's token field, and click **Save token**. This is a one-time step per machine (the token lives user-only next to your DB). Without it, ingest requests are rejected with `401`.\n\n4. **Import your full history (one click).** With a claude.ai tab open, click **Backfill claude.ai history** in the popup. It pages through your entire chat list and pulls every conversation into Memex, skipping the ones already indexed and unchanged (so re-running is cheap and a closed tab just resumes on the next click). Progress shows in the popup. This is what makes a fresh install searchable without a manual export.\n\n5. **Then just use claude.ai.** Every new chat you open or create is ingested automatically. Verify with `memex stats` or by calling `search_chats` from Claude Code.\n\nDetails in [chrome-extension/README.md](chrome-extension/README.md).\n\n#### Autostart (macOS + Windows + Linux)\n\nSo you do not have to run `memex serve` by hand every time you log in (this is also what `memex setup` does for you):\n\n```bash\nmemex install-service          # default action: install\nmemex install-service status   # check current state\nmemex install-service uninstall\n```\n\nThe CLI dispatches to the right installer for your OS:\n\n- **macOS**: writes launchd agents for `serve` + the 15-minute Claude Code ingest backstop, and `launchctl load`s them. Logs in the data dir (`<repo>/data/serve.log` from a clone, `~/Library/Application Support/memex/com.memex.serve.log` from a PyPI install). Add `--remote` to also run the claude.ai connector (needs the `MEMEX_REMOTE_*` config). See [Running always-on](#running-always-on).\n- **Windows**: registers a Scheduled Task (`MemexServe`) that runs `memex serve` at logon. No admin required, no console window, survives VS Code close. Logs at `%LOCALAPPDATA%\\memex\\serve.log`. Auto-restarts up to 3 times if it dies.\n- **Linux**: writes a systemd user unit at `~/.config/systemd/user/memex-serve.service`, enables it, and starts it now. Logs at `~/.local/share/memex/serve.log`. To keep it running across logout: `loginctl enable-linger $USER`. Status: `systemctl --user status memex-serve`.\n\nFrom a `pip`/`pipx` install (no cloned repo), `memex install-service` works on macOS, Linux, and Windows alike: it generates a self-contained agent (launchd / systemd / a logon Scheduled Task) that runs the installed `memex serve` directly, with the database in your per-user data directory. Use `pipx` (not transient `uvx`) so the service has a stable interpreter to launch at boot.\n\n### Making Claude use Memex proactively\n\nBy default, LLMs are conservative with tools: they prefer to ask before invoking anything. If you say *\"remember we talked about X?\"*, Claude tends to answer *\"I don't recall\"* instead of searching.\n\nThe docstrings of the 4 tools already include \"USE PROACTIVELY\" instructions, but you can reinforce it by adding this snippet to your `CLAUDE.md` (global at `~/.claude/CLAUDE.md` for every session, or local at `<project>/CLAUDE.md` for a specific one):\n\n```markdown\n## Memex: persistent memory of Claude.ai chats\n\nThere is an MCP server `memex` with 4 tools: `search_chats`, `get_chat`, `list_recent_chats`, `find_related`.\nThey index ALL of the user's Claude.ai history, reachable via hybrid search\n(semantic + lexical FTS5).\n\n**Operational rule:** before answering \"I have no record\", \"I don't remember\", \"this is\nthe first time I hear about this\", or anything equivalent, call `mcp__memex__search_chats`\nwith the relevant query. Claude Code's native memory starts clean every session; Memex\nis the only path into the user's real history.\n\nTypical triggers: \"remember when...\", \"did I tell you about...\", \"we already talked about...\",\n\"the other day we discussed...\", or any reference to a project / person / decision that might\nlive in history.\n```\n\n## Roadmap\n\nSee [ROADMAP.md](ROADMAP.md) for phases, close criteria, and current status (in Spanish, it is the internal journal).\n\n## Devlog\n\nSee [DEVLOG.md](DEVLOG.md) for the log of decisions, blockers, and progress (in Spanish).\n\n## Inspiration and references\n\n- Official feature request: [anthropics/claude-code#12858](https://github.com/anthropics/claude-code/issues/12858)\n- [Claude Historian](https://mcpmarket.com/server/claude-historian), [claude-conversation-extractor](https://github.com/ZeroSumQuant/claude-conversation-extractor): MCP servers for Claude Code / Desktop history. Reference for tool structure.\n- [claude-conversation-export](https://github.com/Emnolope/claude-conversation-export): Claude.ai exporter using the same capture strategy. Useful as backfill.\n- Spin-off of the [SyncChat](https://github.com/dionipereyrab/SyncChat) project.\n\n## License\n\nMIT.\n",
  "bytes": 50684,
  "sha": "49e7f88eaf5241951e9d0633665cf629b49e81bf02b268ed563498f98dbfdc9f",
  "repo_slug": "dioniipereyraa/memex",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_dioniipereyraa_memex_0c5a7f96/readme"
}