Skip to content

Quickstart

Install

cd your-repo
uvx --from legendary-mcp legendary init

That creates .legendary/, gitignores the derived index, and installs both hooks into .claude/settings.json — merging into your existing settings without touching anything else you have configured there.

You are done. The hooks are the primary channel and need no agent cooperation.

init also prints an MCP snippet. Add it to .mcp.json if you want the agent to be able to search memory deliberately, on top of what gets pushed:

{
  "mcpServers": {
    "legendary": {
      "command": "uvx",
      "args": ["--from", "legendary-mcp", "legendary", "mcp", "--repo", "/path/to/your-repo"]
    }
  }
}

Three tools: remember, recall, deprecate.

Record your first episode

Episodes are the point of the tool, and they require triggers — the verbatim error strings you observed:

from pathlib import Path
from legendary import service

service.remember(
    repo_root=Path("."),
    type="episode",
    title="strip() crashes on None",
    body="Use a guard: data.strip() if data else ''. Retries do not help.",
    anchors=[{"file": "app.py", "symbol": "parse"}],
    triggers=["AttributeError: 'NoneType' object has no attribute 'strip'"],
)

Now the next time any command prints that error, the episode is pushed back automatically. Without the trigger there is nothing to match on, which is why legendary refuses to save an episode that omits it.

See verification work

Edit the anchored function, then trigger the error again. The same memory returns marked [stale - code changed since this was written; verify before trusting].

Run legendary doctor any time for every memory whose code has moved on.