SkillAgentSearch skills...

Constrictor

An agent-first dependency and blast-radius explorer for Python codebases. Generates structured, machine-readable dependency graphs that AI coding agents can query to understand code relationships, assess refactoring impact, and navigate complex projects autonomously.

Install / Use

/learn @ameya1995/Constrictor
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Constrictor

Static dependency and blast-radius analyzer for Python codebases. Answers "what breaks if I change X?" before you touch a line of code.


Agent Integration

Constrictor is designed first for AI agents. Two integration paths are available.

MCP server (Claude Code, Cursor, Copilot, Codex)

# 1. Install
pip install -e .

# 2. Scan the project once
constrictor scan . -o graph.json

# 3. Start the MCP server
constrictor mcp serve --graph graph.json

Add to your agent config (e.g. .claude/mcp.json, ~/.cursor/mcp.json):

{
  "mcpServers": {
    "constrictor": {
      "command": "constrictor",
      "args": ["mcp", "serve", "--graph", "graph.json"]
    }
  }
}

Available MCP tools:

| Tool | Description | |---|---| | constrictor_scan | Scan a project and build the graph | | constrictor_impact | Blast-radius analysis (downstream / upstream) | | constrictor_paths | Enumerate dependency paths between two nodes | | constrictor_search | Search nodes by name, type, or file pattern | | constrictor_file_context | All entities defined in a single file | | constrictor_diff_impact | Blast radius from a git diff or line ranges | | constrictor_batch_impact | Merged impact analysis for multiple nodes | | constrictor_unused | Find dead code candidates (no incoming edges) | | constrictor_cycles | Detect circular import dependencies | | constrictor_dependents | Find all dependents of a file | | constrictor_audit | List ambiguous / unresolved edges | | constrictor_rescan_graph | Rebuild graph.json in place after editing code | | constrictor_check_staleness | Check if graph is stale relative to source files | | constrictor_summary | Human-readable graph summary + statistics |

Graph Staleness Detection

The dependency graph goes stale when source files change after the last scan. Running impact analysis on a stale graph produces inaccurate results.

Before any impact analysis, agents should check staleness:

// 1. Check if graph is stale
constrictor_check_staleness({ "graph_path": "graph.json" })

// Response:
{
  "is_stale": true,
  "changed_file_count": 3,
  "recommendation": "Graph is stale: 3 file(s) modified since last scan. Call `constrictor_rescan_graph` to update."
}

// 2. If stale, rescan before proceeding
constrictor_rescan_graph({ "graph_path": "graph.json" })

// 3. Now run impact analysis with accurate data
constrictor_impact({ "node": "process_order", "graph_path": "graph.json" })

Why this matters:

  • A stale graph won't reflect new imports, function calls, or class hierarchies
  • Impact analysis on stale data will miss downstream dependents
  • Agents may give incorrect refactoring advice based on outdated topology

SSE transport (for HTTP-based agent runtimes):

constrictor mcp serve --transport sse --port 9000

SKILL.md (skill-file agents)

For agent runtimes that discover tools via skill files:

constrictor agent skill -o SKILL.md

Common agent workflows

Staleness-aware impact analysis (recommended):

# 1. Check if graph is stale
constrictor_check_staleness --graph graph.json

# 2. If stale, rescan first
constrictor_rescan_graph --graph graph.json

# 3. Then run impact analysis
constrictor impact --node "app.services::process_order" --graph graph.json

Before refactoring:

constrictor scan . -o graph.json
constrictor impact --node "app.services::process_order" --graph graph.json

Before reviewing a PR:

git diff HEAD~1 | constrictor diff-impact --graph graph.json

Trace data flow to a database table:

constrictor paths --from "POST /api/orders" --to "orders" --graph graph.json

Find dead code:

constrictor unused --graph graph.json --exclude "tests/*"

Detect circular imports:

constrictor cycles --graph graph.json

After an agent edits files:

# Ask the MCP server to rebuild graph.json in place
constrictor mcp serve --graph graph.json

Then call constrictor_rescan_graph from the agent before running impact or path analysis again.


What it does

Constrictor parses every .py file into an AST and builds a rich dependency graph capturing:

  • Import relationships — which modules depend on which
  • Call graphs — which functions call which functions
  • Class hierarchies — inheritance, ABC/Protocol implementations
  • Framework endpoints — FastAPI, Flask, and Django routes
  • Database models — SQLAlchemy and Django ORM with foreign-key relationships
  • HTTP calls — outbound requests/httpx calls
  • Type annotations — parameter and return type relationships
  • Service topology — multi-service projects via docker-compose.yml, Procfile, multiple pyproject.toml files

Every edge has a certainty level (EXACT, INFERRED, AMBIGUOUS, UNRESOLVED).


