{
  "markdown": "# Pensieve\n\n<!-- mcp-name: io.github.praveen-ilangovan/pensieve -->\n\n[![PyPI version](https://img.shields.io/pypi/v/pensieve-mcp)](https://pypi.org/project/pensieve-mcp/)\n[![Python versions](https://img.shields.io/pypi/pyversions/pensieve-mcp)](https://pypi.org/project/pensieve-mcp/)\n[![License: MIT](https://img.shields.io/github/license/praveen-ilangovan/pensieve)](LICENSE)\n[![MCP Registry](https://img.shields.io/badge/MCP_Registry-listed-1f6feb)](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.praveen-ilangovan/pensieve)\n[![Glama score](https://glama.ai/mcp/servers/praveen-ilangovan/pensieve/badges/score.svg)](https://glama.ai/mcp/servers/praveen-ilangovan/pensieve)\n\n**A personal, agent-driven memory that survives across sessions.**\n\nYou talk to an AI assistant (Claude Code) every day, but it forgets everything between\nsessions. Pensieve is the long-term memory you control: **any time** in a conversation you can\nsay *\"add this to pensieve\"* to capture something, or *\"what do I know about X?\"* to pull it\nback — and it's there, organised, current, and yours.\n\n> The metaphor: deliberately draw out a strand of thought and deposit it in the vessel to\n> revisit later.\n\nIt's a small **Python + SQLite** engine with two front doors: an **MCP server** the agent\nuses, and a **CLI** for you. Your memory lives in a single file at `~/.pensieve`.\n\n---\n\n## Philosophy\n\nFive ideas shape every decision in Pensieve:\n\n1. **An information lake, not a project manager.** It stores *what you know* and lets you\n   recall it. It deliberately has no tasks, statuses, or due dates — the agent infers state\n   by reading, the store just holds the information.\n\n2. **Deliberate on both ends.** Pensieve never acts on its own. It writes only when you say\n   *\"remember this,\"* and recalls only when you *ask*. No silent saves, no auto-loading your\n   memory at the start of a session. You stay in control of what goes in and what comes out.\n\n3. **Structure emerges; you don't design it upfront.** You don't build a taxonomy. You keep\n   a few top-level **streams** (the domains you actually work in) and drop notes in. The\n   people, orgs and topics your notes mention become **entities** automatically, and one that\n   keeps recurring earns its own **thread**. Organisation is a *consequence of use*.\n\n4. **Notes are the atoms; everything else references them.** A note can stand alone or live\n   in several streams at once. Entities and threads are *views over notes*, not owners of\n   them — so removing a topic never destroys a note that's also about something else.\n\n5. **Point at the world, don't copy it.** Attach a repo, file or URL as an **asset** — a\n   by-reference pointer with a one-line \"how to use me\" hint. Pensieve stores the pointer and\n   reads it *on demand*; it never crawls your disk or follows a link on its own.\n\n> Want the reasoning in depth — the design decisions, the full model, the tradeoffs?\n> **[`docs/philosophy.md`](docs/philosophy.md).**\n\n---\n\n## The model\n\n| Thing | What it is |\n|---|---|\n| **stream** | A top-level domain of your work/life — `career`, `personal`, `side-projects`. Deliberate and few. |\n| **note** | An atomic piece of information — the unit you capture. Can live in more than one stream. |\n| **entity** | A person / org / topic your notes are *about*. Born from a note (by tagging); never created in a vacuum. |\n| **thread** | An entity that recurred enough to earn its own focused sub-topic under a stream. |\n| **asset** | A by-reference pointer (repo / file / dir / URL / image / doc) + a usage hint, attached to a stream, thread, or note. |\n\n**Recall has three lenses:** by **name** (`find`), by **content** (`search` — full-text,\nstemmed, ranked), and by **time** (`recent` — what changed lately).\n\n---\n\n## Install\n\nAssumes Python 3.12+.\n\n### Recommended: from PyPI\n\nPensieve is a standard MCP server, so the quickest way in is [`pipx`](https://pipx.pypa.io)\n(or [`uv`](https://docs.astral.sh/uv/)):\n\n```bash\npipx install pensieve-mcp     # or: uv tool install pensieve-mcp\n```\n\nThis puts `pensieve` (the CLI) and `pensieve-mcp` (the MCP server) on your PATH. Then point\nyour agent at it. For **Claude Code**:\n\n```bash\nclaude mcp add --scope user pensieve -- pensieve-mcp\n```\n\nFor any other MCP client, register the `pensieve-mcp` command as a stdio server. To run it\nad-hoc without installing, `uvx pensieve-mcp` works too.\n\nPensieve is listed in the official [MCP Registry](https://registry.modelcontextprotocol.io)\nas `io.github.praveen-ilangovan/pensieve`, so registry-aware clients can discover and install\nit directly.\n\n> **Note:** the PyPI package is the engine (CLI + MCP server). The judgment-bearing Claude\n> **skill** (the `capture`/`fetch` flows) ships with the repo, not the wheel — if you want it,\n> use the script install below, which drops it into `~/.claude/skills/pensieve/` for you.\n\n### Agent setup from source\n\n```bash\ngit clone git@github.com:praveen-ilangovan/pensieve.git\ncd pensieve\n./install.sh          # Claude Code (backward-compatible default)\n./install.sh codex    # Codex\n./install.sh all      # both\n```\n\n`install.sh` checks prerequisites up front (and changes nothing if any are missing), ensures\n`pipx`, installs Pensieve (`pensieve` + `pensieve-mcp` on your PATH), installs the selected\nagent skill, and registers the MCP server in that agent's user configuration. Claude's skill\nlives in `~/.claude/skills/pensieve/`; Codex's user-scoped `$pensieve` skill is symlinked at\n`~/.agents/skills/pensieve/`, so it is available from every repository. It's **idempotent** —\nre-run anytime to pick up updates.\n\nThe Codex MCP registration pins `PENSIEVE_HOME=~/.pensieve`, ensuring Codex reads and writes\nthe same personal store as Claude even when Codex is launched from this repository (whose\n`.env` intentionally points development commands at `.local/manual`). The engine and MCP\ntools are unchanged; the Codex skill supplies the same deliberate capture/recall discipline\nas the existing Claude adapter.\n\nThen **restart the selected agent** and, from any directory:\n\n> \"what streams do I have? check pensieve\"\n\nYour memory lives in `~/.pensieve`.\n\n---\n\n## Using it (with the agent)\n\nPensieve shines through the agent — you speak naturally, it does the judgment and calls the\ntools. Everything below is just *talking to Claude Code*.\n\n**Set up your domains** (do this once, deliberately):\n> \"Create a pensieve stream called Career — for my job search and work.\"\n\n**Capture** — any time something worth keeping comes up:\n> \"Add this to pensieve: had a call with Maya about the platform role; she's reviewing my portfolio.\"\n\nThe agent filters for what's *durable*, routes it to the right stream, and recognises that\n\"Maya\" is a person worth tracking — without you managing any of that. If a note spans two\ndomains (say, a talk that's relevant to both your `career` and a `side-project`), it files\n**one** note in both.\n\n**Recall** — pick the lens that fits the question:\n> \"What do I know about Maya?\" · \"What did we decide about salary?\" · \"Catch me up — what's\n> changed lately?\"\n\n**Point at live context** — so the agent knows where to read:\n> \"Add my project repo at ~/projects/acme as an asset on the side-projects stream — hint: read\n> README.md first.\" Later: \"pull up the acme repo.\" (It follows the pointer only when you ask.)\n\n**Promote** — when something recurs, the agent proposes it:\n> \"Maya's come up across 5 notes — want her own thread under Career?\"\n\n**Remove / restore** — everything is soft and reversible:\n> \"Remove that note.\" / \"Actually, bring it back.\" / \"I'm done with the X stream.\"\n\n---\n\n## Using it (the CLI)\n\nThe same engine is a CLI too — handy for a quick check or scripting without the agent\n(`pensieve stream list`, `pensieve search \"…\"`, …). Full command reference with examples:\n**[`docs/cli.md`](docs/cli.md)**.\n\n---\n\n## How it works (under the hood)\n\n- **SQLite** store (`~/.pensieve`), self-migrating via Alembic on first use.\n- **Full-text search** via SQLite FTS5 + a porter stemmer (so \"pricing\" recalls \"priced\").\n- A clean **ports/adapters** core: services depend on a storage *port* with two\n  interchangeable backends (SQLite + an in-memory double), kept honest by a conformance test.\n- The **MCP server** and **CLI** are thin \"op\" layers; the *judgment* (what to keep, how to\n  resolve an entity, when to promote) lives in the agent **skill** (`adapters/claude/`).\n\n---\n\n## Develop on it\n\n```bash\nmake install         # poetry env + pre-commit hooks\nmake test            # unit + integration\nmake eval            # deterministic engine evaluators\nmake check           # ruff (lint+format) + mypy\nmake manual ARGS=\"stream list\"   # run the CLI against the local dev store\n```\n\nThis repo is a self-contained **dev environment** — it never touches your real `~/.pensieve`.\nThe in-repo MCP server and CLI use a local dev store (`.env` → `.local/manual`); the global\ninstall (`./install.sh`) is what points at `~/.pensieve`.\n\nDesign notes live in [`plans/`](plans) (one file per slice, plus\n[`plans/roadmap.md`](plans/roadmap.md)) and [`docs/`](docs)\n([`philosophy.md`](docs/philosophy.md) — the why + model, [`cli.md`](docs/cli.md) — commands).\n\n---\n\n## Status\n\nWorking and in daily use: streams · threads · notes · entities · promotion · assets ·\nsearch · recency · multi-stream notes · soft remove/restore — all via CLI **and** MCP.\nBuilt and validated slice by slice with a real agent. See `plans/roadmap.md` for what's next.\n",
  "bytes": 9474,
  "sha": "8bd5200b72e5e9374b9d3a935589f6e625f71cddac927e5cfbf182475b54b178",
  "repo_slug": "praveen-ilangovan/pensieve",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_praveen_ilangovan_pensieve_47746d79/readme"
}