Content
# Spellbook v1.0 🔮
VectorDB-based AI Agent Memory MCP Server
## Overview
Stores information accumulated during AI agent personalization in VectorDB and searches based on meaning.
**Canon (Main Storage)**:
- **Scribe**: Stores information in Canon (only in REST mode)
- **Memorize**: Semantic search in Canon
- **Find**: Keyword-based search in Canon
**Lore (Sub Storage)**:
- **Chronicle**: Stores information in Lore (only in REST mode, with Lore name specified)
- **Recall**: Semantic search in Lore
- **Recall Find**: Keyword-based search in Lore
Canon and Lore APIs are completely separated. You cannot access Lore data with Canon API, and vice versa.
**Spellbook is a simple storage.** It is up to the user to decide what to store and when to search.
## Key Features
- ✅ **Canon + Lore**: Main storage and purpose-specific sub storage separation
- ✅ **REST State Management**: Ensures consistency with chunking (shared by scribe/chronicle)
- ✅ **Dual Search**: Semantic + keyword-based search (for Canon/Lore respectively)
- ✅ **nomic-embed-text**: 768 dimensions, excellent for Korean/English
- ✅ **HTTP/SSE MCP**: Easy deployment with Docker
- ✅ **Bun Runtime**: Fast startup, native TypeScript execution
## Quick Start
> 📖 **Detailed Installation Guide**:
> - 👤 **Human**: [INSTALL.md](./INSTALL.md) - Interactive installation script
> - 🤖 **AI Agent**: [INSTALL_AI.md](./INSTALL_AI.md) - Environment variable setup guide
### Method 1: Docker Compose (Recommended) ⭐
**Prerequisites**: [Docker](https://docs.docker.com/get-docker/), [Ollama](https://ollama.com)
```bash
git clone https://github.com/zilhak/spellbook.git
cd spellbook
./scripts/setup.sh # Environment check + model download + image build
docker compose up -d
```
setup.sh handles Docker, Ollama checks, embedding model download, and image build.
The system guide seed is automatically performed on the first run.
**Customizing Settings** (optional):
```bash
cp .env.example .env
nano .env
```
| Environment Variable | Default Value | Description |
|-----------|--------|------|
| `PORT` | `17950` | Spellbook server port |
| `QDRANT_PORT` | `17951` | Qdrant external port |
| `QDRANT_DATA_PATH` | `./data/qdrant` | Data storage path |
| `OLLAMA_HOST` | `http://host.docker.internal:11434` | Ollama address |
---
### Method 2: Run Bun Directly (Development)
```bash
git clone https://github.com/zilhak/spellbook.git
cd spellbook
bun install
# Prepare Qdrant + Ollama
docker run -d -p 17951:6333 qdrant/qdrant
ollama pull nomic-embed-text
# Development mode (hot reload)
bun run dev
```
**Requirements**: [Bun](https://bun.sh) (`curl -fsSL https://bun.sh/install | bash`)
---
### Claude Code Setup
**Method 1: CLI Command (Recommended)**
```bash
claude mcp add --transport http spellbook http://localhost:17950/mcp
```
**Method 2: Manual Setup**
`~/.claude/mcp.json`:
```json
{
"mcpServers": {
"spellbook": {
"url": "http://localhost:17950/mcp"
}
}
}
```
### AI Agent System Prompt Setup (Recommended)
To effectively utilize Spellbook, add the following guidelines to the AI agent's system prompt (CLAUDE.md, etc.):
```markdown
## Spellbook Usage Rules
- If you encounter unknown concepts, project conventions, or past decisions, search Spellbook first.
- At the start of each session, use get_index() to check what information is stored.
- Canon search (general knowledge):
- When curious about context/concepts: memorize(query)
- When you know the exact term: find(keywords)
- Lore search (project-specific information):
- When curious about context/concepts: recall(lore, query)
- When you know the exact term: recall_find(lore, keywords)
- Store important decisions, new patterns, and user preferences in REST mode.
- General knowledge → scribe (Canon)
- Project-specific information → chronicle (Lore)
```
This allows the agent to naturally utilize knowledge accumulated from previous sessions.
---
## Usage
### Canon Workflow (Main Storage)
```typescript
// 1. Enter REST mode
const session = await rest();
// 2. Store chunk in Canon
await scribe({
chunk: {
text: "Docker Compose is...",
metadata: {
topic_id: "Infrastructure",
category: "technology",
keywords: ["Docker", "Compose"],
questions: ["What is the Docker Compose setup method?"],
entities: [{name: "Docker", type: "technology"}],
importance: "high"
}
},
session_id: session.session_id
});
// 3. Exit REST mode
await rest_end(session.session_id);
// Canon search
await memorize({query: "Docker container setup"});
await find({keywords: ["Docker", "Qdrant"]});
```
### Lore Workflow (Sub Storage)
```typescript
// 1. Enter REST mode
const session = await rest();
// 2. Store chunk in Lore (automatically creates Lore if it doesn't exist)
await chronicle({
lore: "my-project",
lore_description: "My Project technical decisions",
chunk: {
text: "Authentication is based on JWT...",
metadata: {
topic_id: "auth",
category: "architecture",
keywords: ["JWT", "authentication"],
questions: ["What is the project authentication method?"],
entities: [{name: "JWT", type: "technology"}],
importance: "high"
}
},
session_id: session.session_id
});
// 3. Exit REST mode
await rest_end(session.session_id);
// Lore search
await recall({lore: "my-project", query: "authentication method"});
await recall_find({lore: "my-project", keywords: ["JWT"]});
// Lore management
await list_lores(); // List all Lores + descriptions
await lore_stats("my-project"); // Specific Lore statistics
```
## Data Management
### Persistence
**Using Docker Compose**:
- Use host path directly (`.env`'s `QDRANT_DATA_PATH`)
- Data automatically maintained even if container is restarted/recreated
```bash
# Configure in .env file
QDRANT_DATA_PATH=/your/data/path
# Check data
ls -la /your/data/path
```
**✅ Safe Shutdown** (data maintained):
```bash
docker-compose down # Delete container only, data maintained
docker-compose restart # Restore data
```
---
### Backup/Restore (export/import)
#### Export Tool (Backup)
```bash
# Initialize MCP session and call export
curl -X POST http://localhost:17950/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"clientInfo":{"name":"test"},"protocolVersion":"2024-11-05"},"id":1}'
# Export using session ID
curl -X POST http://localhost:17950/mcp \
-H "Content-Type: application/json" \
-H "mcp-session-id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"export","arguments":{}},"id":2}'
```
#### Import Tool (Restore)
```bash
curl -X POST http://localhost:17950/mcp \
-H "Content-Type: application/json" \
-H "mcp-session-id: YOUR_SESSION_ID" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "import",
"arguments": {
"data": {
"chunks": [
{"text": "Content to restore", "category": "knowledge"}
]
}
}
},
"id": 1
}'
```
**Features**:
- Direct restoration without REST session
- Automatic embedding regeneration for each chunk
- Returns success/failure count
---
## Development
### Local Execution
```bash
# Install dependencies
bun install
# Run Qdrant with Docker
docker-compose up -d qdrant
# Development mode (hot reload)
bun run dev
# Type checking
bun run typecheck
```
### System Guide Seed
```bash
# Initial run only
bun run seed
```
## MCP Tools
### Common
| Tool | Description | Restrictions |
|------|------|------|
| `rest` | Start REST mode | - |
| `rest_end` | End REST mode | - |
| `get_index` | Meta table of contents | - |
| `stats` | Canon statistics | - |
| `filter_guide` | Filter usage guide | - |
| `export` | Canon JSON backup | - |
| `import` | Canon JSON restore | - |
### Canon (Main Storage)
| Tool | Description | Restrictions |
|------|------|------|
| `scribe` | Store chunk in Canon | **REST mode required** |
| `memorize` | Canon semantic search | - |
| `find` | Canon keyword search | - |
| `get_topic` | Topic query | - |
| `erase` | Delete Canon chunk | - |
| `revise` | Modify Canon chunk | - |
### Lore (Sub Storage)
| Tool | Description | Restrictions |
|------|------|------|
| `chronicle` | Store chunk in Lore | **REST mode required** |
| `recall` | Lore semantic search | - |
| `recall_find` | Lore keyword search | - |
| `erase_lore` | Delete Lore chunk | - |
| `revise_lore` | Modify Lore chunk | - |
| `list_lores` | List all Lores | - |
| `delete_lore` | Delete Lore (irreversible) | - |
| `lore_stats` | Lore statistics | - |
| `update_lore` | Modify Lore description | - |
## Architecture
```
Claude Code
│ HTTP/SSE (MCP Protocol)
▼
Spellbook (Bun + MCP SDK)
│
├─ REST session management (shared by scribe/chronicle)
├─ Canon tools (scribe, memorize, find)
├─ Lore tools (chronicle, recall, recall_find)
├─ Lore management (list_lores, delete_lore, lore_stats, update_lore)
├─ Embedding (Ollama + nomic-embed-text)
└─ VectorDB (Qdrant)
├─ Canon: chunks + chunks_metadata
└─ Lore: lore_{name} + lore_{name}_metadata (respectively)
```
## Tech Stack
| Component | Choice |
|----------|------|
| **Runtime** | Bun |
| **Language** | TypeScript (native execution) |
| **MCP** | @modelcontextprotocol/sdk |
| **VectorDB** | Qdrant |
| **Embedding** | Ollama + nomic-embed-text |
| **HTTP** | Express |
## Detailed Documents
- [CLAUDE.md](./CLAUDE.md) - Project-wide design document
- [src/data/system-guides.ts](./src/data/system-guides.ts) - Chunking guide
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
Python tool for converting files and office documents to Markdown.
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
TrendRadar
TrendRadar: Your hotspot assistant for real news in just 30 seconds.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.