Skip to main content
Glama
jjjona

jade-memory

by jjjona
README.md
# jade-memory

Persistent knowledge base and journal for AI agents. Two MCP servers backed by a shared multilingual embedding sidecar, deployed as Docker containers.

**Knowledge base** stores facts, decisions, procedures, and troubleshooting notes with semantic search. Agents call `store` to save knowledge and `recall` to retrieve it. Entries are typed, tagged, and searchable across languages.

**Journal** is a free-form, append-only cognitive tool. Agents write thoughts, reflections, and session notes. Value is in the writing process (structuring thinking), not just retrieval. No categories or sections — semantics live in the content itself.

Both use vector embeddings (768-dim, gte-multilingual-base) for semantic search via sqlite-vec. Both are accessible remotely via MCP Streamable HTTP transport with bearer token auth. API keys are created through the web admin UI — no env vars needed.

## Architecture

```
┌─────────────────────────────────────────────────────┐
│  Docker network (internal bridge)                   │
│                                                     │
│  jade-embeddings (Python, port 3102, internal only) │
│    Alibaba-NLP/gte-multilingual-base                │
│    768 dims, 100+ languages, ~1.2GB RAM             │
│                                                     │
│  jade-knowledge (Bun, port 3100)                    │
│    MCP Streamable HTTP at /mcp                      │
│    Bearer token auth                                │
│                                                     │
│  jade-journal (Bun, port 3101)                      │
│    MCP Streamable HTTP at /mcp                      │
│    Bearer token auth (separate key)                 │
└─────────────────────────────────────────────────────┘
```

The embedding sidecar is internal-only — not exposed outside the Docker network. Both MCP servers call it to generate embeddings on store/write and on search/recall.

## Tools

### Knowledge base (jade-knowledge)

| Tool | Description | Parameters |
|------|-------------|------------|
| `recall` | Search knowledge base | `query` (string), `type?` (enum), `limit?` (int, default 10) |
| `store` | Add knowledge with auto-embedding | `content` (string), `type?` (enum, default "general"), `tags?` (string[]) |
| `forget` | Delete knowledge entry | `id` (int) |

Knowledge types: `fact`, `preference`, `decision`, `procedure`, `troubleshooting`, `general`

### Journal (jade-journal)

| Tool | Description | Parameters |
|------|-------------|------------|
| `write` | Record journal entry | `content` (string) |
| `search` | Semantic search journal | `query` (string), `limit?` (int, default 10) |
| `recent` | List recent entries | `limit?` (int, default 10) |

The journal is append-only. No delete, no edit.

### Context footprint

Both MCPs add approximately **~480 tokens** total to the agent's context window:

- jade-knowledge: ~300 tokens (3 tools)
- jade-journal: ~180 tokens (3 tools)

For comparison, the Playwright MCP adds ~13,700 tokens.

## Installation

### Prerequisites

- Docker and Docker Compose
- Ports 3100 and 3101 available on the host

### 1. Clone and configure

```bash
git clone <repo-url> jade-memory
cd jade-memory
cp .env.example .env
# Edit .env if you need to change ports or DB paths (no API keys needed)
```

### 2. Build and start

```bash
docker compose up -d --build
```

First build downloads the embedding model (~1.2GB) and bakes it into the image. This takes a few minutes. Subsequent builds use the cached layer.

The embedding sidecar has a health check with a 120-second start period to allow for model loading. The knowledge and journal containers wait for it to be healthy before starting.

### 3. Create admin account

Visit `http://<host>:3100` (knowledge) or `http://<host>:3101` (journal) in your browser. On first visit you'll be prompted to create an admin account.

### 4. Create API keys

Log in to the web UI, go to `/admin`, and create API keys. These are used by MCP clients (Claude Code, OpenCode, etc.) to authenticate. Copy the key immediately — it's only shown once.

### 5. Verify

```bash
# Health checks (no auth required)
curl http://localhost:3100/health
curl http://localhost:3101/health

# Test MCP auth with your API key
curl -X POST http://localhost:3100/mcp \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
```

### 6. (Optional) Reverse proxy

If you want to expose the MCPs over HTTPS via traefik or another reverse proxy:

```bash
cp docker-compose.override.yml.example docker-compose.override.yml
# Edit docker-compose.override.yml with your domain names and TLS config
docker compose up -d
```

## Connecting to agents

