Latest release View changelog →

Quick Start

cargo install cartog
cd your-project
cartog init                  # 1. scaffold .cartog.toml
cartog index                 # 2. build the graph (~95ms for 4k LOC)

cartog search validate       # find symbols by name (sub-ms)
cartog refs validate_token   # who calls/imports/references this?
cartog impact validate_token # what breaks if I change this?

# Optional — wire cartog into your editor for AI agents
cartog ide                   # Cursor, VS Code, Claude Desktop, Codex CLI, ...

Two commands to start: init writes .cartog.toml, index builds the graph. Add cartog ide only if you want MCP wired into an editor — CLI users can skip it.

Add semantic search (optional, still fully local)

cartog rag setup             # download models (~1.2GB, one-time)
cartog rag index .           # embed all symbols + documents
cartog rag search "authentication token validation"

Indexes both code (functions, classes, methods) and Markdown documents (READMEs, design docs, API docs). Models are downloaded once to ~/.cache/cartog/models/ and run locally via ONNX Runtime. No API keys needed.

Using Ollama instead? Add this to your .cartog.toml and skip rag setup:

[embedding]
provider = "ollama"

See Embedding Providers for full setup.

Search Modes

Cartog offers two search modes that complement each other:

Query type Command Speed Best for
Symbol name cartog search parse sub-ms You know the name
Natural language cartog rag search "error handling" ~150-500ms You know the behavior
Broad / unsure Run both in parallel sub-ms + ~300ms Catch names + semantics

Recommended Workflow

cartog index .          # 1. build the graph
cartog search foo       # 2. discover exact symbol names
cartog refs foo         # 3. find all usages
cartog callees foo      # 4. see what it depends on
cartog impact foo       # 5. assess blast radius
cartog index .          # 6. re-index after changes

Configuration

Cartog works with zero configuration. Optionally, place a .cartog.toml at your project root to customize database path, embedding provider, and re-ranking.

# .cartog.toml — full reference

[database]
path = "~/.local/share/cartog/myproject.db"

# Embedding provider (optional — defaults to local ONNX)
[embedding]
provider = "local"               # "local" (default) or "ollama"
model = "BAAI/bge-small-en-v1.5" # model name (provider-specific)
dimension = 384                  # auto-detected for built-in models

# Local provider: asymmetric model prefixes
[embedding.local]
query_prefix = "search_query: "
document_prefix = "search_document: "

# Ollama provider settings
[embedding.ollama]
base_url = "http://localhost:11434"
model = "nomic-embed-text"

# Reranker (optional — defaults to local cross-encoder)
[reranker]
provider = "local"               # "local" (default) or "none"

Database path resolution priority: --db flag / CARTOG_DB env > .cartog.toml > git root auto-detection > cwd fallback.

Embedding Providers

Semantic search requires an embedding provider. Two options:

ProviderConfigSetupNotes
local (default) No config needed cartog rag setup ONNX Runtime via fastembed. ~1.2GB model download. Runs on CPU.
ollama [embedding]
provider = "ollama"
ollama pull nomic-embed-text HTTP API. GPU acceleration via Ollama. No model download by cartog.

Example: Ollama with GPU acceleration

# 1. Install cartog (Ollama provider is included by default)
cargo install cartog

# 2. Start Ollama and pull a model
ollama serve
ollama pull nomic-embed-text

# 3. Configure .cartog.toml
cat > .cartog.toml <<EOF
[embedding]
provider = "ollama"
model = "nomic-embed-text"

[embedding.ollama]
base_url = "http://localhost:11434"
EOF

# 4. Index and search — no rag setup needed
cartog index .
cartog rag index .
cartog rag search "authentication flow"

Example: Local with a different model

# Use a larger model for better quality
cat > .cartog.toml <<EOF
[embedding]
provider = "local"
model = "BAAI/bge-base-en-v1.5"
EOF

cartog rag setup     # downloads the configured model
cartog rag index .
cartog rag search "error handling"

Example: Disable re-ranking

# Skip the 1.1GB reranker model download
cat > .cartog.toml <<EOF
[reranker]
provider = "none"
EOF

cartog rag setup     # only downloads embedding model (~80MB)

cartog rag setup

Download embedding and re-ranker models from HuggingFace. Run once before using semantic search with the local provider.

