Every time I ask Claude Code "who calls this?", I watch it grep, open a file, grep again, and open three more. It gets there. It just takes the long way round.
So this week I gave it a map instead. I took Click, the Python CLI library (~17.8k ⭐), built a knowledge graph of it in about 3 seconds, and served that graph to Claude Code as MCP tools. Below is every command, plus the real output, so you can do the same on your own repo in ten minutes.
I work on Graphify, the tool I'm using here. If this ends up useful, a ⭐ on GitHub helps a lot.
TL;DR: pip install "graphifyy[mcp]", run graphify update . in your repo, then claude mcp add the graphify-mcp server. Claude Code gets 10 graph tools for nodes, neighbours, paths and PR impact.
What you need
- Python 3.10+ and a repo you know well (I used Click at commit
8abb77a, so the numbers below are reproducible) - Claude Code installed (
claudeon your PATH) - About ten minutes
Step 1: install the CLI and the MCP extra
pip install "graphifyy[mcp]" graphify --version graphify 0.9.104 The package on PyPI is graphifyy (two y's). The command is graphify. The [mcp] extra adds the graphify-mcp server.
Step 2: build the graph
From the repo root:
git clone https://github.com/pallets/click && cd click graphify update . Re-extracting code files in . (no LLM needed)... [graphify watch] Rebuilt: 3498 nodes, 6798 edges, 213 communities [graphify watch] graph.json, graph.html and GRAPH_REPORT.md updated in graphify-out That took 3.3 seconds of wall-clock time on my box for 156 files. No API key, no embeddings, no vector database. It parses the code with tree-sitter and writes three files into graphify-out/:
-
graph.json, the graph itself, which the MCP server reads -
graph.html, an interactive view you can open in a browser -
GRAPH_REPORT.md, a summary with the most connected nodes and the communities (think subsystems)
Before wiring anything up, I like to sanity-check that the graph "gets" the codebase. The most connected nodes in Click are exactly what you'd guess if you've used it:
graphify god-nodes --top 5 God nodes (most connected): 1. Context - 185 edges 2. Command - 110 edges 3. Parameter - 98 edges 4. CliRunner - 82 edges 5. Option - 66 edges Context sitting at the top with 185 edges is the right answer. Almost everything in Click touches it.
Step 3: register the server with Claude Code
Run this in a normal terminal, not inside a Claude Code session, and use an absolute path to graph.json:
claude mcp add --transport stdio graphify -- graphify-mcp /absolute/path/to/click/graphify-out/graph.json Start a new Claude Code session and run /mcp. You should see graphify listed.
If you use Cursor or another JSON-config client, the same server goes in mcpServers:
{ "mcpServers": { "graphify": { "command": "graphify-mcp", "args": ["/absolute/path/to/click/graphify-out/graph.json"] } } } Step 4: see what Claude Code actually gets back
The server exposes 10 tools. I listed them straight from the server with an MCP client:
query_graph, get_node, get_neighbors, get_community, god_nodes, graph_stats, shortest_path, list_prs, get_pr_impact, triage_prs Here's what three of them return on Click. This is the exact text Claude Code receives, so it's worth seeing once.
graph_stats tells the agent how big the graph is and whether it's fresh:
Nodes: 3498 Edges: 6798 Communities: 213 EXTRACTED: 77% INFERRED: 23% AMBIGUOUS: 0% Built at commit: 8abb77a8432e03ed14a95f972b44f905279415a7 (matches HEAD) That last line is my favourite. The agent can tell whether the graph matches the code it's looking at.
get_neighbors answers "what does this touch, and what touches it?" in one call. Here it is for _resolve_context() in shell completion:
Neighbors of _resolve_context(): --> .make_context() [calls] [INFERRED 0.85] at=src/click/shell_completion.py:L706 --> Command [uses] [INFERRED 0.95] at=src/click/shell_completion.py:L692 --> Context [uses] [INFERRED 0.95] at=src/click/shell_completion.py:L696 --> Group [uses] [INFERRED 0.95] at=src/click/shell_completion.py:L712 <-- .get_completions() [calls] [EXTRACTED] at=src/click/shell_completion.py:L363 Every edge has a direction, a relation, a file and line, and a tag. EXTRACTED means it was read straight from the source. INFERRED means Graphify resolved it, with a confidence score. So the agent knows which hops it can trust as-is.
shortest_path answers "how does A reach B?":
Shortest path (1 hops): echo() --calls [EXTRACTED]--> resolve_color_default() Path confidence: EXTRACTED (weakest hop 1: calls) Step 5: prompts I'd try first
Once it's connected, ask questions that are about structure, not about one file:
- "Use the graphify tools: what calls
_resolve_context()and what does it depend on?" - "Find the shortest path from
echo()toresolve_color_default()and explain each hop." - "Which community does
CliRunnerbelong to, and what else is in it?" - "What are the 10 most connected nodes in this repo? Give me a one-line tour of each."
Saying "use the graphify tools" in the first prompt or two makes it obvious which tools you want. The rest is just asking the questions you'd normally answer with five greps.
Two small things that make it nicer
Names that collide get flagged, not guessed. Click has three different echo() functions. Ask for one by bare name and Graphify tells you so (node IDs trimmed):
Ambiguous: 'echo()' matches 3 nodes in different files. src/click/testing.py src/click/utils.py tests/test_utils/test_prompt.py Retry with path::symbol using one of the paths above For an agent, one extra call beats confidently walking down the wrong function.
Big answers stay inside a budget. query_graph caps its output (2,000 tokens by default) and says when it trimmed something, so the agent knows to narrow the question instead of assuming it saw everything.
Keeping the graph fresh
After you change code, rerun:
graphify update . It only re-extracts code, so it's quick. graphify watch . rebuilds on every change if you'd rather not think about it.
If you don't want to run any of this locally, hosted Graphify indexes your GitHub repos and keeps the graph fresh for you. Claude Code connects to it with one command:
claude mcp add --transport http --scope user graphify https://api.graphify.com/mcp Then sign in from /mcp. There's no API key to paste.
Try it on your repo
pip install "graphifyy[mcp]"graphify update .claude mcp add --transport stdio graphify -- graphify-mcp $(pwd)/graphify-out/graph.json
The MCP server docs cover HTTP mode for teams and every flag. If it helps, a ⭐ on GitHub means a lot, and I hang out in our Discord if you get stuck.
What's the first question you'd ask an agent that can see your whole codebase as a graph? Drop it in the comments and I'll run it on Click.

