graphdb
A Kùzu-backed code-graph MCP server that indexes Ruby on Rails codebases into a queryable graph, enabling token-efficient code navigation without grepping through files.
find_definition(name)— Locate where any class, module, method, or function is defined in the codebasefind_callers(name, depth)— Find all functions/methods that call a given name, transitively up to a specified number of hops, traversing CALLS, ENQUEUES, and DELIVERS edgesfind_references(name)— Discover all inbound references to a name, including calls, imports, and inheritance relationshipsimpact_of(name, max_depth)— Predict the blast radius of a change by finding all transitive callers up to a configurable depthmodule_overview(path)— Get a file-level summary including exports, imports, and most-called internal symbolsroutes_for(controller_or_action)— Look up HTTP routes (verb + URL) that map to a given Rails controller or specific controller actionassociations_of(model)— Retrieve all ActiveRecord associations (has_many, has_one, belongs_to, HABTM) for a model, plus reverse-references from other modelsgraph_stats()— Get a health-check overview with counts of all node and edge types in the indexed graph
Indexes Ruby on Rails codebases into a queryable graph, enabling AI agents to explore model associations, routes, callbacks, jobs, mailers, and more through graph-based queries.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@graphdb query associations User"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
graphdb
A Kùzu-backed code-graph MCP plugin for Claude Code. Indexes Ruby on Rails codebases into a queryable graph of associations, routes, callbacks, jobs, and mailers — a token-efficient alternative to grep for navigating Rails code.

