A memory-augmented chat interface that works with any LLM backend.
Features | Quick Start | Configuration | Usage | API | Development
Cathedral is a self-hosted chat interface with automatic context injection from a persistent knowledge store.
The core idea: relevant memories and documents are retrieved and injected into the prompt before the LLM sees your message. The agent doesn't need to "decide" to search memory - it just has the context. No tool calls required.
Your message arrives
↓
Cathedral retrieves relevant memories + documents (semantic search)
↓
Context is assembled: system prompt → your message → memories → documents → history
↓
Sent to any LLM backend (OpenRouter, Claude CLI, local models, etc.)
↓
Response stored, knowledge extracted for future recall
Works with any LLM provider - cloud APIs via OpenRouter, local models, or CLI tools. The memory layer sits above your choice of backend.
Beyond the core memory system, Cathedral includes optional capabilities: file access, shell commands, web browsing, tool calling, and multi-modal support. Enable what you need, ignore what you don't.
Built with FastAPI, PostgreSQL + pgvector, and designed for local deployment.
| Feature | Description |
|---|---|
| Multi-Thread Chats | Independent conversation threads with separate histories |
| Semantic Search | All messages embedded and searchable via vector similarity |
| Thread Summaries | Automatic summarization of long conversations |
| Personality Per Thread | Different agent behaviors for different threads |
| Context Injection | Automatic retrieval of relevant past conversations |
| Feature | Description |
|---|---|
| Observations | Store facts with confidence scores and domains |
| Concepts | Knowledge graph nodes with relationships |
| Patterns | Synthesized insights across conversations |
| Auto-Extraction | Background extraction of knowledge from chats |
| Knowledge Discovery | Async discovery of relationships via embeddings |
| Feature | Description |
|---|---|
| Document Storage | Store files with automatic organization |
| Content Extraction | Extract text from PDFs, images, audio |
| Semantic Search | Find documents by meaning, not just keywords |
| RAG Context | Automatically inject relevant documents into prompts |
| Multiple Types | Documents, images, audio, artifacts, threads |
| Feature | Description |
|---|---|
| Provider-Agnostic | JSON-in-text protocol works with any LLM |
| 31 Tools | Across 6 Gates: Memory, Files, Shell, Scripture, Browser, SubAgents |
| Policy Control | 5 policy classes: READ_ONLY, WRITE, DESTRUCTIVE, PRIVILEGED, NETWORK |
| Bounded Execution | Configurable limits (iterations, calls per step, total calls) |
| Configurable Prompt | Versioned, editable system prompt with safe fallback |
| UI Integration | Tools toggle, inline execution display, protocol editor |
| Feature | Description |
|---|---|
| Secure Shell | Command execution with blocklist/allowlist validation |
| File Management | Folder-based permissions with auto-backup |
| Web Browsing | Multi-provider search (DuckDuckGo, Brave, SearXNG) |
| Page Fetching | Simple or headless browser with content conversion |
| Sub-Agents | Spawn async worker tasks for background processing |
| Browser Extension | WebSocket server for browser integration |
| Feature | Description |
|---|---|
| Vision | Analyze images with vision-capable models |
| Image Description | Detailed image content descriptions |
| Image Comparison | Compare two images |
| Audio Transcription | Speech-to-text via Whisper API |
| Feature | Description |
|---|---|
| AES-256-GCM | Military-grade encryption for sensitive data |
| Argon2id | Secure password hashing |
| Session Locking | Timeout-based auto-lock |
| Path Validation | Prevent directory traversal attacks |
| Command Filtering | Block dangerous shell commands |
- Python 3.10+
- PostgreSQL 15+ with pgvector extension (or SQLite for testing)
- OpenRouter API key (for LLM access)
- OpenAI API key (for embeddings)
# Clone the repository
git clone https://github.com/PStryder/Cathedral.git
cd Cathedral
# Create virtual environment
python -m venv venv
source venv/bin/activate # Linux/Mac
# or: venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
# Optional: Local LLM for summarization
pip install -r requirements-llama.txt-- Create database
CREATE DATABASE cathedral;
\c cathedral
-- Enable pgvector extension
CREATE EXTENSION vector;# Set environment variable
export DATABASE_URL="postgresql://user:password@localhost:5432/cathedral"# SQLite requires no setup - just set the URL
export DATABASE_URL="sqlite+aiosqlite:///./data/cathedral.db"
export DB_BACKEND="sqlite"
export VECTOR_BACKEND="faiss"# Copy example environment file
cp .env.example .env
# Edit with your settings
nano .env # or your preferred editorMinimum required settings:
# Database
DATABASE_URL=postgresql://user:pass@localhost:5432/cathedral
# API Keys
OPENROUTER_API_KEY=sk-or-v1-...
OPENAI_API_KEY=sk-...# Production
python -m altar.run
# Development (with auto-reload)
uvicorn altar.run:app --reload --port 8000Open http://localhost:8000 in your browser.
Cathedral uses a layered configuration system:
- Environment variables (highest priority)
data/config.json(persistent settings)- Schema defaults (lowest priority)
Access the configuration UI at /config or use the REST API.
| Setting | Description | Required |
|---|---|---|
OPENROUTER_API_KEY |
OpenRouter API key for LLM access | Yes |
OPENAI_API_KEY |
OpenAI API key for embeddings | Yes |
| Setting | Description | Default |
|---|---|---|
DATABASE_URL |
Database connection string | Required |
DB_BACKEND |
Database type: postgres or sqlite |
postgres |
VECTOR_BACKEND |
Vector store: pgvector or faiss |
pgvector |
AUTO_MIGRATE_ON_STARTUP |
Auto-create tables | true |
AUTO_CREATE_EXTENSIONS |
Auto-create pgvector extension | true |
| Setting | Description | Default |
|---|---|---|
DEFAULT_MODEL |
Default LLM model | openai/gpt-4o |
VISION_MODEL |
Vision-capable model | openai/gpt-4o |
EMBEDDING_MODEL |
Embedding model | text-embedding-3-small |
EMBEDDING_DIM |
Embedding dimensions | 1536 |
LOOMMIRROR_MODEL_PATH |
Path to local GGUF model | Optional |
| Setting | Description | Default |
|---|---|---|
HOST |
Server host | 0.0.0.0 |
PORT |
Server port | 8000 |
ALLOWED_ORIGINS |
CORS origins (comma-separated) | * |
DEBUG |
Debug mode | false |
LOG_LEVEL |
Logging level | INFO |
| Setting | Description | Default |
|---|---|---|
ENABLE_MEMORY_GATE |
Enable knowledge system | true |
ENABLE_SCRIPTURE_RAG |
Enable document RAG | true |
ENABLE_SUBAGENTS |
Enable sub-agent spawning | true |
ENABLE_MULTIMODAL |
Enable vision/audio | true |
AUTO_EXTRACT_MEMORY |
Auto-extract from conversations | true |
| Setting | Description | Default |
|---|---|---|
TOOL_PROTOCOL_PROMPT |
Custom tool protocol prompt | (built-in) |
TOOL_MAX_ITERATIONS |
Max tool execution loop iterations | 6 |
TOOL_MAX_CALLS_PER_STEP |
Max tool calls per iteration | 5 |
TOOL_MAX_TOTAL_CALLS |
Max total calls per request | 20 |
| Setting | Description | Default |
|---|---|---|
DATA_DIR |
Runtime data directory | data |
SCRIPTURE_DIR |
Document storage | data/scripture |
AGENTS_DIR |
Sub-agent data | data/agents |
MODELS_DIR |
Local model storage | models |
The primary interface is the web UI at http://localhost:8000/:
- Chat - Main conversation interface (with tools toggle)
- Config (
/config) - Configuration editor - Memory (
/memory) - Memory browser - Scripture (
/scripture) - Document library - Personalities (
/personalities) - Personality manager - Security (
/security) - Encryption settings - Files (
/files) - File browser - Shell (
/shell) - Command interface - Agents (
/agents) - Sub-agent manager - Tool Protocol (
/toolgate) - Tool calling configuration
Cathedral supports 60+ slash commands in the chat interface.
/history Show current thread history
/forget Clear thread memory
/export thread Export thread to scripture
/import bios <path> Import bios file
/import glyph <path> Import glyph file
/search <query> Semantic search across all memory
/usearch <query> Unified search (all sources)
/memory Show memory status
/remember <fact> Store an observation
/memories [domain] List memories by domain
/concept <name> Get concept details
/pattern <cat> <name> Get pattern details
/memstats Detailed memory statistics
/discover <text> Run knowledge discovery
/related <ref> Get related items
/discovery Discovery service status
/loomsearch <query> Search conversation memory
/backfill Backfill missing embeddings
/store <path> Store file as scripture
/scripture <ref> Get scripture by reference
/scriptsearch <query> Search documents
/scriptures [type] List documents
/scriptstats Document statistics
/scriptindex Re-index all documents
/image <path> Analyze image
/describe <path> Describe image content
/compare <p1> <p2> Compare two images
/transcribe <path> Transcribe audio
/audio <path> Audio analysis
/spawn <task> Spawn background agent
/agents List all agents
/agent <id> Get agent status
/result <id> Get agent result
/cancel <id> Cancel agent
/personalities List all personalities
/personality <id> Switch to personality
/personality Show current personality
/personality-info <id> Get personality details
/personality-create <n> Create new personality
/personality-delete <id> Delete personality
/personality-export <id> Export personality
/personality-copy <id> Duplicate personality
/sources List managed folders
/sources-add <id> <p> Add managed folder
/ls <folder:path> List directory
/cat <folder:path> Read file
/writefile <f:path> Write file
/mkdir <folder:path> Create directory
/rm <folder:path> Delete file/directory
/backups [folder] List backups
/restore <backup_id> Restore backup
/shell <cmd> Execute command
/shellbg <cmd> Execute in background
/shellstatus <id> Get command status
/shellkill <id> Cancel command
/shellhistory Command history
/websearch <query> Web search
/fetch <url> Fetch page content
/browse <query> Search + fetch top results
/lock Lock session
/security Security status
/security-status Detailed security status
/meta <target> Query metadata
/metafields List available fields
Cathedral exposes a comprehensive REST API. Full documentation available at /docs (Swagger UI) when the server is running.
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Main chat interface |
POST |
/api/chat/stream |
Stream chat response (SSE) |
GET |
/api/threads |
List conversation threads |
POST |
/api/thread |
Create/switch thread |
GET |
/api/thread/{uid}/history |
Get thread history |
GET |
/api/events |
Subscribe to events (SSE) |
GET |
/api/health |
System health status |
| Method | Endpoint | Description |
|---|---|---|
GET |
/toolgate |
Tool Protocol editor UI |
GET |
/api/toolgate/prompt |
Get current tool prompt config |
POST |
/api/toolgate/prompt |
Update tool prompt (requires acknowledgment) |
POST |
/api/toolgate/prompt/restore |
Restore default prompt |
GET |
/api/toolgate/prompt/validate |
Validate prompt syntax |
GET |
/api/toolgate/tools |
List available tools |
GET |
/api/toolgate/status |
ToolGate health status |
See docs/FEATURES.md for complete endpoint documentation including:
- 90+ REST endpoints across 13 routers
- Request/response formats
- Authentication requirements
- Example usage
Cathedral uses a "Gate" pattern where each subsystem is independently initialized and can be enabled/disabled:
┌─────────────────────────────────────────────────────────────────┐
│ FastAPI Server │
│ (altar/run.py) │
├─────────────────────────────────────────────────────────────────┤
│ API Routers │
│ chat | config | health | memory | scripture | personalities │
│ security | files | shell | browser | subagent | toolgate │
├─────────────────────────────────────────────────────────────────┤
│ Chat Pipeline │
│ (cathedral/pipeline/chat.py) │
├───────────┬───────────┬───────────┬───────────┬────────────────┤
│ StarMirror│ ToolGate │MemoryGate │Scripture │ Personality │
│ (LLM) │ (Tools) │(Knowledge)│ (RAG) │ (Agent) │
├───────────┼───────────┼───────────┼───────────┼────────────────┤
│FileSystem │ Shell │ Browser │ SubAgent │ Security │
│ (Files) │(Commands) │ (Web) │ (Workers) │ (Crypto) │
├───────────┴───────────┴───────────┴───────────┴────────────────┤
│ Shared Utilities │
│ (cathedral/shared: logging, config, db, paths) │
├─────────────────────────────────────────────────────────────────┤
│ Database Layer │
│ PostgreSQL + pgvector | SQLite + FAISS │
└─────────────────────────────────────────────────────────────────┘
User Input
│
├─ Slash Command? ──► Command Router ──► Gate Operations
│
└─ Regular Message:
│
├─ 1. Append to Loom (conversation memory)
│
├─ 2. Build Context (Cathedral Context Assembly Order):
│ ├─ [0] Tool Protocol prompt (if tools enabled)
│ ├─ [1] Personality system prompt
│ ├─ [2] Current user message
│ ├─ [3] Memory context (MemoryGate)
│ ├─ [4] RAG context (ScriptureGate)
│ └─ [5+] Prior conversation history
│
├─ 3. Call StarMirror (LLM)
│ └─ Stream tokens ──► SSE ──► Client
│
├─ 4. Tool Execution Loop (if tools enabled):
│ ├─ Parse tool calls from response
│ ├─ Execute via ToolGate orchestrator
│ ├─ Inject results into conversation
│ └─ Get next response (repeat until done)
│
├─ 5. Store Final Response in Loom
│
└─ 6. Post-Processing:
├─ Auto-extract memory
└─ Emit completion events
Cathedral/
├── altar/ # FastAPI server
│ ├── run.py # Application entry point
│ ├── lifecycle.py # Startup/shutdown handlers
│ ├── api/ # REST API routers
│ │ ├── chat.py # Chat endpoints
│ │ ├── config.py # Configuration endpoints
│ │ ├── health.py # Health check endpoints
│ │ ├── memory.py # MemoryGate endpoints
│ │ ├── scripture.py # ScriptureGate endpoints
│ │ ├── personalities.py # Personality endpoints
│ │ ├── security.py # Security endpoints
│ │ ├── files.py # FileSystemGate endpoints
│ │ ├── shell.py # ShellGate endpoints
│ │ ├── browser.py # BrowserGate endpoints
│ │ ├── subagent.py # SubAgentGate endpoints
│ │ ├── toolgate.py # ToolGate endpoints
│ │ └── events.py # SSE events endpoint
│ ├── services/ # Event bus, agent tracker
│ ├── middleware/ # Security middleware
│ ├── templates/ # Jinja2 HTML templates
│ └── static/ # CSS, JS, images
│
├── cathedral/ # Core subsystems
│ ├── StarMirror/ # LLM interface
│ │ ├── router.py # Multi-backend routing
│ │ └── providers/ # OpenRouter, OpenClaw, Claude CLI, Codex
│ ├── MemoryGate/ # Knowledge system
│ │ ├── conversation/ # Loom conversation memory
│ │ └── discovery.py # Knowledge discovery
│ ├── ScriptureGate/ # Document library
│ │ ├── storage.py # File storage
│ │ ├── indexer.py # Embedding generation
│ │ └── models.py # Database models
│ ├── PersonalityGate/ # Personality management
│ │ ├── models.py # Personality schema
│ │ └── defaults.py # Built-in personalities
│ ├── SecurityManager/ # Encryption & auth
│ │ ├── crypto.py # AES-256-GCM + Argon2
│ │ └── session.py # Session management
│ ├── FileSystemGate/ # File access control
│ │ ├── security.py # Path validation
│ │ ├── operations.py # File operations
│ │ └── backup.py # Backup management
│ ├── ShellGate/ # Command execution
│ │ ├── security.py # Command validation
│ │ └── executor.py # Process execution
│ ├── BrowserGate/ # Web access
│ │ ├── providers/ # Search providers
│ │ ├── fetcher.py # Page fetching
│ │ └── websocket_server.py # Browser extension
│ ├── SubAgentGate/ # Worker agents
│ ├── ToolGate/ # Tool calling system
│ │ ├── models.py # Protocol types (ToolCall, ToolResult)
│ │ ├── registry.py # Tool registry (31 tools)
│ │ ├── protocol.py # JSON parsing/validation
│ │ ├── orchestrator.py # Execution loop
│ │ ├── policy.py # Policy management
│ │ ├── prompt.py # Tool prompt generation
│ │ └── prompt_config.py # Configurable prompt storage
│ ├── MetadataChannel/ # Metadata routing
│ ├── Memory/ # Unified memory interface
│ ├── Config/ # Configuration management
│ │ └── schema.py # Config schema definition
│ ├── commands/ # Slash command router
│ ├── pipeline/ # Chat processing pipeline
│ ├── runtime.py # Lazy-loaded proxies
│ └── shared/ # Shared utilities
│ ├── gate.py # Gate base utilities
│ ├── db.py # Database abstraction
│ └── db_service.py # DB initialization
│
├── data/ # Runtime data
│ ├── config.json # Persistent configuration
│ ├── personalities/ # Custom personalities
│ ├── scripture/ # Document storage
│ ├── agents/ # Sub-agent data
│ └── backups/ # File backups
│
├── models/ # Local models
│ └── memory/ # LoomMirror GGUF models
│
├── tests/ # Test suite
│ ├── conftest.py # Pytest fixtures
│ ├── test_*.py # Unit tests
│ └── ...
│
├── docs/ # Documentation
│ └── FEATURES.md # Complete feature reference
│
├── .env.example # Environment template
├── requirements.txt # Python dependencies
├── requirements-llama.txt # Local LLM dependencies
└── pytest.ini # Pytest configuration
| Layer | Technology |
|---|---|
| Backend | FastAPI 0.115+ / Uvicorn |
| Database | PostgreSQL 15+ with pgvector (or SQLite + FAISS) |
| ORM | SQLAlchemy 2.0 (async) |
| LLM API | OpenRouter (40+ models) / OpenClaw Gateway |
| Local LLM | llama-cpp-python (TinyLlama 1.1B for summarization) |
| Embeddings | OpenAI text-embedding-3-small (1536 dim) |
| Encryption | AES-256-GCM + Argon2id (via cryptography lib) |
| Events | Server-Sent Events (SSE) |
| Frontend | Jinja2 templates + vanilla JS + Tailwind CSS |
| Search | DuckDuckGo / SearXNG / Brave |
| Tool Calling | Provider-agnostic JSON-in-text protocol (31 tools) |
# With auto-reload
uvicorn altar.run:app --reload --port 8000
# With debug logging
DEBUG=true LOG_LEVEL=DEBUG python -m altar.run# All tests
pytest tests/
# With coverage
pytest tests/ --cov=cathedral --cov-report=html
# Specific test file
pytest tests/test_filesystemgate.py -v
# Skip slow/network tests
pytest tests/ -m "not slow and not network"# Type checking
mypy cathedral/
# Linting
ruff check cathedral/
# Formatting
ruff format cathedral/Cathedral uses auto-migration by default. Tables are created on startup.
# Disable auto-migration
AUTO_MIGRATE_ON_STARTUP=false
# Manual migration (if needed)
python -c "from cathedral.shared.db_service import init_db; init_db('your-url')"- Create module in
cathedral/NewGate/ - Implement
__init__.pywith:initialize()functionis_healthy()health checkget_health_status()detailed status__all__exports
- Add to
cathedral/__init__.pyexports - Initialize in
altar/lifecycle.py - Create API router in
altar/api/newgate.py - Add router to
altar/run.py - Add tests in
tests/test_newgate.py - (Optional) Register tools in
cathedral/ToolGate/registry.pyfor agentic access
# Dockerfile example
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "-m", "altar.run"]- Use PostgreSQL (not SQLite) for production
- Set
DEBUG=false - Configure
ALLOWED_ORIGINSfor CORS - Use environment variables for secrets (not
.env) - Enable HTTPS via reverse proxy (nginx/caddy)
- Set up database backups
- Monitor with
/api/healthendpoint - Configure log aggregation
⚠️ SECURITY WARNINGDo not expose Cathedral to the public internet without authentication and network restrictions.
Cathedral provides powerful system access (shell commands, file operations, tool execution). Default deployment should be LAN-only or VPN-only.
- VPN-only (Tailscale/WireGuard) — simplest, strong security
- Reverse proxy + SSO (OAuth2 Proxy / Authelia / Keycloak) — enterprise
- Mutual TLS (mTLS) — for high-security environments
- Basic Auth — bare minimum; acceptable for home lab behind VPN
server {
listen 443 ssl http2;
server_name cathedral.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# ⚠️ BASIC AUTH - minimum viable authentication
# Create with: htpasswd -c /etc/nginx/.htpasswd username
auth_basic "Cathedral";
auth_basic_user_file /etc/nginx/.htpasswd;
# Forward client identity
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
# SSE support (required for streaming responses)
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 1h;
# WebSocket support (if needed)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}- Lock down
ALLOWED_ORIGINS— Don't leave as*in production - Restrict dangerous endpoints — Consider IP-restricting ShellGate, ToolGate prompt editing, and security reset endpoints
- Use firewall rules — Limit access to trusted networks even with auth enabled
-- Connect to your database and run:
CREATE EXTENSION vector;Or set AUTO_CREATE_EXTENSIONS=true in your environment.
Ensure you're running from the project root:
cd /path/to/Cathedral
python -m altar.run- Check your
OPENROUTER_API_KEYis valid - Verify the model name is correct (e.g.,
openai/gpt-4o) - Check your OpenRouter account has credits
- Check your
OPENAI_API_KEYis valid - Ensure the embedding model exists (
text-embedding-3-small) - Check OpenAI API status
- Verify PostgreSQL is running
- Check
DATABASE_URLformat:postgresql://user:pass@host:port/dbname - Ensure the database exists and user has permissions
Install aiosqlite:
pip install aiosqlite- Check the docs/FEATURES.md for complete API reference
- Review server logs (
LOG_LEVEL=DEBUGfor verbose output) - Check
/api/healthfor system status - Open an issue on GitHub
⚠️ Cathedral is designed for local/private deployment only.It provides powerful system access including shell commands, file operations, and AI-driven tool execution. Never expose it to the public internet without proper authentication and network restrictions.
- Default to LAN/VPN only — Do not expose to public internet without authentication
- Use reverse proxy with auth — Basic Auth minimum; SSO/OAuth2 preferred
- Lock down
ALLOWED_ORIGINS— Never use*in production - Firewall rules — Restrict access to trusted networks
These endpoints provide powerful system access and should be restricted:
| Endpoint | Risk | Recommendation |
|---|---|---|
/shell, /api/shell/* |
Command execution | IP-restrict or disable |
/api/toolgate/prompt |
Can modify AI behavior | Require explicit auth |
/api/security/reset |
Factory reset | IP-restrict to localhost |
/api/files/* (write) |
File system modification | Limit folder permissions |
- Use strong passwords — Argon2id is secure, but weak passwords aren't
- Review shell blocklist — Check ShellGate configuration for your environment
- Limit folder access — Only grant
read_writeto necessary folders - Protect API keys — Use environment variables, not
.envin production - Regular backups — Enable FileSystemGate auto-backup feature
- Default policy is READ_ONLY — Explicitly enable WRITE/PRIVILEGED/DESTRUCTIVE
- Custom prompts require acknowledgment — Prevents accidental misconfiguration
- Bounded execution — Max iterations and call limits prevent runaway loops
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure tests pass (
pytest tests/) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow existing code patterns
- Add docstrings to public functions
- Include
__all__exports in modules - Write tests for new features
- Update documentation as needed
MIT License - see the LICENSE file for details.
- FastAPI - Modern Python web framework
- OpenRouter - LLM API aggregator
- pgvector - Vector similarity for PostgreSQL
- llama.cpp - Local LLM inference