cartog rag setup

Downloads ~1.2GB of ONNX models (embedding ~80MB + reranker ~1.1GB). Cached in ~/.cache/cartog/models/.

Note: When using Ollama, skip this — models are managed by the Ollama server.

# To also skip the reranker download:
[reranker]
provider = "none"

cartog rag index

Build the embedding index for semantic search. Indexes both code symbols and Markdown documents (.md files). Requires cartog index first. For the local provider, also requires cartog rag setup.

cartog rag index              # embed all symbols + documents
cartog rag index src/         # embed subdirectory
cartog rag index --force      # re-embed all

Example output

Embedded 697 symbols in 3.1s (224/s)
RAG index ready: 697 vectors, 384 dimensions, sqlite-vec

Semantic search — use natural language to find code by behavior or concept. Returns code only by default; use --kind document for docs or --kind all for both.

cartog rag search "validate authentication tokens"
cartog rag search "error handling" --kind function
cartog rag search "database connection" --limit 5
cartog rag search "deployment architecture" --kind document

Example output

Found 1 results (FTS: 1, vector: 0, merged: 1)

1. function auth_middleware  middleware/auth_mw.py:15-37  [fts5] score=0.0164
    def auth_middleware(request: Dict[str, Any]) -> Dict[str, Any]:
        """Verify authentication token and attach user context."""
        validate_request(request)

Combines keyword (BM25/FTS5) and vector similarity, merged via RRF, then re-ranked by a cross-encoder. By default, returns code only; use --kind document for docs or --kind all for both.

Available --kind values: function, class, method, variable, import, interface, enum, type-alias, trait, module, document, all.

Agent Skill

Install cartog as an agent skill for Claude Code, Cursor, Copilot, and other compatible agents:

npx skills add jrollin/cartog

Or install manually:

cp -r skills/cartog ~/.claude/skills/

The skill teaches your AI agent when and how to use cartog — including search routing, refactoring workflows, and fallback heuristics.

Claude Plugin

For Claude Code users, the simplest setup. Run each command separately:

/plugin marketplace add jrollin/cartog
/plugin install cartog@cartog-plugins

MCP Server

cartog serve exposes 13 tools over stdio for MCP-compatible clients.

ToolDescription
cartog_indexBuild/update the code graph
cartog_mapCodebase orientation: file list + top symbols (call first in a new repo)
cartog_searchFind symbols by partial name
cartog_outlineFile structure (symbols, line ranges)
cartog_refsAll references to a symbol
cartog_calleesWhat a symbol calls
cartog_impactTransitive impact analysis
cartog_hierarchyInheritance tree
cartog_depsFile-level imports
cartog_statsIndex summary
cartog_changesSymbols affected by recent git changes
cartog_rag_indexBuild embedding index
cartog_rag_searchSemantic search

Progress notifications: cartog_index and cartog_rag_index emit standard MCP notifications/progress when the client includes a progressToken in the request's _meta. cartog_index emits 3 phase events (walking, parsing N files, storing N files) plus an optional fourth (resolving with LSP) when the LSP pass runs. cartog_rag_index emits preparing, one embedding processed/total per ~512-symbol batch, then storing. The message field is human-readable, not a contract. Clients that don't supply a progressToken see no notifications.

Wiring cartog into editors: cartog ide

cartog ide is the only verb that writes MCP configs. Run it once per machine, plus any time you install a new editor.

cartog ide                          # all installed clients, all scopes
cartog ide --scope project          # .mcp.json, .cursor/, .vscode/
cartog ide --scope user             # user-scope clients only
cartog ide --client cursor          # one client
cartog ide --dry-run                # preview with before/after diff

Clients: claude-code (project + user), claude-desktop, codex, cursor, gemini, opencode, vscode, windsurf, zed. User-scope clients whose config directory is missing are skipped (treated as "not installed"). Codex stores all servers in one global ~/.codex/config.toml, so cartog writes a per-project [mcp_servers.cartog-<slug>-<hash8>] section. Idempotent: existing servers in each file are preserved.

Known limitation: configs containing JSON-with-comments (JSONC) are left untouched and reported as skipped. Configure those clients manually using the snippets below.

Bootstrap sequence

Two commands to start; the third is optional.

cartog init                  # 1. scaffold .cartog.toml (config only)
cartog index                 # 2. build the code graph

cartog ide                   # optional — wire MCP into installed editors

Edit .cartog.toml between steps 1 and 2 to change DB path or embedding provider before any heavy work runs. CLI-only users stop after step 2; run cartog ide only if you want cartog wired into MCP-aware editors.

Manual setup (per client)

Each block below shows the cartog ide one-liner that writes the right file, plus the manual JSON / TOML if you prefer to edit by hand.

Claude Code — project .mcp.json + user ~/.claude/settings.json
cartog ide --client claude-code
# or:
claude mcp add cartog -- cartog serve --watch                       # user scope
claude mcp add --scope project cartog -- cartog serve --watch       # project scope

Manual:

{
  "mcpServers": {
    "cartog": { "command": "cartog", "args": ["serve", "--watch"] }
  }
}

Only Claude Code gets --watch by default — other clients ship plain ["serve"]. Agent-driven flows churn files faster than human-driven editor flows, so the in-process file watcher pays off. Drop it with cartog ide --no-watch.

Cursor — project .cursor/mcp.json
cartog ide --client cursor

Manual:

{
  "mcpServers": {
    "cartog": { "command": "cartog", "args": ["serve"] }
  }
}
Codex CLI — user-global ~/.codex/config.toml
cartog ide --client codex

Codex stores all MCP servers in this one user-global file (no per-project config), so cartog ide writes a per-project [mcp_servers.cartog-<slug>-<hash8>] section.

[mcp_servers.cartog]
command = "cartog"
args = ["serve"]
Windsurf~/.codeium/windsurf/mcp_config.json
cartog ide --client windsurf
{
  "mcpServers": {
    "cartog": { "command": "cartog", "args": ["serve"] }
  }
}
VS Code (Copilot).vscode/mcp.json
cartog ide --client vscode

Note: top-level key is servers, not mcpServers.

{
  "servers": {
    "cartog": { "type": "stdio", "command": "cartog", "args": ["serve"] }
  }
}
Zed~/.config/zed/settings.json
cartog ide --client zed
{
  "context_servers": {
    "cartog": { "command": "cartog", "args": ["serve"] }
  }
}
OpenCode~/.config/opencode/opencode.json
cartog ide --client opencode
{
  "mcp": {
    "cartog": {
      "type": "local",
      "command": ["cartog", "serve"],
      "enabled": true
    }
  }
}
Gemini CLI~/.gemini/settings.json
cartog ide --client gemini
{
  "mcpServers": {
    "cartog": { "command": "cartog", "args": ["serve"] }
  }
}
Claude Desktopclaude_desktop_config.json
cartog ide --client claude-desktop

macOS: ~/Library/Application Support/Claude/. Windows: %APPDATA%\Claude\. Restart Claude Desktop after editing.

{
  "mcpServers": {
    "cartog": { "command": "cartog", "args": ["serve"] }
  }
}
Any other MCP client

Point your client at cartog serve over stdio. Command: cartog, args: ["serve"].

Teach your agent to use cartog

Wiring MCP is half the job. The other half is telling the LLM when to prefer cartog over grep + read. Drop the snippet from docs/agent-snippet.md into your project's AGENTS.md, CLAUDE.md, .cursor/rules/, or equivalent, and the agent will route navigation questions through cartog's 13 MCP tools instead of flooding context with raw text.

Maps the natural-language question to the right tool:

  • "where is X defined?" → cartog_search
  • "who calls / imports / inherits X?" → cartog_refs
  • "what does X call?" → cartog_callees
  • "what breaks if I change X?" → cartog_impact
  • "find code about <concept>" → cartog_rag_search
  • "orient me in this repo" → cartog_map

Falls back to grep / Read for string literals, comments, config values, or anything outside the indexed root.

cartog index <path>

Build or update the code graph. Run this first, then again after code changes.

cartog index .              # index current directory
cartog index src/           # index a subdirectory
cartog index . --force      # full re-index
cartog index . --no-lsp     # heuristic-only (~1-4s)

Example output

Indexed 70 files (0 skipped, 0 removed)
  697 symbols, 1921 edges (1019 resolved)
  1 files in unsupported languages not indexed (1 .toml)