Installation

Constrictor is not yet published to PyPI. Install from source.

git clone https://github.com/ameya1995/Constrictor.git
cd Constrictor
pip install -e .
# Optional: pip install -e ".[dev]"   # pytest, ruff, mypy
# Optional: pip install -e ".[js]"    # JS/TS support via tree-sitter

Requirements: Python ≥ 3.10


CLI Reference

constrictor scan

constrictor scan <path> -o graph.json [-v] [-i] [--include-js] [-e <glob>]

Scans <path> and writes the dependency graph. -i enables incremental re-scanning (uses .constrictor_cache/).

constrictor impact

constrictor impact --node "app.utils::greet" --graph graph.json [--direction upstream|downstream] [--depth 6] [--format full|compact|files]

Blast-radius analysis for a single node.

constrictor diff-impact

git diff HEAD~1 | constrictor diff-impact --graph graph.json [--format compact]

Maps every changed line in a unified diff to graph nodes; produces a tiered impact report.

constrictor paths

constrictor paths --from "app.routes::create_order" --to "orders" --graph graph.json [--depth 8]

All dependency paths between two nodes (up to 20, capped to avoid combinatorial explosion).

constrictor search

constrictor search "create_order" --graph graph.json [--type FUNCTION] [--limit 10]

Ranked by match quality: exact → prefix → substring → regex.

constrictor context

constrictor context app/routes/users.py --graph graph.json

All entities (imports, functions, classes, endpoints, callers) defined in one file.

constrictor unused

constrictor unused --graph graph.json [--exclude "tests/*"] [--entry-point "main"]

constrictor cycles

constrictor cycles --graph graph.json [--edge-type CALLS]

constrictor watch

constrictor watch /path/to/project -o graph.json [--debounce-ms 1500]

Re-scans incrementally on every file change.

constrictor audit / constrictor summary

constrictor audit --graph graph.json      # list AMBIGUOUS/UNRESOLVED edges
constrictor summary --graph graph.json    # human-readable stats

constrictor export

constrictor export neo4j /path/to/project -o ./neo4j/   # produces nodes.csv, edges.csv

constrictor serve

constrictor serve --graph graph.json --port 8080

Interactive force-directed D3.js graph visualization in the browser.

Web UI quick start

# 1. Build or refresh the graph
constrictor scan . -o graph.json

# 2. Start the browser UI
constrictor serve --graph graph.json --port 8080

# 3. Open the app
open http://127.0.0.1:8080

How to use the UI

The web UI is organized as a three-column workspace:

  • Left panel: view selection, focus controls, filters, and path inspector
  • Center panel: interactive dependency graph or unresolved-audit list
  • Right panel: metadata and blast-radius details for the currently selected node

Recommended workflow:

  1. Start in Workspace topology for a full-project view.
  2. Use Node type filters to remove noise before inspecting a subgraph.
  3. Type in Focus to visually narrow the graph to matching nodes.
  4. Click a node in the graph to open its metadata and impact analysis in the right panel.
  5. Switch Downstream / Upstream to answer either "what does this affect?" or "what depends on this?".
  6. Increase Depth when you want a broader blast radius.
  7. Use Path Inspector when you need concrete paths between two nodes.

Views:

  • Workspace topology: the full graph, useful for general exploration
  • Service/API dependencies: emphasizes service, component, endpoint, and external-service nodes
  • Data/table impact: emphasizes SQLAlchemy models, tables, modules, and packages
  • Unresolved audit: shows ambiguous and unresolved edges in a readable review list

Controls:

  • Node type filter: show or hide classes of nodes without rebuilding the graph on disk
  • Edge type filter: restrict the rendered graph to one edge type such as CALLS or IMPORTS
  • Show ambiguous: hide inferred/ambiguous edges when you want a cleaner exact-only visualization of the current graph
  • Path Inspector: enter a from node and to node, then click Find paths

Interpreting the graph:

  • Larger nodes usually represent higher-level entities like services and components
  • Colored dashed hulls group nodes that belong to the same detected service/component boundary
  • Selecting a node highlights directly connected neighbors and dims unrelated parts of the graph
  • The top stat tiles are a quick orientation aid, not a replacement for detailed analysis

Keeping the UI fresh after code changes:

  • If you are using the CLI directly, rerun constrictor scan . -o graph.json
  • If you are using the MCP server, call constrictor_rescan_graph after a batch of edits
  • If you want automatic refresh on file changes, use constrictor watch . -o graph.json in a separate terminal and reload the b
View on GitHub
GitHub Stars19
CategoryDevelopment
Updated8d ago
Forks3

Languages

Python

Security Score

90/100

Audited on Mar 28, 2026

No findings