neatcode-mcp

neatcode-mcp

Provides deterministic AST graph queries and rule validation for AI coding agents via MCP tools, enabling structural intelligence without LLM calls.

Category
访问服务器

README

<div align="center">

                          _                     _
   _ __    ___    __ _   | |_    ___   ___   __| |   ___
  | '_ \  / _ \  / _` |  | __|  / __| / _ \ / _` |  / _ \
  | | | ||  __/ | (_| |  | |_  | (__ | (_) | (_| | |  __/
  |_| |_| \___|  \__,_|   \__|  \___| \___/ \__,_|  \___|

🧠 neatcode

Local-first repo intelligence for AI coding agents. The graph your agent wishes it had.

npm version npm downloads license node types mcp

</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.05.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 init doesn'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:

  1. Heuristic miningneatcode 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

       ┌──────────────────────────────────────────────────┐
       │  📜 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-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.


🛡️ 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 · built with ❤️ by @HitmanDark07

If neatcode helps your agent stop guessing, star the repo.

</div>

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选