چرا Codebase Memory MCP؟
با بزرگتر شدن پروژههای فرانتاند، فهمیدن ارتباط بین کامپوننتها، Hookها، Storeها، Serviceها و APIها برای Coding Agentها سختتر میشود. ابزارهایی مثل Claude Code، Codex یا Cursor برای پاسخ به یک سؤال ساده ممکن است مجبور شوند چندین فایل را جستوجو و باز کنند. Codebase Memory MCP با ساخت یک Knowledge Graph از پروژه، این ارتباطات را از قبل ذخیره میکند تا Agent بتواند سریعتر ساختار کدبیس را بفهمد.
Codebase Memory MCP چیست؟
Codebase Memory MCP یک MCP Server برای تحلیل ساختاری Codebase است. این ابزار سورسکد را Index میکند و ارتباط بین بخشهای مختلف پروژه را به شکل Graph نگه میدارد.
GitHub پروژه: DeusData/codebase-memory-mcp
در یک پروژه فرانتاند، Nodeهای این Graph میتوانند شامل مواردی مثل Component، Function، Hook، Module و Route باشند و Edgeها ارتباطاتی مثل CALLS، IMPORTS و HTTP_CALLS را نمایش دهند.
ایده اصلی
Codebase
↓
Parse & Index
↓
Knowledge Graph
↓
MCP
↓
Coding Agent
به این ترتیب Agent بهجای اینکه هر بار پروژه را از صفر بررسی کند، میتواند ابتدا درباره ساختار آن سؤال بپرسد و فقط فایلهای مرتبط را باز کند.
مثال در یک پروژه React
فرض کنید ساختار بخشی از یک فروشگاه React به شکل زیر باشد:
src/
├── components/
│ └── AddToCartButton.tsx
├── hooks/
│ └── useCart.ts
├── stores/
│ └── cartStore.ts
└── services/
└── cartApi.ts
کامپوننت دکمه افزودن به سبد خرید:
import { useCart } from "@/hooks/useCart";
type Props = {
productId: string;
};
export function AddToCartButton({ productId }: Props) {
const { addItem } = useCart();
return (
<button onClick={() => addItem(productId)}>
افزودن به سبد خرید
</button>
);
}
Hook مربوط به Cart:
import { useCartStore } from "@/stores/cartStore";
import { addCartItem } from "@/services/cartApi";
export function useCart() {
const addLocalItem = useCartStore((state) => state.addItem);
async function addItem(productId: string) {
addLocalItem(productId);
await addCartItem(productId);
}
return { addItem };
}
و Service مربوط به API:
export async function addCartItem(productId: string) {
return fetch("/api/cart", {
method: "POST",
body: JSON.stringify({ productId }),
});
}
برای یک توسعهدهنده، مسیر اجرای این کد مشخص است؛ اما یک Agent که برای اولین بار Repository را میبیند باید این ارتباطات را کشف کند. Codebase Memory میتواند آنها را به شکل ساختاری ذخیره کند:
AddToCartButton
↓
useCart.addItem
↓
cartStore.addItem
↓
addCartItem
↓
POST /api/cart
حالا سؤالهایی مثل «مسیر اضافه شدن محصول به Cart چیست؟» یا «چه بخشهایی addItem را صدا میزنند؟» بدون جستوجوی گسترده در کل پروژه قابل بررسی هستند.
MCP چه نقشی دارد؟
Codebase Memory خودش LLM یا Coding Agent نیست. MCP یا Model Context Protocol رابطی است که Agent از طریق آن به ابزارهای Codebase Memory دسترسی پیدا میکند.
جریان کلی به این شکل است:
Developer
↓
Coding Agent
↓
MCP Tool
↓
Codebase Memory
↓
Knowledge Graph
↓
Structured Result
برای مثال اگر از Agent بپرسید:
چه چیزی addItem را صدا میزند؟
Agent میتواند از یک ابزار Graph برای دنبال کردن مسیرهای ورودی استفاده کند و سپس نتیجه را برای شما توضیح دهد.
Knowledge Graph چه چیزی ذخیره میکند؟
Knowledge Graph پروژه را به مجموعهای از Nodeها و ارتباطات بین آنها تبدیل میکند.
برای مثال:
ProductPage
│
▼
ProductDetails
│
▼
AddToCartButton
│
▼
useCart
│
▼
addCartItem
│
▼
POST /api/cart
در یک پروژه بزرگ، چنین Graphی میتواند ارتباط بین هزاران Symbol را نگه دارد و به Agent اجازه دهد قبل از خواندن فایلها، محدوده مسئله را پیدا کند.
Codebase Memory چگونه کد را تحلیل میکند؟
این ابزار برای Parse کردن سورسکد از Tree-sitter استفاده میکند. Tree-sitter بهجای نگاه کردن صرف به متن فایل، ساختار Syntax کد را به شکل AST یا Abstract Syntax Tree در اختیار ابزار قرار میدهد.
برای مثال:
import { getUser } from "./userApi";
export async function loadProfile() {
return getUser();
}
جستوجوی متنی فقط میتواند وجود عبارت getUser را پیدا کند، اما تحلیل ساختاری میتواند رابطه زیر را تشخیص دهد:
loadProfile
│ CALLS
▼
getUser
getUser
│ IMPORTED FROM
▼
./userApi
این موضوع در پروژههای TypeScript و React که وابستگی زیادی به Importها، Componentها، Hookها و Function callها دارند اهمیت زیادی دارد.
کاربرد در Next.js
فرض کنید یک صفحه محصول در Next.js داریم:
import { getProduct } from "@/services/productApi";
import { ProductDetails } from "@/components/ProductDetails";
export default async function ProductPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const product = await getProduct(id);
return <ProductDetails product={product} />;
}
و داخل ProductDetails چند کامپوننت دیگر استفاده میشوند:
export function ProductDetails({ product }) {
return (
<>
<ProductGallery images={product.images} />
<ProductPrice price={product.price} />
<AddToCartButton productId={product.id} />
</>
);
}
در چنین پروژهای Agent میتواند سؤالهای ساختاریتری بپرسد:
ProductDetailsدر چه بخشهایی استفاده شده است؟- چه مسیری از
ProductPageبهAddToCartButtonمیرسد؟ getProductاز کدام بخشهای پروژه فراخوانی میشود؟- تغییر
AddToCartButtonممکن است چه بخشهایی را تحت تأثیر قرار دهد؟
این نوع سؤالها همان جایی هستند که Graph نسبت به جستوجوی متنی ساده ارزش بیشتری پیدا میکند.
ابزارهای مهم Codebase Memory MCP
Codebase Memory چندین MCP Tool برای Index کردن، جستوجو و تحلیل Graph در اختیار Agent قرار میدهد.
index_repository
Repository را تحلیل میکند و Graph اولیه پروژه را میسازد.
search_graph
برای پیدا کردن Functionها، Classها، Moduleها و Symbolهای دیگر داخل Graph استفاده میشود.
trace_path
مسیر فراخوانیها را دنبال میکند و برای سؤالهایی مثل «چه چیزی این Function را صدا میزند؟» یا «این Function چه چیزهایی را صدا میزند؟» مناسب است.
get_architecture
یک نمای کلی از Architecture پروژه، Packageها، Routeها، Entry Pointها و بخشهای مهم Codebase میدهد.
detect_changes
تغییرات Git را بررسی میکند و به Agent کمک میکند محدوده احتمالی اثر یک تغییر را پیدا کند.
get_code_snippet
سورس مربوط به یک Symbol مشخص را برمیگرداند تا Agent مجبور نباشد همیشه کل فایل را بخواند.
search_code
برای جستوجوی مستقیم داخل کدهای Indexشده استفاده میشود.
query_graph
امکان اجرای Queryهای پیچیدهتر روی Knowledge Graph را فراهم میکند.
Impact Analysis در پروژههای فرانتاند
یکی از کاربردهای مهم Codebase Memory پیدا کردن Blast Radius یک تغییر است.
فرض کنید یک Button مشترک در Design System دارید:
<Button loading={true}>Save</Button>
و قرار است API آن را تغییر دهید:
<Button status="loading">Save</Button>
اگر این Component در دهها صفحه استفاده شده باشد، قبل از Refactor باید بدانید چه بخشهایی به آن وابسته هستند.
Button
├── LoginForm
├── CheckoutForm
├── ProductCard
├── DeleteModal
└── ProfileSettings
Knowledge Graph میتواند به Agent کمک کند Usageها و مسیرهای وابستگی را پیدا کند و قبل از تغییر، محدوده احتمالی اثر آن را مشخص کند.
تفاوت با grep
grep و Search معمولی بر اساس متن کار میکنند:
grep -R "addItem" src/
این دستور فایلهایی را که عبارت addItem در آنها وجود دارد پیدا میکند، اما الزاماً نمیگوید کدام Symbol واقعاً به کدام Symbol دیگر متصل است.
تفاوت را میتوان اینطور خلاصه کرد:
grep
↓
"عبارت addItem کجاست؟"
در مقابل:
Knowledge Graph
↓
"چه چیزی addItem را صدا میزند؟"
"addItem چه چیزی را صدا میزند؟"
"چه مسیری از یک Component به addItem میرسد؟"
بنابراین Codebase Memory جای Search متنی را نمیگیرد؛ یک لایه ساختاری در کنار آن اضافه میکند.
تفاوت با RAG
در RAG معمولاً کد به Chunkهای کوچک تقسیم میشود و با Embedding و Vector Search، بخشهایی که از نظر معنایی به سؤال نزدیک هستند پیدا میشوند.
Source Code
↓
Chunks
↓
Embeddings
↓
Vector Search
↓
Relevant Code
Knowledge Graph مسئله دیگری را حل میکند:
Component
↓
Hook
↓
Store
↓
Service
↓
API
به زبان ساده، RAG بیشتر به سؤال «کدام کد به موضوع من مرتبط است؟» کمک میکند و Graph بیشتر به سؤال «این بخشهای کد چگونه به هم متصل هستند؟» پاسخ میدهد.
کاهش مصرف Context
Coding Agentها برای تحلیل Repository معمولاً فایلهای زیادی را وارد Context مدل میکنند. هرچه تعداد فایلها بیشتر شود، Token بیشتری مصرف میشود و اطلاعات غیرمرتبط بیشتری وارد Context خواهد شد.
Codebase Memory میتواند روند را به این شکل تغییر دهد:
Whole Repository
↓
Knowledge Graph
↓
Relevant Symbols
↓
Relevant Files
↓
LLM Context
یعنی Agent ابتدا با Graph محدوده مسئله را کوچک میکند و بعد فقط سورس موردنیاز را میخواند.
بهروزرسانی Graph بعد از تغییر کد
یک Knowledge Graph زمانی مفید است که با Codebase هماهنگ بماند. Codebase Memory از تغییرات پروژه پشتیبانی میکند تا بعد از Index اولیه، اطلاعات Graph با تغییر فایلها بهروزرسانی شود.
Initial Index
↓
Knowledge Graph
↓
Code Changes
↓
Incremental Update
↓
Updated Graph
این ویژگی باعث میشود Agent مجبور نباشد بعد از هر تغییر کوچک، کل Repository را دوباره از ابتدا تحلیل کند.
چه زمانی استفاده از Codebase Memory منطقی است؟
- پروژههای متوسط و بزرگ React، Next.js یا TypeScript
- Repositoryهایی با تعداد زیادی Component، Hook، Store و Service
- تیمهایی که مرتب از Coding Agentها استفاده میکنند
- زمانی که دنبال کردن Dependencyها و Call Chainها سخت شده است
- Design Systemها و Component Libraryهای بزرگ
- پروژههایی که Impact Analysis قبل از Refactor اهمیت زیادی دارد
- زمانی که Agent بخش زیادی از وقت خود را صرف Search و باز کردن فایلهای متعدد میکند
برای یک پروژه کوچک با چند فایل، هزینه Index و نگهداری Graph احتمالاً ارزش زیادی ایجاد نمیکند؛ اما با بزرگ شدن Codebase، مزیت داشتن یک نقشه ساختاری بیشتر میشود.
جمعبندی
Codebase Memory MCP یک لایه Structural Memory بین Coding Agent و Codebase ایجاد میکند. بهجای اینکه Agent در هر Task دوباره ارتباط بین فایلها را از صفر کشف کند، میتواند از یک Knowledge Graph دائمی برای پیدا کردن Functionها، Call Chainها، Dependencyها، Routeها و محدوده اثر تغییرات استفاده کند.
در پروژههای بزرگ فرانتاند، این مدل میتواند مسیرهایی مثل Component → Hook → Store → Service → API را برای Agent قابل Query کند و باعث شود قبل از خواندن تعداد زیادی فایل، دقیقتر بداند باید کجا را بررسی کند.
