Open Mind
by theippenguin
README.md
# Open Mind
Self-hosted personal knowledge infrastructure for AI agents. Inspired by [OB1 (Open Brain)](https://github.com/NateBJones-Projects/OB1), built to run on Unraid with Docker.
Store thoughts, ideas, and knowledge in PostgreSQL with pgvector for semantic search. Any MCP-compatible AI tool (OpenClaw, Claude, ChatGPT, Cursor) can read and write to your knowledge base.
## Features
- **Semantic search** via pgvector embeddings — find thoughts by meaning, not keywords
- **Configurable embeddings** — Ollama (local/free), OpenAI (OAuth or API key), or OpenRouter
- **4 core MCP tools** — capture, search, browse, and stats
- **6 extensions** — Household Knowledge, Home Maintenance, Family Calendar, Meal Planning, Professional CRM, Job Hunt Pipeline
- **Capture integrations** — Slack, Discord, and REST API
- **Multi-user support** with Row-Level Security
- **OpenAI OAuth PKCE** — authenticate without raw API keys
## Architecture
```
OpenClaw ◄──MCP──► Express:3100 ◄──► PostgreSQL+pgvector
│
Ollama / OpenAI / OpenRouter
```
## Quick Start (Standard Docker Compose)
```bash
# 1. Clone and configure
git clone https://github.com/theippenguin/open-mind.git
cd open-mind
cp .env.example .env
# 2. Generate an API key
openssl rand -hex 32
# Paste the output into .env as the API_KEY value
# 3. Edit .env with your settings
nano .env
# 4. Start services
docker compose up -d
# 5. Update the default user's API key in the database
docker exec openmind-postgres psql -U openmind -d openmind -c \
"UPDATE users SET api_key = 'YOUR_API_KEY_HERE' WHERE name = 'default';"
# 6. Test
curl -X POST http://localhost:3100/api/capture \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY_HERE" \
-d '{"content": "Hello Open Mind!", "source": "api"}'
```
## Unraid Installation Guide
Unraid uses the **Docker Compose Manager** plugin, which stores compose files in its own directory and doesn't allow pointing to external compose files. Follow these Unraid-specific steps:
### Prerequisites
- Unraid with the **Docker Compose Manager** plugin installed (available in Community Apps)
- An Ollama server accessible from your Unraid box (can be the same machine or a separate server)
- Ollama models pulled: `nomic-embed-text` (embeddings) and a chat model like `llama3.2`, `qwen3`, or `mistral` (metadata extraction)
### Step 1: Generate your API key
From any terminal:
```bash
openssl rand -hex 32
```
Save this key — you'll need it in multiple steps.
### Step 2: Clone the repo on Unraid
SSH into your Unraid server:
```bash
cd /mnt/user/appdata
git clone https://github.com/theippenguin/open-mind.git
cd open-mind
```
If git isn't available on your Unraid box:
```bash
cd /mnt/user/appdata
wget https://github.com/theippenguin/open-mind/archive/refs/heads/main.zip
unzip main.zip
mv open-mind-main open-mind
cd open-mind
```
### Step 3: Create your `.env` file
```bash
cp .env.example .env
nano .env
```
Fill in these values:
```env
POSTGRES_PASSWORD=pick-a-strong-password-here
API_KEY=paste-your-generated-key-from-step-1
# Your Ollama server IP and port
OLLAMA_BASE_URL=http://YOUR_OLLAMA_IP:11434
# Embedding (must be an embedding model — chat models won't work)
EMBEDDING_PROVIDER=ollama
OLLAMA_EMBEDDING_MODEL=nomic-embed-text
# Metadata extraction (any chat/instruct model works)
METADATA_LLM_PROVIDER=ollama
METADATA_LLM_MODEL=llama3.2
```
### Step 4: Create the PostgreSQL data directory
```bash
mkdir -p /mnt/user/appdata/open-mind/postgres
```
### Step 5: Verify Ollama is reachable
From your Unraid terminal, confirm Ollama responds:
```bash
curl http://YOUR_OLLAMA_IP:11434/api/tags
```
You should see a JSON list of models. If you get "connection refused", make sure Ollama is configured with `OLLAMA_HOST=0.0.0.0` so it listens on all interfaces.
Ensure the required models are pulled on your Ollama server:
```bash
ollama pull nomic-embed-text
ollama pull llama3.2 # or qwen3, mistral, etc.
```
### Step 6: Set up the Docker Compose stack in Unraid
The Unraid Docker Compose Manager stores compose files at its own path, so you **cannot** point it to the repo's `docker-compose.yml`. Instead:
1. In the Unraid web UI, go to **Docker → Compose**
2. Click **Add New Stack**, name it **OpenMind**
3. **Set the .env file path** to: `/mnt/user/appdata/open-mind/.env`
4. **Paste the following** into the compose editor:
```yaml
services:
postgres:
image: pgvector/pgvector:pg16
container_name: openmind-postgres
environment:
POSTGRES_DB: openmind
POSTGRES_USER: openmind
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
ports:
- "5433:5432"
volumes:
- /mnt/user/appdata/open-mind/postgres:/var/lib/postgresql/data
- /mnt/user/appdata/open-mind/drizzle/0000_initial_schema.sql:/docker-entrypoint-initdb.d/01-schema.sql
- /mnt/user/appdata/open-mind/drizzle/0001_extensions.sql:/docker-entrypoint-initdb.d/02-extensions.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U openmind"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
mcp-server:
build:
context: /mnt/user/appdata/open-mind
dockerfile: Dockerfile
container_name: openmind-mcp
ports:
- "3100:3100"
environment:
PORT: 3100
DATABASE_URL: postgresql://openmind:${POSTGRES_PASSWORD:-changeme}@postgres:5432/openmind
API_KEY: ${API_KEY:-changeme-generate-with-openssl-rand-hex-32}
EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-ollama}
OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://192.168.1.100:11434}
OLLAMA_EMBEDDING_MODEL: ${OLLAMA_EMBEDDING_MODEL:-nomic-embed-text}
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
OPENAI_CLIENT_ID: ${OPENAI_CLIENT_ID:-}
OPENAI_CLIENT_SECRET: ${OPENAI_CLIENT_SECRET:-}
OPENAI_REDIRECT_URI: ${OPENAI_REDIRECT_URI:-http://localhost:3100/auth/openai/callback}
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
METADATA_LLM_PROVIDER: ${METADATA_LLM_PROVIDER:-ollama}
METADATA_LLM_MODEL: ${METADATA_LLM_MODEL:-llama3.2}
ENABLED_EXTENSIONS: ${ENABLED_EXTENSIONS:-household-knowledge,home-maintenance,family-calendar,meal-planning,professional-crm,job-hunt-pipeline}
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
```
> **Important:** All paths are absolute (`/mnt/user/appdata/open-mind/...`) because the compose file is stored at the plugin's own location, not inside the repo directory. Do **not** include `version: '3.8'` — it's deprecated and will generate a warning.
5. Click **Compose Up**
### Step 7: Update the default user's API key
The database seeds a default user with a placeholder API key. You must update it to match your real key:
```bash
docker exec openmind-postgres psql -U openmind -d openmind -c \
"UPDATE users SET api_key = '$(grep API_KEY /mnt/user/appdata/open-mind/.env | cut -d= -f2)' WHERE name = 'default';"
```
Verify it took:
```bash
docker exec openmind-postgres psql -U openmind -d openmind -c \
"SELECT name, LEFT(api_key, 8) || '...' AS key_preview FROM users;"
```
### Step 8: Verify everything works
```bash
# Health check
curl http://localhost:3100/health
# Capture a test thought
curl -X POST http://localhost:3100/api/capture \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"content": "This is my first thought in Open Mind!", "source": "api"}'
# Verify in the database
docker exec openmind-postgres psql -U openmind -d openmind -c \
"SELECT id, LEFT(content, 50), embedding_model, source FROM thoughts;"
```
### Updating Open Mind on Unraid
When updates are available:
```bash
cd /mnt/user/appdata/open-mind
git pull
```
Then in the Unraid UI: **Compose Down** → **Update Stack** (or Compose Up). This rebuilds the MCP server image with the latest code. The PostgreSQL data persists across updates.
### Troubleshooting
| Problem | Fix |
|---------|-----|
| `extension "pgvector" is not available` | Verify the image is `pgvector/pgvector:pg16`: `docker inspect openmind-postgres \| grep Image` |
| `Invalid API key` | Run the Step 7 command to sync the DB user's key with your `.env` key |
| `Failed to capture thought` | Check `docker logs openmind-mcp --tail 30` for the real error |
| Ollama connection refused | Ensure Ollama has `OLLAMA_HOST=0.0.0.0` and test with `curl http://OLLAMA_IP:11434/api/tags` from Unraid |
| Compose Up reuses old image | Use **Update Stack** button, or manually: `docker rmi` the old image then Compose Up |
| `version` warning in compose | Safe to ignore, or remove the `version: '3.8'` line |
| PostgreSQL skips init on restart | Data dir has stale data. `rm -rf /mnt/user/appdata/open-mind/postgres/*` then Compose Up |
## Connecting to AI Tools
### OpenClaw
Add to your OpenClaw MCP config (`~/.openclaw/config.json` or equivalent):
```json
{
"mcpServers": {
"open-mind": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://YOUR_UNRAID_IP:3100/mcp"],
"env": {
"MCP_AUTH_TOKEN": "your-api-key"
}
}
}
}
```
### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"open-mind": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://YOUR_UNRAID_IP:3100/mcp"],
"env": {
"MCP_AUTH_TOKEN": "your-api-key"
}
}
}
}
```
### Any MCP Client
The MCP endpoint is `http://YOUR_UNRAID_IP:3100/mcp`. Authenticate with `Authorization: Bearer YOUR_API_KEY` header or `?key=YOUR_API_KEY` query parameter.
## Ollama Model Requirements
Open Mind uses **two models** for different purposes:
| Purpose | Config Variable | Model Type | Example |
|---------|----------------|-----------|---------|
| Embeddings (vector search) | `OLLAMA_EMBEDDING_MODEL` | **Embedding model** (required) | `nomic-embed-text` (~274MB) |
| Metadata extraction (tags, categories) | `METADATA_LLM_MODEL` | **Chat/instruct model** (any) | `llama3.2`, `qwen3`, `mistral` |
You **cannot** use a chat model for embeddings — it must be a dedicated embedding model like `nomic-embed-text`.
## Configuration Reference
See `.env.example` for all options. Key settings:
| Variable | Description | Default |
|----------|-------------|---------|
| `EMBEDDING_PROVIDER` | `ollama`, `openai`, or `openrouter` | `ollama` |
| `OLLAMA_BASE_URL` | Your Ollama server URL | `http://192.168.1.100:11434` |
| `OLLAMA_EMBEDDING_MODEL` | Ollama embedding model name | `nomic-embed-text` |
| `API_KEY` | Bearer token for authentication | — |
| `METADATA_LLM_PROVIDER` | `ollama`, `openai`, or `openrouter` | `ollama` |
| `METADATA_LLM_MODEL` | Chat model for metadata extraction | `llama3.2` |
| `ENABLED_EXTENSIONS` | Comma-separated list of extensions | all 6 enabled |
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues