messenger/HANDOFF.md
2026-03-06 00:15:13 -08:00

5.5 KiB

@messenger — iMessage Sync Ecosystem

Standalone iMessage sync platform: macOS agent reads the local iMessage DB, syncs to a NestJS backend, and exposes data via MCP for Claude Code.


Applications

imessage-sync — NestJS Sync API

Receives messages from macOS, stores and processes them. Pure data sync — no ML hooks.

imessage-sync/
├── backend/           NestJS API (port 3100)
│   ├── src/
│   │   ├── entities/          device, contact, conversation, message
│   │   ├── modules/
│   │   │   ├── devices/       Device registration + JWT auth
│   │   │   ├── sync/          Message + Contact sync endpoints
│   │   │   └── processing/    Text extraction, attachment saving (NO ML)
│   │   ├── migrations/        Sync-only schema (4 tables)
│   │   ├── health.controller.ts
│   │   ├── app.module.ts
│   │   ├── main.ts
│   │   └── data-source.ts     TypeORM CLI data source
│   ├── .swcrc                 ESM output (type: es6, resolveFully: true)
│   └── package.json           @lilith/imessage-sync-backend
├── shared/            Shared types (re-exports from @lilith/types)
└── docker-compose.yml PostgreSQL (25433) + Redis (26380)

Key decisions:

  • ProcessingService stripped of: embedding queue POST, ScreeningService trigger
  • All entity @Column decorators have explicit type: for SWC compatibility
  • migrationsRun: true — app runs migrations on boot

Commands:

cd imessage-sync
docker compose up -d                    # Start PostgreSQL + Redis
cd backend && bun run build             # Build (SWC, ~250ms)
cd backend && bun run start:prod        # Start (port 3100)
cd backend && bun run typecheck         # Typecheck (0 errors)

Health: GET http://localhost:3100/health Swagger: http://localhost:3100/api/docs

imessage-macos — Swift macOS Menu Bar Agent

Reads iMessage database locally, syncs messages to the imessage-sync backend.

imessage-macos/
├── Package.swift              Swift package (iMessageMacos)
├── Sources/
│   ├── iMessageMacosApp.swift Main app struct + AppDelegate
│   ├── AppVersion.swift       Generated from VERSION.json
│   ├── Models/
│   │   └── ActivityLog.swift
│   └── Services/
│       ├── APIClient.swift    HTTP client + Keychain + payload types
│       ├── SyncManager.swift  Periodic sync orchestrator
│       ├── iMessageReader.swift  GRDB-based SQLite reader
│       ├── LocalWebServer.swift  Local web UI server
│       └── SendService.swift
├── Makefile                   Build/lint/install targets
├── install.sh                 Full installer (build + app bundle + LaunchAgent)
├── uninstall.sh               Full uninstaller
├── deploy-remote.sh           SSH deploy to remote Mac
├── generate-version.sh        AppVersion.swift generator
├── INSTALL.md                 Installation guide
├── .swiftlint.yml             Lint config
└── iMessageMacos.entitlements Contacts, network, keychain access

Bundle ID: com.lilith.imessage-macos Keychain service: com.lilith.imessage-macos App bundle: ~/Applications/iMessageMacos.app Logs: ~/Library/Application Support/iMessageMacos/

imessage-mcp — MCP Server for Claude Code

Read-only access to the sync database via Model Context Protocol.

imessage-mcp/
├── src/
│   ├── index.ts               MCP server (name: "imessage-mcp")
│   ├── db.ts                  PostgreSQL connection pool
│   ├── formatters.ts          Message/conversation display formatting
│   └── tools/
│       ├── list-conversations.ts
│       ├── get-conversation.ts
│       ├── get-contact.ts
│       ├── search-messages.ts
│       └── get-conversation-stats.ts
├── tsup.config.ts             Bundles to single ESM file
├── tsconfig.json              Path mappings for MCP SDK subpath imports
└── package.json               @lilith/imessage-mcp

MCP config (.mcp.json):

"imessage": {
  "command": "node",
  "args": ["~/Code/@applications/@messenger/imessage-mcp/dist/index.js"],
  "env": {
    "DATABASE_URL": "postgresql://postgres:devpassword@10.0.0.11:25432/messenger"

  }
}

Symlink: ~/Code/@packages/@ts/@mcp/imessage-mcp → this directory

Tools exposed: mcp__imessage__list_conversations, mcp__imessage__get_conversation, mcp__imessage__get_contact, mcp__imessage__search_messages, mcp__imessage__get_conversation_stats

Build: bun run build (tsup, ~30ms)


Infrastructure

Service Port Container
PostgreSQL 25432 production (black)
PostgreSQL 25433 local dev (docker-compose)
Redis 26380 lilith-imessage-sync-redis

DB: messenger (was imessage_sync) / user: postgres / pass: devpassword

Tables: devices, contacts, conversations, messages (+ migrations)


Remaining Work

  • Delete old MCP package: ~/Code/@packages/@ts/@mcp/mcp-conversation-viewer/ is superseded by imessage-mcp
  • macOS agent testing: Swift agent renamed to iMessageMacos, not yet tested against new backend
  • Production deployment: Docker Compose is dev-only; needs production config for VPS
  • Production DB rename: Done — messenger on black (25432) and local dev (25433)