Full Services Diagram
All services across life-manager and its integrated systems (messenger, LLM, voice, health).
System Diagram
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ USER INTERFACES │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────┐ │
│ │ Life-Manager UI │ │ Messenger Web │ │ macOS Menu Bar │ │ Claude Code │ │
│ │ (React SPA) │ │ (React SPA) │ │ (Swift Agent) │ │ (MCP Client) │ │
│ │ apricot:5700 │ │ messenger:5701 │ │ (local app) │ │ (stdio) │ │
│ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ └──────┬───────┘ │
└───────────┼──────────────────────┼──────────────────────┼─────────────────────┼──────────┘
│ │ │ │
▼ ▼ │ │
┌───────────────────┐ ┌───────────────────┐ │ │
│ Caddy :5700 │ │ Caddy :5701 │ │ │
│ (life-manager) │ │ (messenger) │ │ │
│ internal TLS │ │ internal TLS │ │ │
│ │ │ │ │ │
│ /api/* → :3700 │ │ /api/* → :3100 │ │ │
│ /socket.io/* │ │ /* → web dist │ │ │
│ /* → web dist │ │ │ │ │
└─────────┬─────────┘ └─────────┬─────────┘ │ │
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ BACKEND SERVICES │
│ │
│ ┌─────────────────────────────────────┐ ┌──────────────────────────────────────────┐ │
│ │ LIFE-MANAGER API :3700 │ │ MESSENGER SYNC API :3100 │ │
│ │ NestJS — /api prefix │ │ NestJS — /api prefix │ │
│ │ │ │ │ │
│ │ ┌───────────────────────────────┐ │ │ ┌────────────────────────────────────┐ │ │
│ │ │ CORE SERVICES │ │ │ │ DEVICE MANAGEMENT │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ Auth & Encryption │ │ │ │ /api/devices/register (POST) │ │ │
│ │ │ /api/auth/unlock (POST) │ │ │ │ /api/devices/verify (POST) │ │ │
│ │ │ /api/auth/lock (POST) │ │ │ │ /api/devices/:id/status (GET) │ │ │
│ │ │ /api/auth/status (GET) │ │ │ │ │ │ │
│ │ │ │ │ │ │ JWT token auth for device comms │ │ │
│ │ │ Credential Keyring │ │ │ └────────────────────────────────────┘ │ │
│ │ │ /api/credentials/* │ │ │ │ │
│ │ │ pgcrypto encrypted store │ │ │ ┌────────────────────────────────────┐ │ │
│ │ │ │ │ │ │ MESSAGE SYNC │ │ │
│ │ │ Settings │ │ │ │ │ │ │
│ │ │ /api/settings │ │ │ │ /api/sync/messages (POST) │ │ │
│ │ │ user_phone, user_awake │ │ │ │ /api/sync/contacts (POST) │ │ │
│ │ │ │ │ │ │ /api/sync/last/:id (GET) │ │ │
│ │ │ Service Health │ │ │ │ /api/sync/stats (GET) │ │ │
│ │ │ /api/services/status │ │ │ │ │ │ │
│ │ │ checks messenger :3100 │ │ │ │ Guards: JWT Bearer │ │ │
│ │ └───────────────────────────────┘ │ │ └────────────────────────────────────┘ │ │
│ │ │ │ │ │
│ │ ┌───────────────────────────────┐ │ │ ┌────────────────────────────────────┐ │ │
│ │ │ MESSENGER PROXY MODULE │ │ │ │ BROWSE API │ │ │
│ │ │ (forwards to messenger :3100)│ │ │ │ (read-only queries) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ /api/messages/conversations │──┼───┼─▶│ /api/browse/conversations (GET) │ │ │
│ │ │ /api/messages/folders │──┼───┼─▶│ /api/browse/folders (GET) │ │ │
│ │ │ /api/messages/search │──┼───┼─▶│ /api/browse/search (GET) │ │ │
│ │ │ /api/messages/stats │──┼───┼─▶│ /api/browse/stats (GET) │ │ │
│ │ │ /api/messages/self │──┼───┼─▶│ /api/messages/self (GET) │ │ │
│ │ │ /api/messages/queue-stats │──┼───┼─▶│ /api/send-queue/stats (GET) │ │ │
│ │ │ /api/messages/queue-history │──┼───┼─▶│ /api/send-queue/history (GET) │ │ │
│ │ │ /api/messages/attachment │ │ │ │ │ │ │
│ │ │ │ │ │ │ No auth (internal network) │ │ │
│ │ │ Auth: X-Service-Key header │ │ │ └────────────────────────────────────┘ │ │
│ │ └───────────────────────────────┘ │ │ │ │
│ │ │ │ ┌────────────────────────────────────┐ │ │
│ │ ┌───────────────────────────────┐ │ │ │ SEND QUEUE │ │ │
│ │ │ iMESSAGE AI LOOP │ │ │ │ │ │ │
│ │ │ (cron: every 1 min) │ │ │ │ /api/send-queue/enqueue (POST) │ │ │
│ │ │ │ │ │ │ /api/send-queue/pending (GET) │ │ │
│ │ │ Polls self-messages from │──┼───┼─▶│ /api/send-queue/:id/result(POST) │ │ │
│ │ │ messenger browse API │ │ │ │ /api/send-queue/stats (GET) │ │ │
│ │ │ Routes through agent system │ │ │ │ /api/send-queue/history (GET) │ │ │
│ │ │ Sends replies via send-queue │──┼───┼─▶│ │ │ │
│ │ │ │ │ │ │ Guards: JWT (device) or │ │ │
│ │ │ Only active when user_awake │ │ │ │ X-Service-Key (service) │ │ │
│ │ └───────────────────────────────┘ │ │ └────────────────────────────────────┘ │ │
│ │ │ │ │ │
│ │ ┌───────────────────────────────┐ │ │ ┌────────────────────────────────────┐ │ │
│ │ │ AI ASSISTANT │ │ │ │ EMAIL SYNC SERVICES │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ /api/conversations (CRUD) │ │ │ │ ProtonMailSyncService │ │ │
│ │ │ /api/conversations/:id/ask │ │ │ │ IMAP: localhost:1143 │ │ │
│ │ │ (SSE streaming) │ │ │ │ SMTP: localhost:1143 │ │ │
│ │ │ │ │ │ │ Poll interval: 60s │ │ │
│ │ │ /api/skills (CRUD) │ │ │ │ │ │ │
│ │ │ /api/models (list) │ │ │ │ ICloudSyncService │ │ │
│ │ │ │ │ │ │ IMAP: imap.mail.me.com:993 │ │ │
│ │ │ Agents: multi-agent routing │ │ │ │ SMTP: smtp.mail.me.com:587 │ │ │
│ │ │ Tools: file, exec, web, │ │ │ │ Poll interval: 60s │ │ │
│ │ │ memory, browser, search │ │ │ │ │ │ │
│ │ └──────────────┬────────────────┘ │ │ │ Credentials fetched from │ │ │
│ │ │ │ │ │ life-manager /api/credentials │ │ │
│ │ ▼ │ │ └────────────────────────────────────┘ │ │
│ │ ┌───────────────────────────────┐ │ │ │ │
│ │ │ LIFE-MANAGER FEATURES │ │ │ ┌────────────────────────────────────┐ │ │
│ │ │ │ │ │ │ CLASSIFICATION │ │ │
│ │ │ /api/tasks (CRUD) │ │ │ │ │ │ │
│ │ │ /api/habits (CRUD) │ │ │ │ MessageTypeClassifier │ │ │
│ │ │ /api/goals (CRUD) │ │ │ │ → message_types[] │ │ │
│ │ │ /api/health (CRUD) │ │ │ │ ContentModerator │ │ │
│ │ │ /api/finance (CRUD) │ │ │ │ → safety_flags[] │ │ │
│ │ │ /api/income (CRUD) │ │ │ │ │ │ │
│ │ │ /api/projects (CRUD) │ │ │ │ Triggers after message sync │ │ │
│ │ │ /api/contacts (CRUD) │ │ │ └────────────────────────────────────┘ │ │
│ │ │ /api/scheduling (CRUD) │ │ │ │ │
│ │ │ /api/diary (CRUD) │ │ │ ┌────────────────────────────────────┐ │ │
│ │ │ /api/learning (CRUD) │ │ │ │ MATRIX BRIDGE │ │ │
│ │ │ /api/checklists (CRUD) │ │ │ │ │ │ │
│ │ │ /api/consumables (CRUD) │ │ │ │ /api/matrix/send (POST) │ │ │
│ │ │ /api/routines (CRUD) │ │ │ │ MatrixSyncService │ │ │
│ │ │ /api/automations (CRUD) │ │ │ │ Homeserver: :8448 │ │ │
│ │ │ /api/notifications(CRUD) │ │ │ └────────────────────────────────────┘ │ │
│ │ │ /api/budgeting (CRUD) │ │ │ │ │
│ │ │ /api/analytics (read) │ │ │ ┌────────────────────────────────────┐ │ │
│ │ │ /api/today (read) │ │ │ │ HEALTH CHECK │ │ │
│ │ │ /api/ad-subscriptions │ │ │ │ │ │ │
│ │ │ /api/bookings │ │ │ │ /api/health/status (GET) │ │ │
│ │ │ /api/escort/checkins │ │ │ │ DB latency, device status │ │ │
│ │ │ /api/companion (lifecycle)│ │ │ └────────────────────────────────────┘ │ │
│ │ └───────────────────────────────┘ │ │ │ │
│ └─────────────────────────────────────┘ └──────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ MESSENGER MCP SERVER (stdio) │ │
│ │ TypeScript — connects directly to messenger Postgres │ │
│ │ │ │
│ │ Tools: │ │
│ │ list_conversations get_conversation get_contact search_messages │ │
│ │ get_conversation_stats send_message check_send_status │ │
│ │ cancel_message list_folders get_folder get_new_messages │ │
│ │ list_display_rules add_display_rule remove_display_rule │ │
│ │ │ │
│ │ Display Rules Engine: IFTTT conditions → persona overrides │ │
│ │ Send: enqueues via SQL directly into pending_messages table │ │
│ └─────────────────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ DATA LAYER │
│ │
│ ┌─────────────────────────────────┐ ┌────────────────────────────────────────────┐ │
│ │ PostgreSQL :25471 │ │ PostgreSQL :25432 │ │
│ │ DB: life_manager_prod │ │ DB: messenger │ │
│ │ │ │ │ │
│ │ Tables: │ │ Tables: │ │
│ │ tasks, habits, goals │ │ devices (macOS agents) │ │
│ │ health_measurements │ │ contacts (phone/email/name) │ │
│ │ medical_entries (encrypted) │ │ conversations (provider, external_id)│ │
│ │ exercise_sessions │ │ messages (provider, direction, │ │
│ │ food_entries │ │ message_types[], │ │
│ │ lab_results, heart_rate │ │ safety_flags[]) │ │
│ │ sleep_entries, hrt_doses │ │ email_folders (provider folder list) │ │
│ │ dreams, appointments │ │ message_folders (message↔folder join) │ │
│ │ transactions, budgets │ │ pending_messages (send queue) │ │
│ │ projects, sprints │ │ display_rules (IFTTT engine) │ │
│ │ contacts, call_logs │ │ │ │
│ │ routines, automations │ │ Dev: localhost:25433 │ │
│ │ notifications, reminders │ │ Prod: 10.0.0.11:25432 │ │
│ │ ai_conversations, ai_msgs │ │ │ │
│ │ skills, settings │ │ │ │
│ │ diary_entries │ │ │ │
│ │ keyring_credentials │ │ │ │
│ │ ad_subscriptions, bookings │ │ │ │
│ └─────────────────────────────────┘ └────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────────────────┐ │
│ │ Redis :26370 (life-manager) Redis :26380 (messenger) │ │
│ │ Cache + BullMQ queues Cache + rate limiting │ │
│ └──────────────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ EXTERNAL SERVICES │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ LLM API │ │ Proton │ │ iCloud │ │ Epic FHIR │ │ Matrix │ │
│ │ :8210 │ │ Bridge │ │ Mail │ │ OAuth2 │ │ :8448 │ │
│ │ │ │ :1143 │ │ :993/:587 │ │ │ │ │ │
│ │ qwen3-8b │ │ IMAP+SMTP │ │ IMAP+SMTP │ │ DiagReport │ │ Homesvr │ │
│ │ qwen3-4b │ │ │ │ │ │ Observation │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └───────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────────────────────────┐ ┌──────────────┐ │
│ │ Chatterbox │ │ macOS iMessage DB (SQLite) │ │ Brave │ │
│ │ TTS/STT │ │ Read by Swift agent via GRDB │ │ Search │ │
│ │ :41222 │ │ Full Disk Access required │ │ (optional) │ │
│ │ ws:/ws/stt │ └──────────────────────────────────┘ └──────────────┘ │
│ │ ws:/ws/tts │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────────────┘
Host Topology
┌─────────────────────────────────────────────────────────┐
│ apricot (dev workstation) │
│ │
│ life-manager API :3700 messenger sync :3100 │
│ life-manager Caddy :5700 messenger Caddy :5701 │
│ Postgres :25471 Postgres :25433 │
│ Redis :26370 Redis :26380 │
│ LLM :8210 Proton Bridge :1143 │
│ Chatterbox :41222 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ black (production server) │
│ │
│ life-manager API :3700 messenger sync :3100 │
│ life-manager Caddy :5700 messenger Caddy :5701 │
│ Postgres :25471 Postgres :25432 │
│ Redis :26370 Redis :26380 │
│ LLM :8210 Matrix :8448 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ plum (macOS build host) │
│ │
│ iMessage Swift Agent (menu bar app) │
│ Reads local chat.db → syncs to black :3100 │
│ Polls pending messages → sends via Messages.app │
└─────────────────────────────────────────────────────────┘
Port Map
| Port |
Service |
Protocol |
Network |
| 3700 |
Life-Manager API |
HTTP |
internal |
| 5700 |
Life-Manager Caddy |
HTTPS |
LAN |
| 3100 |
Messenger Sync API |
HTTP |
internal |
| 5701 |
Messenger Caddy |
HTTPS |
LAN |
| 25471 |
Life-Manager Postgres |
TCP |
localhost |
| 25432 |
Messenger Postgres (prod) |
TCP |
10.0.0.11 |
| 25433 |
Messenger Postgres (dev) |
TCP |
localhost |
| 26370 |
Life-Manager Redis |
TCP |
localhost |
| 26380 |
Messenger Redis |
TCP |
localhost |
| 8210 |
LLM API (model-boss) |
HTTP |
localhost |
| 41222 |
Chatterbox TTS/STT |
HTTP+WS |
localhost |
| 8448 |
Matrix Homeserver |
HTTP |
LAN |
| 1143 |
Proton Bridge IMAP/SMTP |
TCP |
localhost |
Scheduled Tasks
| Interval |
Service |
System |
Purpose |
| 1 min |
iMessage AI Loop |
life-manager |
Poll self-messages, agent routing, auto-reply |
| 1 min |
Notification Scanner |
life-manager |
Evaluate and fire pending reminders |
| 1 min |
Automation Engine |
life-manager |
Evaluate time-of-day triggers |
| 60s |
ProtonMail Sync |
messenger |
IMAP poll for new Protonmail messages |
| 60s |
iCloud Sync |
messenger |
IMAP poll for new iCloud messages |
| midnight |
Task Recurrence |
life-manager |
Spawn recurring task instances |
| midnight |
Habit Streaks |
life-manager |
Reset missed streak tracking |
| midnight |
Routine Streaks |
life-manager |
Reset missed routine tracking |
Auth Boundaries
| Boundary |
Method |
Detail |
| macOS Agent → Messenger Sync |
JWT Bearer |
Device registers, verifies, gets token |
| Life-Manager → Messenger Sync |
Service Key |
X-Service-Key header from env |
| Messenger Sync → Life-Manager |
HTTP |
LIFE_MANAGER_API_URL for credential fetches |
| MCP Server → Messenger Postgres |
Direct SQL |
Connection string (no HTTP layer) |
| Life-Manager → LLM |
API Key |
LLM_API_KEY |
| Life-Manager → Epic FHIR |
OAuth2 |
Authorization code flow with PKCE |
| Web UIs → Caddy |
Internal TLS |
Self-signed certificates |