assistgraph
v0.2.0
Published
File-level dependency knowledge graph CLI for JS/TS/Python codebases. Produces a JSON graph, an Obsidian vault, and an MCP server so agents like Claude and Codex can query your repo without grepping.
Downloads
218
Maintainers
Readme
assistgraph
File-level dependency knowledge graph for JavaScript, TypeScript, and Python codebases. Produces a JSON graph, an Obsidian vault, and an MCP server so agents like Claude and Codex can query your repo without grepping.
What it does
Run assistgraph build in any repo (or subfolder) and you get:
assistgraph/graph.json— a machine-readable dependency graph of every file and every importassistgraph/vault/— an Obsidian-compatible knowledge vault with wiki links, pre-configured colour groups, and community pagesassistgraph/audit.md(viaassistgraph audit) — cycles, orphans, hubs, and cross-folder coupling- An MCP stdio server (via
assistgraph mcp) — 12 tools so Claude Code / Codex can query the graph directly, including areload_graphtool that picks up rebuilds without restarting the session
All parsing is deterministic and offline. Zero LLM calls, zero databases, zero Python runtime required.
Why
Large codebases burn agent tokens fast. "Who imports UserService?" normally means opening dozens of files and grepping each. With assistgraph, that same question is a single MCP call returning a few hundred tokens — O(1) graph lookup instead of O(N) file reads.
The same structural view also powers migrations: feature boundaries, blast-radius of a change, dead code, cycles, and cross-folder coupling are all one call away.
Features
- Languages: TypeScript, TSX, JavaScript, JSX, MJS, CJS, Python
- Strict
.gitignoreenforcement: anything in.gitignoreis invisible to assistgraph, including wildcard patterns - CWD is the scan root: run it anywhere — at the repo root for the full picture, or in a subfolder for a focused graph
- Works in monorepos: respects the topmost
tsconfig.jsonabove the scan root, stopping at parent project boundaries - Folder-based communities: folders become feature communities automatically, mirroring your codebase structure
- Cycle detection: iterative Tarjan SCC — doesn't blow the JS stack on deep dependency chains
- Hub/bloat metrics: top imported files, top bloat candidates
- Cross-folder coupling: shows you exactly how tangled up
ui/andapp/really are - Orphan detection with entrypoint heuristics: dead code is separated from legitimate entrypoints (
index.ts,main.py,manage.py, etc.) - Content hashing: every node has a stable hash for future incremental builds
- Obsidian colour groups: each top-level folder gets its own colour automatically so your graph view pops from the first click
Requirements
- Node 18+ or Bun 1.0+
- No Python runtime required even for Python projects — parsing is pure JavaScript
Install
The fastest way to run assistgraph is via npx — no install needed:
cd your-project
npx -y assistgraph buildOr install a persistent global binary:
# Node / npm
npm install -g assistgraph
# Bun
bun install -g assistgraphoxc-parser ships platform-specific native bindings that npm picks automatically on install. Once installed globally, drop the npx -y prefix from every command below.
Quick start
# Build the graph + Obsidian vault in any repo
cd your-project
npx -y assistgraph build
# Peek at the stats
npx -y assistgraph stats
# Show what a file imports and who imports it
npx -y assistgraph query src/features/auth/Login.tsx
# Full audit: cycles, orphans, hubs, coupling → also writes assistgraph/audit.md
npx -y assistgraph audit
# Install Claude + Codex skills so agents know to prefer the graph
npx -y assistgraph install-skills
# Start the MCP server (for Claude Code / Codex)
npx -y assistgraph mcpThen point Obsidian at ./assistgraph/vault/ to see the graph visually.
CLI reference
assistgraph build [--root <dir>] [--no-vault] Scan CWD → assistgraph/graph.json + vault/
assistgraph query <path> Deps + dependents for a file
assistgraph stats Graph stats
assistgraph audit [--out <path>] Cycles, orphans, hubs, coupling (+ audit.md)
assistgraph mcp Start MCP stdio server
assistgraph install-skills [--force] [--claude-only] [--codex-only]
Install Claude + Codex skill files
assistgraph init Create assistgraph.config.jsonOutput layout
<cwd>/
├── assistgraph.config.json ← optional, check into git
└── assistgraph/ ← generated, add to .gitignore
├── graph.json ← canonical graph
├── audit.md ← generated by `assistgraph audit`
└── vault/ ← Obsidian-compatible vault
├── .obsidian/graph.json ← pre-configured colour groups
├── README.md ← entry MOC
├── _communities/ ← one MOC per folder community
├── _externals/ ← one stub per external package
└── <mirror of your source tree>/*.mdClaude Code / Codex integration
MCP server config
Add one of the following to your Claude Code / Codex / Cursor MCP config. The npx / bunx variants require no pre-install — the package is fetched on first run and cached for subsequent launches.
Node / npm (recommended):
{
"mcpServers": {
"assistgraph": {
"command": "npx",
"args": ["-y", "assistgraph", "mcp"]
}
}
}Bun:
{
"mcpServers": {
"assistgraph": {
"command": "bunx",
"args": ["assistgraph", "mcp"]
}
}
}Globally installed binary:
{
"mcpServers": {
"assistgraph": {
"command": "assistgraph",
"args": ["mcp"]
}
}
}The MCP server reads ./assistgraph/graph.json from the agent's current working directory and holds it in memory. Re-run assistgraph build whenever you want the graph to reflect new or moved files, then either restart the agent session or have the agent call the reload_graph tool — it swaps the in-memory graph without needing a respawn.
One-time skill install
npx -y assistgraph install-skillsWrites:
~/.claude/skills/assistgraph/SKILL.md~/.codex/skills/assistgraph/SKILL.md
The Claude skill tells Claude Code when to prefer mcp__assistgraph__* tools over grepping imports.
Tools exposed by the MCP server
| Tool | Purpose |
|---|---|
| graph_stats | Node/edge/language counts |
| list_files | Paginated file summaries, optional language filter |
| get_file | Full metadata for one file |
| get_dependencies | Transitive deps with optional depth |
| get_dependents | Transitive dependents with optional depth |
| find_path | Shortest dependency path between two files |
| search_files | Fuzzy file search by basename or path |
| list_communities | All folder communities |
| get_community | Members of a community |
| find_cycles | All dependency cycles (Tarjan SCC) |
| find_orphans | Orphan files, with isLikelyEntrypoint flag |
| reload_graph | Re-read graph.json after a rebuild; swaps the in-memory graph atomically and returns before/after counts |
Obsidian integration
Point Obsidian at ./assistgraph/vault/ and open the graph view. Colour groups are pre-configured so each top-level folder gets its own colour, with language colours as a fallback.
To customise colours manually: Graph view → Settings (gear) → Groups. Your changes are preserved on subsequent assistgraph build runs — the default config is only written when no custom colour groups exist.
Each file note contains:
- YAML frontmatter (path, language, community, loc, exports, tags)
## Exports— named + default exports## Imports— wiki-linked to sibling files + external stubs## Imported By— reverse index## Metrics— LOC, size, import/dependent counts, content hash
Configuration
Optional assistgraph.config.json at the scan root:
{
"include": ["**/*"],
"exclude": [
"assistgraph/**",
"node_modules/**",
"dist/**",
"build/**",
"__pycache__/**",
".venv/**"
],
"resolver": {
"tsconfig": null,
"pythonRoots": ["."]
},
"output": {
"dir": "assistgraph"
}
}Everything has sensible defaults. You only need this file if the defaults don't fit your project.
Running in a subfolder
cd src/features/auth
npx -y assistgraph buildThe scan root becomes the current folder. Imports that leave the scan root become external leaf nodes (with their absolute path preserved). This lets you build a focused graph for a single feature or component folder.
When scanning a subfolder, assistgraph still walks up to find the nearest tsconfig.json, stopping at any parent package.json — so @/... and @shared/... aliases keep resolving correctly.
Graph schema
interface Graph {
version: '1.0';
generatedAt: string;
scanRoot: string;
stats: { nodes; edges; orphans; cycles; languages };
nodes: Record<string, GraphNode>;
edges: GraphEdge[];
communities: Record<string, GraphCommunity>;
cycles: GraphCycle[];
}
interface GraphNode {
id: string; // scan-root-relative path
name: string; // basename
path: string;
absolutePath: string;
language: 'ts' | 'tsx' | 'js' | 'jsx' | 'mjs' | 'cjs' | 'py' | 'external';
isExternal: boolean;
loc: number;
sizeBytes: number;
exports: string[];
imports: ImportRef[];
community: string;
contentHash: string;
}
interface ImportRef {
raw: string; // the literal specifier, e.g. "./foo" or "@/lib/bar"
resolved: string | null;
symbols: string[]; // named bindings pulled in — symbol-aware, migration-ready
kind: 'static' | 'dynamic' | 'type' | 'require' | 'reexport' | 'python';
}
interface GraphEdge {
from: string;
to: string;
kind: ImportRef['kind'];
}
interface GraphCommunity {
id: string; // folder path, e.g. "src/features/auth"
members: string[];
parent: string | null;
}
interface GraphCycle {
members: string[];
length: number;
}What assistgraph does NOT do
- Function- or class-level resolution — file-level imports only
- Runtime analysis — static AST parsing only
- Type inference beyond what's declared in imports
- HTML or Vue SFC or Astro parsing
- Call graph construction
- LLM-based enrichment (roadmap)
FAQ
Why are all the files the same colour in Obsidian's graph view?
Obsidian starts every vault with no colour groups. assistgraph build writes .obsidian/graph.json with sensible defaults (one colour per top-level folder). If you already had the vault open, quit Obsidian fully (⌘Q), re-run assistgraph build, then reopen — Obsidian caches the settings in memory and overwrites the file on close.
Why aren't my ui/ and app/ folders visually split?
Obsidian uses a force-directed layout; folder structure isn't an input. If ui/ and app/ are intermingled, they're geometrically intertwined because of edges between them. Run assistgraph audit and check the "Cross-folder Coupling" section to see exactly how many edges cross the boundary.
Does this work in a monorepo?
Yes. Run assistgraph build at the repo root for a unified view, or in a specific package for a focused view. The resolver stops at parent package.json boundaries so a nested package's tsconfig.json takes priority over the monorepo root.
Does this replace dependency-cruiser / madge?
No — those are richer JS-only tools. assistgraph trades depth for breadth: one tool across JS/TS + Python, an Obsidian vault for humans, and an MCP server for agents.
License
MIT.
