{
  "markdown": "<!-- mcp-name: io.github.premanand8800/cogsession -->\n\n# 🌳 CogSession\n\n**Session memory for AI coding agents.** Your agent forgets everything when the context\nwindow fills. CogSession remembers the parts worth keeping, and tells you when they stop\nbeing true.\n\n[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-green.svg)](LICENSE)\n[![MCP](https://img.shields.io/badge/MCP-server-orange.svg)](https://modelcontextprotocol.io/)\n[![Tests](https://img.shields.io/badge/tests-83%20passing-brightgreen.svg)](tests/)\n\n---\n\n## The problem\n\n```\nSession 1 (context fills) → Session 2 starts fresh → Session 3 starts fresh\n    Everything lost.          Repeats the mistakes.   Starts blind again.\n```\n\nYou explain the codebase again. The agent tries the approach that already failed. The\nconstraint you agreed on in session 1 is gone by session 3.\n\nThe usual answer is \"write better notes\", which fails for the same reason all documentation\nfails: **it is true when written and nobody notices when it stops being true.**\n\n## What CogSession does\n\nThree things, and the third is the one that does not exist elsewhere.\n\n**1. It records without being asked.** A session opens on its own. Decisions, dead ends,\nassumptions and errors are written as they happen, each stamped with the local time and the\nrepo state it happened at (`main@a1b2c3d+2`, where `+2` is dirty files).\n\n**2. It makes that searchable without loading it.** Every session keeps a `session.md`:\nappend-only, one block per event, every entry line self-describing. So one `grep` answers a\nquestion without pulling a file into context.\n\n```bash\ngrep -A4 \"dead_end\"      .cogsessions/*/session.md   # what already failed\ngrep \"2026-08-27 01:\"    .cogsessions/*/session.md   # what happened that hour\ngrep \"main@a1b2c3d\"      .cogsessions/*/session.md   # what happened at that commit\n```\n\n**3. It tells you when what you wrote stops being true.** Record a claim with the command\nthat *proves* it. When the files it watches change, the proof is re-run:\n\n```\n[CogSession] 1 claim(s) no longer hold:\n  ✗ the composite key includes the tenant column\n    expected '1', got '0'\n    asserted in: PR description, line 26\n    proof: grep -c 'UNIQUE (a, b, c)' migrations/007_schema.sql\n```\n\nNo model judgement involved. It stores the command that proved something and re-runs it.\nSilence means everything still holds.\n\n## Why the third one matters\n\nEvery expensive failure in three weeks of daily use reduced to one sentence: *something was\ntrue when it was written and stopped being true.* A pull request description explaining a\nschema the code no longer had. A comment naming a constraint that moved. A test asserting a\nshape the implementation had dropped. A docstring contradicting its own function.\n\nAn agent cannot notice that from a transcript. A human notices it in review, which is the\nexpensive place. A stored proof notices it for free.\n\n---\n\n## Is this the thing you are looking for?\n\nYou are probably here because of one of these:\n\n- **Claude Code hit its context limit** and the next session knows nothing about the last one\n- Your agent **retried an approach that already failed**, because nothing recorded that it failed\n- A constraint you agreed on in one session was **gone three sessions later**\n- You keep **re-explaining the same codebase** at the start of every session\n- A comment, a doc or a PR description **described the code as it used to be**, and review caught it rather than you\n\nThe first four are what any agent-memory tool is for. The fifth is the one CogSession\nwas actually built to solve, and it is the reason for the claims feature above.\n\n### How this differs from just writing notes\n\nNotes go stale silently. That is the entire problem, and no amount of discipline fixes it,\nbecause the failure is not that you forgot to write something down — it is that what you\nwrote stopped being true and nothing told you.\n\nA claim is a note with a **proof attached**. When the proof stops passing, you hear about it.\n\n### How this differs from your agent's built-in memory\n\nBuilt-in memory decides what to keep. This records what happened, in a plain file you own,\nin your repo's directory, greppable with tools you already have. It works the same whether\nthe agent is Claude Code today or something else next year, because the output is markdown\nand JSONL rather than a vendor's store.\n\n---\n\n## What a session looks like on disk\n\n```\n.cogsessions/\n├── sess_001_discover/\n│   ├── session.md          ← greppable timeline, every entry timestamped + git-stamped\n│   ├── handoff.md          ← the brief the next session reads first\n│   ├── claims.json         ← assertions with the commands that prove them\n│   ├── dead_ends.md        ← what failed and why, so it is not retried\n│   ├── assumptions.md      ← what was assumed but never verified\n│   ├── tasks.json          ← done / remaining / blocked\n│   ├── decisions.json      ← flagged when made under high context pressure\n│   ├── environment.json    ← the commands that restore a working state\n│   ├── architecture.mermaid← auto-generated dependency diagram\n│   └── session_log.jsonl   ← append-only machine log\n├── sess_002_auth/          (parent: sess_001)\n└── sess_003_payments/      (parent: sess_001, sibling of sess_002)\n```\n\nSessions form a tree, like branches, because work does. `session_tree` shows it; `session_log`\nis a `git log --oneline` across all of them.\n\n---\n\n## Requirements\n\n- Python 3.11+\n- [`uv`](https://docs.astral.sh/uv/) for the install script\n- An MCP-capable agent. Built against Claude Code; also usable from Codex (see below)\n- `git` is optional. Without it the journal records `no-git` and stays useful\n\n## Install\n\n```bash\npip install cogsession        # or: uv tool install cogsession\ncogsession-admin install\n```\n\nTwo commands on purpose. The first installs the MCP server; the second wires the\n**hooks**, which is what makes CogSession record without being asked. A package\ncannot write to `~/.claude/settings.json` on its own, so without the second command\nyou get eleven tools you must call by hand and none of the recording.\n\n`cogsession-admin install` backs up your settings first, adds the six hooks\nalongside anything already there, and **will not overwrite a status line you\nalready set**.\n\n<details>\n<summary>Installing from a clone instead (for working on CogSession itself)</summary>\n\n```bash\ngit clone https://github.com/premanand8800/cogsession.git\ncd cogsession\nuv sync\nuv run cogsession-admin install --repo .\n```\n\n`--repo` points the hooks at your checkout through `uv`, so edits take effect\nwithout reinstalling.\n</details>\n\nThe installer syncs dependencies with `uv`, registers the MCP server with Claude Code, and\nwrites the hooks that let it observe a session without being asked. It touches\n`~/.claude/settings.json` and nothing inside your projects.\n\n**It will not write to a file git tracks.** The handoff goes to `CLAUDE.local.md`, which is\nauto-loaded the same way `CLAUDE.md` is but never committed. If that filename happens to be\ntracked in your repo, CogSession refuses to write rather than dirtying your tree, and tells\nyou where the handoff is on disk instead. Add `.cogsessions/` to your `.gitignore`.\n\n### The tools\n\nEleven MCP tools, in four groups:\n\n| Group | Tools |\n|---|---|\n| Lifecycle | `session_init` · `session_checkpoint` · `session_load` · `session_status` |\n| Recording | `session_update` |\n| Searching | `session_search` · `session_log` · `session_tree` · `session_diagram` |\n| Claims | `claim_record` · `claim_check` |\n\nPlus six hooks (`SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PostToolUse`,\n`PreCompact`, `SessionEnd`) that do the recording you never have to ask for.\n\n### What it does *not* do\n\nWorth saying plainly, because it is the first thing people assume:\n\n**CogSession does not store your conversations.** It reads the transcript only to measure how\nfull the context window is. What it keeps is conclusions — decisions, dead ends, assumptions,\nclaims — plus the mechanical events from the hooks. That is deliberate: a memory made of every\nword said is a memory nobody re-reads. But it does mean the quality of a session's memory\ndepends on things being recorded as they are decided.\n\n---\n\n## Usage\n\n**Start of every session: nothing.** The `SessionStart` hook opens a session and\nloads the previous handoff on its own. Tracking that depends on someone\nremembering to turn it on is tracking that silently does not happen.\n\nName the session when you know what it is about — the focus line is the only\npart a tool cannot infer:\n```\nsession_update(type=\"focus\", content=\"auth module\")\n```\n\n`session_init` still exists for a session you want to start deliberately, or to\nattach to a parent:\n```\nsession_init(project_root=\"/your/project\", focus=\"auth module\")\nsession_load(project_root=\"/your/project\")   # load a previous handoff by hand\n```\n\n**Throughout the session:**\n```\nsession_update(type=\"decision\", content=\"Use python-jose for JWT\", reasoning=\"Handles RS256 edge cases\")\nsession_update(type=\"dead_end\", content=\"Using httpx for auth\", why_failed=\"Breaks streaming in /login\", use_instead=\"Use requests library\")\nsession_update(type=\"assumption\", content=\"users table has hashed_password column\", risk_level=\"HIGH\", how_to_verify=\"Run \\\\d users in psql\")\nsession_update(type=\"task_complete\", content=\"Build /register endpoint\")\nsession_update(type=\"task_add\", content=\"Build /refresh endpoint\")\nsession_update(type=\"danger_zone\", content=\"Don't touch middleware.py — custom CORS order line 45\")\nsession_status(context_pct=67)\n```\n\n**At 70-80% context:**\n```\nsession_checkpoint(context_pct=78, one_liner=\"Built JWT auth. Refresh token next.\")\n```\n\n**Look something up without loading anything.** Every session keeps a\n`session.md`: append-only, one block per event, each header carrying its own\nlocal timestamp, event type, and the repo state it happened at\n(`branch@commit+dirty`). So one `grep` answers a question:\n\n```\ngrep -n -A4 \"dead_end\"  .cogsessions/<session>/session.md   # what already failed\ngrep -n \"2026-08-27 01:\" .cogsessions/<session>/session.md   # what happened that hour\ngrep -n \"main@a1b2c3d\"   .cogsessions/<session>/session.md   # what happened at that commit\n```\n\nEvery entry line is self-describing, which is what makes a bare `grep` useful:\na match tells you when, what kind, and against which state of the code, with no\nneed to scroll for context. Tool calls are deliberately left out — hundreds per\nsession would bury the decisions someone is actually searching for; they stay in\n`session_log.jsonl`.\n\n**Scan history like `git log`:**\n```\nsession_log()                        # newest first, all sessions\nsession_log(type_filter=\"dead_end\")  # what has already failed here\n```\n\n```\nwhen                       what         repo                   session\n2026-08-27 01:43:57 +0545  error        master@3d4d1fd+2       sess_20260827_...\n2026-08-27 01:43:57 +0545  dead_end     master@3d4d1fd+1       sess_20260827_...\n```\n\nScan, then grep the journal for the entry that matters. The commit id is the\njoin back to real `git log`, so a decision can be lined up with the state of\nthe code that produced it.\n\n**Claims — for anything you write down that could go stale:**\n```\nclaim_record(\n  claim=\"the composite key includes the tenant column\",\n  verified_by=\"grep -c 'UNIQUE (a, b, c)' migrations/007_schema.sql\",\n  expect=\"1\",\n  watches=[\"migrations/007_schema.sql\"],\n  asserted_in=\"PR description, line 26\",\n)\nclaim_check()          # re-runs the proofs whose files moved\n```\n\nA claim stores the *command that proved it*, not a note about how to check it.\nWhen the file changes, the next session is told which statements stopped being\ntrue, where they were asserted, and how they were checked. Silence means\neverything still holds.\n\nThis exists because the most expensive failure is not a wrong decision. It is a\nright one that quietly stopped being true — a description of a schema the code\nno longer has, a comment naming a constraint that moved, a test asserting a\nshape the implementation dropped.\n\n**Explore history:**\n```\nsession_tree(project_root=\"/your/project\")\nsession_search(project_root=\"/your/project\", query=\"httpx\", type_filter=\"dead_end\")\nsession_diagram(project_root=\"/your/project\")\n```\n\n---\n\n## How It Works: Inverted Control (Observer-First)\n\nCogSession operates automatically via agent hooks and transcript inspection. **You don't need to manually report token percentages or call tools.**\n\n1. **Automatic Context Measurement**: Context load is read directly from Claude Code session transcripts (`input_tokens + cache_creation + cache_read + output_tokens`).\n2. **Automatic Injection**:\n   - `SessionStart`: Injects L0 manifest & L1 handoff unprompted.\n   - `UserPromptSubmit`: Nudges at 65%–74%, recommends at 75%–79%, and mandates checkpoints at $\\ge$80%. Surfaces prompt-relevant dead ends and danger zones.\n   - `PreToolUse`: Blocks file edits targeting recorded danger zones.\n3. **Deterministic Distillation**: Tracks file edits, git operations, commands, and test failures without relying on LLM guesses.\n\n---\n\n## What Makes It Different\n\n| Feature | Other Systems | CogSession |\n|---|---|---|\n| Dead ends tracking | ❌ | ✅ Automatic extraction of failed approaches & reasons |\n| Context load measurement | ❌ Guesswork | ✅ Ground truth token measurement from transcript |\n| Decision quality flags | ❌ | ✅ Automatically flagged if made at >75% context |\n| Tree structure | ❌ linear | ✅ Branches like git |\n| Token-aware warnings | ❌ | ✅ Automatic: 65% nudge, 75% alert, 80% mandate |\n| Auto CLAUDE.md handoff | ❌ | ✅ Handoff written automatically at checkpoint |\n| Architecture diagram | ❌ | ✅ Auto-generated Mermaid |\n| Environment snapshot | ❌ | ✅ Exact start commands, ports, env vars |\n\n\n---\n\n## Connect\n\nCogSession is an MCP stdio server. If `cogsession` is installed in the\nenvironment where your agent runs, register it with `uv run cogsession`.\n\n**Codex CLI:**\n```bash\ncodex mcp add cogsession -- uv run cogsession\n```\n\nIf you are running CogSession directly from a local source checkout, point `uv`\nat that checkout:\n\n```bash\ncodex mcp add cogsession -- uv --directory /path/to/cogsession run cogsession\n```\n\nVerify the server is registered:\n```bash\ncodex mcp list\ncodex mcp get cogsession\n```\n\nRestart Codex after adding the MCP server. Codex loads MCP tools when a new\nCodex session starts.\n\n**Claude Code:**\n```bash\nclaude mcp add cogsession -- uv run cogsession\n```\n\nFor a local source checkout:\n\n```bash\nclaude mcp add cogsession -- uv --directory /path/to/cogsession run cogsession\n```\n\n**Cursor** (`.cursor/mcp.json`):\n```json\n{\"mcpServers\": {\"cogsession\": {\"command\": \"uv\", \"args\": [\"run\", \"cogsession\"]}}}\n```\n\nFor a local source checkout:\n\n```json\n{\n  \"mcpServers\": {\n    \"cogsession\": {\n      \"command\": \"uv\",\n      \"args\": [\"--directory\", \"/path/to/cogsession\", \"run\", \"cogsession\"]\n    }\n  }\n}\n```\n\n**Disable for a project:**\n```bash\necho '{\"enabled\": false}' > .cogsession.json\n```\n\n---\n\n## Using CogSession with Codex\n\nCogSession is project-local. It stores session data inside the target project:\n\n```text\n/your/project/.cogsessions/\n```\n\nStart Codex from the project you want to remember:\n\n```bash\ncd /your/project\ncodex\n```\n\nThen ask Codex to use CogSession in plain language:\n\n```text\nload the session and handoff from cogsession\n```\n\nor be explicit:\n\n```text\nUse cogsession to load the latest handoff for this project.\n```\n\nIf this is the first session for the project:\n\n```text\nUse cogsession to initialize a session for this project with focus \"initial setup\".\n```\n\nDuring work, record important facts:\n\n```text\nUse cogsession to record a decision: \"Use the existing service layer for account updates\" because \"It keeps validation and audit logging in one place\".\n```\n\n```text\nUse cogsession to record a dead end: \"Calling the external API directly from the route handler\" because \"It bypassed retries and request tracing\" and use instead \"Call the existing API client wrapper\".\n```\n\nBefore stopping, checkpoint the session:\n\n```text\nUse cogsession to checkpoint this session with context 64% and summary \"Implemented account update flow; remaining work is integration tests.\"\n```\n\n### Codex Example\n\n```text\ndeveloper@workstation:~/projects/example-app$ codex\n╭───────────────────────────────────────────────╮\n│ >_ OpenAI Codex (v0.130.0)                    │\n│                                               │\n│ model:     gpt-5.5   /model to change         │\n│ directory: ~/projects/example-app             │\n╰───────────────────────────────────────────────╯\n\n› load the session and handoff from cogsession\n\n• Called\n  └ cogsession.session_load({\n      \"project_root\": \"/home/developer/projects/example-app\",\n      \"load_level\": \"handoff\"\n    })\n\n[CogSession] Handoff from sess_20260513_101500_account_updates_a1b2:\n\n# Handoff: sess_20260513_101500_account_updates_a1b2\n\n**Focus:** Account update flow\n**Closed:** 64% context | 2026-05-13 23:33\n**Parent:** root\n\n## Summary\nAccount update flow is implemented, validation is wired through the existing\nservice layer, and lint/type checks are passing. Remaining work is integration\ntest coverage for error cases.\n```\n\nAfter loading the handoff, Codex can continue with the saved context:\n\n```text\nI implemented the account update flow using the existing service layer:\n\n- Added src/services/account_service.py for update orchestration.\n- Updated src/api/account_routes.py to call the service layer.\n- Added validation in src/schemas/account.py.\n- Documented required environment variables in .env.example.\n\nVerification:\npytest             passed\nruff check .       passed\nmypy src           passed\n\nRemaining work:\n- Add integration tests for validation failures.\n- Confirm production environment variables before release.\n```\n\n### Project-Local vs Global\n\nCogSession does not use one global memory store by default. Each project gets\nits own `.cogsessions/` directory.\n\nFor this project:\n\n```text\n/home/developer/projects/example-app/.cogsessions/\n```\n\nFor another project:\n\n```text\n/home/developer/projects/admin-tool/.cogsessions/\n```\n\nThose are separate histories. To inspect a specific project, ask Codex:\n\n```text\nUse cogsession to show the session tree for /home/developer/projects/example-app.\n```\n\nCodex may show an approval prompt before running a CogSession tool:\n\n```text\nAllow the cogsession MCP server to run tool \"session_tree\"?\n\n1. Allow\n2. Allow for this session\n3. Always allow\n4. Cancel\n```\n\nChoose `Allow for this session` or `Always allow` if you want fewer prompts.\n\n### Useful Codex Prompts\n\n```text\nUse cogsession to load the latest handoff for this project.\n```\n\n```text\nUse cogsession to initialize a new session for this project with focus \"auth fixes\".\n```\n\n```text\nUse cogsession to show the session tree for this project.\n```\n\n```text\nUse cogsession to search this project for \"account update\".\n```\n\n```text\nUse cogsession to checkpoint this session with context 70% and summary \"Implemented auth changes and recorded build blocker.\"\n```\n",
  "bytes": 19155,
  "sha": "9fa7cca7e1315527c17b8048f5fe0c4c3636ce3be7659ff6272b2f8d5409a0a3",
  "repo_slug": "premanand8800/cogsession",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_premanand8800_cogsession_b8563a06/readme"
}