repo-atlas-mcp
Provides a graph-based code analysis to coding agents, enabling tools to trace call dependencies, assess change impact, and identify hotspots using tree-sitter and Neo4j.
README
repo-atlas-mcp
An MCP server that gives coding agents a graph of your codebase instead of a text search over it.
Grep finds a name. It cannot tell you who calls that function, what breaks if you change it, or whether
any test reaches it. Those are relationship questions, so repo-atlas-mcp parses your repository with
tree-sitter, loads the call and import structure into Neo4j, and exposes it to your agent as MCP tools.
▸ hotspots
17 callers stock_analyzer/base.py:54 is_num
10 callers stock_analyzer/data/market.py:144 get_row
9 callers stock_analyzer/base.py:12 Finding
▸ impact_of is_num
21 production caller(s) across 11 file(s).
⚠ No test reaches this symbol on any call path — changes here are unguarded.
Why a graph
Reachability is transitive, and transitive questions are exactly what a graph database answers in one
query and a text search cannot answer at all. impact_of walks every call path upstream of a symbol,
partitions the callers into production code and tests, and tells you when nothing guards the change.
That is the query that stops an agent from confidently editing shared code.
Requirements
- Node.js 18+
- A Neo4j instance. AuraDB Free is enough for repositories in the hundreds-of-thousands-of-lines range and costs nothing.
Setup
Create a free AuraDB instance, then note the connection URI and password it gives you.
Add the server to your MCP client:
{
"mcpServers": {
"repo-atlas": {
"command": "npx",
"args": ["-y", "repo-atlas-mcp"],
"env": {
"NEO4J_URI": "neo4j+s://xxxxxxxx.databases.neo4j.io",
"NEO4J_USER": "neo4j",
"NEO4J_PASSWORD": "your-password"
}
}
}
}
For Claude Code that goes in .mcp.json at your project root, or run:
claude mcp add repo-atlas -- npx -y repo-atlas-mcp
Then ask your agent to index the project once:
index this repo at /path/to/project
Re-indexing is incremental — unchanged files are skipped by content hash, so running it again after a few edits takes about as long as parsing the files you touched.
Tools
| Tool | Question it answers |
|---|---|
index_repo |
Build or refresh the graph for a repository |
find_symbol |
Where is this function/class/method defined? |
who_calls |
What reaches this symbol, transitively? |
what_it_calls |
What does this symbol depend on, transitively? |
impact_of |
What breaks if I change this — and do any tests cover it? |
path_between |
How does control flow from A to B? |
hotspots |
Which symbols have the most distinct callers? |
module_map |
What does the top-level package structure depend on? |
list_repos |
What is indexed? |
drop_repo |
Remove a repository from the graph |
Languages
Python, TypeScript, TSX, and JavaScript, via tree-sitter WASM grammars — no native compilation, so
npx works on a clean machine without build tools.
How call resolution works, and where it is wrong
Resolving a call to a definition properly requires full type inference. This does something cheaper and tells you when it is guessing. What the call looks like decides how it is resolved:
self.foo() / this.foo() — resolves to foo on the enclosing class, else to a definition in the
same file. This is the one method form that resolves precisely. Tier: local.
foo() — a bare call, very likely a repo-level function. Resolved against a definition in the same
file (local), then in a file this one imports (imported), then repo-wide if three or fewer
candidates exist (global).
something.foo() — the receiver's type is unknown. Accepted only when foo is defined exactly once
in the whole repository and is not a well-known builtin name. Tier: receiver.
That last rule matters more than it looks. Without it, one repo method named get absorbs every
dict.get() and response.get() in the codebase; on a real 26-file project it produced a phantom
symbol with 59 callers, ranked as the most-called code in the project. The denylist in
COMMON_METHOD_NAMES (get, add, update, join, map, read, …) is a heuristic, and it is
consulted only for this weakest case — a bare get() still resolves normally.
Every CALLS edge stores which tier produced it, and the tools surface anything above local.
Known limitations, stated plainly:
- Dynamic dispatch is invisible.
getattr(obj, name)(), reflection, and dependency-injection wiring produce no edges. - Polymorphism is not modelled. Two classes with a
run()method cannot be told apart, so calls on a non-selfreceiver to a name defined more than once are dropped rather than guessed. - Calls into third-party packages are dropped. Only symbols defined inside the repository become nodes.
- Top-level code is attributed to a synthetic
<module>symbol per file, so route registration and CLI wiring still appear in the graph rather than being discarded. - Repeated calls between the same pair collapse to one edge, which keeps the last line number seen.
The practical effect: the graph under-reports rather than over-reports. impact_of can miss a caller
that goes through dynamic dispatch, so treat its output as a strong lead, not a proof — but a symbol it
names really is a caller.
Graph model
(:Repo)-[:HAS_FILE]->(:File)-[:DEFINES]->(:Symbol)
(:File)-[:IMPORTS]->(:File)
(:Symbol)-[:CALLS {line, confidence}]->(:Symbol)
Symbol.isTest is set from the defining file's path, which is what lets impact_of separate covering
tests from production callers.
Ranking in hotspots uses caller in-degree rather than PageRank, so it runs on AuraDB Free, which does
not include the Graph Data Science library.
Development
npm install
npm run build
node scripts/smoke.mjs # parser check, no database needed
node scripts/bulk-parse.mjs /some/repo # parse a real repo and report totals
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。