Skip to main content

A code intelligence platform that turns repositories, docs, and tickets into one searchable graph.

Project description

Loom

A persistent symbol index for AI coding agents. Agents find functions instantly. Agents write summaries as they work. The cache gets richer every session — zero LLM cost from Loom's side.

What Loom is

Loom indexes your codebase into a local SQLite database using tree-sitter. It extracts functions, classes, methods, and call relationships across all languages. Agents query it to skip file exploration and read only what they need. When an agent understands a function, it writes a summary back — the next agent gets it for free.

Core loop:

loom analyze .              # tree-sitter indexes all symbols → ~/.loom/projects/myrepo.db
search_code("login")        # instant: {name, path, line, summary, signature}
get_context(node_id)        # full picture: summary + callers + callees, one call
store_understanding(id, s)  # cache what you learned → returned on future searches

No Docker. No embeddings. No LLM calls from Loom. Pure tree-sitter + SQLite.

Why it matters

Every Claude Code / Cursor / Codex session starts by re-exploring the codebase: reading CLAUDE.md, grepping for functions, re-discovering structure. Loom eliminates that.

Repo Files Without Loom With Loom Reduction
replay-agent 35 Python ~22,112 tokens ~433 tokens 51× fewer
finpower 678 TS/TSX/Python/Go ~794,462 tokens ~527 tokens 1,507× fewer
  • Session 1: agent reads files, stores summaries → Loom gets smarter
  • Session 2+: summaries returned instantly → file reads skipped entirely
  • Compounding: every session makes Loom richer for every future agent

Installation

pip install loom-tool
# or with uv:
uv add loom-tool

Requirements: Python 3.10+. Tested on 3.10, 3.11, 3.12, 3.13, 3.14. No Docker. No external services.

Claude Code plugin

Anyone can install directly from GitHub:

/plugin marketplace add ddevilz/loom
/plugin install loom@loom-tool

Installs the MCP server (uvx --from loom-tool loom-mcp) and the /loom skill automatically.

Prerequisite: uv must be installed before the plugin can start the MCP server.

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
winget install astral-sh.uv

Recommended setup order:

  1. Install uv (above)
  2. /plugin marketplace add ddevilz/loom && /plugin install loom@loom-tool
  3. loom install — writes absolute uvx path into your MCP config (solves PATH issues on macOS/Linux)
  4. Restart Claude Code — tools appear

Quick start

cd loom
loom analyze .      # index the repo (~10s for 500 files)
loom install        # configure Claude Code, Cursor, Windsurf, Codex + git hook
loom serve          # start MCP stdio server

After loom install, MCP clients connect automatically. Claude Code sessions get the loom://primer resource loaded at startup.

Project-isolated databases

Loom auto-detects the git root and creates a per-project database. No flags needed.

~/.loom/projects/
  my-api.db          ← cd ~/projects/my-api && loom analyze .
  frontend.db        ← cd ~/projects/frontend && loom analyze .
  loom.db            ← cd ~/projects/loom && loom analyze .

~/.loom/loom.db      ← fallback when not inside a git repo

Override with LOOM_DB_PATH env var or --db flag.

CLI reference

Command Purpose
loom analyze <path> Index or refresh the graph for a repo
loom sync [--old-sha] [--new-sha] Incremental sync of changed files via SHA-256
loom context [-m module] Print ~200-token session primer (modules, hot functions, coverage)
loom serve Start MCP stdio server
loom install [--platform] [--list-plugins] Configure MCP for all detected AI tools + git hook
loom query <text> FTS5 / name search across nodes
loom blast-radius <target> Show transitive callers of a function
loom callers <target> Direct callers (one-hop incoming CALLS)
loom callees <target> Functions this target calls (one-hop outgoing CALLS)
loom communities Run Louvain community detection
loom dead-code Mark functions with no incoming CALLS
loom summaries [-n N] Show agent-written summaries, most recent first
loom savings [-n N] Token savings dashboard — totals + recent cache hits
loom stats Node/edge counts by kind
loom export Self-contained interactive HTML graph

MCP tools

Tool Purpose
search_code(query, limit) FTS5 search — returns summary + signature when cached
get_context(node_id, brief?, callers_limit?, callees_limit?) Full context packet: summary, signature, callers, callees, staleness. Use brief=True for metadata-only. Use callers_limit=0 / callees_limit=0 to skip traversal.
get_blast_radius(node_id, depth) Transitive callers via recursive CTE — each result includes summary
get_neighbors(node_id, depth, limit) All edges, both directions — each result includes summary
get_community(community_id, limit) All members of a community cluster — each result includes summary
shortest_path(from_id, to_id) Shortest directed path on CALLS subgraph — each hop includes summary
graph_stats(include_cohesion?) Node/edge counts by kind. include_cohesion=True adds per-cluster cohesion scores (0.0–1.0, < 0.2 = refactor candidate).
god_nodes(limit) Most-called functions (highest in-degree) — each result includes summary
store_understanding(node_id, summary, force?) Cache agent-generated summary permanently. Returns skipped: true if summary already fresh — no re-write needed.
store_understanding_batch(updates) Batch version, max 50 per call
get_savings() Token savings report — all-time totals + 10 recent hits
start_session(agent_id) Register session start, returns session_id
get_delta(previous_session_id) What changed since last session (changed + deleted nodes)
suggest_questions(limit) Graph-topology investigation priorities: dead code, bridge nodes, missing summaries, low-cohesion clusters
get_surprising_connections(limit) Non-obvious cross-module CALLS edges — returns caller_summary and callee_summary per result
get_status() Live indexing progress + DB health
get_work_plan() Prioritized next actions: DOCUMENT / INVESTIGATE / EXPLORE / NOTHING

MCP resources:

Resource Purpose
loom://primer ~200-token codebase overview — load at session start
loom://savings Token savings report — totals + recent cache hits

Node ID format

{kind}:{relative-path}:{symbol}

function:src/auth.py:validate_token
method:src/models/user.py:User.save
class:src/models/user.py:User
file:src/auth.py

Agent workflow

# Session start — register first, then orient
start_session(agent_id="claude-code")    # store returned session_id

# Or if returning:
get_delta(previous_session_id="<id>")   # only what changed since last time

resource = read("loom://primer")         # orient: modules, hot functions, coverage
suggest_questions()                      # dead code, bridge nodes, missing summaries

# Finding code
results = search_code("validate token") # summary + signature included
# If results[0].summary → read summary, skip file

# Before reading any file
ctx = get_context("function:src/auth.py:validate_token")
# Returns callers, callees, summary, staleness — often enough to reason without reading

# After understanding a function
store_understanding(
    node_id="function:src/auth.py:validate_token",
    summary="Validates JWT tokens, returns False if expired or signature invalid."
)
# Returns {"ok": true, "skipped": false} — written
# Returns {"ok": true, "skipped": true}  — already fresh, no re-write needed

How summaries work

Auto-summaries: loom analyze fills summaries from static metadata (params, return type, decorators) via tree-sitter. Coverage goes from 0% → ~80% on first analyze. No LLM.

Agent summaries: store_understanding stores a summary permanently with a summary_hash (snapshot of content_hash at write time).

  • If source changes → summary_stale: true in get_context → agent re-reads and updates
  • If source unchanged → store_understanding returns skipped: true → no duplicate writes
  • Pass force: true to overwrite regardless

Priority: Agent summaries are never overwritten by auto-summaries. Re-analyzing preserves agent work.

Plugin system

loom install uses a plugin registry. Built-in plugins: claude-code, cursor, windsurf, codex.

Add a custom platform without editing any source:

# ~/.loom/plugins/zed.py
from loom.cli.plugins import Plugin, register
from pathlib import Path

register(Plugin(
    name="zed",
    config_path=Path.home() / ".config" / "zed" / "mcp.json",
    config_key="mcpServers",
))
loom install --list-plugins   # see all registered plugins
loom install --platform zed   # install only for Zed

Session delta — how it works

Session 1:                     Session 2:
  start_session()                get_delta(previous_session_id)
  [work on auth.py]              → {changed: [2 fns], deleted: [], unchanged: 310}
  session_id stored              Only read the 2 changed functions. Skip the rest.

Delta uses updated_at on nodes — only bumped when content_hash changes. Safe against false positives from re-analyzing identical files.

Token savings tracking

Every search_code hit with a cached summary records how many tokens were saved (source line count × 15 — no extra deps, no index overhead).

loom savings          # CLI dashboard
Total tokens saved: 127,400
Cache hits: 847  (agent: 23  auto: 824)
agent = store_understanding summaries (provably skipped file reads)
auto  = metadata summaries from loom analyze

Inside Claude Code, call get_savings() MCP tool or load loom://savings resource for the same report.

search_code results include tokens_saved and summary_type per hit when a summary is cached.

Auto-indexing

When installed via the Claude Code plugin, Loom auto-indexes the current project on first session start — no manual loom analyze needed. If the DB is empty when the MCP server starts, indexing runs in the background while the session continues.

Supported languages

Code extraction (functions, methods, classes, calls): Python, TypeScript, TSX, JavaScript, JSX, Java

Indexed as file nodes: HTML, CSS, JSON, YAML, TOML, XML, INI, .env, .properties

Schema

Full DDL in src/loom/core/schema.sql. Two core tables:

nodes    -- id, kind, name, path, language, summary, summary_hash,
            token_count, content_hash, start_line, end_line, metadata, deleted_at, updated_at
edges    -- from_id, to_id, kind, confidence
savings  -- ts, node_id, query, tokens_saved, summary_type
sessions -- id, agent_id, started_at
meta     -- key/value counters (savings totals)

FTS5 virtual table nodes_fts indexes name + summary + path for full-text search. Sessions table tracks agent session timestamps for delta context.

Architecture

src/loom/
├── core/          # Node/Edge models, DB context, schema.sql
├── ingest/        # index_repo, sync_paths, tree-sitter parsers per language
├── analysis/      # communities (Louvain), coupling (git co-change), dead code
├── query/         # search, blast_radius, context packets, primer, delta
├── store/         # nodes CRUD, sessions, savings, FTS5 sync
├── mcp/           # FastMCP server (server.py), standalone entry point (run.py)
├── cli/           # typer commands
│   └── plugins/   # platform plugin registry (claude-code, cursor, windsurf, codex)
├── templates/     # graph.html — interactive export UI
└── data/          # loom-skill.md — Claude Code skill installed by loom install

Development

git clone https://github.com/ddevilz/loom
cd loom
uv sync
uv run pytest
uv run ruff check .
uv run mypy src/

License

MIT - Free for personal and commercial use

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

loom_tool-0.5.2.tar.gz (357.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

loom_tool-0.5.2-py3-none-any.whl (123.3 kB view details)

Uploaded Python 3

File details

Details for the file loom_tool-0.5.2.tar.gz.

File metadata

  • Download URL: loom_tool-0.5.2.tar.gz
  • Upload date:
  • Size: 357.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for loom_tool-0.5.2.tar.gz
Algorithm Hash digest
SHA256 2c73ed863a5fed31afa429f7406fe392bb5e5b7be23ae516702c72c5c91264a9
MD5 dceb42921d5f57e57f0eadaa79f81e1f
BLAKE2b-256 667119e11122701ba197ff2acd26ca47f865b7844b3ca5421a79e465f3a79abd

See more details on using hashes here.

Provenance

The following attestation bundles were made for loom_tool-0.5.2.tar.gz:

Publisher: publish-pypi.yml on ddevilz/loom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file loom_tool-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: loom_tool-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 123.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for loom_tool-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 48912a5e7eb551b09fa135f49ba968fe8ae79cd0c4167d7e188162202aa00d08
MD5 ab8dbff71e0beca3568ee7018e17a2a0
BLAKE2b-256 2ae2de0b1467b80beda28824bb317a80d1a02a5c6b0863bbd298bb86921e3155

See more details on using hashes here.

Provenance

The following attestation bundles were made for loom_tool-0.5.2-py3-none-any.whl:

Publisher: publish-pypi.yml on ddevilz/loom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page