neatcode-mcp
by HITMANdark07
README.md
<div align="center">
```text
_ _
_ __ ___ __ _ | |_ ___ ___ __| | ___
| '_ \ / _ \ / _` | | __| / __| / _ \ / _` | / _ \
| | | || __/ | (_| | | |_ | (__ | (_) | (_| | | __/
|_| |_| \___| \__,_| \__| \___| \___/ \__,_| \___|
```
# ๐ง neatcode
**Local-first repo intelligence for AI coding agents.**
*The graph your agent wishes it had.*
[](https://www.npmjs.com/package/@neatcodeai/cli)
[](https://www.npmjs.com/package/@neatcodeai/cli)
[](./LICENSE)
[](https://nodejs.org)
[](#typescript-compatibility)
[](#mcp-integration)
</div>
---
> Stop letting your agent re-grep your repo on every turn.
> neatcode indexes your TypeScript codebase into a real AST graph, learns the conventions your code already follows, and answers your agent's structural questions over MCP โ **deterministic, no LLM in the hot path**.
```text
โโโโโโโโโโโโโโโโโโโโ MCP โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ป your editor โ โโโโโstdioโโโโโโถ โ โ๏ธ neatcode-mcp (11 tools) โ
โ โ โ |
โ Claude Code โ โ ๐ query_graph ๐ find_node โ
โ Cursor โ โ ๐ค๏ธ trace_flow โ
validate โ
โ Codex โ โ ๐ก propose_rule ๐ get_rules โ
โโโโโโโโโโโโโโโโโโโโ โ ๐ add_note ๐ repo_overview โ
โ โฎ accept_proposed_rule โ
โ โฎ derive_candidates โ
โ โฎ accept_derived_candidates โ
โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโผโโโโโโโโโโโโ
โ ๐ .neatcode/ โ
โ โโโ graph.db โ
โ โโโ skills.yaml โ
โ โโโ decisions.yaml โ
โ โโโ REPO_OVERVIEW โ
โโโโโโโโโโโโโโโโโโโโโโโโโ
```
## ๐ก Why
| Without neatcode | With neatcode |
| --- | --- |
| Agent re-greps the repo every turn | Agent calls `query_graph` against an indexed AST |
| "What conventions does this repo follow?" โ vibes | Heuristic miner derives conventions from real code |
| Agent writes `BookingHandler` despite a Controller convention | `validate_diff` flags it before the file is written |
| Rules live in tribal memory or stale `CONTRIBUTING.md` | Rules live in `.neatcode/skills.yaml`, validated bidirectionally |
| Each chat starts cold | `get_repo_overview` ships the one-page brief at session start |
---
## ๐ Quickstart โ 3 commands
```bash
# 1. Install (one tarball, both binaries)
npm i -g @neatcodeai/cli
# 2. Index your repo
cd ~/your/typescript/repo
neatcode init
# 3. Wire it into Claude Code
neatcode claude install
```
Restart Claude Code. Your agent now has 11 structural tools โ and a fresh `.neatcode/REPO_OVERVIEW.md` for instant context.
> ๐ฏ **Founder's target:** *installed in 10 minutes, useful in 1 hour.*
### ๐ฌ What it looks like in practice
```text
๐ค You: "Where do we handle booking cancellation?"
๐ค Agent: [calls query_graph with "booking cancellation"]
โ
๐ BookingsController.cancel (apps/api/src/bookings/โฆ)
๐ BookingsService.cancel (called by Controller)
๐ RefundService.issueRefund (called by Service)
๐ BookingCancelledEvent (emitted at end)
Here's the flow: Controller โ Service โ RefundService,
with a domain event published on completion.
```
vs. without neatcode: agent runs 4 grep calls, reads 18 files, and still misses the event publisher.
---
## ๐ท TypeScript compatibility
neatcode ships TypeScript types and is built around `ts-morph`. It indexes any TypeScript codebase that compiles.
| What | Compatibility |
| --- | --- |
| TypeScript versions | `5.0` โ `5.7+` (uses `ts-morph` 24.x; tracks the bundled compiler) |
| File extensions | `.ts`, `.tsx` (skips `.d.ts` and `.generated.ts(x)`); `.js` / `.cjs` not yet indexed |
| Module systems | ESM, CommonJS, mixed โ output target doesn't matter |
| `tsconfig.json` | Auto-detected at repo root; respects `paths`, `baseUrl`, `composite` |
| JSX / TSX | Yes โ `.tsx` parsed, JSX edges emitted |
| Decorators | Stage-3 standard + experimental (NestJS, TypeORM, class-validator) |
| Type-aware queries | Uses TS TypeChecker for cross-file call-graph resolution |
| Strict mode | Recommended but not required |
| Monorepos | pnpm / yarn / npm workspaces โ each package gets its own `qualified_name` namespace |
| Frameworks | NestJS, React, Next.js, Express, Fastify (auto-detected; no rule packs) |
Not on TypeScript? neatcode v0.1 is TS-only by design โ Python, Go, and JS support are roadmapped (see [Roadmap](#roadmap)).
---
## โก CLI reference
```text
neatcode <command> [options]
```
### ๐ฅ Indexing
| Command | What it does |
| --- | --- |
| `neatcode init` | First-time setup. Creates `.neatcode/`, indexes every `.ts`/`.tsx` file, runs the heuristic miner, drops `REPO_OVERVIEW.md`. |
| `neatcode sync [--force]` | Re-index changed files. Content-hash cached โ editing 3 files re-parses 3 files. |
| `neatcode ask "<question>"` | Ad-hoc graph query from the terminal. Same engine as `query_graph` over MCP. |
### ๐ Skills (conventions)
| Command | What it does |
| --- | --- |
| `neatcode skills derive [--threshold 0.85] [--min-population 3]` | Mine the graph for high-coverage patterns. Writes `skills.candidates.yaml`. |
| `neatcode skills accept <id> [--all] [--confidence high\|medium] [--local]` | Promote candidates into `skills.yaml` (committed) or `skills.local.yaml` (gitignored). |
| `neatcode skills reject <id> [--reason "โฆ"]` | Mark a candidate as rejected so the next `derive` skips it. |
### โ
Validation
| Command | What it does |
| --- | --- |
| `neatcode validate [<filesโฆ>] [--json]` | No args โ check whole graph. With files โ treat as planned diff. Pre-existing offenders are grandfathered under `scope: "new"`. |
| `neatcode exception add <rule_id> <location> [--days N] [--reason "โฆ"]` | Silence a specific violation. Auto-expires with `--days`. |
| `neatcode exception list` | Show active exceptions. |
| `neatcode exception revoke <rule_id> <location>` | Append-only revoke (original entry preserved). |
### ๐ Editor integration
| Command | What it does |
| --- | --- |
| `neatcode claude install` | Merges `.mcp.json`, appends MCP guidance to `CLAUDE.md`. Idempotent. |
| `neatcode claude uninstall` | Reverses both. Pre-existing CLAUDE.md content is preserved. |
| `neatcode cursor install` *(coming v0.2)* | Wires neatcode-mcp into Cursor's MCP config. |
| `neatcode codex install` *(coming v0.2)* | Wires neatcode-mcp into Codex. |
---
## ๐ MCP integration
The agent gets 11 tools the moment Claude Code restarts after `neatcode claude install`:
**Discovery + queries**
| Tool | When the agent calls it |
| --- | --- |
| `get_repo_overview` | Once per session. Returns frameworks, top symbols, layout, active rules, dirty-file status. |
| `query_graph` | "What handles X?", "what calls Y?" โ keyword-scored search with optional 1-hop expansion. |
| `find_node` | Exact lookup by name or `qualified_name`. Returns merged class+method decorators. |
| `trace_flow` | Multi-hop path traversal. "From `BookingsController.create` to the DB" returns the call chain. |
**Rules + validation**
| Tool | When the agent calls it |
| --- | --- |
| `get_rules` | Returns active rules, candidates, rejected list, and repo context for curation flows. |
| `validate_diff` | Pre-flight on a planned change. Returns violations + four-option suggestions block. |
| `propose_rule_from_prompt` | Inspects a user utterance for rule-language ("never", "must", "always"). Surfaces a structured proposal. |
| `accept_proposed_rule` | Promote a single proposed rule into `skills.yaml`. |
| `derive_candidates` | Run the heuristic miner on demand and return candidate rules. |
| `accept_derived_candidates` | Bulk-accept miner candidates by id, confidence, or `--all`. |
**Memory**
| Tool | When the agent calls it |
| --- | --- |
| `add_note` | Persist a fact the user shared. Appends to `.neatcode/memory/notes-YYYY-MM-DD.md`. |
All deterministic. No LLM call inside the server. The agent is the brain; neatcode is the spine.
---
## ๐ What lives in `.neatcode/`
`neatcode init` creates the directory and seeds it with the indexer output and miner proposals. The remaining files appear on demand as you accept rules, record exceptions, and let the agent take notes.
**Created by `neatcode init`:**
```text
<repo-root>/
โโโ .neatcodeignore team-shared excludes (commit it)
โโโ .neatcode/
โโโ graph.db SQLite graph (regenerate; should gitignore)
โโโ skills.candidates.yaml miner proposals (regenerated each sync)
โโโ REPO_OVERVIEW.md session-start brief (commit it)
โโโ plans/ /writing-plans skill scaffold (commit it)
โโโ specs/ /brainstorming skill scaffold (commit it)
```
**Appears on demand:**
```text
.neatcode/
โโโ skills.yaml on first `skills accept` (commit it)
โโโ skills.local.yaml on `skills accept --local` (should gitignore)
โโโ skills.rejected.yaml on first `skills reject` (commit it)
โโโ decisions.yaml on first exception/supersede (commit it)
โโโ memory/ on first `add_note` MCP call (commit it)
โโโ mcp.log on first MCP server start (should gitignore)
```
> โน๏ธ `neatcode init` doesn't touch your `.gitignore`. Add the regeneratable bits yourself:
> ```gitignore
> .neatcode/graph.db*
> .neatcode/skills.candidates.yaml
> .neatcode/skills.local.yaml
> .neatcode/mcp.log
> ```
`graph.db` is regeneratable from a single `neatcode sync`. The committed files above form the team-shared memory of the repo โ that's the part you code-review.
---
## ๐ How rules emerge
Three sources, one lifecycle:
1. **Heuristic mining** โ `neatcode skills derive` proposes candidates above the coverage threshold. Four primitives mined today: `decorator-required`, `annotation-forbidden`, `naming-pattern`, `folder-naming-convention`.
2. **Prompts** โ when the user says *"all classes with @Controller must use @UseGuards"*, the agent calls `propose_rule_from_prompt`. A local keyword classifier โ **no LLM in the loop** โ extracts a structured candidate. User confirms, agent runs `skills accept`.
3. **Manual** โ hand-edit `.neatcode/skills.yaml` (create it on first rule). The schema is documented and stable.
Rules are validated **bidirectionally**:
- A diff that violates a rule โ four-option UX (record exception ยท time-bounded ยท supersede the rule ยท abort).
- A rule that no longer matches the codebase โ can be superseded with an entry in `decisions.yaml`.
### ๐งฉ The six primitives
| Primitive | Mined? | Example |
| --- | :-: | --- |
| `decorator-required` | yes | classes with `@ApiTags` must also have `@Controller` |
| `annotation-forbidden` | yes | classes with `@Controller` must not carry `@Deprecated` |
| `naming-pattern` | yes | classes with `@Module` end with `"Module"` |
| `folder-naming-convention` | yes | files in `apps/api/services/` end with `.service.ts` |
| `import-forbidden` | via prompt | `never import from packages/internal/` |
| `edge-forbidden` | via prompt | `controllers must not call repositories directly` |
Layer constraints (*"controllers can't reach repositories"*) are expressed via `edge-forbidden` โ no special "layer" type.
### ๐ฑ Default rule scope: `new`
Rules default to `scope: "new"` โ pre-existing violations are **grandfathered**. Only code introduced *after* the rule was promoted gets checked. Set `scope: "all"` in YAML to enforce against existing code.
This avoids the classic *"we accepted 30 conventions and now CI is on fire"* problem.
---
## ๐๏ธ Architecture
```text
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ ts-morph parser โโโถ ๐๏ธ polymorphic graph โ
โ (SQLite) โ
โโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
๐ query_graph ๐ skills derive โ
validate_diff
๐ find_node (heuristic miner) (engine.ts)
๐ค๏ธ trace_flow โ โ
โ โผ โผ
โ skills.candidates active rules โฉ
โ โ accept decisions.yaml
โผ โ
๐ค agent answers โโโโโโโโโโโโโโโโโโโโโโโโโโ โ ๏ธ violations
+ 4-option UX
```
Every relationship gets a confidence label (`EXTRACTED` | `INFERRED` | `AMBIGUOUS`); the validator **never fires on rules built solely from `AMBIGUOUS` edges**. The repo-root-relative `qualified_name` is the FK that ties nodes, edges, rules, and decisions together. There's no LLM in the hot path of any MCP tool โ the LLM lives in the agent harness (Claude Code, Cursor, Codex), and neatcode is the spine.
---
## ๐ฆ Packages
The CLI bundles everything you need; the others are split for advanced use.
| Package | Install for | What it gives you |
| --- | --- | --- |
| [`@neatcodeai/cli`](https://www.npmjs.com/package/@neatcodeai/cli) | Most users | `neatcode` + `neatcode-mcp` binaries (depends on the others). |
| [`@neatcodeai/mcp`](https://www.npmjs.com/package/@neatcodeai/mcp) | Bare MCP server | The stdio MCP binary alone. |
| [`@neatcodeai/core`](https://www.npmjs.com/package/@neatcodeai/core) | Library users | `parseFile`, `Database`, `ask`, miner โ all typed. |
Single install gets you everything:
```bash
npm i -g @neatcodeai/cli
which neatcode neatcode-mcp
```
---
## ๐ ๏ธ Develop
```bash
pnpm install # builds better-sqlite3 native module
pnpm build # builds all three packages
pnpm typecheck # tsc --noEmit across packages
pnpm test # vitest run
pnpm test:watch
pnpm clean
# Smoke-test
node packages/cli/dist/index.js --help
```
Node 20+, TypeScript strict + `verbatimModuleSyntax`, ESM only.
---
## ๐บ๏ธ Roadmap
- **v0.1** *(shipped)* โ TypeScript-only, 11 MCP tools, validation engine, four-option UX, heuristic miner with four primitives, Claude Code installer.
- **v0.2** โ Cursor + Codex installers, `import-forbidden` / `edge-forbidden` mining, agent-proposed rules (`skills derive --with-agent`).
- **v0.3** โ Watcher mode (`neatcode dev`), JavaScript / `.js` / `.cjs` indexing, TypeScript LSP integration.
- **Later** โ Python via `tree-sitter`, Go via `go/parser`, multi-language graphs joined by import-edge inference.
Issues, feature requests, and convention horror stories: [github.com/HitmanDark07/neatcodeai/issues](https://github.com/HitmanDark07/neatcodeai/issues).
---
## ๐ก๏ธ Hard rules (project guarantees)
- No framework rule packs โ conventions emerge per-repo.
- Decorators / generics / JSX live in `extra` JSON, not schema columns.
- `qualified_name` is **always** repo-root-relative.
- Rules built solely on `AMBIGUOUS` edges never enforce.
- v0.1 doesn't solve general NestJS DI โ `@Module({ providers, controllers, imports })` arrays become direct edges and we stop there.
---
<div align="center">
### ๐ License
[MIT](./LICENSE) ยท built with โค๏ธ by [@HitmanDark07](https://github.com/HitmanDark07)
โญ *If neatcode helps your agent stop guessing, star the repo.*
</div>
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues