{
  "markdown": "```\n██╗     ██╗██╗   ██╗███████╗\n██║     ██║██║   ██║██╔════╝\n██║     ██║██║   ██║█████╗\n██║     ██║╚██╗ ██╔╝██╔══╝\n███████╗██║ ╚████╔╝ ███████╗\n╚══════╝╚═╝  ╚═══╝  ╚══════╝\n███╗   ███╗███████╗███╗   ███╗ ██████╗ ██████╗ ██╗   ██╗\n████╗ ████║██╔════╝████╗ ████║██╔═══██╗██╔══██╗╚██╗ ██╔╝\n██╔████╔██║█████╗  ██╔████╔██║██║   ██║██████╔╝ ╚████╔╝\n██║╚██╔╝██║██╔══╝  ██║╚██╔╝██║██║   ██║██╔══██╗  ╚██╔╝\n██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║╚██████╔╝██║  ██║   ██║\n╚═╝     ╚═╝╚══════╝╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═╝   ╚═╝\n        always-up-to-date codebase memory for Claude Code · ask, don't re-read\n```\n\n# Live Memory — Claude Code plugin\n\n**A cheap, always-on model that learns your repo — so your agent stops re-reading it.**\nLive Memory runs a separate, cheap large-context model as a long-lived MCP server that accumulates\nknowledge of your codebase across sessions. Instead of re-reading the same files every session, your\nagent asks one **read-only** tool, `ask_live_memory`, the broad-understanding questions — *\"where is X,\nhow does Y work, what calls Z\"* — and Live Memory answers in a way that **bootstraps the primary agent to\nstart doing productive work** (e.g., edits). It **learns passively** from your agent's own reads and edits\n(teed via hooks — no extra reading) and stays current as the repo changes (modifications and deletions).\nRead-only and path-jailed (it can never edit, create, or run anything); zero-config on a Claude\nsubscription (Haiku, no API key); the memory model is pluggable — point it at a local model or any\nOpenAI-compatible endpoint.\n\n![Live Memory answering a question from accumulated memory — zero files re-read by the agent](media/live-memory.gif)\n\n## How it works\n\n```mermaid\nflowchart LR\n  repo[(\"Your repo\")]\n  subgraph sessions[\"Claude Code sessions — premium model (many, over time)\"]\n    agent[\"Agent\"]\n  end\n  agent -->|\"reads / edits files\"| repo\n  agent -. \"PostToolUse / FileChanged hooks<br/>tee file content — passive learning (free)\" .-> lm\n  agent ==>|\"ask_live_memory(question, cwd)<br/>one read-only MCP tool\"| lm\n  lm ==>|\"grounded answer — no file re-reading\"| agent\n  subgraph server[\"Live Memory — one MCP server per workspace (singleton)\"]\n    lm[\"Cheap / local large-context model<br/>+ accumulating context window<br/>append-only · neutral compaction to a ledger\"]\n    lm --> snap[(\"Local JSON snapshot<br/>persists across sessions\")]\n  end\n```\n\nYour agent **reads or edits files as usual**; hooks quietly tee that content to the server so it **learns\nfor free**. When the agent needs to understand something, it **asks** `ask_live_memory` instead of\nre-reading — the server answers from its accumulated, per-workspace memory (or reads the code itself,\nread-only, if it hasn't seen it yet). One server serves every session and **persists across sessions**.\n\n## Benchmarks\n\nA/B on a real repo, **cost per task, run to completion**. Cost is shown three ways: the **premium\n(building) model's bill** — what your *expensive* model spends, since the companion runs on a cheap or\nlocal model — and **all-in**, also counting the companion's own cost on **DeepSeek-v4-flash** or **Haiku**:\n\n| per task | premium-model bill | all-in · DeepSeek-flash† | all-in · Haiku | faster |\n|---|---|---|---|---|\n| **Understanding-heavy** (trace / comprehend) | **−61%** | **−57%** | **−25%** | **~22%** |\n| **Hybrid** (understand-then-edit: bug fixes + features) | **−28%** | **−26%** | **−11%** | **~11%** |\n| Pure edit / execution | ~break-even | ~break-even | ~break-even | ~0 |\n\nUnderstanding-heavy work also offloads **~93%** of the premium model's codebase-reading tokens (with lower\ncost variance), and correctness never regressed on the hybrid tasks (**12/12** passed with *and* without\nit). DeepSeek-v4-flash **matched Haiku's answer accuracy** (98% vs 91% over 3 reps) at ~8× lower token\nprice; a **local** companion is ≈ free, so all-in ≈ the premium-model bill. Fully reproducible + audited\n(human + Fable). Full numbers + methodology: [`benchmark/results/RESULTS.md`](./benchmark/results/RESULTS.md).\n\n<sub>† companion re-priced at DeepSeek-v4-flash rates (~8× cheaper than Haiku); exact for the\nunderstanding case, derived from the measured cost ratio for the hybrid case.</sub>\n\n**Lineage:** Live Memory began as a feature of **[shofer.dev](https://shofer.dev)** (Arkware's\nparallel multi-agent coding platform), where sessions share an in-sync codebase memory. This is that\nidea as a **standalone Claude Code plugin** — a fresh implementation, self-contained, with no\ndependency on shofer. Part of the **shofer** Claude Code plugin family (with\n[slang-workflows](https://github.com/shofer-dev/claude-code-slang-orchestrator)).\nDesign: [`DESIGN.md`](./DESIGN.md) · How it compares to Copilot/Cursor: [`COMPARISON.md`](./COMPARISON.md) · Testing: [`TESTING.md`](./TESTING.md) · Privacy: [`PRIVACY.md`](./PRIVACY.md).\n\n## Quickstart\n\nlive-memory is an **HTTP MCP server you run once** (a singleton that serves every Claude Code session)\nplus a plugin that registers `ask_live_memory`, the hooks, and the slash commands. **Start the server\nfirst** — Claude Code only *connects* to it (it never spawns it), so if it isn't running you'll get a\nconnection error.\n\n**1 — Start the server** (zero-config on a Claude subscription → Haiku; no API key needed):\n\n```bash\ngit clone https://github.com/shofer-dev/claude-code-live-memory\ncd claude-code-live-memory/deploy && ./install-service.sh   # venv + user systemd service, auto-starts on boot\n# …or just run it in a terminal:\n#   cd claude-code-live-memory/server && pip install -e . && python -m live_memory\n```\n\n**2 — Install the plugin** (inside a Claude Code session):\n\n```\n/plugin marketplace add shofer-dev/claude-code-live-memory\n/plugin install live-memory@shofer-live-memory\n```\n\nAsk your agent a whole-repo question — it'll call `ask_live_memory` instead of reading files.\n`/live-memory-stats` shows accumulated knowledge + cost · `/live-memory-config` switches\nmodel/provider · `/live-memory-empty` wipes memory · `/live-memory-reset` starts a workspace\nover with its configured preload docs re-loaded. Providers, systemd, workspaces, and concurrency\nare detailed below.\n\n## Shape\n\n```\nlive-memory/\n├── .claude-plugin/plugin.json     # plugin manifest\n├── .mcp.json                      # registers the server (type:http, explicit timeout)\n├── hooks/                         # PostToolUse(Read|Write|Edit|…) + FileChanged → TEE file content (passive learning)\n│   ├── hooks.json\n│   └── notify.py\n├── skills/live-memory/SKILL.md    # tells the agent when/why to call ask_live_memory\n├── commands/                      # USER-facing slash commands (not agent tools)\n│   ├── live-memory-stats.md       # /live-memory-stats  → GET /stats\n│   ├── live-memory-config.md      # /live-memory-config → set model/provider, hot-reload\n│   ├── live-memory-empty.md       # /live-memory-empty  → wipe memory (this workspace or `all`)\n│   ├── live-memory-reset.md       # /live-memory-reset  → drop history + re-preload configured docs\n│   ├── stats.py · config.py · empty.py · reset.py\n├── settings.json\n├── deploy/                        # systemd unit + env example + install-service.sh\n└── server/                        # the long-running MCP server (Python, asyncio)\n    ├── pyproject.toml             # deps + mypy(strict) + pytest config\n    ├── tests/                     # pytest unit suite (mocked; no network)\n    └── live_memory/\n        ├── __main__.py            # entrypoint: python -m live_memory\n        ├── server.py              # MCP (HTTP) ask_live_memory + /health + /stats + /notify + /clear + /reset + /reload\n        ├── workspace.py           # per-cwd state registry (window + queue + store); fork/commit\n        ├── manager.py             # the agent loop (process one question); compaction\n        ├── context_window.py      # budget; file-context evict, Q&A summarize; fork/clone\n        ├── summarizer.py          # NEUTRAL, query-agnostic knowledge-ledger summarization\n        ├── question_queue.py      # per-workspace admission (serial/parallel) + per-entry timeout\n        ├── async_jobs.py          # opt-in fire-and-forget job registry (submit/poll)\n        ├── keep_warm.py           # background KV/prompt-cache keep-warm loop\n        ├── conversation_store.py  # versioned JSON snapshot (SHA-256 file validation)\n        ├── llm_client.py          # provider-pluggable: Anthropic Messages | OpenAI-compatible\n        ├── oauth.py               # subscription OAuth credential + auto-refresh (zero-config)\n        ├── config.py              # layered config (env > config.json > defaults) + provider knowledge\n        ├── constants.py           # ALL tunable magic numbers + defaults, centralized (config sources its defaults here)\n        ├── models.py              # core dataclasses (ChatMessage, FileContext, QuestionResult, …)\n        ├── tool_executor.py       # read-only tools (Read/Grep/Glob/find_paths/git/…), path-jailed\n        ├── preload.py             # configured preload globs → verbatim docs on workspace load\n        ├── directory_tree.py      # workspace scan, ~10% context cap\n        ├── pricing.py             # per-model USD cost (+ env overrides)\n        ├── logging_setup.py       # stderr→journald + optional rotating file\n        └── prompts.py             # system prompt + neutral-summary prompt\n```\n\n## Architecture (see DESIGN.md for the full rationale)\n\n- **One externally-supervised, idempotent HTTP MCP server** (singleton) serves all\n  Claude Code sessions; state is keyed **per workspace** (`cwd`).\n- **Model = independent + provider-pluggable**: the server runs its *own* cheap\n  model (not the session's). Two adapters cover ~everything — **Anthropic Messages**\n  (with `cache_control`) and **OpenAI-compatible** (DeepSeek/OpenAI/gateways).\n  **Zero-config**: with no key but a Claude subscription, it uses the subscription\n  OAuth token (auto-refreshed) on Haiku.\n- **Passive (organic) learning**: PostToolUse/FileChanged hooks **tee the content**\n  of the files your agent reads/edits into the memory, so it warms up for free from\n  real work; `ask_live_memory` is the active fallback for anything unseen.\n- **Preload globs (opt-in)**: `preload_globs` (e.g. `docs/*.md`) names reference\n  docs loaded **verbatim into the system prompt** whenever a workspace is\n  (re)loaded — the memory starts out knowing them. They behave like observations:\n  compaction later distills them into the knowledge ledger under pressure.\n  `/live-memory-reset` drops a workspace's history trail and re-preloads them fresh.\n- **Append-only window between compactions**; compaction = **batched neutral\n  summarization** with a high/low-watermark (rare, batched) — observed files + Q&A\n  distilled into a query-agnostic knowledge ledger — never front-truncation.\n- **Frozen volatile block + observation deltas (KV-cache preservation)**: the\n  volatile system block (ledger + preloaded/observed content + manifest) is\n  frozen between compactions and re-sent byte-identical; changes that arrive\n  in between (a teed file, a staleness notice) are **appended to the history\n  as delta messages** instead of mutating the block — so the provider's prefix\n  cache keeps matching instead of truncating at the first changed byte.\n- **Two-tier timeout**: `ask_live_memory(question, cwd, max_answer_tokens?)`\n  blocks up to the **server-configured** soft budget (`default_timeout_s`,\n  default 60s — no longer a tool argument) and returns a best-effort answer\n  before the hard `.mcp.json` MCP timeout.\n- **Disclosed answer-length budget**: the answer is hard-capped (default\n  `LIVE_MEMORY_MAX_ANSWER_TOKENS`) *and* the model is told the cap, so it\n  self-regulates instead of being truncated mid-sentence; the optional\n  `max_answer_tokens` arg overrides it per question.\n- **Human status** via the `/live-memory-stats` slash command (→ `/stats`), kept\n  off the agent's tool surface.\n\n## Installation\n\n**Prerequisites:** Python ≥ 3.10; **ripgrep** (`rg`) recommended (powers\n`Grep`); `git` optional (powers `git_search` / `get_changed_files`).\n\n**1. Install the server:**\n\n```bash\ncd server\npip install -e .          # runtime deps (mcp, anthropic, starlette, uvicorn, watchdog, httpx)\n# for development/tests:  pip install -e \".[dev]\"   # adds mypy, pytest, pytest-asyncio\n```\n\n**2. Install the plugin into Claude Code** so it reads `.mcp.json`, the hooks, the\nskill, and the slash commands. The repo root doubles as a single-plugin\n**marketplace** (`.claude-plugin/marketplace.json`); `/plugin install` only\ninstalls *from a marketplace*, never a bare directory — so add the marketplace\nfirst, then install from it. Inside a Claude Code session:\n\n```\n/plugin marketplace add https://github.com/shofer-dev/claude-code-live-memory\n/plugin install live-memory@shofer-live-memory\n```\n\n`shofer` is the marketplace name; `live-memory` is the plugin name. To install\nfrom a local clone instead, point `add` at the checkout directory:\n\n```\n/plugin marketplace add /ABSOLUTE/PATH/TO/claude-code-live-memory\n/plugin install live-memory@shofer-live-memory\n```\n\nAfter editing plugin files later, run `/plugin marketplace update shofer` then\n`/reload-plugins` (installed plugins are cached under `~/.claude/plugins/`, so\nsource edits aren't picked up live).\n\n**For local development**, skip the marketplace entirely and launch Claude Code\nwith the plugin loaded directly — this *does* pick up edits via `/reload-plugins`:\n\n```bash\nclaude --plugin-dir /ABSOLUTE/PATH/TO/claude-code-live-memory\n```\n\n(The server in step 3 must be running before Claude Code connects — `.mcp.json`\npoints at a `type:http` endpoint Claude Code only *connects* to, never spawns; if\nthe server is down you'll see a connection error in `/plugin`'s Errors tab.)\n\n**3. Run the server** (next section). **4. Dev checks:** `mypy live_memory/ && pytest`.\n\n## Running the server\n\nThe HTTP transport requires the server to be **already running** before Claude\nCode connects (Claude Code does not start `type:http` servers) — run it under an\nexternal supervisor (systemd/container/etc.).\n\n**Zero-config** (no API key): if you're logged into a Claude subscription, it\njust works — the server reuses that credential (auto-refreshed) on **Haiku**.\n\n```bash\ncd server && pip install -e .\npython -m live_memory\n# serves MCP at http://127.0.0.1:7711/mcp  (+ /health, /stats, /notify, /reload)\n```\n\n> The subscription path draws on your subscription's **rate-limit** budget (not\n> $-metered) — a documented ToS gray area. For an always-on service prefer a key.\n\n**Pick any model/provider** — env vars *or* the `/live-memory-config` slash\ncommand (writes `config.json`, hot-reloads, no restart):\n\n```bash\n# DeepSeek (cheap, recommended), via env:\nLIVE_MEMORY_PROVIDER=openai LIVE_MEMORY_BASE_URL=https://api.deepseek.com \\\n  LIVE_MEMORY_API_KEY=sk-... LIVE_MEMORY_MODEL=deepseek-chat  python -m live_memory\n\n# …or at runtime, from inside Claude Code:\n/live-memory-config set provider=openai base_url=https://api.deepseek.com model=deepseek-chat api_key=sk-...\n/live-memory-config show\n```\n\nSupported providers: `anthropic` (Messages API + Bedrock/Vertex/gateways, API key\nor subscription OAuth) and `openai` (any OpenAI-compatible endpoint: OpenAI,\nDeepSeek, local models, gateways). Then enable the plugin so Claude Code reads\n`.mcp.json` and connects.\n\n## Run as a systemd service\n\n`deploy/` has the boilerplate. One command registers and starts it:\n\n```bash\ncd deploy\n./install-service.sh            # user service (recommended — see below)\n./install-service.sh --system   # system-wide (best for API-key setups)\n```\n\nIt creates a venv + installs the server, writes a config at\n`~/.config/live-memory/live-memory.env` (from `live-memory.env.example` — edit it\nfor provider/model/key), installs `live-memory.service`, enables lingering, and\nstarts it. Config is supplied to the process by systemd via `EnvironmentFile=`.\n\n- **Persistence survives restarts** automatically: per-workspace snapshots live\n  in `LIVE_MEMORY_DATA_DIR` (default `~/.claude/plugins/data/live-memory`), so a\n  restart reloads each workspace's memory on its next query.\n- **Subscription (zero-config) auth needs a *user* service** (the default): it\n  runs as you, so it can read `~/.claude/.credentials.json` and reuse your Claude\n  login (auto-refreshed). A `--system` service can also do this, but the unit\n  must set `User=` + `Environment=HOME=…` (the installer does this for you).\n\n```bash\nsystemctl --user status live-memory\njournalctl --user -u live-memory -f\nsystemctl --user restart live-memory     # after editing the env file\n```\n\n### Logs\n\nBy default the server logs to **stderr**, which systemd captures into the\n**journal** — the idiomatic place, with rotation and unit/PID metadata:\n\n```bash\njournalctl --user -u live-memory -f          # user service\nsudo journalctl -u live-memory -f            # system service\n```\n\nTwo caveats and the escape hatch:\n- A **user** service's journal only persists across reboots if journald has\n  persistent storage (`/var/log/journal` exists). If yours is volatile, those\n  logs vanish on reboot.\n- For a durable, greppable plain-text log regardless, set\n  `LIVE_MEMORY_LOG_FILE` (e.g. `/var/log/live-memory/live-memory.log` for a\n  system service, or an absolute path under `~/.local/state/live-memory/` for a\n  user one). It's a **rotating** handler (`LIVE_MEMORY_LOG_MAX_BYTES` ×\n  `LIVE_MEMORY_LOG_BACKUPS`) and writes *in addition* to journald.\n  `LIVE_MEMORY_LOG_LEVEL` (default `INFO`) tunes verbosity.\n\n## Workspaces & `cwd`\n\nMemory is keyed **per workspace**, from the `cwd` passed to `ask_live_memory`.\n`cwd` must be an **absolute** path (a relative path is rejected — the shared\nserver can't resolve it against your session). By default the server snaps each\n`cwd` to its enclosing **git repo root**, so a subdirectory and the repo root\nshare one memory:\n\n| Env var | Default | Effect |\n|---|---|---|\n| `LIVE_MEMORY_CANONICALIZE_WORKSPACE` | `true` | Snap `cwd` to its git repo root. Set `false` for a distinct memory per exact directory. |\n| `LIVE_MEMORY_REPO_ROOT_MODE` | `nearest` | Inside a submodule/worktree: `nearest` = the submodule's own root (git's default); `outermost` = the superproject root (fold submodule questions into the parent's memory). |\n\n### Preload globs — start out knowing your docs\n\n`preload_globs` names glob patterns (relative to each workspace root) whose\nmatching files are read from disk and loaded **verbatim into the system prompt**\nevery time a workspace is (re)loaded — reference material the memory knows\nbefore its first question. Preloaded content is treated like an observation:\nrendered inline under its own heading until compaction distills it into the\nknowledge ledger and sheds the raw bytes under budget pressure.\n\n```\n/live-memory-config set preload_globs=docs/*.md,README.md      # or:\nLIVE_MEMORY_PRELOAD_GLOBS=\"docs/*.md,README.md\"\n```\n\n| Env var | Default | Effect |\n|---|---|---|\n| `LIVE_MEMORY_PRELOAD_GLOBS` | *(empty)* | Comma-separated globs (relative to the workspace root, `**` supported) preloaded verbatim on workspace load. Absolute patterns and matches escaping the workspace (symlinks) are skipped, as are binary files. |\n| `LIVE_MEMORY_PRELOAD_MAX_TOTAL_BYTES` | `2097152` | Total cap across all preloaded files per workspace (per-file cap is `LIVE_MEMORY_PASSIVE_MAX_FILE_BYTES`). The effective cap is additionally clamped to the **window budget** (`compaction_floor × LIVE_MEMORY_MAX_CONTEXT_TOKENS`) — preloading past the floor would just make the first question distill + shed the docs immediately. To preload a corpus bigger than ~300 KB, raise `LIVE_MEMORY_MAX_CONTEXT_TOKENS` too. |\n\nNotes:\n\n- Preload runs when a workspace is **loaded** — its first query after a server\n  start, `/live-memory-empty`, or a config change. A glob change via\n  `/live-memory-config` applies to already-loaded workspaces on their next\n  reset/restart, not retroactively.\n- **`/live-memory-reset`** starts a workspace over in one step: it drops the\n  current history trail (Q&A history, knowledge ledger, file manifest — memory\n  and on-disk snapshot) and immediately re-preloads the configured globs fresh\n  from disk. Use it when the accumulated trail has gone stale but you want the\n  verbose reference docs back. (`/live-memory-empty` is the same wipe without\n  the eager re-preload — the docs still load lazily on the next question.)\n\n### Monitoring scope (`file_globs`) and the question timeout\n\n| Env var / config key | Default | Effect |\n|---|---|---|\n| `LIVE_MEMORY_FILE_GLOBS` / `file_globs` | *(empty — monitor everything)* | Comma-separated fnmatch patterns (workspace-relative; `*` also crosses `/`). When set, the **file-change feed** — passive ingestion, stale/deleted tracking, modified hints — applies **only** to matching paths; everything else is dropped at the workspace boundary. Pair it with `preload_globs` for a docs-only memory: `/live-memory-config set preload_globs=docs/*.md file_globs=docs/*.md`. |\n| `LIVE_MEMORY_DEFAULT_TIMEOUT_S` / `default_timeout_s` | `60` | The soft per-question time budget. `ask_live_memory` **no longer takes a `timeout` argument** — callers get this configured budget; the model is told it and returns a best-effort answer at the deadline. Keep it below the hard `.mcp.json` MCP timeout. |\n\nScoping matters for cache stability too: an unscoped feed tees every file your\nagents touch, and each new observation is a delta the next question must carry.\nA docs-only scope keeps the memory focused and its prompt small.\n\n### Concurrency\n\nQuestions to the **same** workspace are admitted by one of two models:\n\n| Env var | Default | Effect |\n|---|---|---|\n| `LIVE_MEMORY_CONCURRENCY` | `parallel` | `parallel` (default) = no queue delay — each question forks the window, up to `MAX_PARALLEL_QUERIES` run at once, and the fork that **explored the most codebase** commits back (others still return their answer but don't update shared memory). `serial` = one question at a time per workspace (shared window grows in place; strongest cache locality, concurrent callers wait). |\n| `LIVE_MEMORY_MAX_PARALLEL_QUERIES` | `4` | Max concurrent questions per workspace in `parallel` mode. |\n\n(Questions to *different* workspaces always run concurrently, regardless of this setting.)\n\n### Async (fire-and-forget) tools — opt-in\n\nMCP tool calls block the caller's turn until they return. If you want the agent\nto submit a slow query, keep working, and collect the answer later, set\n`LIVE_MEMORY_ASYNC_TOOLS=true` to additionally expose:\n\n- `ask_live_memory_submit(question, cwd)` → returns a `job_id` immediately.\n- `ask_live_memory_result(job_id)` → the answer when ready, or `[running]` to poll again.\n\nThe agent drives the polling (Claude Code can't push completion into a running\nturn). Off by default; `ask_live_memory` (synchronous) is always available.\n\n### Cache keep-warm\n\n**Off by default** — opt in with `LIVE_MEMORY_KEEP_WARM=true`, or via the slash\ncommand: `/live-memory-config set keep_warm=true`. A background loop pings each\nrecently-active workspace's prefix (`max_tokens=1`, output discarded) so the\nprovider's KV/prompt cache doesn't go cold between questions — keeping the next\nreal query on cache-hit pricing instead of a full cold re-read. The heartbeat\ninterval is provider knowledge: **4 minutes** (240s) for Anthropic/OpenAI (just\nunder their minute-scale cache TTLs), and auto-set very long for **DeepSeek**\n(its disk cache lasts hours/days, so even enabled it self-disables there).\nOverride with `LIVE_MEMORY_KEEP_WARM_INTERVAL_S` /\n`/live-memory-config set keep_warm_interval_s=…`, or stop warming idle\nworkspaces sooner with `LIVE_MEMORY_KEEP_WARM_MAX_IDLE_S`.\n`/live-memory-stats` shows when the cache was last refreshed.\n",
  "bytes": 23765,
  "sha": "56e71a012eb5cb97960dcecbd38fad545ab67e79ddd7d0a0cc6e78a767dc56ae",
  "repo_slug": "shofer-dev/claude-code-live-memory",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_shofer_dev_live_memory_1ced9524/readme"
}