Local Code Intelligence MCP
Monorepo: indexer (SQLite + embedding local tùy chọn), MCP server (8 tools), CLI codeintel.
Làm từ đầu — từng bước và lệnh
Dưới đây là thứ tự làm việc đầy đủ. Thay ~/Documents/Code/grapuco-mcp bằng đường dẫn thật tới monorepo trên máy bạn; thay ~/Documents/Code/my-app bằng thư mục dự án muốn index (nơi sẽ xuất hiện .codeintel/).
| Bước | Việc cần làm | Lệnh (ví dụ) | |------|----------------|----------------| | 0 | (Nếu chưa có mã) clone repo và vào thư mục monorepo | git clone <url-repo> grapuco-mcp rồi cd grapuco-mcp | | 1 | Kiểm tra Node ≥ 20 | node -v | | 2 | Bật pnpm 9 qua Corepack (một lần trên máy) | corepack enable → corepack prepare pnpm@9.15.4 --activate | | 3 | Cài dependency và build toàn bộ | cd ~/Documents/Code/grapuco-mcp → pnpm install → pnpm build | | 4 | Chuyển vào thư mục dự án (workspace được index) | cd ~/Documents/Code/my-app<br>(hoặc thử: cd ~/Documents/Code/grapuco-mcp/examples/nest-sample) | | 5 | Khởi tạo CodeIntel (tạo .codeintel/, config.json) | node ~/Documents/Code/grapuco-mcp/apps/cli/dist/index.js init | | 6 | (Khuyến nghị) Sửa .codeintel/config.json — include / exclude | Mở file bằng editor | | 7 | Index toàn bộ mã nguồn | node ~/Documents/Code/grapuco-mcp/apps/cli/dist/index.js index --full | | 8 | Kiểm tra DB và cấu hình | node ~/Documents/Code/grapuco-mcp/apps/cli/dist/index.js stats<br>node ~/Documents/Code/grapuco-mcp/apps/cli/dist/index.js doctor | | 9 | (Tùy chọn) Tự reindex khi file đổi | node ~/Documents/Code/grapuco-mcp/apps/cli/dist/index.js watch (Ctrl+C để dừng) | | 10 | (Tùy chọn) Gắn MCP vào Cursor: thêm server với cwd = thư mục bước 4 | Xem mục Kết nối MCP bên dưới | | 11 | Lưu cấu hình MCP và khởi động lại Cursor (hoặc reload MCP) | Theo giao diện Cursor |
Một khối lệnh copy được (sau khi chỉnh đường dẫn cho đúng):
# --- A. Build monorepo (một lần hoặc sau khi pull code mới) ---
cd ~/Documents/Code/grapuco-mcp
corepack enable
corepack prepare pnpm@9.15.4 --activate
pnpm install
pnpm build
# --- B. Index một dự án ---
export CODEINTEL_REPO=~/Documents/Code/grapuco-mcp
export MY_APP=~/Documents/Code/my-app # hoặc: $CODEINTEL_REPO/examples/nest-sample
cd "$MY_APP"
node "$CODEINTEL_REPO/apps/cli/dist/index.js" init
node "$CODEINTEL_REPO/apps/cli/dist/index.js" index --full
node "$CODEINTEL_REPO/apps/cli/dist/index.js" stats
Yêu cầu hệ thống
- Node.js >= 20
- pnpm 9 (repo khai báo
packageManager: pnpm@9.15.4)
Bật pnpm qua Corepack (khuyến nghị):
corepack enable
corepack prepare pnpm@9.15.4 --activate
Cài đặt từ mã nguồn
Trong thư mục gốc monorepo:
pnpm install
pnpm build
(pnpm build chạy Turbo và build toàn bộ apps/, packages/.)
Sau khi build, binary CLI nằm tại apps/cli/dist/index.js (lệnh codeintel), MCP nằm tại apps/mcp-server/dist/index.js (lệnh codeintel-mcp nếu cài link).
Sử dụng CLI
CLI cần chạy trong thư mục dự án mà bạn muốn index (nơi sẽ có .codeintel/).
Cách gọi lệnh
1. Qua node (ổn định, không cần link): từ monorepo, dùng đường dẫn tương đối tới bản build:
node /đường/dẫn/tới/grapuco-mcp/apps/cli/dist/index.js init
node /đường/dẫn/tới/grapuco-mcp/apps/cli/dist/index.js index --full
node /đường/dẫn/tới/grapuco-mcp/apps/cli/dist/index.js stats
2. Qua pnpm workspace (khi đang đứng ở root monorepo):
pnpm --filter @codeintel/cli exec codeintel -- init
pnpm --filter @codeintel/cli exec codeintel -- index --full
pnpm --filter @codeintel/cli exec codeintel -- stats
Lưu ý: các lệnh trên dùng process.cwd() của shell — hãy cd vào đúng thư mục dự án trước khi chạy.
3. Link global (tùy chọn):
cd apps/cli && pnpm link --global
Sau đó trong thư mục dự án: codeintel init, codeintel index --full, v.v.
Luồng làm việc thông thường
init— tạo cấu trúc.codeintel/vàconfig.jsonmặc định (database, vectors, logs, cache).index --full— index toàn bộ workspace theoinclude/excludetrong config.doctor— kiểm tra cơ bản rằng config và schema DB đang hiện diện.stats— xem số dòng các bảng chính và breakdown cache hiện có.minimal-context --mode deep— lấy thứ tự đọc file ngắn gọn cho task hiện tại trước khi mở code.trace-flow --kind route --mode deep— lần theo execution flow cho route; đây là đường dùng chín nhất hiện nay.watch(tùy chọn) — tự reindex khi file thay đổi.mcp:start— khởi chạy MCP server trỏ vào workspace hiện tại (xem phần dưới).
Các lệnh CLI
| Lệnh | Mô tả | |------|--------| | codeintel init | Tạo .codeintel/ và config.json | | codeintel index [--full] | Index gia tăng hoặc full (--full) | | codeintel reindex [file...] | Reindex danh sách file (hoặc rỗng) | | codeintel watch | Theo dõi file và reindex theo batch | | codeintel trace-flow [value] [--kind route\|symbol\|task] [--method GET] [--mode lite\|deep] [--max-depth N] | In execution flow tổng quát; route là path chín nhất, còn symbol / task hiện là fallback sớm | | codeintel minimal-context [task] [--mode lite\|deep] [--max-files N] | Gợi ý thứ tự đọc file tối thiểu cho một task cụ thể | | codeintel mcp:start (hoặc mcp) | Spawn MCP server, CODEINTEL_CWD = thư mục hiện tại | | codeintel doctor | Kiểm tra cơ bản config + DB/schema presence | | codeintel stats | In số dòng các bảng chính trong DB, kèm breakdown flow_cache.execution_flow và flow_cache.minimal_context | | codeintel config:show | In nguyên config.json |
Workflow gợi ý cho bugfix / refactor
- Chạy
codeintel doctorđể xác nhận config và schema cơ bản đã sẵn sàng. - Chạy
codeintel statsđể xem DB córoutes,calls,module_roles,side_effect_edges, và cache hiện tại đang có gì. - Chạy
codeintel minimal-context "mô tả task" --mode deepđể lấy danh sáchRead first/Then checktrước khi mở editor. - Nếu task bám theo route rõ ràng, chạy
codeintel trace-flow "/api/orders/:id" --kind route --method GET --mode deepđể thấy flow tổng quát. - Khi cần chi tiết hơn ở cấp symbol, dùng MCP tools như
search_symbols,get_symbol_context,find_callers,find_callees.
Ghi chú về cache
- Deep
trace-flowchoroutevà deepminimal-contextdùng bảngflow_cacheđể tái sử dụng payload đã tính. codeintel statssẽ in tổng số record trongflow_cachevà breakdown theoexecution_flow/minimal_contextđể dễ kiểm tra thủ công.- Purge incremental hiện xóa
flow_cachetoàn cục để tránh cache cũ sau reindex. - Cache key có kèm version salt nội bộ để tự nhiên bust cache khi query contract/algorithm thay đổi.
Cấu hình
File .codeintel/config.json (sau init) điều khiển:
workspaceRoot,dbPath,vectorDirenabledLanguages,include,excludewatch,embeddings(bật/tắt embedding local, v.v.)
Chỉnh include / exclude cho khớp cấu trúc repo của bạn, rồi chạy lại index --full khi cần.
Ví dụ với examples/nest-sample
cd examples/nest-sample
node ../../apps/cli/dist/index.js init
node ../../apps/cli/dist/index.js index --full
node ../../apps/cli/dist/index.js stats
(Đường dẫn ../../apps/cli/... giả định bạn đang ở trong cây monorepo grapuco-mcp.)
Kết nối MCP (Cursor / client khác)
MCP server đọc workspace qua biến CODEINTEL_CWD (thư mục đã init và đã index). Nếu không set, server dùng process.cwd().
Cách A — Dùng CLI làm launcher (đặt cwd = thư mục dự án đã index):
{
"mcpServers": {
"codeintel": {
"command": "node",
"args": ["/ABS/PATH/grapuco-mcp/apps/cli/dist/index.js", "mcp:start"],
"cwd": "/ABS/PATH/dự-an-của-bạn"
}
}
}
Cách B — Gọi thẳng MCP server:
{
"mcpServers": {
"codeintel": {
"command": "node",
"args": ["/ABS/PATH/grapuco-mcp/apps/mcp-server/dist/index.js"],
"env": {
"CODEINTEL_CWD": "/ABS/PATH/dự-an-của-bạn"
}
}
}
}
Thay /ABS/PATH/... bằng đường dẫn thật trên máy. Trước khi dùng MCP, hãy đảm bảo đã chạy codeintel init và codeintel index --full trong dự-an-của-bạn.
Nhiều dự án: cwd / CODEINTEL_CWD thế nào?
Mỗi lần chạy MCP là một tiến trình gắn với đúng một thư mục dự án (nơi đã có .codeintel/config.json và DB). Bạn không thể dùng một dòng cwd duy nhất trỏ “cả hai repo” — mỗi repo đã init/index riêng thì cần một cặp (tên server + cwd hoặc CODEINTEL_CWD) riêng.
Cách làm: khai báo nhiều MCP server trong Cursor, tên key (codeintel-api, codeintel-web, …) khác nhau, còn command/args có thể giống nhau:
{
"mcpServers": {
"codeintel-biomics": {
"command": "node",
"args": ["/ABS/PATH/grapuco-mcp/apps/cli/dist/index.js", "mcp:start"],
"cwd": "/ABS/PATH/biomics-app"
},
"codeintel-khach": {
"command": "node",
"args": ["/ABS/PATH/grapuco-mcp/apps/cli/dist/index.js", "mcp:start"],
"cwd": "/ABS/PATH/du-an-khac"
}
}
}
Tương đương nếu gọi thẳng mcp-server: mỗi entry có env.CODEINTEL_CWD trỏ về root từng dự án (đã init + index).
Trong chat: nói rõ agent nên gọi tool trên server nào (ví dụ “dùng MCP codeintel-biomics”) để đúng DB.
Một dự án tại một thời điểm: chỉ cần một server; khi đổi dự án có thể sửa cwd / CODEINTEL_CWD và reload MCP (không cần nhiều entry).
Gói chính trong monorepo
| Package | Vai trò | |---------|---------| | apps/mcp-server | MCP stdio, tools search_symbols, get_symbol_context, … | | apps/indexer | Pipeline index full / incremental | | apps/cli | init, index, reindex, watch, mcp:start, doctor, stats, config:show | | packages/graph | Truy vấn SQLite (symbols, calls, routes, impact) | | packages/embeddings | Embedding local + cosine search | | packages/storage | SQLite + schema |
Hướng dẫn dùng MCP tools
Mỗi tool trả về một block văn bản chứa JSON (đã pretty-print). Client (ví dụ Cursor) sẽ nhận chuỗi đó; bạn có thể parse JSON để đọc results, callers, v.v.
Điều kiện: MCP phải trỏ đúng dự án đã init + index --full (xem Kết nối MCP). Dữ liệu chỉ phản ánh những file đã được indexer xử lý theo include / enabledLanguages trong .codeintel/config.json.
Luồng gợi ý cho agent
- Gọi
search_symbolsvới từ khóa (tên hàm, class, một phầnfqName) để lấy danh sách ứng viên vàsymbolId. - Dùng
symbolIdhoặc chuỗisymbol(khớpnamehoặcfq_nameđầu tiên trong DB) cho các tool còn lại. - Khi task còn rộng, gọi
get_minimal_context_for_tasktrước để lấy read order tối thiểu thay vì mở quá nhiều file. - Muốn hiểu nhanh một symbol:
get_symbol_context(gồm callers/callees lân cận). - Muốn xem execution flow tổng quát: ưu tiên
trace_execution_flowvớiroute;symbol/taskhiện chỉ là đường fallback sớm và có thể trả về placeholder/low-confidence. - Muốn đi sâu call graph:
find_callers/find_calleeshoặcanalyze_impact. - Dự án Nest có route đã index và cần output legacy theo controller → handler → callees:
trace_route_flow. - Tìm theo ngữ nghĩa (embedding):
search_code_semantic— cầnembeddings.enabled: truetrong config và đã index sau khi bật. - Tổng quan file/module:
summarize_module.
get_minimal_context_for_task
Trả về một bundle đọc nhanh cho task đang làm, chia thành readFirst, thenCheck, skipForNow, và unknownsToVerify.
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | task | Có | Mô tả task bằng ngôn ngữ tự nhiên, ví dụ fix login bug in auth flow. | | mode | Không | lite hoặc deep (khuyến nghị deep khi cần đọc ít file nhưng đúng hơn). | | maxFiles | Không | Số file tối đa muốn ưu tiên trong bundle. |
Kết quả: object có readFirst[], thenCheck[], skipForNow[], unknownsToVerify[]; deep mode có thể trả thêm cacheHit để cho biết bundle được lấy từ flow_cache.
trace_execution_flow
Theo dõi execution flow tổng quát cho ba loại entrypoint: route, symbol, task. Hiện tại route là path chín nhất; symbol và task vẫn là entrypoint sớm/fallback nên có thể chỉ trả về kết quả giới hạn hoặc low-confidence placeholder.
Với Laravel/Rails trong wave hiện tại, route/controller flow đã usable cho các convention phổ biến; ORM/model awareness cũng đã usable cho các pattern Eloquent/ActiveRecord thông dụng. Các route DSL phức tạp hơn, app namespace-heavy, hoặc nhánh macro-heavy / dynamic metaprogramming vẫn có thể xuất hiện unknowns hoặc alternatives thay vì một flow hoàn toàn deterministic.
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | entryKind | Có | route, symbol, hoặc task. Khuyến nghị dùng route khi có thể. | | value | Có | Route path, symbol name/fqName, hoặc task text. | | method | Không | Chỉ dùng khi entryKind = route; mặc định GET. | | mode | Không | lite hoặc deep. | | maxDepth | Không | Giới hạn số hop call graph cần đi. |
Kết quả: object gồm summary, segments, alternatives, confidence, unknowns; deep route mode có thể trả thêm cacheHit khi payload được đọc lại từ flow_cache. Với symbol / task, hiện nên xem output như tín hiệu thử nghiệm hơn là flow đầy đủ.
search_symbols
Tìm symbol theo text (SQL LIKE trên name và fq_name), xếp hạng nội bộ rồi trả về tối đa k kết quả.
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | query | Có | Chuỗi tìm kiếm (ví dụ UserService, getOrder). | | k | Không | Số kết quả tối đa (mặc định 10). | | kind | Không | Lọc thêm theo loại symbol (ví dụ class, function) sau khi truy vấn. |
Kết quả: results[] — mỗi phần tử có symbolId, name, fqName, kind, filePath, startLine, endLine, score.
get_symbol_context
Một “ảnh chụp” symbol: thông tin symbol + callers/callees trong bán kính radius (số bước trên đồ thị gọi, mặc định 1).
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | symbolId | Một trong hai | UUID symbol trong DB (nên lấy từ search_symbols). | | symbol | Một trong hai | Tên hoặc fq_name (symbol đầu tiên khớp). | | radius | Không | Độ sâu lân cận (mặc định 1). |
Kết quả: symbol, callers, callees — hoặc { "error": "symbol not found" }.
find_callers / find_callees
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | symbolId / symbol | Một trong hai | Giống get_symbol_context. | | k | Không | Giới hạn số cạnh trả về (mặc định 20). |
Kết quả: find_callers → target (fqName) + callers. find_callees → source + callees. Nếu không tìm thấy symbol: error + mảng rỗng.
trace_route_flow
Theo dõi luồng Nest-style đã được indexer gắn với bảng routes (HTTP method + path).
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | method | Có | Ví dụ GET, POST (theo cách lưu trong DB). | | path | Có | Đường dẫn route, ví dụ /users/:id. |
Kết quả: object mô tả luồng controller → service → … — hoặc { "error": "route not found", "route": { ... } } nếu không có route khớp.
analyze_impact
BFS callers từ một symbol để ước lượng tác động khi sửa (ai gọi tới ai).
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | symbolId / symbol | Một trong hai | Giống trên. | | depth | Không | Độ sâu BFS (mặc định 4). |
Kết quả: origin (fqName) + impacted (danh sách các symbol bị ảnh hưởng theo chỉ mục).
search_code_semantic
Embedding local (cosine similarity) trên các bản ghi trong bảng embeddings. Cần đã index khi embeddings.enabled bật (mặc định trong config).
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | query | Có | Mô tả bằng ngôn ngữ tự nhiên hoặc đoạn code tương tự. | | k | Không | Số kết quả (mặc định 10). | | pathPrefix | Không | Giới hạn symbol thuộc file có path khớp (ký tự * được thay bằng % trong SQL LIKE). |
Kết quả: results[] gồm symbolId, name, fqName, kind, filePath, dòng, score. Nếu chưa có embedding trong DB, danh sách có thể rỗng.
summarize_module
Tóm tắt nhanh theo đường dẫn file hoặc chuỗi module (dùng cho mệnh đề LIKE trên f.path).
| Tham số | Bắt buộc | Mô tả | |--------|----------|--------| | filePath | Một trong hai | Ví dụ src/auth/login.ts hoặc đoạn đặc trưng trong path. | | module | Một trong hai | Tương tự, thay thế khi không truyền filePath. |
Kết quả: summary (dòng mô tả số symbol / route), topSymbols (tối đa 12), routes (các route Nest gắn với file khớp). Phải truyền ít nhất một tham số; nếu không: { "error": "filePath or module required" }.
Prompt ví dụ (Cursor / chat)
Dán vào chat và thay tên class/hàm/path/route/module bằng thứ có trong dự án đã index. Nhắc agent dùng đúng MCP CodeIntel (tên server bạn đặt trong mcp.json, ví dụ codeintel).
Luồng nhiều bước (khuyến nghị khi refactor):
Dùng MCP local code intelligence: gọi search_symbols với query "PaymentService",
chọn đúng symbol khớp dự án, sau đó get_symbol_context với symbolId đó (radius 2),
rồi find_callers và analyze_impact (depth 4). Tóm tắt ai gọi tới service này và
những chỗ có thể bị ảnh hưởng khi đổi chữ ký hàm.
search_symbols:
Qua MCP CodeIntel, chạy search_symbols: query "validateToken", k 15.
Liệt kê top kết quả kèm filePath và dòng.
Tìm mọi symbol class liên quan tới "User" bằng search_symbols (query "User", kind "class").
get_symbol_context:
Dùng MCP: get_symbol_context cho symbol "OrderController#create" (hoặc symbolId nếu đã có), radius 2.
Giải thích mối quan hệ callers/callees.
find_callers / find_callees:
MCP find_callers: symbol "sendNotificationEmail", k 25 — ai đang gọi hàm này?
MCP find_callees: symbol "CheckoutService.process" — hàm đó gọi những symbol nào?
trace_route_flow (Nest):
MCP trace_route_flow: method GET, path /api/orders/:orderId — luồng xử lý từ controller xuống service.
analyze_impact:
Nếu sửa hàm "calculateTax" trong codebase đã index, dùng MCP analyze_impact (symbol đó, depth 5).
Liệt kê các symbol / file cần review.
search_code_semantic:
MCP search_code_semantic: query "xử lý refund và hoàn tiền cho đơn hủy", k 8.
Ưu tiên symbol có score cao và chỉ rõ file.
Tìm code liên quan tới "JWT refresh token rotation" bằng search_code_semantic,
pathPrefix "src/auth" (hoặc thư mục tương đương trong repo).
summarize_module:
MCP summarize_module: filePath "src/features/billing" — tóm tắt symbol chính và route (nếu có).
Gợi ý: Trong Cursor, có thể thêm câu “Chỉ dùng dữ liệu từ MCP, không đoán path nếu JSON không có.” để giảm hallucination.
License
Private / theo dự án của bạn.