API keys are created through the web admin UI at `/admin` after logging in. Replace `<API_KEY>` below with a key you created there.

### Claude Code

#### Option A: CLI (recommended)

```bash
claude mcp add --transport http jade-knowledge http://<host>:3100/mcp \
  --header "Authorization: Bearer <API_KEY>"

claude mcp add --transport http jade-journal http://<host>:3101/mcp \
  --header "Authorization: Bearer <API_KEY>"
```

Use `--scope user` to make them available across all projects, or `--scope local` (default) for the current project only.

#### Option B: JSON config

Add to `~/.claude.json` (or project-level `.claude/settings.json`) under `mcpServers`:

```json
{
  "mcpServers": {
    "jade-knowledge": {
      "type": "http",
      "url": "http://<host>:3100/mcp",
      "headers": {
        "Authorization": "Bearer <API_KEY>"
      }
    },
    "jade-journal": {
      "type": "http",
      "url": "http://<host>:3101/mcp",
      "headers": {
        "Authorization": "Bearer <API_KEY>"
      }
    }
  }
}
```

### OpenCode

Add to `opencode.json` in your project root:

```json
{
  "mcp": {
    "jade-knowledge": {
      "type": "remote",
      "url": "http://<host>:3100/mcp",
      "headers": {
        "Authorization": "Bearer <API_KEY>"
      }
    },
    "jade-journal": {
      "type": "remote",
      "url": "http://<host>:3101/mcp",
      "headers": {
        "Authorization": "Bearer <API_KEY>"
      }
    }
  }
}
```

You can use `{env:KNOWLEDGE_API_KEY}` instead of a literal key to reference environment variables.

### Other MCP clients

Any client that supports MCP Streamable HTTP transport can connect. The servers accept:

- `POST /mcp` — MCP JSON-RPC messages (requires `Accept: application/json, text/event-stream`)
- `GET /mcp` — SSE stream for server-initiated messages
- `DELETE /mcp` — Session cleanup
- `GET /health` — Health check (no auth required)

### Prompting the agent

For best results, instruct the agent to use the knowledge base proactively. Add something like this to your system prompt or CLAUDE.md:

```
You have access to a persistent knowledge base (jade-knowledge) and journal (jade-journal).

**Knowledge base**: Use `recall` when starting a task to check for relevant prior knowledge.
Use `store` when you learn something reusable — facts, decisions, troubleshooting solutions,
procedures. Tag entries with project names for cross-project retrieval.

**Journal**: Use `write` when you want to think through a problem, reflect on your approach,
or note something for your own reference. The value is in the writing process itself.
```

## Development

### Project structure

```
jade-memory/
├── packages/
│   ├── shared/          # Auth, embed client, DB helpers, types
│   ├── knowledge/       # Knowledge base MCP server
│   └── journal/         # Journal MCP server
├── embeddings/          # Python embedding sidecar
├── docker-compose.yml
└── .env.example
```

### Running tests

```bash
# All tests (from repo root)
bun test

# Specific package
bun test --filter knowledge
bun test --filter journal
bun test --filter shared
```

Tests mock the embedding sidecar and use in-memory SQLite databases. No Docker required.

### Running locally (without Docker)

```bash
# Terminal 1: Start embedding sidecar
cd embeddings
pip install -r requirements.txt
uvicorn main:app --port 3102

# Terminal 2: Start knowledge MCP
cd packages/knowledge
EMBEDDINGS_URL=http://localhost:3102 bun run src/index.ts

# Terminal 3: Start journal MCP
cd packages/journal
EMBEDDINGS_URL=http://localhost:3102 bun run src/index.ts
```

No API keys needed at startup. Visit `http://localhost:3100` to create an admin account, then go to `/admin` to create API keys for MCP clients.

## Resource usage

| Container | RAM | CPU | Disk |
|-----------|-----|-----|------|
| jade-embeddings | ~1.2 GB | Low (idle), moderate (encoding) | ~2 GB (model) |
| jade-knowledge | ~50 MB | Minimal | Grows with entries |
| jade-journal | ~50 MB | Minimal | Grows with entries |

The embedding model (gte-multilingual-base) is the main resource cost. It supports 100+ languages including English, Spanish, French, German, and Dutch. Cross-language search works — you can store in one language and recall in another.

Maintenance

ActivityInactive
ResponsivenessNo issues