This guide explains how to run the Umbra Personal Assistant in Docker containers.
┌─────────────────────────────────────────────────────────────────────────┐
│ DOCKER COMPOSE NETWORK │
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ claude (Claude Code) │ │
│ │ - Claude Code CLI (sandboxed) │ │
│ │ - qmd (semantic search) │ │
│ │ - Read-only vault access │ │
│ │ - Read-write / folder (self-modifying) │ │
│ │ - Connects to MCPs via HTTP/SSE │ │
│ └──────────────────────────────────────────────────────────────────┬─┘ │
│ │ │
│ ┌────────────────────┬───────────────────┬──────────────────┘ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ obsidian │ │ gmail │ │ calendar │ │
│ │ :4001 │ │ :4002 │ │ :4003 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
- Docker Desktop or Docker Engine with Docker Compose
- Anthropic account with Claude Code subscription (or API key)
- Google Cloud credentials for Gmail and Calendar APIs
- Obsidian vault accessible on your filesystem
cd umbra
# Copy environment template
cp .env.example .env
# Edit .env with your paths
nano .envClaude Code requires authentication. Run this on your host machine first:
# Install Claude Code if not already installed
npm install -g @anthropic-ai/claude-code
# Login with your Anthropic account
claude loginYour credentials are saved to ~/.claude/ and will be mounted into the container.
./setup.shThis will:
- Validate your configuration
- Build Docker images
- Guide you through OAuth setup for Gmail and Calendar
# Start all services
docker compose up -d
# Run Claude Code interactively
docker compose run --rm claude# Anthropic Authentication
# Option 1: API Key
ANTHROPIC_API_KEY=sk-ant-api03-your-key
# Option 2: Subscription (via mounted ~/.claude config)
CLAUDE_CONFIG_PATH=${HOME}/.claude
# Paths
OBSIDIAN_VAULT_PATH=/path/to/your/obsidian/vault
# OAuth Credentials (from Google Cloud Console)
GMAIL_CREDENTIALS_PATH=${HOME}/.config/umbra/gmail-credentials.json
CALENDAR_CREDENTIALS_PATH=${HOME}/.config/umbra/calendar-credentials.json
# Ports (optional, for debugging)
MCP_OBSIDIAN_PORT=4001
MCP_GMAIL_PORT=4002
MCP_CALENDAR_PORT=4003- Go to Google Cloud Console
- Create a new project or select existing
- Enable Gmail API and Google Calendar API
- Create OAuth 2.0 credentials (Desktop app type)
- Download credentials JSON files
- Save as:
~/.config/umbra/gmail-credentials.json~/.config/umbra/calendar-credentials.json
# Start Claude Code with all MCPs
docker compose run --rm claude# Run a specific skill
docker compose run --rm claude --skill email-review
# Chat mode
docker compose run --rm claude chat# All services
docker compose logs -f
# Specific service
docker compose logs -f obsidian
docker compose logs -f gmail# Check all services
docker compose ps
# Individual health endpoints
curl http://localhost:4001/health # obsidian
curl http://localhost:4002/health # gmail
curl http://localhost:4003/health # calendar- Start the Gmail service:
docker compose up -d gmail - Visit http://localhost:4002/auth
- Complete OAuth flow
- Repeat for additional accounts
- Start the Calendar service:
docker compose up -d calendar - Visit http://localhost:4003/auth
- Complete OAuth flow
- Gmail: http://localhost:4002/accounts
- Calendar: http://localhost:4003/accounts
Both Gmail and Calendar support multiple Google accounts. Each service stores one token file per authenticated account.
- Single OAuth App: You create ONE OAuth app in Google Cloud Console
- Multiple Authentications: Each account is authenticated separately via
/authendpoint - Token Storage: Tokens are stored in a Docker volume (one file per account)
- Start the Gmail service:
docker compose up -d gmail - Visit http://localhost:4002/auth
- Sign in with a Google account and authorize
- Repeat steps 2-3 for each additional account
- View all accounts: http://localhost:4002/accounts
- Start the Calendar service:
docker compose up -d calendar - Visit http://localhost:4003/auth
- Sign in with a Google account and authorize
- Repeat for additional accounts
When using Gmail tools, specify which account:
list_accounts- shows all authenticated accounts- All other tools accept an
accountparameter (email address)
Calendar automatically aggregates events from all authenticated accounts.
For production, use the production compose override:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -dThis:
- Removes exposed ports (internal network only)
- Adds resource limits
- Enables restart policies
- Configures log rotation
- Claude container: Read-only vault access, can only interact via MCPs
- MCP containers: Limited filesystem access via bind mounts
- Network: Internal Docker network, no direct internet exposure
| Volume | Container | Access | Purpose |
|---|---|---|---|
| Obsidian vault | claude | read-only | qmd search |
| Obsidian vault | obsidian | read-write | Note operations (Asystent/ folder) |
/ |
claude | read-write | Self-modifying instructions |
| qmd-index | claude | read-write | Search index |
| OAuth tokens | gmail, calendar | read-write | Auth tokens |
| ~/.claude | claude | read-only | Auth credentials only |
The / folder is mounted read-write, allowing Claude to update its own:
CLAUDE.md- Core instructions.claude/skills/- Skill definitions.claude/settings.json- Permissions.mcp.json- MCP configuration
This enables the assistant to learn and improve its workflows. Changes are persisted to your local filesystem and can be committed to version control.
Security note: The .env file and secrets are NOT exposed to the assistant.
- Never commit
.envto version control - Store OAuth credentials securely
- Consider using Docker secrets for production
# Check logs
docker compose logs obsidian
# Rebuild images
docker compose build --no-cache- Ensure credentials file exists and is readable
- Check token directory permissions
- Re-authenticate: visit
/authendpoint
# Check if MCP service is healthy
docker compose ps
# Test health endpoint
curl http://localhost:4001/health# Enter claude container
docker compose exec claude bash
# Check qmd installation
qmd --version
# Initialize index
qmd index /vault# Pull latest changes
git pull
# Rebuild images
docker compose build
# Restart services
docker compose up -d# Stop and remove containers
docker compose down
# Remove volumes (WARNING: deletes OAuth tokens and qmd index)
docker compose down -v
# Remove images
docker compose down --rmi all