Incremental by default — skips unchanged files (git + SHA-256), and within changed files, uses Merkle-tree diffing to update only modified symbols. The LSP pass skips edges already classified as unresolvable (typo, dyn dispatch, macro) or external (stdlib, deps, node_modules); both auto-retry when a matching symbol is added in-tree. --force resets those markers for a clean retry.

Files in unsupported languages are reported, not silently dropped: on a mixed repo the summary adds a line like 12 files in unsupported languages not indexed (8 .dart, 4 .swift) (also as files_unsupported / unsupported_by_ext under --json).

Find symbols by partial name. Results ranked: exact match → prefix → substring.

cartog search validate                   # prefix + substring match
cartog search validate --kind function   # functions only
cartog search config --file src/db.rs    # scoped to one file
cartog search parse --limit 5            # cap results

Example output

function  validate           api/v1/auth.py:16
function  validate_token     auth/tokens.py:38
function  validate_request   utils/helpers.py:16
function  validate_login     validators/user.py:41
function  validate_email     validators/common.py:15
method    _validate_payment  services/payment/processor.py:122
document  Validate           README.md:8

Available --kind values: function, class, method, variable, import, interface, enum, type-alias, trait, module, document.

cartog outline <file>

Show all symbols in a file with types, signatures, and line ranges. Use this instead of reading a file when you need structure.

cartog outline auth/tokens.py

Example output

from datetime import datetime, timedelta  L3
from typing import Optional  L4
from models.user import User  L7
from config import SECRET_KEY, TOKEN_EXPIRY  L9
class TokenError  L12-15
class ExpiredTokenError  L18-21
function generate_token(user: User, expires_in: int = TOKEN_EXPIRY) -> str  L30-35
function validate_token(token: str) -> Optional[User]  L38-52
function refresh_token(old_token: str) -> str  L60-64
function revoke_token(token: str) -> bool  L67-73

cartog refs <name>

All references to a symbol — calls, imports, inherits, type references.

cartog refs UserService                  # all reference types
cartog refs validate_token --kind calls  # only call sites

Example output (cartog refs validate_token)

imports  ..auth.tokens     middleware/auth_mw.py:7
calls    auth_middleware   middleware/auth_mw.py:28
imports  auth.tokens       auth/service.py:5
calls    get_current_user  auth/service.py:44
calls    change_password   auth/service.py:52
imports  .tokens           auth/__init__.py:4
calls    refresh_token     auth/tokens.py:62

Available --kind values: calls, imports, inherits, references, raises, implements, type-of.

cartog callees <name>

Find what a function calls — answers "what does this depend on?".

cartog callees validate_token

Example output

lookup_session    auth/tokens.py:45
TokenError        auth/tokens.py:47
datetime.utcnow   auth/tokens.py:49
ExpiredTokenError auth/tokens.py:50

cartog impact <name>

Transitive impact analysis — follows the caller chain up to N hops (default 3).

cartog impact validate_token --depth 3

Example output (indentation shows hop depth)

  imports  middleware/auth_mw.py:7
  calls    auth_middleware           middleware/auth_mw.py:28
  imports  auth/service.py:5
  calls    AuthService.get_current_user  auth/service.py:44
  calls    AuthService.change_password   auth/service.py:52
  calls    refresh_token             auth/tokens.py:62
    calls  auth_required.wrapper     auth/middleware.py:21
    calls  get_current_user          auth/middleware.py:61

Answers "what breaks if I change this?".

cartog hierarchy <class> [--mermaid]

Show inheritance relationships — both parents and children. Add --mermaid for a graph TD diagram you can paste into a PR description, doc, or mermaid.live.

cartog hierarchy AuthService
cartog hierarchy AuthService --mermaid

Example output

AuthService -> BaseService
AdminService -> AuthService

With --mermaid

graph TD
    AuthService["AuthService"] --> BaseService["BaseService"]
    AdminService["AdminService"] --> AuthService["AuthService"]

cartog deps <file> [--mermaid]

List symbols imported by a file — answers "what does this file depend on?". Add --mermaid for a graph LR diagram rooted at the file.

cartog deps auth/service.py
cartog deps auth/service.py --mermaid

Example output

Optional         L3
validate_token   L5
generate_token   L5
revoke_token     L5
User             L6
get_logger       L7

With --mermaid

graph LR
    auth_service_py["auth/service.py"]
    auth_service_py --> validate_token["validate_token (L5)"]
    auth_service_py --> generate_token["generate_token (L5)"]
    auth_service_py --> User["User (L6)"]

cartog stats [--savings]

Summary of the index — file count, symbol count, edge resolution rate. On an unindexed repo all counts are 0 and the output ends with a hint to run cartog index .. Pass --savings to show per-tool query counts and estimated tokens saved instead (or use the cartog savings alias).

cartog stats
cartog stats --savings

Example output

Files:    70
Symbols:  697
Edges:    1921 (1019 resolved)
Languages:
  python: 69 files
  markdown: 1 files
Symbols by kind:
  import: 256
  method: 217
  function: 90
  variable: 80
  class: 52

cartog savings

Shows tokens used by cartog vs an equivalent grep+read flow, plus the saved delta and a per-tool call-count breakdown. Visible alias of cartog stats --savings; shipped as a top-level verb so the retention hook is one keystroke away.

cartog savings
cartog --json savings

Example output

cartog · my-project · 5 queries

████████░░  ~83% tokens saved

Without cartog    ~8.5k tokens   (~1700 / query)
With cartog       ~1.4k tokens   (~280 / query)
──────────────────────────────────────────────
Saved             ~7.1k tokens   (~1420 / query)

By tool (call counts):
     2  search
     1  impact
     1  map
     1  refs

Baseline: ~1700 tokens for an equivalent grep+read sweep vs cartog's ~280.
Measured across 13 benchmark scenarios (see crates/cartog/benches/queries.rs).

The header reads cartog · <project> · <N> queries. By tool lists call counts — every tool uses the same flat baseline (1,420 tokens saved per call), so the breakdown shows which navigation patterns you rely on, not which tool saved the most.

Only queries returning a non-empty result count toward the totals. Empty-index calls, typo'd symbol names, and outline against missing files are skipped so the figure reflects real work.

Data comes from a local query_log table inside .cartog/db.sqlite. Nothing leaves the machine; no query payloads are recorded — only the tool name, call surface (cli / mcp), and a timestamp. Secondary read-only MCP attaches can't write, so multi-MCP-server setups under-report secondary traffic rather than double-counting it.

cartog doctor

Validate that all requirements are met and everything is working. Checks git repo, config, database, embedding provider, and reranker.

cartog doctor                 # check all requirements
cartog --json doctor          # structured JSON output

Example output

  [+] git: git repository at /your/repo
  [+] config: loaded from /your/repo/.cartog.toml
  [+] database: 70 files, 697 symbols at .cartog/db.sqlite
  [+] embedding: local model cached
  [+] reranker: local model cached
  [+] remote: not configured (local-only)

All 6 checks passed

Each check reports OK, Warn, or Error. Exits with code 1 if any check is an error. Run this when commands fail unexpectedly or after first setup.

cartog map

Token-budget-aware codebase summary — file tree + top symbols ranked by reference count. Add --mermaid for a graph TD rooted at "Repo"; the token budget still applies (renderer stops adding nodes before it overflows).

cartog map                    # default 4000 tokens
cartog map --tokens 2000      # compact
cartog map --tokens 8000      # detailed
cartog map --mermaid          # paste-into-PR diagram

Example output (truncated)

# Codebase Map (70 files)

  README.md
  api/v1/auth.py
  api/v1/payments.py
  api/v2/auth.py
  app.py
  auth/middleware.py
  auth/service.py
  auth/tokens.py
  ...

With --mermaid (truncated)

graph TD
    repo["Repo"]
    repo --> README_md["README.md"]
    repo --> auth_service_py["auth/service.py"]
    repo --> auth_tokens_py["auth/tokens.py"]
    auth_tokens_py --> auth_tokens_py__validate_token["validate_token (function)"]
    auth_tokens_py --> auth_tokens_py__generate_token["generate_token (function)"]
    ...

--json wins over --mermaid when both are passed.

cartog changes

Show symbols affected by recent git changes.

cartog changes                    # last 5 commits + working tree
cartog changes --commits 10       # last 10 commits
cartog changes --kind function    # only functions

