Skip to main content
ClaudeWave

cross-project memory tool for AI agents

MCP ServersOfficial Registry1 stars0 forksPythonMITUpdated today
ClaudeWave Trust Score
95/100
Verified
Passed
  • Open-source license (MIT)
  • Actively maintained (<30d)
  • Clear description
  • Topics declared
  • Documented (README)
Last scanned: 9/11/2026
Install in Claude Code / Claude Desktop
Method: UVX (Python) · loci
Claude Code CLI
claude mcp add loci -- uvx loci
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "loci": {
      "command": "uvx",
      "args": ["loci"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Package name inferred from the repository name. Verify it exists on PyPI, or clone https://github.com/3M1RY33T/loci and follow its README.
Use cases

MCP Servers overview

# loci

<!-- mcp-name: io.github.3M1RY33T/loci -->

**Scoped memory for coding agents.** A router in front of two stores.

```
question ──▶ router ──▶ ┌── structure store   what calls what
             (no LLM)   └── episode store     what happened and why
                        └─▶ merged, cited answer   │
                            or ABSTAIN ────────────┘
```

Knowledge graphs hold structure but no prose, so they cannot answer *why did the
cookie get dropped*. Verbatim-recall systems hold prose but no call graphs, so
they cannot answer *what calls `run_agent_turn`*. Both make you name the
namespace when you **write**.

loci decides the scope when you **read**. One question path serves *"how does
auth work here"* and *"have I solved this in any project"* — only the size of
the scope set changes.

---

## The shape, in one picture

A street of independent shops. Each **shop** is one project — its own stock, its
own books, nothing pooled in a shared warehouse. Each keeps **two ledgers**:
what calls what, and what happened and why. They are read together or not at
all.

Shops wear overlapping **badges** — yours, this client's, that vendor's, this
monorepo's. A badge can cover shops at opposite ends of the street, which is why
they are labels rather than a hierarchy.

You never walk the street yourself. You ask the **dispatcher**, who knows only
which *uncommon* words are stocked where. They send you into at most three
shops, or say nobody here carries that and name who might.

Each shop also hangs a **signboard** naming what it *is* — repository, package,
command — and keeps a list of what it **reaches for**. Reading one against the
other is how the street answers *which of my shops buys from another*, which no
amount of asking the dispatcher ever could: that question is about the road
between two shops, and the dispatcher only knows what is stocked inside them.

One thing the street still lacks: **aisles** inside a shop, so a word found in a
test fixture does not count like the same word in shipped code.

---

## The problem it solves

Put every project in one index and the largest one wins regardless of the
question. Measured against a merged graph of ten real repositories:

| question | on-topic nodes returned |
|---|---|
| "why was the admin session cookie dropped on localhost?" | **18%** — 19 of 31 came from the biggest project |
| "what happens when a user clicks Save as ZIM?" | **2%** — 61 of 62 came from the biggest project |
| "how does the reserved landing step work?" | 98% — and the biggest project *was* the answer |

That third row is the trap. Merged retrieval looks excellent whenever the answer
happens to live in the largest corpus and collapses when it does not. It is the
same failure in both directions, visible in only one.

---

## Install

The distribution is **`loci-mem`**; the command, the import and the project are
all `loci`. PyPI's `loci` is an unrelated outlier-detection package abandoned in
2018 — the same split as `python-dateutil` installing as `dateutil`.

```bash
pipx install loci-mem                 # routing + lexical search, one dependency
pipx install 'loci-mem[all]'          # + graphify, local embeddings, MCP server
```

The base install pulls **`numpy`, and nothing else**. Routing, BM25 and the
char-gram matrix are a compiled Rust extension as of 0.6.0, so `scikit-learn`
(and `scipy` behind it), `rank-bm25` and `joblib` are gone. No torch, no vector
database, no model download unless you ask for one.

Wheels are published for macOS, Linux and Windows; installing from the sdist
builds from source and needs a Rust toolchain (1.75+).

| extra | adds |
|---|---|
| `graphify` | code-symbol extraction across ~18 languages |
| `embeddings` | local `bge-small` semantic ranking |
| `rerank` | cross-encoder reranking (opt-in per query) |
| `mcp` | the MCP server |

---

## Quickstart

```bash
pipx install 'loci-mem[all]'
loci setup             # scan, graph, index, embed, calibrate -- one pass
loci ask "why was the session cookie dropped on localhost?"
```

`setup` asks only what it cannot decide for you: which directories hold your
projects, whether to register the repositories it found that are not yours, and
whether to spend a one-time model download on semantic search. It ends by
running `doctor`, so whatever it could not cover is the last thing you read
rather than something you discover from a bad answer a week later.

Every prompt takes its default when stdin is not a terminal, so it is safe to
run unattended in a container or under an agent. `-y` does the same from a
terminal, and `--no-graphs` / `--no-embed` / `--no-calibrate` decide individual
steps up front.

The same thing by hand. The order is a dependency chain, not a preference:
graphs are what the index is built from, the index writes the chunks `embed`
encodes, and `calibrate` fits its semantic floor from those vectors.

```bash
loci scan ~/code       # register every git repo it finds, one scope each
loci graphs            # optional: add code symbols (free, no model calls)
loci index             # build the routing index + episode store
loci embed             # optional: local vectors for semantic recall
loci calibrate         # optional: fit routing thresholds to your corpus
loci doctor            # what is missing, and the command that fixes it

loci ask "which projects use wrangler and D1?"
loci eval              # measure routing accuracy on YOUR corpus
```

Each step writes what the next one reads, which is what makes the order fixed
rather than preferred:

```mermaid
flowchart TD
    scan["loci scan ~/code<br/>writes ~/.loci/scopes.json"]
    graphs["loci graphs<br/>writes graphify-out/graph.json, one per scope"]
    index["loci index<br/>writes ~/.loci/episodes.json, scope_index.json, rankers/"]
    embed["loci embed<br/>writes ~/.loci/embeddings.npz"]
    calibrate["loci calibrate<br/>writes ~/.loci/calibration.json"]
    doctor["loci doctor<br/>writes nothing at all"]

    scan -->|"there is nothing to graph or index until a scope exists"| graphs
    graphs -->|"the index is built FROM graph.json; index first<br/>and every project routes on prose alone"| index
    index -->|"embed encodes episode chunks, and they do not<br/>exist until index has written the store"| embed
    embed -->|"calibrate fits a per-scope semantic floor from<br/>those vectors; with none it keeps a default"| calibrate
    calibrate -->|"and then reports whatever is still missing"| doctor
```

Running it out of order does not fail loudly. It produces an install that works
and quietly retrieves worse, which is the failure `doctor` exists to name.

`scan` registers one scope per git repository. It also reads who owns each
repository out of git, prints who owns what, and asks before registering the
ones that are not yours; that prompt takes its default like every other, which is to
register everything.

A monorepo can become one scope per package instead. `--split` on `loci scan` or
`loci setup` takes anything carrying `package.json`, `pyproject.toml`,
`Cargo.toml` or `go.mod` one level down; a repo-local `.loci.json` names the rest
and is honoured with or without the flag. **`--split` is off by default**, and
the reason is measured rather than cautious: a new scope's aliases include its
bare directory name, and an alias outranks your working directory (6.0 to 4.0).
On the development corpus, splitting a repository holding `glasses/` sent eight
hand-written questions about a *different* project to `Delroy/glasses` — seven of
them had routed correctly before the split, and six of the eight reverted when
the alias boost was zeroed. A Jekyll `_site/` build directory became a scope of
its own on the same run. A `.loci.json` you wrote does not have that problem: you
named those sub-projects deliberately, so you can see what they are called.

`ask` uses your working directory by default, and should. Questions that name no
project — *"how is this deployed?"*, *"how do I run the tests?"* — route
correctly **100% of the time with cwd**. Without it they are unanswerable, and
loci abstains on all of them rather than guessing. cwd is not a tiebreaker
signal here, it is the primary one.

---

## Concepts

**Scope.** One project, one namespace. A registered git repository, one package
of a monorepo (under `--split`, or named in `.loci.json`), or anything you add
explicitly. Scopes are never merged.

**Group.** An overlapping label on a scope: `me` and `vendor:<org>`, read from
git provenance; `client:acme` and anything else you assert by hand; and a
monorepo's own id, carried by every package inside it *and* by the monorepo
itself, so `--group <monorepo>` reaches the code no package claimed. A scope can
be in several, and the scope set stays flat: grouping never merges scopes or
nests one inside another.

What a group does to a question is its **mode**, and the mode answers two
different questions. Reached through your working directory, `explicit` does
nothing, `soft` (the default) multiplies every outside scope's evidence base by
0.5, and `hard` confines routing to members and abstains when the best answer is
outside. Named on the command line with `--group X`, **all three modes confine
to X's members** — the mode decides only what happens when the best answer is
outside them: `hard` abstains and says so, `soft` and `explicit` answer with the
best member anyway. Membership lives in the scope registry, mode in
`groups.json`, so a re-scan — which rewrites the registry wholesale — cannot
discard policy. Measured: `hard`
anchored on cwd fires on questions that *name* an outside project (12 of 12) and
not on questions carrying only its vocabulary (0 of 24), so in practice `--group`
and project names drive it rather than where you are standing.

**Structure store.** What calls what — symbols, files, references, traversals
with `file:line` citations. Supplied by [graphify](https://github.com/safishamsi/graphify)
through an adapter.

**Episode store.** Wha
ai-agentsclaudellmmcpmcp-servermemorypythonrag

What people ask about loci

What is 3M1RY33T/loci?

+

3M1RY33T/loci is mcp servers for the Claude AI ecosystem. cross-project memory tool for AI agents It has 1 GitHub stars and its last recorded update is dated 2026-09-11.

How do I install loci?

+

You can install loci by cloning the repository (https://github.com/3M1RY33T/loci) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is 3M1RY33T/loci safe to use?

+

Our security agent has analyzed 3M1RY33T/loci and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.

Who maintains 3M1RY33T/loci?

+

3M1RY33T/loci is maintained by 3M1RY33T. The last recorded GitHub activity is dated 2026-09-11, with 0 open issues.

Are there alternatives to loci?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy loci to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: 3M1RY33T/loci
[![Featured on ClaudeWave](https://claudewave.com/api/badge/3m1ry33t-loci)](https://claudewave.com/repo/3m1ry33t-loci)
<a href="https://claudewave.com/repo/3m1ry33t-loci"><img src="https://claudewave.com/api/badge/3m1ry33t-loci" alt="Featured on ClaudeWave: 3M1RY33T/loci" width="320" height="64" /></a>

More MCP Servers

loci alternatives