pkgrank
pkgrank ranks nodes in a Cargo dependency graph using centrality metrics.
Install
TL;DR
# Rank local crates by importance (PageRank)
# Rank by "who consumes this?" (Consumer PageRank)
Graph model
- Nodes are Cargo packages (from
cargo metadata). - Directed edges are $A \to B$ iff crate A depends on crate B.
Interpretation
- PageRank on the depends-on graph tends to surface shared dependencies / “substrate” crates.
- To surface top-level orchestrators / consumers, use the “consumer PageRank” (PageRank on the reversed graph).
Usage (local crate graph)
Analyze the current directory (finds Cargo.toml if present):
Pick the “top-level orchestrators” view:
Bound JSON output explicitly:
Write per-repo artifacts under evals/pkgrank/ (super-workspace mode):
Triage (artifact-backed summary, same payload as MCP pkgrank_triage):
JSON output shape (stable wrapper)
For commands that support --format json, the JSON is wrapped for forwards-compatible parsing:
pkgrank analyze --format json also includes explicit bounding metadata:
rows_total: total rows computedrows_returned: rows included inrowstruncated: whetherrowswas truncatedjson_limit: the applied limit (if any)
Usage (module/item graph via cargo-modules)
pkgrank modules shells out to cargo-modules and parses its DOT output.
Install once:
Defaults are tuned for a “fast, actionable hotspot scan”:
- aggregate by file
- include types + traits
- hide functions / externs / sysroot
- show a few strongest edges
- cache
cargo-modulesDOT output
Note on CLI vs MCP defaults:
- The CLI
pkgrank modulesdefaults include types + traits (and hide functions). - The MCP
pkgrank_modulestool is more conservative by default (hides fns/types/traits unless you opt in viapresetorinclude_*), because MCP payloads are easy to blow up accidentally.- If you want the CLI-like view from MCP, pass a
presetlikefile-apiorfile-full.
- If you want the CLI-like view from MCP, pass a
File-level hotspots (explicit, but these are now close to the defaults):
Workspace sweep (summary-only):
Use presets when you want a different “view” quickly:
# Item-level view, more verbose
Failure semantics:
- Default: continue on error and report which packages failed.
--fail-fast: stop on first failure.--continue-on-error=false: equivalent explicit form.
Caching:
modules/modules-sweepcachecargo modules dependenciesDOT output underevals/pkgrank/modules_cache/.- Use
--cache-refreshto force regeneration.
MCP stdio server (Cursor)
pkgrank mcp-stdio runs an MCP server over stdio. Stdout is reserved for JSON-RPC frames.
Run:
Toolset selection (optional):
- Default: slim (small tool surface; “just works” for Cursor)
- Opt-in:
PKGRANK_MCP_TOOLSET=fullto expose advanced tools (e.g. module/type graph centrality)PKGRANK_MCP_TOOLSET=debugto also expose internal artifact-inspection tools
Environment (optional):
PKGRANK_ROOT: default root directory for artifact-backed toolsPKGRANK_OUT: default artifacts directory (defaultevals/pkgrank)
Tools (high level):
- Default (Cursor MCP):
pkgrank_view,pkgrank_triage,pkgrank_analyze,pkgrank_repo_detail,pkgrank_crate_detail,pkgrank_snapshot,pkgrank_compare_runs - Advanced (opt-in:
PKGRANK_MCP_TOOLSET=full):pkgrank_status,pkgrank_modules,pkgrank_modules_sweep - Debug (opt-in:
PKGRANK_MCP_TOOLSET=debug): internal artifact-inspection tools (e.g. TLC tables, invariants list, PPR summaries)
Tests (E2E targets)
- Default test suite is offline/deterministic and uses local real targets (the dev super-workspace itself).
- URL-backed tests (crates.io crawl) are opt-in:
- set
PKGRANK_E2E_NETWORK=1before running tests.
- set
Invariants (must not drift)
- Edge meaning: $A \to B$ means “A depends on B”.
- Dependency kind gating:
--dev/--buildcontrol whether those edges exist. - Workspace restriction: “workspace-only” means nodes/edges restricted to the current Cargo workspace members.
User stories (what this is for)
These are the “real” workflows this tool is meant to serve.
- Onboarding / orientation: “What are the most central crates in this workspace? Who are the orchestrators?”
- Use:
pkgrank analyze(metricpagerankvsconsumers-pagerank) andpkgrank triage.
- Use:
- Dependency slimming / graph sanity: “Why is this crate so central / so sticky? What depends on it?”
- Use:
pkgrank analyze --metric consumers-pagerank+ drill into origins and degrees; optionally generate artifacts viapkgrank view.
- Use:
- Refactor hotspots inside a crate: “Which files/modules/items are the coupling hotspots?”
- Use:
pkgrank moduleswith--aggregate file(hot files) or--aggregate node(hot items).
- Use:
- Workspace sweep: “Run that hotspot scan across a bunch of crates and summarize failures/results.”
- Use:
pkgrank modules-sweep(summary-only by default).
- Use:
- Shareable artifacts: “Write an HTML snapshot I can point people at.”
- Use:
pkgrank view/pkgrank sweep-local.
- Use:
Evidence pointers (qualitative):
- Community demand for “internal dependency graph visualization” (rust-analyzer crate graph is commonly suggested):
https://www.reddit.com/r/rust/comments/x04zko/visualizing_internal_dependencies_as_a_graph/ - Cursor’s framing of MCP: “connect to external tools and data sources” (so MCP tends to be used for “triage + drilldown”):
https://cursor.com/docs/context/mcp - Cargo’s own
cargo treedocs emphasize dependency display, reverse-deps (--invert), and “duplicates” as a common pain point:https://doc.rust-lang.org/cargo/commands/cargo-tree.html
Dependencies / integration notes
pkgrankincludes its centrality algorithms internally (PageRank / PPR / betweenness / reachability), to stay buildable as a standalone repo (no cross-repo path deps).