Open Mind
Self-hosted personal knowledge base with semantic search, enabling AI agents to capture, search, and manage thoughts using PostgreSQL with pgvector.
README
Open Mind
Self-hosted personal knowledge infrastructure for AI agents. Inspired by OB1 (Open Brain), 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)
# 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 likellama3.2,qwen3, ormistral(metadata extraction)
Step 1: Generate your API key
From any terminal:
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:
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:
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
cp .env.example .env
nano .env
Fill in these values:
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
mkdir -p /mnt/user/appdata/open-mind/postgres
Step 5: Verify Ollama is reachable
From your Unraid terminal, confirm Ollama responds:
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:
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:
- In the Unraid web UI, go to Docker → Compose
- Click Add New Stack, name it OpenMind
- Set the .env file path to:
/mnt/user/appdata/open-mind/.env - Paste the following into the compose editor:
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 includeversion: '3.8'— it's deprecated and will generate a warning.
- 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:
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:
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
# 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:
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):
{
"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:
{
"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
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.