The animation above shows the CLI. The same eight tools are exposed to Claude Code via MCP — see docs/PROMPTS.md for natural-language prompts you can try directly in a Claude Code session.
Why
Rails encodes most of its architecture in DSL declarations (has_many,
before_action, resources, include) rather than direct method calls. Grep
matches the strings but cannot turn them into relationships:
Question | Grep | graphdb |
"What models reference User?" | 200+ matches across |
|
"What routes hit | Scan 218-line |
|
"Who delivers |
|
|
"What jobs do | Multi-step grep + read |
|
Related MCP server: sonde
Status
Proof of concept, validated against a real Rails 8 / Ruby 3.3 codebase
(smart-hub-backend, 494 indexed .rb files):
nodes: 2913 edges: 4731 index time: ~0.8s
60 models 63 controllers 25 concerns 121 services 67 serializers
7 mailers 6 jobs 109 migrations 230 routes 421 actionsValidation against grep ground truth on smart-hub-backend:
Pattern | Grep | Graph | |
| 52 | 52 | exact |
| 79 | 79 | exact |
| 15 | 15 | exact |
| 66 | 66 | exact |
| 11 | 11 | exact |
| 48 lines | 58 edges | each call's rules expand to one edge per rule |
| 46 lines | 377 edges | each filter × N actions in |
Quickstart
# Set up a venv with uv (sidesteps Homebrew's broken ensurepip on macOS)
uv venv .venv --python 3.13
uv pip install --python .venv/bin/python -e .
# Index a Rails project (writes to ~/.cache/graphdb/<repo>-<hash>.kuzu/;
# nothing is written to the target repo)
.venv/bin/graphdb --root /path/to/rails_app index /path/to/rails_app
# CLI queries
.venv/bin/graphdb --root /path/to/rails_app query def User
.venv/bin/graphdb --root /path/to/rails_app query associations User
.venv/bin/graphdb --root /path/to/rails_app query routes Api::V1::UsersController
.venv/bin/graphdb --root /path/to/rails_app query callers UserInviteMailer --depth 2
.venv/bin/graphdb --root /path/to/rails_app query impact ScheduleExecutionJob
.venv/bin/graphdb --root /path/to/rails_app query refs Account
.venv/bin/graphdb --root /path/to/rails_app statsMCP integration with Claude Code
Add to your Claude Code MCP config (~/.claude.json or project-level):
{
"mcpServers": {
"graphdb": {
"command": "/path/to/Graph_DB/.venv/bin/graphdb-mcp",
"env": { "GRAPHDB_ROOT": "/path/to/your/rails_app" }
}
}
}Tools exposed to Claude:
Tool | Answers |
| Where is |
| Who calls/enqueues/delivers |
| All inbound edges to |
| Transitive callers — predicted blast radius |
| File-level summary: exports, imports, hotspots |
| HTTP routes that hit a controller / action |
| All |
| Counts of nodes/edges by kind |
Graph schema
NODE KINDS
file, module, class, method, class_method,
model, controller, action, concern, service, serializer,
job, mailer, validator, helper, channel, error_class,
migration, route, external
EDGE KINDS
Generic Ruby: CONTAINS, CALLS, INHERITS, INCLUDES
Model DSL: HAS_MANY, BELONGS_TO, HAS_ONE, HABTM, VALIDATES, SCOPES
Controllers: BEFORE_ACTION, AFTER_ACTION, SKIP_BEFORE, RENDERS
Routes: HANDLES, MOUNTS
Async: ENQUEUES, DELIVERSHow it works
indexer.pyparses every.rbunderapp/,lib/,config/,db/migrate/with tree-sitter-ruby. Two passes:Pass 1: register every class/module/method as a node, build a qualname index used for resolution.
Pass 2: walk again, emit
INHERITS,INCLUDES,CALLS, and the Rails-specific edges (HAS_MANY,BEFORE_ACTION,ENQUEUES, etc.)Pass 3: a separate walker handles
config/routes.rb(DSL outside any class), producingRoutenodes withHANDLESedges to controller actions.
graph.pybuffers nodes/edges in memory and bulk-flushes via CypherUNWINDat end of indexing. Drops full-repo indexing from ~8 minutes (individual inserts) to ~0.8 seconds.queries.pyissues Cypher patterns likeMATCH (caller)-[:CALLS|ENQUEUES|DELIVERS*1..3]->(target)— the database does the BFS.mcp_server.pyexposes the queries as MCP tools for Claude Code.
Known PoC limitations
Static parsing only. Doesn't run Rails — no type inference, no resolution of
define_method/method_missing/ dynamicclass_eval.Relative imports / autoload constants: resolved by unique-name fallback; ambiguous names are skipped silently.
Custom DSLs (acts_as_paranoid, paper_trail's
has_paper_trail, amoeba): not yet specialized — they emit genericCALLSedges at class scope.Routes:
scope, member/collection custom routes,constraints,concerns(route concerns), nested resources past 1 level — partial or skipped. The 7 standard REST actions,namespace,mount,devise_for, andget/post/...withto:work fully.Reindex is one-shot. Edit a file, rerun
graphdb index. No file watcher.
Roadmap
Specialize the major Gemfile DSLs in smart-hub-backend (paper_trail, discard, amoeba, flipper).
Member / collection / nested resource routes.
Incremental reindex via file-watcher.
AI-generated per-method summaries stored on nodes (read summary first, file second).
Benchmark harness: grep-only vs graph-only Claude sessions on identical tasks.
Available Tools
8 toolsassociations_ofA
Rails-specific: all ActiveRecord associations on a model.
Returns outgoing has_many/has_one/belongs_to/HABTM plus reverse-references (other models that point at this one).
Inputs: model (required). Returns: result
find_callersA
Functions that call name, transitively up to depth hops.
Inputs: name (required), depth. Returns: result
find_definitionB
Find all definitions matching a simple name (functions/classes/methods).
Inputs: name (required). Returns: result
find_referencesA
All inbound references to name (calls, imports, inheritance).
Inputs: name (required). Returns: result
graph_statsB
Counts of nodes/edges by kind — quick health check.
Inputs: no named parameters. Returns: result
impact_ofB
Transitive callers — predict what may break if name changes.
Inputs: name (required), max_depth. Returns: result
module_overviewA
Summary of a single module: exports, imports, most-called internal symbols.
path is the file path relative to the indexed root.
Inputs: path (required). Returns: result
routes_forA
Rails-specific: HTTP routes that hit a controller (or controller#action).
Accepts a bare class ("UsersController"), fully qualified ("Api::V1::UsersController"), or qualified action ("Api::V1::UsersController#create"). Returns verb/url/handler.
Inputs: controller_or_action (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Each tool targets a distinct aspect of code analysis: definitions, references, callers, impact, module overview, and Rails-specific associations/routes. No overlap in purpose.
All tool names follow a consistent snake_case pattern with a clear verb_noun or noun_of structure, making them predictable.
8 tools is well-scoped for a code analysis server, covering both general and Rails-specific functionality without bloat.
The set covers key analysis operations (definitions, references, callers, impact, module overview, routes, associations). A minor gap is the lack of a tool to list all modules without a specific path.
Maintenance
Related MCP Connectors
Codebase intelligence for AI agents — dead code, blast radius, ownership.
Code intelligence for LLMs. Analyze, search, and retrieve code from any public git repository.
Ask a codebase what calls what: search, blast radius, paths between symbols, and diffs.
Give your AI agent a persistent map of your project's structure, dependencies, and bugs.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides Claude Code with a repository symbol graph via tree-sitter, enabling instant symbol lookup, file skeletons, call-site analysis, and persistent notes, reducing token usage by reading signatures instead of whole files.121MIT
- AlicenseNot gradedqualityBmaintenanceIndexes a codebase into a symbol-level graph and exposes tools for finding symbols, querying relationships, and assessing impact, letting AI coding agents answer structural questions in a single call within a token budget.83 npm4Apache 2.0
- AlicenseNot gradedqualityAmaintenanceTurns a codebase into a persistent knowledge graph so AI coding agents can answer structural questions about functions, call chains, routes, and cross-service links through graph queries instead of reading files one by one.MIT
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI agents to explore a repository by querying a pre-built structural knowledge graph of symbols and their relationships — definitions, callers, callees, blast radius, and file-level impact — instead of grepping and reading files. This cuts the tokens spent on code exploration by roughly 96–99% while running entirely on local SQLite with tree-sitter parsing.1MIT