# Pyvisualizer

> A deterministic, AST-verified call graph for any Python project — every edge traceable to a file:line. The reproducible, CI-gateable alternative to LLM-generated diagrams. No code executed. Nothing leaves your machine.

- **Type:** MCP server
- **Install:** `agentstack add mcp-haider1998-pyvisualizer`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [haider1998](https://agentstack.voostack.com/s/haider1998)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [haider1998](https://github.com/haider1998)
- **Source:** https://github.com/haider1998/pyvisualizer
- **Website:** https://haider1998.github.io/pyvisualizer/

## Install

```sh
agentstack add mcp-haider1998-pyvisualizer
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 🗺️ py-code-visualizer

[](https://pypi.org/project/py-code-visualizer/)
[](https://pypi.org/project/py-code-visualizer/)
[](https://github.com/haider1998/PyVisualizer/actions/workflows/ci.yml)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
[](#architecture)

> **Deterministic, AST-verified architecture ground truth for Python.**
> LLMs guess your architecture. **py-code-visualizer proves it** — every edge is
> traceable to a `file:line`.

  

  ⚡ Try it live in your browser →
  &nbsp;·&nbsp; drop a .py file, see the graph, nothing uploaded

py-code-visualizer reads your Python source with static analysis (no code is ever
imported or executed) and produces a call graph you can trust: self-healing
README diagrams, PR architecture-change reports, CI gates that block circular
dependencies, and a fully offline interactive map. Because the output is
**deterministic**, it lives in your pipelines and never drifts.

```bash
pip install py-code-visualizer && py-code-visualizer visualize .
```

**Who is this for?** Any Python developer, whatever your stack:
[**Django**](https://haider1998.github.io/pyvisualizer/for/django.html) (real
request flow, not just the model schema) ·
[**FastAPI**](https://haider1998.github.io/pyvisualizer/for/fastapi.html) (every
route's blast radius, async + decorators) ·
[**ML pipelines**](https://haider1998.github.io/pyvisualizer/for/ml-pipelines.html)
(map the pipeline, find dead experiments). See the
[honest comparison](https://haider1998.github.io/pyvisualizer/compare.html) and
[measured facts](https://haider1998.github.io/pyvisualizer/facts.html).

---

## Why this exists (and why an LLM can't do it)

An LLM asked to diagram your repo produces the architecture it *expects* a repo
like yours to have — plausible, confident, and subtly wrong. It invents links
between modules that never call each other, silently drops what didn't fit the
context window, and gives a different answer every run, so you can never diff it
or put it in CI.

PyVisualizer is the opposite by construction:

| | LLM diagram | PyVisualizer |
|---|---|---|
| **Correctness** | Inferred, often hallucinated | Parsed from the AST |
| **Provenance** | None | Every edge → `file:line` |
| **Determinism** | Different every run | Byte-identical |
| **Ambiguity** | Hidden behind confidence | Flagged, with candidates kept |
| **CI-able** | No | Yes — gates, diffs, drift checks |
| **Code leaves the machine** | Usually | Never |

When a call genuinely can't be resolved to one target, we **don't pick one and
pretend** — we tag the edge `ambiguous` and keep the full candidate list. That
honesty is the whole product.

---

## Install

```bash
pip install py-code-visualizer
```

## 60-second start

```bash
# Interactive, fully self-contained HTML map (opens offline, zero network)
py-code-visualizer visualize ./your_project -o architecture.html

# Keep a live diagram inside your README forever
py-code-visualizer readme ./your_project

# Fail CI on new circular dependencies
py-code-visualizer check ./your_project --fail-on-cycles

# What breaks if I touch this function?
py-code-visualizer impact your_pkg.core.save ./your_project
```

---

## ⚡ AI agent context — 97% fewer tokens

> **Full guide:** [AI_CONTEXT.md](AI_CONTEXT.md)

Instead of pasting your whole codebase into Claude / ChatGPT / Cursor, give it the
verified 4,000-token slice that actually matters. Three commands cover every workflow:

```bash
# Option A — describe the task in plain English (no function name needed)
py-code-visualizer context . --task "add retry logic to the HTTP client" --budget-tokens 4000

# Option B — you know the function
py-code-visualizer context . --focus send_request --budget-tokens 4000

# Option C — wire it in permanently (agents read it automatically)
py-code-visualizer export --for-ai .
```

**Copy the output of A or B → paste it before your question in the AI chat.**
The AI now has the right context instead of 140,000 guessed tokens.

| Approach | Tokens | Claude Opus 5 cost | Signal per 1k tokens |
|---|---|---|---|
| Full source | 139,697 | $2.10 | 1× |
| Keyword grep | 24,652 | $0.37 | 6× |
| **pyvisualizer `--task`** | **~4,000** | **$0.06** | **35×** |

_Measured on httpx (real open-source project, 1,076 functions). See [measured facts](https://haider1998.github.io/pyvisualizer/use-cases/agent-context.html)._

---

## For a scrappy startup 🚀

You will never schedule a "docs sprint." So don't. Add one line to CI and your
README always carries a current architecture diagram — investor- and
due-diligence-ready for free — while every PR gets a comment showing exactly
what changed structurally.

```yaml
# .github/workflows/architecture.yml
- uses: haider1998/PyVisualizer@v2
  with: { mode: readme }
```

A new contractor onboards from the interactive map instead of a three-day Slack
Q&A. Pivots stop being archaeology.

## For a Fortune 500 enterprise 🏛️

- **Code never leaves the machine.** Pure AST, no execution, no API calls — the
  anti-LLM tool for security review. Generated HTML is a single file with zero
  network requests (air-gap safe).
- **Architecture-as-code gates.** Declare layers and forbidden dependencies;
  the build fails on violations — at the *call-graph* level, stricter than
  import linters.
- **Audit trail.** Deterministic diagrams committed by CI make git history your
  dated, attributable architecture change-log (SOC 2 / review boards).
- **Monorepo scale.** Hierarchical rollup (module → class → function), never
  silent sampling.

```toml
# pyproject.toml
[tool.pyvisualizer.rules]
layers = ["api", "domain", "infra"]
forbid = ["domain -> api", "domain -> infra"]
```

---

## Commands

| Command | What it does |
|---|---|
| `review  --base ` | **PR review report**: changed functions, blast radius, risk flags, focused subgraph — clickable `file:line` on every reference |
| `context  --focus ` | **Verified context pack for AI agents**: task-scoped, budget-bounded, zero guessed edges |
| `context  --task ""` | Same pack, seeded from a **natural-language task description** (named symbols first, lexical matches as labeled hints; `--strategy graph\|text\|hybrid`) |
| `visualize` | Render `html` · `mermaid` · `json` · `c4` · `svg`/`png` |
| `readme` | Inject/update a Mermaid diagram in any Markdown file (idempotent) + jump-to-source index |
| `json` | Emit the canonical, diffable graph JSON |
| `diff base.json head.json` | PR-ready architecture-change report (+ new-cycle gate) |
| `check` | Enforce layering rules & cycles — CI gate (`--dead-code` too) |
| `impact ` | Blast-radius: transitive callers/callees + risk line (`--format markdown`) |
| `health` | Architecture health score (A–F) with an SVG badge |
| `export` | `ARCHITECTURE.json` + `ARCHITECTURE.md` + AGENTS.md wiring (`--check` freshness gate) |
| `init` | Opt-in setup — generate only the automation you choose (`review`/`readme`/`context`/`gates`) |

**Two jobs, one engine.** *review* makes code review on a large repo a focused
few-minute pass; *context* gives an AI agent a verified, **97%-smaller** slice of the
architecture instead of the whole repo. See [`VISION.md`](VISION.md) and the
[use-case walkthroughs](https://haider1998.github.io/pyvisualizer/use-cases/).

### MCP server (real-time, mid-task)

If you use Claude Code or Cursor, the MCP server lets the agent query the verified
graph when it needs it — no manual copy-paste required:

```bash
pip install 'py-code-visualizer[mcp]'   # Python 3.10+
pyvisualizer-mcp /path/to/project
```

Add to `.mcp.json` and three tools become available: `search_code`, `context_pack`,
and `impact`. The server rebuilds only when files change.

Full usage guide (all flags, troubleshooting, output walkthrough): **[AI_CONTEXT.md](AI_CONTEXT.md)**

## Use cases (real commands, real output)

Three end-to-end walkthroughs, each backed by a runnable fixture in
[`examples/scenarios/`](examples/scenarios) — every command and every line of
output is reproducible, nothing is staged:

- 🗺️ **[The orphan monolith](https://haider1998.github.io/pyvisualizer/use-cases/orphan-monolith.html)** —
  onboard onto an undocumented codebase with `visualize` + `health` + `check --dead-code`.
- 🛡️ **[The audit deadline](https://haider1998.github.io/pyvisualizer/use-cases/soc2-audit.html)** —
  enforce layering rules at the call-graph level and produce dated SOC 2 evidence.
- 🧨 **[The fearless refactor](https://haider1998.github.io/pyvisualizer/use-cases/fearless-refactor.html)** —
  `impact` blast radius, then a `diff` gate that fails a PR on a new cycle.

See the [full use-case index + a recipe for every command](https://haider1998.github.io/pyvisualizer/use-cases/).

**Measured** (reproduce with `python benchmarks/bench.py` → [`docs/benchmarks.json`](docs/benchmarks.json)):
a **98,669-line** project maps to a full call graph in **~4.9 s** (26,658 functions),
**100%** of edges carry `file:line`, output is **byte-identical** across runs, and the
generated HTML makes **0** network requests. *(macOS arm64, Python 3.14; speed is
hardware-dependent — provenance, determinism, and zero-network are structural.)*

## The interactive map

A single self-contained HTML file (no CDN, works offline):

- **Layered abstraction** — toggle module → class → function views
- **Click any node** — signature, `file:line`, callers & callees (all clickable)
- **⌘K command palette**, live search, module filter
- **Deep links** — the URL encodes the selected node; paste it in Slack and your
  teammate lands on the exact function
- **Tour mode** — auto-generated walkthrough from detected entry points
- **Overlays** — cycles (red), ambiguity (dashed), and `--churn` git-heatmap
- Minimap, pan/zoom/drag, light/dark, SVG export

## Feed the graph to your AI tools

```bash
py-code-visualizer export --for-ai ./your_project
```

Point Cursor / Claude at the verified `ARCHITECTURE.json` instead of asking a
model to re-derive structure from raw source. **Point your agent at the graph,
not the repo.**

---

## Accuracy guarantees

- Nested classes, methods, and closures are collected with correct qualified
  names (`pkg.Outer.Inner.method`, `mod.func..inner`).
- Chained calls (`get_client().fetch()`), comprehensions, and lambdas are
  captured.
- `super()`/inherited calls resolved through the computed MRO (tagged
  `inherited`).
- Parameter and variable type annotations drive method resolution.
- Calls to stdlib/third-party code produce **no edge** — we never invent one.
- Ambiguous calls are tagged and kept as candidates; `--strict` drops them.

See [`docs/integrations.md`](docs/integrations.md) for GitHub Actions, GitLab
CI, and pre-commit setup.

## Configuration

```toml
[tool.pyvisualizer]
exclude = ["tests", "migrations"]
max_nodes = 120
target = "README.md"
detail = "module"          # module | class | function
```

## Roadmap

- ⏳ **Time-travel** — scrub your architecture's evolution across releases
- 🔁 **Watch mode** — live-reloading map while you refactor
- ✅ ~~**MCP server**~~ — shipped: `pyvisualizer-mcp` (`search_code`, `context_pack`, `impact`)

## Architecture

The diagram below is generated by PyVisualizer itself and kept in sync by CI.

*120 functions · 214 calls · health F (46/100) — detail: module*

```mermaid
flowchart LR
    g0["bench"]
    g1["genproject"]
    g2["main"]
    g3["models"]
    g4["services"]
    g5["urls"]
    g6["repos"]
    g7["services"]
    g8["evaluate"]
    g9["features"]
    g10["ingest"]
    g11["pipeline"]
    g12["train"]
    g13["cli"]
    g14["pipeline"]
    g15["transforms"]
    g16["core"]
    g17["service"]
    g18["billing"]
    g19["api"]
    g20["changes"]
    g21["cli"]
    g22["config"]
    g23["context"]
    g24["analyzer"]
    g25["graph"]
    g26["diff"]
    g27["export"]
    g28["gates"]
    g29["impact"]
    g30["inject"]
    g31["mcp_server"]
    g32["metrics"]
    g33["overlays"]
    g34["retrieval"]
    g35["review"]
    g36["c4"]
    g37["json_graph"]
    g38["setup_init"]
    g39["file_discovery"]
    g40["d3"]
    g41["html"]
    g42["mermaid"]
    g0 --> g1
    g0 --> g19
    g0 --> g37
    g0 --> g41
    g1 --> g6
    g4 --> g3
    g7 -.-> g4
    g7 --> g6
    g11 --> g8
    g11 --> g9
    g11 --> g10
    g11 --> g12
    g13 --> g14
    g14 -.-> g7
    g14 --> g15
    g15 -.-> g4
    g17 --> g16
    g19 --> g25
    g19 --> g31
    g19 --> g39
    g20 --> g31
    g20 --> g33
    g21 --> g14
    g21 --> g19
    g21 --> g22
    g21 --> g23
    g21 --> g26
    g21 --> g27
    g21 --> g28
    g21 --> g29
    g21 --> g30
    g21 --> g31
    g21 --> g32
    g21 --> g33
    g21 --> g35
    g21 --> g36
    g21 --> g37
    g21 --> g40
    g21 --> g42
    g22 --> g31
    g23 --> g4
    g23 --> g20
    g23 --> g28
    g23 --> g29
    g23 --> g31
    g23 --> g32
    g23 --> g33
    g23 --> g34
    g24 --> g31
    g25 --> g4
    g25 --> g31
    g26 --> g4
    g26 --> g31
    g26 --> g32
    g27 --> g28
    g27 --> g30
    g27 --> g31
    g27 --> g32
    g27 --> g37
    g28 --> g31
    g29 --> g20
    g31 --> g19
    g31 --> g23
    g31 --> g29
    g31 --> g34
    g32 --> g31
    g32 --> g34
    g33 --> g31
    g34 --> g4
    g34 --> g31
    g35 --> g20
    g35 --> g28
    g35 --> g31
    g35 --> g32
    g35 --> g42
    g36 --> g42
    g37 --> g31
    g38 --> g19
    g38 --> g30
    g38 --> g31
    g38 --> g32
    g38 --> g42
    g39 --> g4
    g39 --> g6
    g40 --> g41
    g41 --> g37
    g42 --> g31
```

🔒 Deterministic, AST-verified — no code executed. Generated by [py-code-visualizer](https://github.com/haider1998/PyVisualizer).

📍 Jump to source (120 functions)

- [`benchmarks.bench._bench_target`](benchmarks/bench.py#L177)
- [`benchmarks.bench._determinism_proof`](benchmarks/bench.py#L113)
- [`benchmarks.bench._html_network_proof`](benchmarks/bench.py#L132)
- [`benchmarks.bench.run`](benchmarks/bench.py#L221)
- [`benchmarks.genproject._gen_module`](benchmarks/genproject.py#L41)
- [`benchmarks.genproject.generate`](benchmarks/genproject.py#L135)
- [`examples.sample_project.main.main`](examples/sample_project/main.py#L7)
- [`examples.scenarios.django_shop.models.Cart.for_user`](examples/scenarios/django_shop/models.py#L12)
- [`examples.scenarios.django_shop.services.CartService.add`](examples/scenarios/django_shop/services.py#L11)
- [`examples.scenarios.django_shop.services.OrderService.checkout`](examples/scenarios/django_shop/services.py#L22)
- [`examples.scenarios.django_shop.services.OrderService.get`](examples/scenarios/django_shop/services.py#L29)
- [`examples.scenarios.django_shop.urls.dispatch`](examples/scenarios/django_shop/urls.py#L7)
- [`examples.scenarios.fastapi_svc.repos.OrderRepo.insert`](examples/scenarios/fastapi_svc/repos.py#L8)
- [`examples.scenarios.fastapi_svc.services.OrderFlow.fetch`](examples/scenarios/fastapi_svc/services.py#L22)
- [`examples.scenarios.fastapi_svc.services.OrderFlow.place`](examples/scenarios/fastapi_svc/services.py#L16)
- [`examples.scenarios.ml_pipeline.evaluate.evaluate_model`](examples/scenarios/ml_pipeline/evaluate.py#L4)
- [`examples.scenarios.ml_pipeline.features.build_features`](examples/scenarios/ml_pipeline/features.py#L4)
- [`examples.scenarios.ml_pipeline.ingest.load_dataset`](examples/scenarios/ml_pipeline/ingest.py#L4)
- [`examples.scenarios.ml_pipeline.pipeline.run`](examples/scenarios/ml_pipeline/pipeline.py#L9)
- [`examples.scenarios.ml_pipeline.train.train_model`](examples/scenarios/ml_pipeline/train.py#L4)
- [`examples.scenarios.orphan_monolith.app.cli.run`](examples/scenarios/orphan_monolith/app/cli.py#L7)
- [`examples.scenarios.orphan_monolith.app.pipeline.ReportPipeline.build`](examples/scenarios/orphan_monolith/app/pipeline.py#L11)
- [`examples.scenarios.orphan_monolith.app.pipeline.ReportPipeline.render`](examples/scenarios/orphan_monolith/app/pipeline.py#L16)
- [`examples.scenarios.orphan_monolith.app.transforms.summarize`](examples/scenarios/orphan_monolith/app/transforms.py#L11)
- [`examples.scenarios.refactor.a

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [haider1998](https://github.com/haider1998)
- **Source:** [haider1998/pyvisualizer](https://github.com/haider1998/pyvisualizer)
- **License:** MIT
- **Homepage:** https://haider1998.github.io/pyvisualizer/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-haider1998-pyvisualizer
- Seller: https://agentstack.voostack.com/s/haider1998
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
