Persistent semantic memory HTTP server for AI agents. No cloud, no API keys. Local vector index with Ollama/TF-IDF embeddings. Endpoints: /store, /recall, /forget, /list, /health
225 lines
5.2 KiB
Markdown
225 lines
5.2 KiB
Markdown
# memory-bridge
|
|
|
|
A lightweight local HTTP server that gives Claude (or any LLM) persistent long-term memory via a local vector database. **No cloud. No API keys. Runs fully on your machine.**
|
|
|
|
Pairs with [Desktop Commander](https://github.com/wonderwhy-er/ClaudeComputerCommander) — Claude can call these endpoints from any conversation to store and recall context across sessions.
|
|
|
|
---
|
|
|
|
## Quick start
|
|
|
|
### Option A — Full install (recommended)
|
|
|
|
```bash
|
|
cd memory-bridge
|
|
chmod +x install.sh
|
|
./install.sh
|
|
```
|
|
|
|
This will:
|
|
1. Install npm dependencies
|
|
2. Pull the `nomic-embed-text` embedding model via Ollama (~274 MB, one-time)
|
|
3. Register a launchd agent so the server starts on every login
|
|
4. Print your auth token
|
|
|
|
### Option B — Manual start
|
|
|
|
```bash
|
|
npm install
|
|
node server.js
|
|
```
|
|
|
|
Your auth token is printed to stdout on first run and persisted to `~/.memory-bridge/.env`.
|
|
|
|
---
|
|
|
|
## Configuration
|
|
|
|
All config lives in `~/.memory-bridge/.env` (auto-generated on first run):
|
|
|
|
| Variable | Default | Description |
|
|
|---|---|---|
|
|
| `MEMORY_BRIDGE_TOKEN` | auto-generated | Bearer token for API auth |
|
|
| `MEMORY_BRIDGE_PORT` | `3722` | Port to listen on |
|
|
| `OLLAMA_URL` | `http://localhost:11434` | Ollama base URL |
|
|
|
|
---
|
|
|
|
## API reference
|
|
|
|
All endpoints except `GET /health` require:
|
|
|
|
```
|
|
Authorization: Bearer <your-token>
|
|
```
|
|
|
|
### `GET /health`
|
|
|
|
Returns server status. No auth required.
|
|
|
|
```bash
|
|
curl http://localhost:3722/health
|
|
```
|
|
|
|
```json
|
|
{
|
|
"status": "ok",
|
|
"version": "1.0.0",
|
|
"embeddingMode": "ollama",
|
|
"memoriesCount": 42
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### `POST /store`
|
|
|
|
Embed and persist a memory.
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3722/store \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"text": "The database migration runs every Sunday at 2am UTC", "tags": ["ops", "db"], "source": "conversation"}'
|
|
```
|
|
|
|
```json
|
|
{ "id": "550e8400-...", "createdAt": "2026-03-21T10:00:00.000Z" }
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|---|---|---|---|
|
|
| `text` | string | yes | The memory content to embed and store |
|
|
| `tags` | string[] | no | Optional labels for filtering |
|
|
| `source` | string | no | Where this memory came from |
|
|
|
|
---
|
|
|
|
### `POST /recall`
|
|
|
|
Semantic search over stored memories.
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3722/recall \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"query": "database maintenance schedule", "limit": 5}'
|
|
```
|
|
|
|
```json
|
|
{
|
|
"memories": [
|
|
{
|
|
"id": "550e8400-...",
|
|
"text": "The database migration runs every Sunday at 2am UTC",
|
|
"tags": ["ops", "db"],
|
|
"source": "conversation",
|
|
"createdAt": "2026-03-21T10:00:00.000Z",
|
|
"score": 0.94
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
| Field | Type | Default | Description |
|
|
|---|---|---|---|
|
|
| `query` | string | required | Natural language search query |
|
|
| `limit` | number | `10` | Max results returned (max 100) |
|
|
| `tags` | string[] | `[]` | Filter results to only these tags |
|
|
|
|
---
|
|
|
|
### `POST /forget`
|
|
|
|
Delete a memory by ID.
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3722/forget \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"id": "550e8400-..."}'
|
|
```
|
|
|
|
```json
|
|
{ "message": "forgotten", "id": "550e8400-..." }
|
|
```
|
|
|
|
---
|
|
|
|
### `GET /list`
|
|
|
|
List all memories, paginated.
|
|
|
|
```bash
|
|
curl "http://localhost:3722/list?page=1&pageSize=20" \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
```
|
|
|
|
```json
|
|
{
|
|
"data": [...],
|
|
"total": 42,
|
|
"page": 1,
|
|
"pageSize": 20,
|
|
"pages": 3
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## How Claude uses it
|
|
|
|
Configure Claude's system prompt to call these endpoints at the start and end of each conversation:
|
|
|
|
```
|
|
At the start of each conversation, call POST /recall with the current topic
|
|
to retrieve relevant memories. At the end of each conversation, call POST /store
|
|
to persist any important facts, decisions, or user preferences discovered.
|
|
```
|
|
|
|
With **Desktop Commander**, Claude can make HTTP requests directly. Add the server details to Claude's context:
|
|
|
|
```
|
|
memory-bridge: http://localhost:3722
|
|
Authorization: Bearer <your-token>
|
|
```
|
|
|
|
### Example workflow
|
|
|
|
1. User asks: "What did we decide about the auth system last month?"
|
|
2. Claude calls `POST /recall` with `{ "query": "auth system decisions" }` → retrieves relevant memory with high score
|
|
3. Claude answers informed by past context
|
|
4. At conversation end, Claude calls `POST /store` to record new decisions made this session
|
|
|
|
---
|
|
|
|
## Embedding modes
|
|
|
|
| Mode | Quality | Requires |
|
|
|---|---|---|
|
|
| `ollama` | Semantic — understands paraphrases and synonyms | Ollama + `nomic-embed-text` |
|
|
| `tfidf` | Keyword — exact term matching with bigrams | Nothing (zero-config fallback) |
|
|
|
|
The server detects Ollama automatically at startup. Run `GET /health` to see the active mode.
|
|
|
|
---
|
|
|
|
## Logs & persistence
|
|
|
|
| Path | Contents |
|
|
|---|---|
|
|
| `~/.memory-bridge/index/` | Vector index (vectra) |
|
|
| `~/.memory-bridge/.env` | Auth token and config |
|
|
| `~/.memory-bridge/server.log` | Stdout (when running as launchd service) |
|
|
| `~/.memory-bridge/server-error.log` | Stderr (when running as launchd service) |
|
|
|
|
---
|
|
|
|
## Uninstall
|
|
|
|
```bash
|
|
launchctl unload ~/Library/LaunchAgents/com.memory-bridge.plist
|
|
rm ~/Library/LaunchAgents/com.memory-bridge.plist
|
|
rm -rf ~/.memory-bridge # deletes all stored memories
|
|
```
|