LOOM

LOOM

A git-native decision journal that uses a local LLM to infer and store the rationale behind code changes, providing MCP tools for AI coding tools to query commit history.

Category
Visit Server

README

Loom

A git-native decision journal for AI-assisted development.

Loom watches your commit history, uses a local LLM to infer why things changed (not just what), and stores that narrative as a git-tracked, Obsidian-compatible markdown vault — so any MCP-compatible AI coding tool (Claude Code, Cursor, Kiro, Windsurf, …) picks up your project's real history the moment it's pointed at the repo.

No API keys. No GPU. No cloud. Everything runs on local CPU inference via Ollama.

The problem

AI coding tools reset context between sessions and between tools. CLAUDE.md / .cursorrules files are static, manually maintained, and rot — they capture "current state" at best, never why we got here or what we tried and abandoned. Switching tools mid-project means re-explaining history from scratch.

Existing memory tools (Mem0, Supermemory, agentmemory, …) extract memory from what was said in a chat. Loom extracts memory from what actually happened in the codebase — via git history, whether or not any AI was involved in writing the code. That's why it also works retroactively on years-old repos (loom backfill) and for teammates who don't use AI tools at all. Loom is the commit-narrative layer the conversation-memory tools are missing; it can feed them, not replace them.

How it works

git commit
   │
   ▼
post-commit hook (thin, async — never slows your commit)
   │
   ▼
capture daemon (localhost)
   │  heuristic noise filter: typos, wip, formatting, lockfiles → skipped
   │  before any model call
   ▼
local LLM via Ollama (llama3.2:3b, CPU-only)
   │  infers: what changed, why, what was abandoned, significance,
   │  whether it supersedes an earlier decision
   ▼
.loom/entries/2026-07-16-switched-storage-from-json-to-sqlite.md
   ← YAML frontmatter + markdown + [[wikilinks]]; filename is a readable
     slug of the decision, so Obsidian graph labels read as decisions
   │
   ├─→ Obsidian: open .loom/ as a vault (graph view, backlinks, search — free)
   └─→ MCP server (HTTP, localhost): any AI tool queries the history directly

Each entry is simultaneously a machine-queryable record and a readable journal note:

---
date: 2026-07-16T05:52:17Z
commit: ae96be6
files: [store.js]
category: architecture
significance: 0.7
supersedes: ["2026-07-16-persist-urls-to-a-json-file"]
tags: [url-shortener, http-server, sqlite]
---

## What changed
Switched storage from JSON file to SQLite...

## Why
The previous JSON file-based storage ([[2026-07-16-persist-urls-to-a-json-file]]) caused every
write operation (including redirects) to rewrite the entire file...

Install

Requirements: Node ≥ 18, git, Ollama with a small model pulled:

ollama pull llama3.2:3b

Then:

git clone https://github.com/Palak11245/LOOM.git && cd LOOM
npm install
npm link          # makes `loom` available globally

Quickstart

In any git repo:

loom init

This installs the post-commit hook, creates the .loom/ vault, verifies Ollama and the model, starts the capture daemon and the MCP server, and prints ready-to-paste MCP config:

Claude Code (run inside this repo):
  claude mcp add --transport http loom http://127.0.0.1:4578/mcp

Cursor / Windsurf / other JSON-config tools:
  { "mcpServers": { "loom": { "url": "http://127.0.0.1:4578/mcp" } } }

Kiro / stdio-only tools (.kiro/settings/mcp.json):
  { "mcpServers": { "loom": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://127.0.0.1:4578/mcp", "--allow-http"]
  } } }

Then just commit as usual. Meaningful commits become journal entries; noise doesn't. CPU inference takes 20–40s+ per commit, fully in the background — git commit returns instantly.

Journal an existing repo

loom backfill              # walk the whole git log, oldest first
loom backfill --limit 20   # or just part of it; re-run to continue

Backfill is idempotent and uses each commit's original date, so a years-old repo gets a correctly-dated decision history on day one.

Other commands

loom status    # daemon health, MCP health, entry count, last capture
loom daemon    # run the capture daemon in the foreground
loom serve     # run the MCP server in the foreground

The MCP tools

Tool What it answers
loom_get_recent_decisions(limit) "What's been decided lately?"
loom_search_history(query) "Why did we do X?" / "Did we ever try Y?"
loom_get_context_for_file(path) "What's the story of this file?"
loom_get_superseded_decisions() "What did we replace, and why?"

Search is plain keyword scoring over the markdown — no vector DB, no embeddings, nothing to babysit.

The noise filter

If every commit generated an entry, the vault would be useless within a week. Loom filters twice:

  1. Heuristics (no model call): typo/wip/formatting/lint messages, lockfile-only and generated-file-only changes, merge commits, tiny diffs, vault-only commits.
  2. Model judgment: every surviving commit gets a significance_score (0–1) and a category (architecture | dependency-change | approach-change | bugfix | trivial | abandoned-path). trivial entries are dropped; the score threshold is configurable per repo in .loom/config.json.

Inference runs at temperature 0, so the same commit always gets the same verdict.

Honest limitations (v1)

  • supersedes detection is weak. A 3–4B CPU-only model reliably narrates what/why for a single commit, but often misses "this contradicts a decision from three weeks ago." Expect to add some supersedes links manually in Obsidian — the vault is just markdown, so that's a one-line edit. An inherent tradeoff of the zero-cost/zero-GPU constraint.
  • Category labels are loose at the edges. Feature additions tend to land on approach-change; borderline commits (e.g. a pure rename) sometimes get journaled when a human wouldn't bother.
  • Latency is real. 45–160s per commit on a typical laptop CPU depending on diff size. It's asynchronous and never blocks git, but a large backfill is an overnight job.

Configuration

.loom/config.json (created by loom init):

{
  "model": "llama3.2:3b",        // any Ollama model tag
  "port": 4577,                  // capture daemon
  "mcpPort": 4578,               // MCP server
  "significanceThreshold": 0,    // drop entries scored below this
  "skipTrivialCategory": true,   // drop category=trivial entries
  "recentEntriesInPrompt": 8,    // continuity window for the model
  "maxDiffChars": 8000           // truncate huge diffs before inference
}

Runtime files (daemon.log, skipped.log, pid files, .obsidian/) are auto-gitignored; entries and config are committed with your repo, so your team gets the journal by cloning.

What's deliberately not here (v1)

No cloud version, no team sync, no auth, no dashboard (Obsidian is the viewer), no fine-tuned or paid models, no vector search, no non-git VCS support.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured