neatcode-mcp
Provides deterministic AST graph queries and rule validation for AI coding agents via MCP tools, enabling structural intelligence without LLM calls.
README
<div align="center">
_ _
_ __ ___ __ _ | |_ ___ ___ __| | ___
| '_ \ / _ \ / _` | | __| / __| / _ \ / _` | / _ \
| | | || __/ | (_| | | |_ | (__ | (_) | (_| | | __/
|_| |_| \___| \__,_| \__| \___| \___/ \__,_| \___|
๐ง neatcode
Local-first repo intelligence for AI coding agents. The graph your agent wishes it had.
</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.
โโโโโโโโโโโโโโโโโโโโ 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
# 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
๐ค 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).
โก CLI reference
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:
<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:
.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 initdoesn't touch your.gitignore. Add the regeneratable bits yourself:.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:
- Heuristic mining โ
neatcode skills deriveproposes candidates above the coverage threshold. Four primitives mined today:decorator-required,annotation-forbidden,naming-pattern,folder-naming-convention. - 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 runsskills accept. - 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
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ 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 |
Most users | neatcode + neatcode-mcp binaries (depends on the others). |
@neatcodeai/mcp |
Bare MCP server | The stdio MCP binary alone. |
@neatcodeai/core |
Library users | parseFile, Database, ask, miner โ all typed. |
Single install gets you everything:
npm i -g @neatcodeai/cli
which neatcode neatcode-mcp
๐ ๏ธ Develop
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-forbiddenmining, agent-proposed rules (skills derive --with-agent). - v0.3 โ Watcher mode (
neatcode dev), JavaScript /.js/.cjsindexing, TypeScript LSP integration. - Later โ Python via
tree-sitter, Go viago/parser, multi-language graphs joined by import-edge inference.
Issues, feature requests, and convention horror stories: github.com/HitmanDark07/neatcodeai/issues.
๐ก๏ธ Hard rules (project guarantees)
- No framework rule packs โ conventions emerge per-repo.
- Decorators / generics / JSX live in
extraJSON, not schema columns. qualified_nameis always repo-root-relative.- Rules built solely on
AMBIGUOUSedges 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 ยท built with โค๏ธ by @HitmanDark07
โญ If neatcode helps your agent stop guessing, star the repo.
</div>
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.