GitLoom

CLI

The gitloom binary — memory on your own machine, and an MCP server for your editor.

The CLI keeps memory in a git repository on your machine. Same engine as the hosted API, no network on the read path, and every operation is also available to an assistant over MCP.

Install

curl -fsSL https://gitloom.cloud/install.sh | sh   # current: 0.3.0

One static binary, no runtime dependency. The installer verifies a checksum and puts it in /usr/local/bin if that is writable, ~/.local/bin otherwise — override with GITLOOM_PREFIX.

Or take an archive directly from https://gitloom.cloud/dl/: builds exist for macOS (Apple silicon and Intel), Linux (x86-64 and arm64) and Windows, with SHA256SUMS alongside them.

The local CLI is licensed software, on the [Starter plan or above](/docs/pricing.html#starter-is-the-floor-for-running-the-cli-locally). Create a licence key at [app.gitloom.cloud](https://app.gitloom.cloud/) and activate once:
gitloom license activate gll_...

Activation exchanges the key for a signed token that is verified offline, so day-to-day use needs no network. It renews itself when you are online and nearing expiry. version, license and --help work without a licence.

Which memory?

You will have more than one — personal, per-project, a scratch one. A command resolves its memory in this order, and gitloom repo where tells you which and why:

  1. --repo <path>
  2. GITLOOM_REPO
  3. a memory at or above the working directory — the way git finds a repository
  4. the one selected with gitloom repo use
gitloom init ~/memories/work        # creates, registers and selects it
gitloom init ~/memories/personal
gitloom repo list
#   personal  ~/memories/personal
# * work      ~/memories/work

gitloom repo use personal           # change the default
gitloom repo where                  # which one would this command use?

Standing anywhere inside a memory selects it, so a project that keeps its memory alongside the code needs no flags and no configuration.

## Writing and reading
# store a memory (body on stdin)
echo "Maya moved to Lisbon in March 2026." |
  gitloom write -p facts/people/maya.md --tags person -m "maya moved"

# ranked search over structure and full text
gitloom search "where does maya live"

# one memory, or one section of one
gitloom get facts/people/maya.md
gitloom section facts/people/maya.md#housing

Every command takes --json when you want to pipe it somewhere.

A memory's ## headers are indexed as their own nodes, which makes the store a navigable table of contents rather than a pile of files. That is the PageIndex loop: descend the tree, then pull only the section you decided you wanted.

gitloom tree                       # whole table of contents
gitloom tree facts/db --depth 2    # one subtree
gitloom section facts/db/replication.md#failover

It matters at scale. Retrieving whole documents and hoping the answer is inside them costs context and buries the sentence you needed; descending to a section costs two cheap calls.

Following relationships

Memories link to each other with [[wikilinks]] and labelled relations.

gitloom related facts/people/maya.md
gitloom related facts/people/maya.md --label spouse
gitloom related facts/db/replication.md --direction in --depth 2

--direction in finds what points at a memory — the question "what else depends on this?" that a search cannot answer. Depth beyond 1 pulls a cluster rather than a neighbour list; useful deliberately, expensive as a habit.

Semantic search only sees memories whose retrieval cues have been embedded. Writing a memory queues its cues; draining that queue is explicit:

gitloom embed --stats     # how much is covered
gitloom embed             # embed what is pending

Querying the index directly

The index is a SQLite database derived entirely from git — nodes, the section tree, an FTS5 table, cue vectors, the link graph. gitloom rebuild recreates it from scratch, so reading it is safe and writing to it is refused by the database itself.

gitloom index stats
gitloom index schema nodes
gitloom index query "SELECT tier, count(*) FROM nodes WHERE kind='file' GROUP BY tier"
## Ingestion and answering

ingest turns conversations into memories: it extracts what is durable, places it in a tier, folds it into an existing memory where it updates one rather than repeating it, and attaches retrieval cues.

gitloom ingest sessions.json
cat chat.jsonl | gitloom ingest --provider openai --model gpt-5

Input is a JSON array of sessions, or one per line:

{"id":"s1","date":"2026-03-04T10:00:00Z","turns":[
  {"role":"user","content":"I moved to Lisbon"},
  {"role":"assistant","content":"How is it?"}]}

answer retrieves and has a model write the sentence:

gitloom answer "where does Maya live?" --evidence

Both need a model, and both use your provider key — ANTHROPIC_API_KEY, OPENAI_API_KEY, and so on, or --base-url for a local server. Your licence is a flat fee; inference is between you and your provider.

MCP server

Every operation above is exposed to an assistant over the Model Context Protocol. The tools are generated from the same definitions the CLI dispatches through, so the two cannot drift apart. See MCP for the full picture, including the hosted server for a namespace instead of a local repository.

gitloom mcp --repo ~/memory              # stdio: what editors launch
gitloom mcp --read-only                  # search and recall, no writes
gitloom mcp --http 127.0.0.1:7000 --token "$(openssl rand -hex 16)"

Connecting an agent

gitloom install writes the configuration in each host's own shape:

gitloom install claude-code      # print it
gitloom install codex --write    # write it
gitloom install opencode --project

Supported: claude-code, openclaw, opencode, codex, hermes. All of them speak MCP, so there is no plugin to install — GitLoom already serves the protocol and this just points them at it.

To use a hosted namespace instead of a memory on this machine, add --cloud. That points the host at @gitloomhq/mcp via npx, which needs GITLOOM_API_KEY and no local repository at all:

export GITLOOM_API_KEY=gl_live_...
gitloom install claude-code --cloud --write

Claude Desktop, in claude_desktop_config.json:

{
  "mcpServers": {
    "gitloom": {
      "command": "gitloom",
      "args": ["mcp", "--repo", "/absolute/path/to/memory"]
    }
  }
}
Model-driven tools (`ingest`, `answer`) appear only when a model is configured via `GITLOOM_MODEL` and a provider key, so a client listing tools sees what will actually work rather than operations that fail on every call.

Working with the cloud

The local CLI and the hosted API are separate memories. gitloom cloud reaches the hosted one, authenticated with an API key in GITLOOM_API_KEY — separate from your licence, so either can be rotated without disturbing the other.

gitloom cloud whoami
gitloom cloud namespaces --create staging
gitloom cloud recall "where does maya live" --namespace staging
gitloom cloud push --namespace staging --dry-run

push uploads finished memories as they are — ingestion is not re-run, no model is called, and the text you curated locally is what lands.

Environment

Variable Purpose
GITLOOM_API_KEY API key for gitloom cloud
GITLOOM_MODEL model for ingest, answer, and the MCP tools that need one
GITLOOM_PROVIDER provider name (default anthropic)
GITLOOM_BASE_URL OpenAI-compatible endpoint, overrides the provider
GITLOOM_API API base URL, for pointing at a different deployment
GITLOOM_REPO which memory to use, when not passing --repo
GITLOOM_HOME where the licence and registry live (default: your config dir)