Coding & Development✨gemini🤖claude🌐universal

Qdrant MCP on Raspberry Pi 5

Persistent semantic memory for AI agents on Raspberry Pi 5 — local Qdrant + MCP, no cloud, ~3s per query

Quick Start

Install this Skill

npx skills add rockywuest/qdrant-mcp-pi5
# Qdrant MCP on Raspberry Pi 5

[![Works with OpenClaw](https://img.shields.io/badge/Works_with-OpenClaw-blue?logo=data:image/svg+xml;base64,PHN2Zz48L3N2Zz4=)](https://openclaw.ai)
[![Works with Claude Code](https://img.shields.io/badge/Works_with-Claude_Code-orange)](https://docs.anthropic.com/en/docs/claude-code)
[![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-green)](https://modelcontextprotocol.io)

![Qdrant MCP on Pi 5](assets/hero.png)

**Persistent semantic memory for AI agents — local, private, $0 cost.**

Give your AI agent a real memory that survives reboots, searches by meaning (not keywords), and runs entirely on a Raspberry Pi 5 with no cloud dependencies.

> **New:** Includes an [OpenClaw Hard Enforcement Plugin](#hard-enforcement-plugin-openclaw) that automatically injects memories before every response — no LLM decision required.

> **Note (2026-03-19):** drift-memory was deprecated in Feb 2026 — all 105 entries migrated into Qdrant. This repo now stands alone. Embeddings migrated from all-MiniLM-L6-v2 (384d) → Gemini gemini-embedding-001 (3072d) via OpenClaw's memorySearch config.

---

## The Problem

AI agents forget. Between sessions, context compaction loses details, and text-based memory search only finds exact keyword matches. A typical agent can make **10+ memory errors in its first week** — wrong dates, stale data, presenting old topics as new.

## The Solution

Local vector database (Qdrant) with MCP (Model Context Protocol) integration. Facts are stored as 384-dimensional embeddings and retrieved by **semantic similarity** — meaning-based, not keyword-based.

```
"What's the wifi password?" → finds "Office wifi: network 'Workspace5G', password is 'correct-horse-battery'"
```

The words don't match, but the meaning does. That's the difference.

---

## Stack

| Component | Version | Purpose |
|-----------|---------|---------|
| **Raspberry Pi 5** | 8GB RAM | Hardware |
| **Qdrant MCP Server** | v0.8.1 | Vector storage + search |
| **Gemini gemini-embedding-001** | 3072-dim | Embedding model (API, migrated from MiniLM) |
| **mcporter** | v0.7.3 | MCP client / bridge |
| **OpenClaw** | 2026.3.13 | Agent framework (optional) |

## Performance (Pi 5, ARM64)

| Operation | Time | Notes |
|-----------|------|-------|
| Store (embed + write) | ~3s | Includes model load |
| Search (embed + cosine) | ~3s | Includes model load |
| RAM spike | ~200MB | During inference, then drops |
| Storage | ~KB per entry | SQLite-backed, negligible |

---

## Quick Start (5 minutes)

### 1. Install dependencies

```bash
# Qdrant MCP Server
pip3 install mcp-server-qdrant

# mcporter (MCP client)
npm install -g mcporter
```

### 2. Create mcporter config

```bash
mkdir -p ~/.mcporter
```

Create `~/.mcporter/mcporter.json`:

```json
{
  "mcpServers": {
    "qdrant-memory": {
      "command": "mcp-server-qdrant",
      "description": "Persistent vector memory using local Qdrant storage",
      "env": {
        "QDRANT_LOCAL_PATH": "/home/pi/.qdrant-data",
        "COLLECTION_NAME": "agent-memory"
      }
    }
  }
}
```

> **Note:** Use an absolute path for `QDRANT_LOCAL_PATH`. Tilde (`~`) is not expanded in environment variables passed by mcporter. If `mcporter list` can't find the server, also try the full path for `command` (e.g. `/home/pi/.local/bin/mcp-server-qdrant`).

### 3. Verify it works

```bash
# Check server is registered
mcporter list

# Store a memory
mcporter call qdrant-memory.qdrant-store \
  information="The project runs on a Raspberry Pi 5 in my office"

# Search by meaning
mcporter call qdrant-memory.qdrant-find \
  query="Where does the project run?"
```

That's it. No Docker, no cloud accounts, no GPU.

---

## How It Works

```
Agent wants to remember something
  ↓
mcporter call qdrant-memory.qdrant-store information="..."
  ↓
mcp-server-qdrant spawns (STDIO)
  ↓
all-MiniLM-L6-v2 creates 384-dim embedding (ONNX, CPU)
  ↓
Qdrant stores vector + text in local SQLite
  ↓
Process exits cleanly

Agent wants to recall something
  ↓
mcporter call qdrant-memory.qdrant-find query="..."
  ↓
Query embedded with same model
  ↓
Cosine similarity search over stored vectors
  ↓
Top results returned by semantic relevance
```

Key insight: The MCP server is **stateless** — it spawns per-call, does its work, and exits. No daemon process eating RAM. Qdrant's local mode uses SQLite, so data persists without a running server.

---

## Seed Script

Use `seed-memory.sh` to bulk-load memories:

```bash
./seed-memory.sh
```

Or store individual facts:

```bash
mcporter call qdrant-memory.qdrant-store \
  information="Weekly standup is every Monday at 09:00 in the main conference room" \
  metadata='{"type": "recurring", "day": "monday"}'
```

The optional `metadata` field accepts any JSON — useful for filtering or categorization.

---

## Use Cases

### AI Agent Memory
Store decisions, corrections, and facts. Before generating responses, search memory to verify claims. Prevents confabulation.



... (truncated)
Repository
10stars
2forks
View on GitHub
Details
DiscoveredMar 28, 2026
Last UpdatedMar 28, 2026
Quality Score
45/100