A self-hosted personal AI agent that runs in a single Docker container. MPA acts as a unified interface across messaging channels (Telegram, WhatsApp), email, calendars, and contacts β capable of autonomous action, scheduled tasks, voice interaction, and persistent memory.
- Messaging β Telegram (and WhatsApp) with text and voice messages
- Email β Read, compose, and manage emails via Himalaya CLI
- Calendar β CalDAV integration (Google Calendar, iCloud, etc.)
- Contacts β CardDAV providers via the built-in contacts CLI
- Memory β Two-tier system: permanent long-term facts and expiring short-term context, both extracted automatically from conversations
- Scheduled tasks β Cron-based jobs for morning briefings, email checks, contact sync, and custom tasks
- Voice β Speech-to-text (faster-whisper) and text-to-speech (edge-tts)
- Web search β Tavily integration for real-time information
- Permissions β Glob-pattern rules (ALWAYS/ASK/NEVER) with interactive Telegram approval for write actions
- Admin UI β Web dashboard for configuration, skills editing, memory inspection, job management, and agent lifecycle control
- Skills β Teach the agent new capabilities by writing markdown files instead of code
- Setup wizard β Step-by-step first-boot configuration via the admin UI
MPA follows a Python orchestrator + CLI tools design. Python glues everything together, while battle-tested CLI tools handle protocol complexity:
| Concern | Tool |
|---|---|
| LLM | Anthropic Claude, OpenAI, Grok (xAI), DeepSeek |
| Himalaya CLI (Rust) | |
| Contacts | Built-in contacts CLI |
| Calendar | python-caldav |
| Storage | SQLite (4 databases) |
| Voice | faster-whisper (STT) + edge-tts (TTS) |
| Admin UI | FastAPI + HTMX + Tailwind CSS |
Instead of hardcoded integrations, the agent learns to use CLI tools via markdown "skill" files in skills/. Adding a new capability means writing a markdown file and adding the tool's command prefix to the executor whitelist.
- Docker and Docker Compose
- An Anthropic API key
- A Telegram bot token
git clone https://github.com/mattmezza/mpa.git
cd mpa
cp .env.example .env
cp config.yml.example config.yml
cp character.md.example character.md
cp personalia.md.example personalia.mdEdit .env with your API keys and secrets. Edit config.yml to customize the agent name, owner, channels, calendar providers, and scheduled jobs.
docker compose up -dThe admin UI will be available at http://localhost:8000. On first boot, MPA starts in setup mode β a wizard walks you through the initial configuration.
Requires Python 3.14+ and uv.
make setup # creates venv, installs deps, copies example configs
# edit .env and config.yml
make run # starts the agentMPA uses a dual-layer config system:
config.yml+.envβ File-based seed config loaded on first boot. Supports${ENV_VAR}interpolation.- SQLite config store (
data/config.db) β Becomes the source of truth after setup. Managed through the admin UI.
| File | Purpose |
|---|---|
.env |
API keys and secrets |
config.yml |
Agent settings, channels, calendar, scheduler jobs |
character.md |
Agent personality and communication style (editable) |
personalia.md |
Agent identity facts β name, owner, context (append-only) |
skills/*.md |
Skill documents that teach the agent how to use tools |
cli-configs/ |
Configuration for Himalaya |
core/ Core agent modules
agent.py LLM tool-use loop
config.py Pydantic config models, YAML loader
config_store.py SQLite-backed config store + setup wizard
executor.py CLI command executor with prefix whitelist
history.py Conversation history persistence
main.py Entry point, lifecycle management
memory.py Two-tier memory extraction + consolidation
permissions.py Permission engine with approval flow
scheduler.py APScheduler wrapper for cron/one-shot jobs
skills.py Skills store + lazy loading for LLM
channels/ Communication channels
telegram.py Telegram bot (text, voice, approvals)
api/ Admin web interface
admin.py FastAPI routes + HTMX partials
templates/ Jinja2 templates
static/ CSS (Tailwind)
voice/ Voice pipeline
pipeline.py Whisper STT + edge-tts TTS
tools/ CLI helper scripts
calendar_read.py CalDAV event reader
calendar_write.py CalDAV event creator
wacli/ WhatsApp CLI (vendor)
skills/ Markdown skill files
schema/ Database schemas
tests/ Test suite
data/ Runtime SQLite databases (gitignored)
make install-dev # install all dependencies including dev tools
make dev # auto-restart on code changes + CSS watch
make test # run tests
make lint # lint with ruff
make format # format with ruff
make css # build minified CSSuv run pytest # run all tests
uv run pytest -n auto # run in parallelSkills are markdown documents stored in SQLite that teach the agent how to use CLI tools. Seed files in skills/ are loaded into the DB at startup. The agent loads skills on-demand during conversations.
Example skills included:
himalaya-email.mdβ Email management via Himalaya CLIcontacts.mdβ Contact lookup and managementcaldav-calendar.mdβ Calendar event reading and creationmemory.mdβ Memory querying via sqlite3voice.mdβ Voice response conventionsweather.mdβ Weather lookupsjq.mdβ JSON processing
Create new skills by adding .md files to skills/, through the admin UI's skill editor, or via the skills CLI:
python3 /app/tools/skills.py upsert --name my-skill --stdinBehavior and identity are configured in character.md.example and personalia.md.example.
MPA uses wacli to authenticate and sync WhatsApp locally. The admin UI starts auth, displays the QR code, and manages sync.
See tools/wacli/ for the vendored CLI source and build instructions.
- Python 3.14 with uv for package management
- Anthropic Claude, OpenAI, Grok (xAI), or DeepSeek as the LLM backend
- SQLite via aiosqlite for all persistence
- FastAPI + Jinja2 + HTMX + Alpine.js + Tailwind CSS v4 for the admin UI
- python-telegram-bot for the Telegram channel
- APScheduler for cron jobs
- faster-whisper + edge-tts for voice
- ruff for linting and formatting
- pytest with asyncio and xdist for testing
- Docker for production deployment
- Fork the repository
- Create a feature branch
- Make your changes
- Run
make lintandmake test - Open a pull request
See LICENSE for details.