Grph
I’m curious about how agentic tools can better understand a codebase if they know how to traverse a Graph.
For that reason, I (read Claude Code) have put together a CLI tool to easily consume a Graph. I call it grph.
How does this work?
The CLI is a thin wrapper around the Python library NetworkX. The codebase exposes a number of features.
The CLI ingests a graph formatted with GEXF format. This is a universal way of defining a graph.
Neighbours
Imagine you have an airline route network. You’re at Gatwick and want to know where you can fly direct:
$ grph neighbors routes.gexf Gatwick
Neighbors of Gatwick (depth=1, direction=all)
┌───────────┬─────────────┐
│ ID │ Label │
├───────────┼─────────────┤
│ Barcelona │ Barcelona │
│ Amsterdam │ Amsterdam │
│ Nice │ Nice │
│ Berlin │ Berlin │
│ Lisbon │ Lisbon │
└───────────┴─────────────┘
What about with one layover?
$ grph neighbors routes.gexf Gatwick --depth 2
Shortest Path
How do I get from Edinburgh to Dubrovnik with the fewest connections?
$ grph path routes.gexf Edinburgh Dubrovnik
Path found (length: 3)
Edinburgh → Gatwick → Split → Dubrovnik
Or find all the options:
$ grph all-paths routes.gexf Edinburgh Dubrovnik --max-depth 4
PageRank
Which airports are the most critical hubs in the network? PageRank reveals where traffic flows through:
$ grph centrality routes.gexf --type pagerank --top 5
┌───────────┬───────────┐
│ Node │ Score │
├───────────┼───────────┤
│ Gatwick │ 0.0892 │
│ Barcelona │ 0.0734 │
│ Amsterdam │ 0.0651 │
│ Milan │ 0.0612 │
│ Paris │ 0.0598 │
└───────────┴───────────┘
And more
Find isolated route clusters - are there parts of the network disconnected from each other?
$ grph components routes.gexf --list
Blast radius - if Gatwick closes, which destinations become unreachable from Edinburgh?
$ grph reachable routes.gexf Edinburgh
Extract a subgraph - pull out just the UK airports for focused analysis:
$ grph subgraph routes.gexf --nodes Gatwick,Edinburgh,Manchester,Bristol --output uk-routes.gexf
But why?
I work in a medium-sized Android codebase. It has a lot of complexity baked into it: modularisation and a complex DI graph. I want Claude Code to be able to browse and understand both static and dynamic connections.
The same queries that answer “how do I fly from Edinburgh to Dubrovnik?” can answer “how does MainActivity depend on DatabaseHelper?” - it’s all just graph traversal.