Example output

20 files changed in last 5 commits, 2 symbols affected

README.md:
  document webapp_py# webapp_py       L1-7
  document Validate## Validate        L8-13

cartog config

Print the resolved configuration (merged defaults, .cartog.toml, and env overrides). Useful for verifying [rag] tuning, watch debounce, and provider selection.

cartog config              # human-readable
cartog config --json       # JSON for scripts

Example output (truncated)

Config file: /your/repo/.cartog.toml
Database:    /your/repo/.cartog/db.sqlite

[embedding]
  provider:          local (default)
  model:             -
  dimension:         -

[embedding.ollama]
  base_url:          http://localhost:11434 (default)
  model:             nomic-embed-text (default)
  ...

cartog watch

Watch for file changes and auto-re-index. Keeps the graph fresh during development.

cartog watch                       # watch CWD
cartog watch src/                  # watch subdirectory
cartog watch --rag                 # also auto-embed
cartog watch --rag --rag-delay 60  # embed after 60s idle
cartog watch --debounce 10         # 10s debounce window
cartog watch --json                # NDJSON event stream

Refuses to start if another watch holds the lock for this database — fail-fast prevents two writers stomping each other:

Error: another cartog process holds the watch lock for this database
       (slot watch-a902bb89f9a6b484, PID 64311); stop it before running `cartog watch`

cartog serve

Start cartog as an MCP server over stdio. No banner — stdio is reserved for JSON-RPC traffic between the client and the server. Run cartog stats in another shell to confirm it's up; role: primary means the writer, role: read-only means an attached secondary.

cartog serve                  # MCP server only
cartog serve --watch          # + background file watcher
cartog serve --watch --rag    # + watcher + auto RAG

cartog init

Scaffold a .cartog.toml template in the current project. That's all it does — config only, no editor wiring, no indexing. The next-steps hint points at cartog ide and cartog index.

cartog init                  # scaffold .cartog.toml
cartog init --dry-run        # preview without writing

Example output (already-initialized project, --dry-run)

+ .cartog.toml (/your/repo/.cartog.toml): already present, left untouched

Dry run only. Re-run without --dry-run to apply.

Never overwrites an existing .cartog.toml. Re-running is a no-op (still prints the next-steps hint).

cartog ide / cartog install

Wire cartog serve into one or all MCP-compatible editors. Two shapes:

  • cartog install <client>... — positional, brew/npm/pip convention, always non-interactive. Safe for scripts and agents.
  • cartog ide — original, supports an interactive multi-select picker (bare) and the long-form flags below.
cartog install cursor                 # one editor
cartog install cursor vscode codex    # several at once
cartog install                        # all detected editors
cartog install cursor --dry-run       # preview

cartog ide                            # interactive picker (TTY only)
cartog ide --client cursor            # single client via flag
cartog ide --scope project            # only project-scoped (.mcp.json, .cursor/, .vscode/)
cartog ide --dry-run                  # preview with before/after diff
cartog ide --no-watch                 # drop --watch from Claude Code args

Example output (cartog ide --client cursor --dry-run)

+ cursor (project, /your/repo/.cursor/mcp.json): would create
  --- after ---
    {
      "mcpServers": {
        "cartog": {
          "command": "cartog",
          "args": ["serve"]
        }
      }
    }

1 clients: 1 created, 0 updated, 0 unchanged, 0 skipped, 0 errors
Dry run only. Re-run without --dry-run to apply.

Example output (cartog install cursor vscode --dry-run)

+ cursor (project, /your/repo/.cursor/mcp.json): would create
  --- after ---
    {
      "mcpServers": {
        "cartog": { "command": "cartog", "args": ["serve"] }
      }
    }
+ vscode (project, /your/repo/.vscode/mcp.json): would create
  --- after ---
    {
      "servers": {
        "cartog": { "type": "stdio", "command": "cartog", "args": ["serve"] }
      }
    }

2 clients: 2 created, 0 updated, 0 unchanged, 0 skipped, 0 errors
Dry run only. Re-run without --dry-run to apply.

Clients: claude-code (project + user), claude-desktop, codex, cursor, gemini, opencode, vscode, windsurf, zed. See the Bootstrap sequence for the recommended verb order.

cartog self <update|version|rollback|migrate-db>

Manage the installed cartog binary in place: upgrade, inspect, or roll back. cargo install cartog users get an exit-3 refusal pointing at cargo install cartog --force; release-tarball installs swap atomically with SHA256 verification and a <bin>.old rollback slot.

cartog self update              # upgrade to the latest stable
cartog self update --check      # exit 1 if outdated, 0 if current
cartog self version             # target + install source + last check
cartog self rollback            # restore the previous binary
cartog self migrate-db          # move legacy .cartog.db into .cartog/db.sqlite
cartog self migrate-db --dry-run # preview the move without touching disk

Example output (cartog self version)

cartog 0.18.0
  target:            aarch64-apple-darwin
  install source:    release-tarball
  last update check: 2026-05-27T14:50:47Z

Auto-check runs at most once per 24h on interactive sessions; suppressed under CARTOG_NO_UPDATE_CHECK=1, non-TTY stdout, and inside cartog serve/watch. migrate-db refuses to overwrite an existing .cartog/db.sqlite, refuses to run while a peer process holds the lock for this project's database (a peer on an unrelated project does not block it), and refuses symlinked sources. See docs/updates.md for the full exit-code matrix and state file location.

cartog completions <shell>

Generate shell completion scripts for bash, zsh, fish, powershell, or elvish.

cartog completions zsh   > ~/.zfunc/_cartog
cartog completions bash  > /usr/local/etc/bash_completion.d/cartog
cartog completions fish  > ~/.config/fish/completions/cartog.fish

Example output (first lines of cartog completions zsh)

#compdef cartog

autoload -U is-at-least

_cartog() {
  ...

cartog manpage

Emit a roff-formatted man page on stdout. Intended for packagers and distro maintainers.

The output filename must end in .1 (the section-1 extension man looks for) and the target directory must exist:

sudo mkdir -p /usr/local/share/man/man1
cartog manpage | sudo tee /usr/local/share/man/man1/cartog.1 > /dev/null
man cartog

Example output (first lines)

.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH cartog 1  "cartog 0.18.0"
.SH NAME
cartog \- Map your codebase. Navigate by graph, not grep.
  ...

JSON Output

All commands accept --json for structured output:

cartog --json refs validate_token
cartog refs validate_token --json    # equivalent
cartog --json stats

Token Budget

All query commands accept --tokens N to limit output:

cartog --tokens 500 search validate
cartog --tokens 200 outline src/db.rs

Uses len / 4 byte-to-token approximation. Ignored when --json is used.

Supported Languages

LanguageExtensionsSymbolsEdges
Python.py, .pyifunctions, classes, methods, imports, variablescalls, imports, inherits, raises, type refs
TypeScript.ts, .tsxfunctions, classes, methods, imports, variablescalls, imports, inherits, type refs, new
JavaScript.js, .jsx, .mjs, .cjsfunctions, classes, methods, imports, variablescalls, imports, inherits, new
Rust.rsfunctions, structs, traits, impls, importscalls, imports, inherits, type refs
Go.gofunctions, structs, interfaces, importscalls, imports, type refs
Ruby.rbfunctions, classes, modules, importscalls, imports, inherits, raises, rescue types
Java.javaclasses, interfaces, enums, methods, importscalls, imports, inherits, raises, type refs, new
PHP.phpclasses, interfaces, traits, enums, methods, functions, importscalls, imports, inherits, implements, references (traits, new)
Dart.dartclasses, mixins, extensions, enums, methods, functions, typedefs, importscalls, imports, inherits, implements, type refs
Markdown.mddocument sections (chunked by heading)

Performance

Indexing: 69 files / 4k LOC in 95ms (Python fixture, release build).

Query typeLatency
outline8-14 μs
hierarchy8-9 μs
deps25 μs
stats32 μs
search81-102 μs
callees177-180 μs
refs258-471 μs
impact (depth 3)2.7-17 ms

Edge Resolution: Heuristic vs LSP

ProjectLanguageHeuristicWith LSPTime
TS microservice (230 files)TypeScript37%81%13s
Vue.js SPA (739 files)Vue/TS/JS31%72%25s
Rust CLI (358 files)Rust25%44%72s
PHP webapp fixture (25 files)PHP82%84%22s