Quick Start

Analyze your first project in three commands.

Start the visualization server

Navigate to any Python, JavaScript/TypeScript, or Rust project and run:

serpentine serve

Serpentine will analyze the project, start a local server at http://127.0.0.1:8765, and open the interactive graph in your browser. File changes are detected automatically and the graph updates in real time via WebSocket. See the UI Overview for a tour of the interface.

The agent-oriented workflow

If you’re using Serpentine to give an AI agent structural context, the workflow is three commands:

# 1. Get the lay of the land — module names, rough scale
serpentine stats .

# 2. Find relevant node IDs by name
serpentine catalog . --filter "*auth*"

# 3. Get the subgraph and source for the relevant area
serpentine analyze . --select "*auth*.*" --source

Read the source and edges to understand what connects to what, then read only the files that are actually relevant. For a walkthrough of how this works in practice, see Why I Give Claude a Dependency Graph Instead of File Dumps.

Wire it in

Run this once inside any project:

serpentine init

This creates .serpentine.yml, updates .gitignore, and installs configuration for whichever AI coding tools are detected. For Claude Code: installs the code-analysis skill to .claude/skills/code-analysis/ and appends to CLAUDE.md. After that, Claude orients structurally — running stats, catalog, and analyze before reading files or writing a plan — on every task.

Also supports Cursor (.cursor/rules/serpentine.mdc), GitHub Copilot (.github/copilot-instructions.md), Codex, and OpenCode (AGENTS.md). Use --harness to target one explicitly:

serpentine init --harness cursor

What Serpentine tracks

Serpentine builds a code reference graph — every place one definition statically mentions another, resolved through the language’s scoping rules to the specific definition it refers to.

Reference typeExampleEdge
Function callresult = parse(data)result --calls--> parse
Constructorloader = CSVLoader(path)loader --has-a--> CSVLoader
Name referencedefault = MISSINGdefault --references--> MISSING
Inheritanceclass Stats(Base)Stats --is-a--> Base

All four edge types resolve through imports — so a reference to an imported name traces all the way back to its definition.

Next steps