Skip to main content
Glama

Feedback Graph

Your coding agent keeps making the same mistakes. Feedback Graph remembers the corrections.

Every time you tell Claude Code or Codex "that's not good enough" or "you missed X", the lesson dies with the session. Feedback Graph runs on your machine, reads the sessions of the project folders you choose, finds the moments you pushed back, works out what was missed and why, and, once you approve it, hands that lesson to the next agent session before it starts and again before it says "done".

  • Local first. Runs in Docker with a local model (Ollama) by default. Nothing leaves your machine unless you configure a provider.

  • You decide what is learned. Every flagged moment and every lesson waits for your confirmation.

  • Evidence, not vibes. Each lesson links back to the feedback, the miss, its cause, the code it touched and the fix.

  • Works with your agents through MCP and a skill: context before a task, a check before "done".

Apache-2.0 · Operations · Security · Changelog · Contributing · Editions · Design: docs/superpowers/specs/2026-10-22-feedback-graph-design.md

Quickstart

You need Docker, git and Ollama on the host. Claude Code or Codex is needed for the agent hookup in the last step.

git clone https://github.com/ChaosDeSelva/Feedback-Graph.git feedback-graph
cd feedback-graph
ollama pull gemma4 && ollama pull nomic-embed-text
./scripts/setup.sh                             # asks one question (your projects folders), writes .env with generated passwords, checks Ollama
docker compose up -d --build
open http://localhost:8787                     # or visit it in a browser; Settings: choose the project folders to read
./scripts/install-agent.sh                     # connect Claude Code and Codex (see below)

setup.sh asks only one thing: Project folders, comma-separated, with its best guess in brackets (Enter takes it). It asks on a first run in a terminal; when PROJECTS_DIRS or PROJECTS_DIR is already set (in the environment or .env), or there is no terminal, it uses that or its guess without asking, and it ends by printing the next commands. It never overwrites an existing .env: to change the folders later, edit PROJECTS_DIRS in .env (comma-separated) and re-run ./scripts/setup.sh, which regenerates the mounts. Then work as usual: push back on your agent when it misses something, confirm the flagged moment in the Inbox, and approve the lesson. To see the whole loop without your own projects, try the demo project.

  • setup.sh suggests the folders your Claude Code sessions ran in (PROJECTS_DIRS=~/code,~/work ./scripts/setup.sh answers it ahead on a first run). Several folders are mounted through a generated docker-compose.override.yml, so docker-compose.yml stays as shipped. It also creates ./state, ~/.claude/projects and ~/.codex/sessions if missing (Docker would create them owned by root). On Linux, see docs/operations.md for Ollama's OLLAMA_HOST and file ownership.

  • Port 8787 taken? Set API_PORT in .env: the UI is then at http://localhost:<API_PORT> and the MCP server at http://localhost:<API_PORT>/mcp. setup.sh prints the right address, and install-agent.sh registers it (re-run it after a change, removing the old registration as it tells you).

  • Neo4j browser: http://localhost:7476 (bolt on 7689)

  • Transcripts (~/.claude/projects and Codex's ~/.codex/sessions), your projects folders and ./examples are mounted read-only.

  • Nothing is read until you choose which project folders to include (Settings). The worker lists every folder under your project roots with how many Claude Code and Codex sessions ran in it, and reads only the ones you select.

  • Secrets are redacted before anything is stored or sent to a model, and secret files are never read (see SECURITY.md).

  • Health, backups, upgrades, running it behind TLS with a token: docs/operations.md.

Related MCP server: MIHAD

Connect your agents

./scripts/install-agent.sh sets up every coding agent it finds; ./scripts/install-agent.sh claude or ... codex sets up one. It registers http://localhost:<API_PORT>/mcp from .env (8787 by default); point it at another install with FEEDBACK_GRAPH_URL=https://feedback.example.com; when .env sets API_TOKEN, the MCP server is registered with it as a Bearer header.

  • Claude Code (claude on your PATH): the feedback-graph MCP server at user scope (claude mcp add --transport http), and the feedback-graph and postmortem skills linked into ~/.claude/skills. Type /postmortem what it missed to record a miss.

  • Codex (codex on your PATH, or ~/.codex present; CODEX_HOME is respected): a [mcp_servers.feedback-graph] table in ~/.codex/config.toml with the streamable HTTP url (and http_headers carrying the token, after which the file is made readable by you only), and the same guidance as the skill in ~/.codex/AGENTS.md between <!-- BEGIN feedback-graph --> and <!-- END feedback-graph --> markers. Ask Codex to record a miss for the post-mortem path.

Re-running is safe: a server already registered is left alone, the guidance block is rewritten only when it changed (the rest of your AGENTS.md is untouched), and a Codex file is copied to <file>.bak.<time> before it changes. To change the URL or token, remove the server (claude mcp remove feedback-graph --scope user, or delete the table from config.toml) and re-run.

How it works

  1. Ingest: reads the Claude Code and Codex session transcripts of the folders you selected and maps each to its project folder, with the repo files each session read and edited. A project is also identified by its git remote (origin, normalized to e.g. github.com/org/repo, credentials dropped): a second clone of a known repo in another folder is recorded under the existing project.

  2. Code map: each selected project's code is parsed (tree-sitter, no model) into files, symbols, imports, the tests covering each file and 90 days of churn, and kept current as the repo changes. Misses are linked to the files their session edited, so the graph can say which modules agents keep getting corrected on, and why.

  3. Detect: a keyword prefilter, then a classifier (gemma4 by default), flags pushback. It handles the newest feedback first.

  4. Inbox: you confirm or reject each flagged moment. Nothing is learned without your confirmation. Agents can also report a miss (report_feedback, e.g. from /postmortem); a report of pushback the detector already flagged becomes part of that same Inbox item, with both sources kept.

  5. Post-mortem: works out what was missed, why (a typed cause), and which context would have prevented it. The context hunt covers code facts, uploaded docs, PR reviews and Linear tickets. The proposed lesson is scoped to the files the fix touched when the evidence supports it. It also reads the instruction files the agent had: CLAUDE.md and AGENTS.md in the repo and each parent folder up to your project root, and Claude Code's memory notes, each labelled with whether that session's agent loads it (Claude Code: CLAUDE.md and memory; Codex: AGENTS.md).

  6. Lessons: you approve, edit or reject them. Only approved lessons reach agents.

  7. Agents use MCP. get_task_context serves lessons, past misses, code facts and doc excerpts; given the files the agent will touch, it puts the lessons tied to those files first and adds a short code map of them (importers, tests, last miss). get_module_context describes one file (facts, exported symbols, importers, imports, tests, lessons and misses tied to it) and impact lists what depends on a set of files, the tests to run, and lessons and misses there. check_before_done judges finished work against those lessons (a lesson with no verdict counts as a gap); given files_changed, it also names the importers and tests of those files the change did not touch and what the last misses there were about.

  8. Activity: every fact, code map build, flag, decision, post-mortem, served context and check is logged with who or what did it and why.

UI

Page

What

Inbox

Flagged feedback to confirm or reject (j/k, c, r)

Lessons

Evidence chain per lesson, edit and approve, plus its history

Graph

Clickable map from feedback to miss, cause, lesson, context and fix commits

Patterns

Misses by cause, repeated misses, weekly trend, pre-done catch rate, where agents struggle (top hotspots)

Projects

Code map (stats, sortable hotspots, a module panel per file linking to its lessons and Inbox items), scan code into facts (choose the model), browse facts with "how was this created?", upload docs

Activity

The provenance log, filterable by project and kind

The header shows whether the worker is running. Projects also has Export (a versioned JSON bundle), Import bundle (its lessons arrive proposed unless you keep them approved) and Delete project data. Settings picks the project folders to read and, when team sync is configured, shows the Cloud sync card.

Configuration (.env)

Variable

Purpose

PROJECTS_DIR, PROJECTS_DIRS, FEEDBACK_TOOL_DIR

Host folders: your projects folder (or several, comma-separated in PROJECTS_DIRS; re-run setup.sh after changing it), and this repo (for the examples). setup.sh fills them in.

POLL_SECONDS, CLASSIFY_BATCH, SCAN_MAX_FILES, SCAN_MAX_BYTES

Worker pace and bounds: seconds between cycles (30), turns classified per cycle (50), files per project (400) and bytes per file (80000) the code map and scans read. Empty: the default.

INGEST_PROJECTS

Seeds the project selection on the very first start only (e.g. demo-shop); after that, the selection in Settings decides. Empty: nothing is read until you choose (an upgrade selects the projects that already hold your approved lessons, confirmed feedback, docs or scans). Global lessons reach every folder under a root that is not excluded, selected or not.

EXCLUDE_PROJECTS

Never read, scan or serve these projects, whatever is selected. Settings shows them as excluded and cannot select them.

CODEX_SESSIONS_DIR

Codex session transcripts on the host. Default ~/.codex/sessions; if it does not exist the worker carries on without Codex.

TURN_RETENTION_DAYS

Remove the text of unflagged turns older than this. Empty keeps everything.

MEMORY_AUTO_APPROVE

false (default): Claude Code feedback memories (type: feedback) are imported as proposed lessons that you approve in Lessons. true: they are approved on import. Either way, once you edit, approve or reject one, re-importing its file never changes it.

API_TOKEN, PUBLIC_HOSTS, API_BIND

Reach the API from other machines: every call then needs the token. Without one, only localhost: an API_BIND other than 127.0.0.1 without API_TOKEN refuses to start.

ALLOW_UNCONFINED_CODEX

Set to 1 to let codex-cli run. Codex can read everything the worker can (SECURITY.md); claude-cli is confined to the project folder.

CLAUDE_CODE_OAUTH_TOKEN

From claude setup-token. Post-mortems then run on your Claude subscription (otherwise gemma4).

CLASSIFY_LLM, POSTMORTEM_LLM, SCAN_LLM, CHECK_LLM

Model per job: ollama:<model>, claude-cli, codex-cli, openai:<model>, openrouter:<model>, groq:<model>, anthropic:<model>, jev (classification only)

OPENAI_API_KEY, OPENAI_BASE_URL, OPENROUTER_API_KEY, GROQ_API_KEY, ANTHROPIC_API_KEY, TYPESAFE_API_KEY

Bring-your-own keys

GITHUB_TOKEN, GITHUB_REPOS

PR discussions as context: GITHUB_REPOS=demo-shop=me/demo-shop,other=me/other

LINEAR_API_KEY

Linear tickets searched during post-mortems

STORE, DATABASE_URL, POSTGRES_PASSWORD, COMPOSE_PROFILES

Storage backend: neo4j (default) or postgres. With the bundled Postgres, COMPOSE_PROFILES=postgres includes it in every docker compose command. See Storage.

CLOUD_URL, CLOUD_TOKEN, SYNC_INTERVAL_MINUTES, SYNC_PROJECTS, SYNC_SUGGESTIONS

Optional team sync to a Feedback Graph Cloud org. Off unless the first two are set. See Team sync.

The Codex provider uses your ChatGPT login: CODEX_AUTH_FILE (only that file is mounted). It explores a copy of the repository without secret files.

OLLAMA_EMBED_MODEL is recorded in the graph; changing it later needs pnpm reembed (the services tell you).

Team sync (optional)

The tool is complete on its own and sends nothing anywhere by default. Feedback Graph Cloud is a separate, hosted team product built on this core: a shared team graph, single sign-on, a team MCP endpoint and pull request checks. If your team uses it, the sync client in this repo pushes your project knowledge to your org:

  1. In the cloud web app, create an access token with the sync scope.

  2. Set CLOUD_URL=https://<your cloud> and CLOUD_TOKEN=fgc_pat_... in .env, then docker compose up -d.

  3. Press Sync now on the Cloud sync card in Settings, or set SYNC_INTERVAL_MINUTES=60 to sync on a schedule. SYNC_PROJECTS=a,b narrows which selected projects are sent.

What is sent, per selected project: its key and git remote, its approved lessons, misses (what was missed and why), current code facts, document titles and links, and the code map's paths with their hotspot numbers. Only lessons you approved leave: they become the team's (or wait for an admin, if your org reviews them). A proposed lesson stays on this machine until you approve it; SYNC_SUGGESTIONS=true sends proposed ones too, as suggestions for an admin. A lesson you reject or move back to proposed, or anything you delete, is taken back out of the team graph on the next sync. Never sent: transcripts (including the feedback you typed), source code, excerpts, document text, embeddings, or anything from an unselected or excluded project. Every sync is logged in Activity. Details: docs/operations.md.

Storage

Everything the tool learns is stored in Neo4j by default, which also gives you the Neo4j browser to explore the graph. Nothing changes for existing installs.

It can run on Postgres with pgvector instead, with the same code: every repository is an interface (packages/core/src/store.ts) with a Neo4j and a Postgres implementation (packages/store-postgres), and one contract test suite runs against both in CI. Redaction, Activity entries, export and delete behave the same on either.

# in .env: STORE=postgres, POSTGRES_PASSWORD=<letters and digits> (setup.sh generates one) and COMPOSE_PROFILES=postgres
docker compose up -d --build

The postgres profile adds a pgvector/Postgres 17 container (127.0.0.1:5434, volume postgres-data). To use your own Postgres 17 server with the vector extension available (pgvector 0.8.0 or newer; an older one is refused at startup), set DATABASE_URL=postgres://user:password@host:5432/db and leave the profile off. The schema is migrated at startup. /api/status and /api/ready report which store is in use. Switching backend starts empty: to carry your lessons and code facts over, Export on the old one and Import bundle on the new one's Projects page (see docs/operations.md). Backups in Postgres mode use pg_dump (./scripts/backup.sh does it for you).

Try it on the demo project

examples/demo-shop is a small multi-tenant API with rules in its CLAUDE.md.

# select demo-shop in Settings (or, on a fresh install, set INGEST_PROJECTS=demo-shop in .env first), then: docker compose up -d
./scripts/demo-pushback.sh   # a real Claude session plus a pushback turn; demo-shop is restored afterwards

Then open the Inbox, confirm the flagged pushback, wait for the post-mortem, and approve the lesson. Ask for context on a similar task (an invoices list) and run check_before_done with a summary that skips the sort order: the lesson and the gap both show up.

Develop

pnpm install
pnpm test                                                                 # unit + ui
docker compose -f docker-compose.test.yml up -d --wait && TEST_STORES=neo4j,postgres pnpm test:int   # contract suites on both backends
./scripts/check.sh                                                        # everything CI runs

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides coding agents with durable, cross-session lessons-learned memory, enforcing that success or failure verdicts can only come from human approval, human correction, or objective metrics—never from the agent itself.
    Apache 2.0
  • F
    license
    A
    quality
    B
    maintenance
    Enables coding agents to build and query a verified project memory through the MCP protocol, so skills, facts, and user preferences are captured as experience and adopted only after passing independent checks. It also briefs agents at each request, flags known pitfalls live, and runs an executable review before changes are finalized.
    4
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Briefs a coding agent with the repository's conventions, architecture decisions, and proven checks before every task, and lets the agent record new lessons as work proceeds. Entries are proven by running checks and flagged as stale when the code, docs, or diagrams they govern change, so agent behavior and documentation stay from drifting.
    565 PyPI
    4
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables coding agents such as Claude Code and Cursor to check a team's learned decisions from pull requests, reviews, and docs before writing code, showing whether breaking them is blocking or advisory. It also provides locally computed symbol impact/blast-radius analysis so source code never leaves the machine.
    356 npm
    1
    MIT