{"id":45843745,"url":"https://github.com/mattmezza/mpa","last_synced_at":"2026-06-07T01:04:05.539Z","repository":{"id":340769598,"uuid":"1159882597","full_name":"mattmezza/mpa","owner":"mattmezza","description":"🤖 My Personal AI Agent (aka Matteo's Personal Assistant)","archived":false,"fork":false,"pushed_at":"2026-03-06T15:46:23.000Z","size":986,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-06T17:34:37.043Z","etag":null,"topics":["agent","agentic-ai","agentic-workflow","agents","assistant","assistant-chat-bots","assistants","calendar-assistant","chatbot","emailbot","openclaw","telegrambot","weather-assistent","whatsapp-bot"],"latest_commit_sha":null,"homepage":"https://matteo.merola.co/mpa","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mattmezza.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-17T09:27:32.000Z","updated_at":"2026-03-06T15:29:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mattmezza/mpa","commit_stats":null,"previous_names":["mattmezza/mpa"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/mattmezza/mpa","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattmezza%2Fmpa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattmezza%2Fmpa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattmezza%2Fmpa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattmezza%2Fmpa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattmezza","download_url":"https://codeload.github.com/mattmezza/mpa/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattmezza%2Fmpa/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34005032,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","agentic-ai","agentic-workflow","agents","assistant","assistant-chat-bots","assistants","calendar-assistant","chatbot","emailbot","openclaw","telegrambot","weather-assistent","whatsapp-bot"],"created_at":"2026-02-27T01:06:27.670Z","updated_at":"2026-06-07T01:04:05.525Z","avatar_url":"https://github.com/mattmezza.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MPA — My Personal Agent\n\nA 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.\n\n## Features\n\n- **Messaging** — Telegram (and WhatsApp) with text and voice messages\n- **Email** — Read, compose, and manage emails via [Himalaya](https://github.com/pimalaya/himalaya) CLI\n- **Calendar** — CalDAV integration (Google Calendar, iCloud, etc.)\n- **Contacts** — CardDAV providers via the built-in contacts CLI\n- **Memory** — Two-tier system: permanent long-term facts and expiring short-term context, both extracted automatically from conversations\n- **Scheduled tasks** — Cron-based jobs for morning briefings, email checks, contact sync, and custom tasks\n- **Voice** — Speech-to-text (faster-whisper) and text-to-speech (edge-tts)\n- **Web search** — Tavily integration for real-time information\n- **Permissions** — Glob-pattern rules (ALWAYS/ASK/NEVER) with interactive Telegram approval for write actions\n- **Admin UI** — Web dashboard for configuration, skills editing, memory inspection, job management, and agent lifecycle control\n- **Skills** — Teach the agent new capabilities by writing markdown files instead of code\n- **Setup wizard** — Step-by-step first-boot configuration via the admin UI\n\n## Architecture\n\nMPA follows a **Python orchestrator + CLI tools** design. Python glues everything together, while battle-tested CLI tools handle protocol complexity:\n\n| Concern | Tool |\n|---------|------|\n| LLM | Anthropic Claude, OpenAI, Grok (xAI), DeepSeek |\n| Email | Himalaya CLI (Rust) |\n| Contacts | Built-in contacts CLI |\n| Calendar | python-caldav |\n| Storage | SQLite (4 databases) |\n| Voice | faster-whisper (STT) + edge-tts (TTS) |\n| Admin UI | FastAPI + HTMX + Tailwind CSS |\n\nInstead 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.\n\n## Quick start\n\n### Prerequisites\n\n- Docker and Docker Compose\n- An [Anthropic API key](https://console.anthropic.com/)\n- A [Telegram bot token](https://core.telegram.org/bots#botfather)\n\n### 1. Clone and configure\n\n```bash\ngit clone https://github.com/mattmezza/mpa.git\ncd mpa\ncp .env.example .env\ncp config.yml.example config.yml\ncp character.md.example character.md\ncp personalia.md.example personalia.md\n```\n\nEdit `.env` with your API keys and secrets. Edit `config.yml` to customize the agent name, owner, channels, calendar providers, and scheduled jobs.\n\n### 2. Run with Docker Compose\n\n```bash\ndocker compose up -d\n```\n\nThe 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.\n\n### 3. Run without Docker\n\nRequires Python 3.14+ and [uv](https://docs.astral.sh/uv/).\n\n```bash\nmake setup       # creates venv, installs deps, copies example configs\n# edit .env and config.yml\nmake run         # starts the agent\n```\n\n## Configuration\n\nMPA uses a dual-layer config system:\n\n- **`config.yml`** + **`.env`** — File-based seed config loaded on first boot. Supports `${ENV_VAR}` interpolation.\n- **SQLite config store** (`data/config.db`) — Becomes the source of truth after setup. Managed through the admin UI.\n\n### Key files\n\n| File | Purpose |\n|------|---------|\n| `.env` | API keys and secrets |\n| `config.yml` | Agent settings, channels, calendar, scheduler jobs |\n| `character.md` | Agent personality and communication style (editable) |\n| `personalia.md` | Agent identity facts — name, owner, context (append-only) |\n| `skills/*.md` | Skill documents that teach the agent how to use tools |\n| `cli-configs/` | Configuration for Himalaya |\n\n## Project structure\n\n```\ncore/           Core agent modules\n  agent.py        LLM tool-use loop\n  config.py       Pydantic config models, YAML loader\n  config_store.py SQLite-backed config store + setup wizard\n  executor.py     CLI command executor with prefix whitelist\n  history.py      Conversation history persistence\n  main.py         Entry point, lifecycle management\n  memory.py       Two-tier memory extraction + consolidation\n  permissions.py  Permission engine with approval flow\n  scheduler.py    APScheduler wrapper for cron/one-shot jobs\n  skills.py       Skills store + lazy loading for LLM\nchannels/       Communication channels\n  telegram.py     Telegram bot (text, voice, approvals)\napi/            Admin web interface\n  admin.py        FastAPI routes + HTMX partials\n  templates/      Jinja2 templates\n  static/         CSS (Tailwind)\nvoice/          Voice pipeline\n  pipeline.py     Whisper STT + edge-tts TTS\ntools/          CLI helper scripts\n  calendar_read.py   CalDAV event reader\n  calendar_write.py  CalDAV event creator\n  wacli/              WhatsApp CLI (vendor)\nskills/         Markdown skill files\nschema/         Database schemas\ntests/          Test suite\ndata/           Runtime SQLite databases (gitignored)\n```\n\n## Development\n\n```bash\nmake install-dev   # install all dependencies including dev tools\nmake dev           # auto-restart on code changes + CSS watch\nmake test          # run tests\nmake lint          # lint with ruff\nmake format        # format with ruff\nmake css           # build minified CSS\n```\n\n### Running tests\n\n```bash\nuv run pytest          # run all tests\nuv run pytest -n auto  # run in parallel\n```\n\n## Skills\n\nSkills 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.\n\nExample skills included:\n- `himalaya-email.md` — Email management via Himalaya CLI\n- `contacts.md` — Contact lookup and management\n- `caldav-calendar.md` — Calendar event reading and creation\n- `memory.md` — Memory querying via sqlite3\n- `voice.md` — Voice response conventions\n- `weather.md` — Weather lookups\n- `jq.md` — JSON processing\n\nCreate new skills by adding `.md` files to `skills/`, through the admin UI's skill editor, or via the skills CLI:\n\n```bash\npython3 /app/tools/skills.py upsert --name my-skill --stdin\n```\n\nBehavior and identity are configured in `character.md.example` and `personalia.md.example`.\n\n## WhatsApp\n\nMPA uses wacli to authenticate and sync WhatsApp locally. The admin UI starts auth, displays the QR code, and manages sync.\nSee `tools/wacli/` for the vendored CLI source and build instructions.\n\n## Tech stack\n\n- **Python 3.14** with **uv** for package management\n- **Anthropic Claude**, **OpenAI**, **Grok (xAI)**, or **DeepSeek** as the LLM backend\n- **SQLite** via aiosqlite for all persistence\n- **FastAPI** + **Jinja2** + **HTMX** + **Alpine.js** + **Tailwind CSS v4** for the admin UI\n- **python-telegram-bot** for the Telegram channel\n- **APScheduler** for cron jobs\n- **faster-whisper** + **edge-tts** for voice\n- **ruff** for linting and formatting\n- **pytest** with asyncio and xdist for testing\n- **Docker** for production deployment\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Run `make lint` and `make test`\n5. Open a pull request\n\n## License\n\nSee [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattmezza%2Fmpa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattmezza%2Fmpa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattmezza%2Fmpa/lists"}