project-brain-mcp
by AiraAlfredSF
README.md
# project-brain-mcp
Standalone [MCP](https://modelcontextprotocol.io) server that gives CLI
coding agents (Claude Code, Cline, Cursor, opencode) persistent decision
memory, codebase dependency-graph awareness, plan validation against
architectural constraints, and a self-bootstrapping `constraints.md` file —
backed by a local SQLite database (`.project-brain/decisions.db`) in each
project it's wired into.
## CLI agent support status
| Agent | Status |
|---|---|
| **Claude Code** | ✅ Tested end-to-end (indexing, dependency graph, decision memory, plan validation, bootstrap, all 24 tools). |
| **Cline** | ⚠️ Skill package shipped (`skills/cline/`), install script support present — not yet verified end-to-end. |
| **Cursor** | ⚠️ Skill package shipped (`skills/cursor/`), install script support present — not yet verified end-to-end. |
| **opencode** | ⚠️ Skill package shipped (`skills/opencode/`), install script support present — not yet verified end-to-end. |
If you try this with Cline, Cursor, or opencode, please open an issue with
what worked / didn't — that feedback directly shapes which agent gets
verified next.
---
## Use case scenarios
These are real flows this server enables once wired into a project (the
examples below are from testing against a Laravel/PHP codebase, but the same
flows apply to any supported language):
- **Onboarding into an unfamiliar codebase.** Run `index_codebase` once, then
`run_bootstrap` — the agent walks every module, records its inferred
purpose/constraints/caveats via `log_module_intent`, and generates a draft
`constraints.md` (Architectural Boundaries, Technology Constraints) for you
to review and correct.
- **"What breaks if I change this?"** Before editing a shared model or
service, the agent calls `get_dependents` / `get_blast_radius` to see every
file that transitively depends on it — e.g. confirming that changing
`app/Models/User.php` only affects `database/seeders/DatabaseSeeder.php`,
not half the app.
- **Don't repeat past mistakes.** When an approach fails (a library doesn't
fit, a migration breaks under load, etc.), the agent logs it with
`log_failure`. In a later session, `get_context(topic)` surfaces that
failure before the agent tries the same thing again.
- **Plan review against architectural rules.** Before executing a multi-step
plan, `validate_plan(task, steps)` checks each step against logged hard
constraints and graph-derived boundaries, returning `PLAN: blocked` with
specific fixes if a step would violate one.
- **"Where do I even start?"** For a feature request described in plain
English, `find_entry_points(intent)` does a semantic search over indexed
modules — e.g. `intent="HTTP request entry point for the web application"`
returned the relevant controllers in a Laravel app.
- **Tracking structural drift over time.** `diff_graph(since_commit)` shows
which dependency edges were added/removed since a given commit — useful
after pulling a large set of changes before continuing work.
---
## Supported languages
The code-graph indexer (`index_codebase`) parses these file types via
[tree-sitter](https://tree-sitter.github.io/tree-sitter/):
| Language | Extensions |
|---|---|
| TypeScript / JavaScript | `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.cjs` |
| Python | `.py` |
| Rust | `.rs` |
| Go | `.go` |
| Java | `.java` |
| C / C++ | `.c`, `.h`, `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hh` |
| PHP | `.php` (PSR-4 `use` resolution via `composer.json`) |
Other file types are indexed as plain nodes but produce no dependency edges.
---
## Prerequisites
- Node.js `^20 || ^22 || >=24`
- A git working tree for the project you want to wire this into (most tools
work without git, but `diff_graph` and the incremental CLI ingest path use
the current commit hash)
---
## Install & build
```bash
git clone <this-repo>
cd code-brain-mcp
npm install
npm run build
```
This produces `dist/src/index.js` (the MCP server entry point) and
`dist/cli/index.js` (the `project-brain` CLI for remote ingest, see below).
---
## Setup in a project
### Option A — automated install script (recommended)
From the root of the project you want to add code-brain-mcp to:
```bash
/path/to/code-brain-mcp/scripts/install.sh
```
The script:
1. Detects which agent(s) you use, based on marker files in your project:
- **Claude Code**: `CLAUDE.md` or `.claude/`
- **Cline**: `.clinerules` or `.cline/`
- **Cursor**: `.cursorrules` or `.cursor/`
- **opencode**: `AGENTS.md` or `.opencode/`
2. Installs/merges the matching skill package from `skills/<agent>/` into
your project (project-memory instructions + a bootstrap flow), preserving
any existing content in those files (code-brain-mcp's block is wrapped in
`<!-- code-brain-mcp:start/end -->` markers).
3. Registers the MCP server in your agent's config (`.mcp.json`,
`.cursor/mcp.json`, `opencode.json`). Cline stores MCP config outside the
repo — the script prints the entry to add manually via the Cline "MCP
Servers" panel.
4. Creates `.project-brain/` (the local SQLite database directory) if it
doesn't already exist.
5. Installs a `.git/hooks/post-commit` hook (for the optional remote-ingest
workflow, see below).
If no marker file is detected, the script exits with instructions for adding
one manually.
### Option B — manual config (Claude Code)
Add to `.mcp.json` (or your global `~/.claude.json` under `mcpServers`):
```json
{
"mcpServers": {
"code-brain": {
"command": "node",
"args": ["/path/to/code-brain-mcp/dist/src/index.js"]
}
}
}
```
Then copy `skills/claude-code/CLAUDE.md` and `skills/claude-code/bootstrap.md`
into your project so Claude Code knows how/when to call the tools.
---
## First run
> **You don't need to type these calls yourself.** Once
> `skills/claude-code/CLAUDE.md` is installed in your project root (via
> `scripts/install.sh` or copied manually), Claude Code auto-loads it every
> session and treats the steps below as always-on behavior — it calls these
> tools on its own as part of normal work, and `get_session_health()`
> self-corrects if it skips one. The steps below are what happens under the
> hood, useful mainly for the very first run or for manual/CLI testing.
In a fresh Claude Code session in your project:
1. `start_session()`
2. `get_context(topic="...")` — loads project memory, required before other
tool calls per the session-health checker.
3. `index_codebase(incremental=false)` — builds the initial dependency graph.
4. `get_bootstrap_status()` — if `never_run`, run `run_bootstrap(path)`
repeatedly (see `skills/<agent>/bootstrap.md` for the full multi-turn
flow) to populate `constraints.md` with the project's architectural
boundaries and technology constraints.
After that, `CLAUDE.md` (or the equivalent rule file for your agent) describes
the always-on behaviors: calling `get_dependents`/`get_dependencies`/
`get_blast_radius` before changing a module, `validate_plan` before executing
a multi-step plan, `log_decision`/`log_failure` to build up project memory,
etc.
---
## Transport modes
| Mode | Default | Auth | Notes |
|---|---|---|---|
| `local` (stdio) | yes | none | Single project, single SQLite file, spawned by your agent. |
| `remote` (HTTP) | set `TRANSPORT_MODE=remote` | `PROJECT_BRAIN_TOKEN` bearer token (required — server refuses to start without it) | Enables `WAL` mode + `SQLITE_BUSY_TIMEOUT_MS` for concurrent access; see `scripts/project-brain.service` for a systemd unit example. |
Remote mode env vars: `TRANSPORT_MODE`, `PROJECT_BRAIN_TOKEN`, `HOST`
(default `127.0.0.1`), `PORT` (default `8420`), `SQLITE_BUSY_TIMEOUT_MS`
(default `5000`).
### Remote ingest CLI
For the remote-server setup, the `project-brain` CLI (`dist/cli/index.js`)
pushes graph updates from a separate machine/CI job:
```bash
project-brain index --full --push --url https://your-server --token $PROJECT_BRAIN_TOKEN
project-brain index --since <commit> --push --url https://your-server --token $PROJECT_BRAIN_TOKEN
```
The installed `post-commit` git hook runs the `--since HEAD~1 --push`
incremental form automatically if `PROJECT_BRAIN_URL` is set in your
environment.
---
## Project memory file: `constraints.md`
`export_constraints_file()` generates a human-readable `constraints.md` at
your project root (YAML frontmatter + Architectural Boundaries / Technology
Constraints / Flagged-for-review sections). Edit it by hand, then call
`ingest_constraints_file()` to sync your edits back into the database. See
`constraints.md` in this repo for a live example of the format.
---
## A note on secrets
`index_codebase` never reads or stores raw file contents — it only parses
source files (per the extensions listed above) for import/dependency edges,
and stores file paths + module names in `.project-brain/decisions.db`. It
never reads `.env` files or similar.
The `decisions`/`failures`/`module_intents`/`constraints` tables store
free-text written by your agent via `log_decision`, `log_failure`, and
`log_module_intent` — avoid having your agent paste secrets/credentials into
those calls, the same way you would with any chat. `.project-brain/` is
already in `.gitignore`, so this database stays local and is never committed.
---
## Roadmap
- **Verify Cline / Cursor / opencode support.** Skill packages and install
paths exist for all three (`skills/<agent>/`), but only Claude Code has
been tested end-to-end so far.
- **Plugin-based language support.** Today, adding a language means adding a
tree-sitter grammar dependency and a walker function in
`src/parser/treesitter.ts` (see PHP support as the most recent example).
The goal is to make this a drop-in plugin interface so the community can
add languages (Java/Kotlin for Android, C#/.NET, etc.) without touching
core indexer code.
- **Composer autoload beyond PSR-4.** PHP support currently resolves `use`
statements via PSR-4 only; `classmap`/`files`/`psr-0` autoload strategies
and multi-`composer.json` monorepos are not yet covered.
- **Non-code / document repos.** The dependency-graph model is code-specific
today (tree-sitter ASTs). An exploratory direction is a parallel
"document graph" mode for non-code repositories (e.g. a folder of legal
contracts or policy documents) — same decision-memory/constraints-file
mechanics, but relationships derived from document structure/references
instead of imports. This is an early idea, not yet scoped into a spec.
Contributions and issue reports toward any of the above are welcome.
---
## Development
```bash
npm test # vitest
npm run build # tsc
npm run dev # run the server directly via tsx, stdio mode
```
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues