SkillAgentSearch skills...

loci-db

Spatial memory for Physical AI. Robots, drones & world models remember what they saw, where and when, and notice what's new. 4D (x,y,z,t) vector memory · novelty detection · MCP server.

Install / Use

claude mcp add zd87pl -- npx -y github:zd87pl/loci-db

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

83/100

Supported Platforms

Claude Code
Claude Desktop

Our assessment of loci-db

loci-db scores 83/100 on our quality scale, 498th of 607 Data & Analytics skills we index.

Its MCP Server is 19 KB long, well organised into 45 sections with 16 code examples: a thorough specification that gives an agent plenty to work with.

It has 3 GitHub stars, so there is little community track record yet; judge it on its content.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
3/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 15 days ago, so loci-db is actively maintained.
  • It is released under the Apache-2.0 license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 92/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

loci-db compared with similar skills

All 4 of these similar skills score higher than loci-db; compare them before choosing.

SkillScoreStarsUpdatedFormat
loci-db (this skill)by zd87pl83315d agoMCP Server
Agent-Reachby Panniantong10096.5k4d agoCLAUDE.md
headroomby headroomlabs-ai10075.1ktodayCLAUDE.md
CowAgentby zhayujie10047.4ktodayCLAUDE.md
Scraplingby D4Vinci10087.0ktodayMCP Server

Frequently asked questions

How do I install loci-db?
Run claude mcp add zd87pl -- npx -y github:zd87pl/loci-db. The install tabs above show the steps for each supported agent.
Which AI agents does loci-db work with?
It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
Is loci-db safe to use?
It is Apache-2.0-licensed and scores 92/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is loci-db still maintained?
The repository was last updated 15 days ago, so loci-db is actively maintained.
<p align="center"> <img src="https://raw.githubusercontent.com/zd87pl/loci-db/main/docs/assets/loci-banner.png" alt="LOCI: spatial memory for Physical AI" width="100%"> </p> <p align="center"> <b>Spatial memory for Physical AI.</b><br> Robots, drones and world models remember <i>what</i> they saw, <i>where</i> and <i>when</i>, and notice what's new. </p> <p align="center"> <a href="https://github.com/zd87pl/loci-db/actions/workflows/ci.yml"><img src="https://github.com/zd87pl/loci-db/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <a href="https://pypi.org/project/loci-stdb/"><img src="https://img.shields.io/pypi/v/loci-stdb.svg?label=pypi%3A%20loci-stdb" alt="PyPI"></a> <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+"></a> <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-green.svg" alt="License: Apache 2.0"></a> <a href="docs/MCP_SERVER.md"><img src="https://img.shields.io/badge/MCP-server-8A2BE2" alt="MCP server"></a> <a href="https://github.com/zd87pl/loci-db/stargazers"><img src="https://img.shields.io/github/stars/zd87pl/loci-db?style=social" alt="GitHub stars"></a> </p> <p align="center"> <a href="#quick-start">Quick start</a> · <a href="#run-the-demo">Demo</a> · <a href="#mcp-server-spatial-memory-for-agents">MCP server</a> · <a href="#how-it-works">How it works</a> · <a href="ARCHITECTURE.md">Architecture</a> · <a href="ROADMAP.md">Roadmap</a> </p> <p align="center"> <img src="https://raw.githubusercontent.com/zd87pl/loci-db/main/docs/assets/loci-demo.gif" alt="A simulated warehouse robot builds spatial memory while it patrols, then answers place-and-time and similarity queries" width="100%"> <br> <sub>A warehouse robot builds memory as it patrols, then answers <i>"what happened in this aisle?"</i> and <i>"where have I seen this before?"</i> Runs locally in about 30 seconds: <a href="#run-the-demo">run the demo</a>.</sub> </p>

Why LOCI?

Physical AI runs on memory. A robot that forgets where it saw the pallet, a drone that can't tell what changed since yesterday's flight, a world model with no record of the futures it has already lived through: each of them needs to remember what it perceived, where, and when.

Vector databases store the what. LOCI stores all three, indexes them together, and answers the questions embodied systems actually ask:

| The question | The LOCI call | |:--|:--| | "Where did I last see the red toolbox?" | query(vector) returns the matching memory with its (x, y, z, t) | | "What happened in aisle 3 in the last 10 minutes?" | query(vector, spatial_bounds=..., time_window_ms=...) | | "Is what I'm about to see new?" | predict_and_retrieve(...), which returns a novelty score in [0, 1] | | "How did I get here?" | get_trajectory(...) / get_causal_context(...) |

| | Plain vector DB | LLM agent memory | LOCI | |:--|:--|:--|:--| | Built for | any embedding | chat and text facts | sensor and world-model embeddings in space and time | | (x, y, z, t) as a first-class index | payload filters you wire up yourself | not applicable | Hilbert-bucketed 4D address | | Space + time + similarity in one call | DIY | not applicable | one query(...) | | "Is this new?" | not built in | not built in | calibrated novelty score | | Trajectories and causal links | not built in | not built in | built in | | Memory that ages gracefully | TTL / delete | varies | episodic → summary consolidation, bounded storage | | Infra needed to try it | a server | varies | none (in-process), or Qdrant for production |

Quick start

No server, no Docker, no GPU:

pip install loci-stdb
import time
import numpy as np
from loci import LocalLociClient, WorldState

rng = np.random.default_rng(0)
memory = LocalLociClient(vector_size=64)  # in-process: no server, no Docker

# A robot drives down a corridor. Each step it stores WHAT it sees
# (any embedding: CLIP, DINOv2, V-JEPA 2, ...), WHERE, and WHEN.
t0 = int(time.time() * 1000)
mug = rng.normal(size=64)
for step in range(100):
    seen = mug if step == 42 else rng.normal(size=64)  # passes a mug at step 42
    memory.insert(WorldState(
        x=step / 100, y=0.5, z=0.0,          # where (normalised to [0, 1])
        timestamp_ms=t0 + step * 100,         # when
        vector=seen.tolist(),                 # what
        scene_id="corridor",
        metadata={"step": step},
    ))

# "Where did I see this mug?"
hit = memory.query(vector=mug.tolist(), limit=1)[0]
print(f"mug seen at x={hit.x:.2f}, step {hit.metadata['step']}")   # x=0.42, step 42

# "What did I see in this part of the corridor, in the first 5 seconds?"
region = {"x_min": 0.3, "x_max": 0.5, "y_min": 0, "y_max": 1, "z_min": 0, "z_max": 1}
recent = memory.query(vector=mug.tolist(), spatial_bounds=region,
                      time_window_ms=(t0, t0 + 5_000), limit=3)

# "Is this new?" Novelty is 0 for familiar scenes and close to 1 for unseen ones.
for name, view in [("the mug", mug), ("something new", rng.normal(size=64))]:
    r = memory.predict_and_retrieve(context_vector=view.tolist(), predictor_fn=lambda v: v,
                                    current_position=(0.42, 0.5, 0.0))
    print(f"{name}: novelty={r.prediction_novelty:.2f}")   # the mug: 0.00, something new: 0.69

Swap LocalLociClient for LociClient("http://localhost:6333", ...) to use the same code on a persistent Qdrant backend (see Production setup).

Run the demo

The warehouse robot from the GIF above. Everything runs in-process, with no API keys needed:

git clone https://github.com/zd87pl/loci-db.git && cd loci-db
pip install -e . fastapi "uvicorn[standard]"
uvicorn demo.app.main:app
# open http://localhost:8000 and click through the five guided steps

There is also a spatial memory assistant in demo_spatial/: point your phone camera around a room, then ask out loud "where did I leave my keys?" It uses a VLM for object detection and LOCI for the where and when.

What you can build

  • Robot fleets and warehouses: shared memory of where things are, plus "what changed since the last patrol?"
  • Drones and inspection: geo-temporal recall of defects and anomalies across flights.
  • Autonomous vehicles and mobile robots: retrieve scenes by place and time for replay, debugging, and edge-case mining.
  • AR and assistive tech: "where did I leave my keys?" (see demo_spatial/).
  • World models (V-JEPA 2, DreamerV3, ...): predict-then-retrieve memory for imagination rollouts, with a novelty signal for safety monitors and exploration.
  • LLM agents with a body: give Claude or any MCP client a spatial memory.

MCP server: spatial memory for agents

LOCI ships a Model Context Protocol server, so Claude Desktop, Claude Code, or any MCP client gets five tools: remember, recall, novelty, trajectory, and memory_stats.

pip install "loci-stdb[mcp]"
claude mcp add loci-memory --env LOCI_MCP_MODE=local -- loci-mcp

Backends: local (in-memory), qdrant (persistent), or cloud. See docs/MCP_SERVER.md for Claude Desktop config, the env table, the tool reference, and agent recipes.

How it works

LOCI is a memory layer on top of Qdrant, with an in-process backend for zero-infra use. Three primitives make space and time first-class:

1. Multi-resolution Hilbert bucketing

(x, y, z, t) is encoded on a 4D Hilbert curve at several resolutions (p = 4, 8, 12). A spatial bounding box becomes a single integer pre-filter on the curve, followed by an exact payload post-filter as the authoritative geometric check, so there are no false negatives at box boundaries. With adaptive=True, dense regions are promoted to finer resolutions at query time.

         Naive Qdrant               LOCI
    ┌──────────────────┐     ┌──────────────────┐
    │ x_min ≤ x ≤ x_max│     │                  │
    │ y_min ≤ y ≤ y_max│ →   │ hilbert_r4 ∈ {…} │
    │ z_min ≤ z ≤ z_max│     │  (single filter)  │
    └──────────────────┘     └──────────────────┘

2. Bounded storage that ages like memory

All raw states live in one loci_data collection and consolidated summaries in one loci_summary collection, so the collection count stays fixed however long you ingest. Epochs (default 5 s) are logical: the unit of consolidation and of Hilbert t-normalisation. Time-windowed queries use an indexed timestamp_ms range filter. With a ConsolidationPolicy, old episodes fold into per-scene summaries instead of being deleted: recent memory stays sharp, old memory becomes gist, and storage stays bounded.

3. Predict-then-retrieve with novelty detection

One atomic call composes your world model with memory search and returns analogs plus a novelty score:

result = client.predict_and_retrieve(
    context_vector=current_embedding,
    predictor_fn=my_world_model,
    future_horizon_ms=2000,
    current_position=(0.5, 0.3, 0.8),
)
print(f"Novelty: {result.prediction_novelty:.2f}")
# 0.0 = "I've seen this before"
# 1.0 = "This is new territory"

By default this searches stored history for analogs of the predicted future. Pass search_time_window_ms=(start, end) to restrict retrieval to an absolute time range.

Architecture

┌───────────────────────────────────────────────┐
│              Application Layer                │
│  LociClient / AsyncLociClient / LocalLociClient│
│  insert · query · predict_and_retrieve        │
│  REST server · MCP server · CLI               │
├───────────────────────────────────────────────┤
│              Retrieval Layer                  │
│  predict.py — predict-then-retrieve + novelty │
│  funnel.py  — multi-scale coarse→fine search  │
├───────────────────────────────────────────────┤
│           Indexing & Routing Layer            │
│  spatial/  — multi-res Hilbert + overlap      │
│  temporal/ — logical epochs: consolidation,   │
│              retention, decay scoring         │
├───────────────────────────────────────────────┤
│              Adapters Layer                   │
│  V-JEPA 2 · DreamerV3 · Generic numpy/torch  │
├───────────────────────────────────────────────┤
│              Storage Layer                    │
│  Qdrant — two bounded collections per tenant: │
│    loci_data (raw) + loci_summary (aged)      │
│  MemoryStore (in-process, no infra needed)    │
└───────────────────────────────────────────────┘

See ARCHITECTURE.md for the full design.

Production setup

Docker (REST API + Qdrant)

docker compose up

This starts the LOCI REST API on http://localhost:8000 (interactive docs at /docs) and Qdrant on http://localhost:6333, with Qdrant data persisted in a named volume.

# Health check
curl http://localhost:8000/health

# Insert a world state. The vector length must match the server's
# LOCI_VECTOR_SIZE (512 in docker-compose.yml). Wrong-length vectors are
# rejected with HTTP 422, so the payload is generated rather than hand-typed:
python3 -c 'import json; print(json.dumps({
    "x": 0.5, "y": 0.3, "z": 0.8,
    "timestamp_ms": 1700000000000,
    "vector": [0.1] * 512,
    "scene_id": "s1"}))' \
  | curl -X POST http://localhost:8000/insert \
      -H 'Content-Type: application/json' -d @-

# Query by vector similarity. Spatial bounds and the time window are optional;
# omit them to search everything:
python3 -c 'import json; print(json.dumps({
    "vector": [0.1] * 512,
    "x_min": 0.0, "x_max": 1.0, "y_min": 0.0, "y_max": 1.0,
    "z_min": 0.0, "z_max": 1.0,
    "limit": 10}))' \
  | curl -X POST http://localhost:8000/query \
      -H 'Content-Type: application/json' -d @-

Pytho

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars3
CategoryData
Updated15d ago
Forks0

Languages

Python

Trust signals

92/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 low