Your AI butler. Your server. Your data.
A privacy-first, self-hosted AI assistant that connects WhatsApp, Signal, calendars, contacts, and tasks — powered entirely by a local LLM with zero cloud dependencies.
Quickstart · Features · Docs · Security
Your messages live on someone else's server. Your calendar, your contacts, your tasks — accessible through APIs you don't control, processed by models you can't audit.
Niles takes it back.
One ./scripts/start.sh, and you have a personal AI assistant running on your hardware —
with WhatsApp and Signal integration, calendar management, task tracking, and a Notion-powered
knowledge base. All processed by a local LLM. No cloud. No subscription. No data leaving your network.
Self-hosted by design. Niles runs entirely on hardware you control. LLM inference happens locally via Ollama, per-user credentials are Fernet-encrypted at rest, and your data never leaves your server.
- Privacy by architecture, not by promise — 100% local LLM inference via Ollama. No cloud API calls, no telemetry, no data broker.
- Talk to it like a person — "Hey Niles, was steht morgen an?" via WhatsApp self-chat, Signal, or the web UI. Natural language in, tool calls under the hood.
- Connects your world — Calendar via CalDAV + ICS (incl. Google Calendar as read-only ICS subscription), contacts (CardDAV), tasks (Vikunja), knowledge base (Notion + pgvector RAG), web search (SearXNG), weather — one assistant for everything.
- Extensible via MCP — Add community tools via Model Context Protocol. Destructive operations are automatically blocked.
- Multi-user from day one — Google OAuth login, per-user WhatsApp sessions, per-user task lists.
- One command to run it — Docker Compose, auto-provisioned accounts, automated briefings. No manual wiring.
- WhatsApp self-chat via "Hey Niles" trigger (Evolution API, per-user instances)
- Signal integration as linked device (signal-cli-rest-api, WebSocket listener)
- Automated daily/weekly briefings via WhatsApp, Signal, or both (no LLM, template-based)
- Local LLM agent with tool-call loop (Ollama, llama3.1:8b default, max 5 rounds)
- Notion RAG knowledge base: sync, chunk, embed, pgvector search (nomic-embed-text-v2-moe)
- Web search (SearXNG meta search) + web page extraction (trafilatura, SSRF-protected)
- Persistent key-value memory injected into every conversation
- Multi-source calendar sync (CalDAV + ICS, incl. read-only Google Calendar via ICS) with event search and creation
- Task management via Vikunja (list, create, complete) with auto-provisioned per-user accounts
- Contact sync via CardDAV with multi-phone support
- Chat with SSE streaming, markdown rendering (marked.js + DOMPurify)
- Settings dashboard, calendar/contact/WhatsApp/Signal management
- Dark mode, WCAG accessibility (labels, ARIA, skip-link, focus-visible)
Prerequisites: Docker Desktop, Ollama (native on host), Python >= 3.14
# 1. Clone and configure
git clone https://github.com/gerfru/NilesAI.git Niles && cd Niles
cp .env.example .env
# Set: EVOLUTION_POSTGRES_PASSWORD, EVOLUTION_API_KEY, CREDENTIAL_ENCRYPTION_KEY
# 2. Pull the LLM model
ollama pull llama3.1:8b
# 3. Start homelab-gateway (HTTPS reverse proxy)
# See: https://github.com/gerfru/homelab-gateway
# 4. Start all services
./scripts/start.sh
# 5. Open Web UI
# https://niles.example.local/ui/loginFull walkthrough: docs/Deployment.md
| Deployment Guide | Complete setup: Ollama, OAuth, WhatsApp, Signal, CalDAV, Vikunja, Notion, Tailscale |
| API Reference | Every endpoint, auth methods, webhook configuration, request tracing |
| Development Guide | Local dev, testing, Docker workflow, conventions |
| Technical Spec | Architecture, components, database schema, configuration reference |
| RAG Architecture | Notion knowledge base: pipeline, chunking, embedding, retrieval |
| LLM Evaluation | Model comparison (llama3.1:8b vs mistral:7b), Claude-as-Judge framework |
| Quality Assessment | Codebase quality scores across 10 dimensions |
| Legal | Third-party licenses, WhatsApp risk disclosure, GDPR, EU AI Act |
Self-hosting your AI butler only helps if the app itself is hard to break into. Niles ships
with Argon2id password hashing, rate-limited auth, CSRF protection (double-submit), signed
httpOnly session cookies (SameSite=Lax), Fernet-encrypted per-user credentials, parameterized
queries (asyncpg), a strict nonce-based CSP ('strict-dynamic'), and SAST/SCA/container scanning
in CI (bandit, semgrep, pip-audit, Trivy, gitleaks, detect-secrets).
Vulnerability reports and threat model: SECURITY.md
| Layer | Technology |
|---|---|
| Backend | FastAPI (Python 3.14) · uvicorn |
| Web UI | Jinja2 · htmx · Tailwind CSS · SSE |
| LLM | Ollama (local, llama3.1:8b) |
| Embeddings | nomic-embed-text-v2-moe (Ollama, 768d) |
| Database | PostgreSQL 15 · pgvector · Alembic |
| Evolution API v2.3.7 | |
| Signal | signal-cli-rest-api (v0.13.24) |
| Tasks | Vikunja 1.1.0 |
| Knowledge Base | Notion API · pgvector RAG |
| Web Search | SearXNG (self-hosted, optional) |
| Reverse Proxy | homelab-gateway (Caddy · CoreDNS) |
| Extensions | MCP (Model Context Protocol) |
The LLM can invoke these tools during conversations:
| Tool | Description |
|---|---|
find_contact |
Search contacts by name (multi-phone support) |
send_whatsapp |
Send WhatsApp message (by name or number, per-user instance) |
get_whatsapp_messages |
Read WhatsApp chat history (last 30 days) |
send_signal |
Send Signal message (by name or number) |
get_signal_messages |
Read Signal chat history (last 30 days) |
find_event |
Search calendar events (CalDAV + ICS sources) |
create_event |
Create calendar event on writable source |
list_tasks / create_task / complete_task |
Vikunja task management |
remember / recall |
Persistent key-value memory |
search_notion |
Semantic search over Notion knowledge base (pgvector) |
mcp__fetch__fetch_url |
Fetch and extract text from web pages (SSRF-protected) |
mcp__searxng__web_search |
Web search via SearXNG (when enabled) |
mcp__weather__* |
Weather data (current + forecast, Open-Meteo) |
Additional MCP tools from external servers are automatically discovered.
# Install dependencies (requires uv: https://docs.astral.sh/uv/)
uv sync --frozen --extra dev
# Run tests
uv run pytest tests/ -v
# Run pre-commit hooks
pre-commit run --all-filesDevelopment Guide — testing, Docker workflow, conventions
AGPL-3.0-only — see LEGAL.md for third-party licenses and obligations.