Skip to content

anngbaum/task-bert

Repository files navigation

Bert

Bert turns your text messages into a clear, organized action list—so you never miss a reply, appointment, or important detail again.

A local search engine for your iMessage history. Reads your macOS chat.db, loads it into an embedded Postgres (PGLite) with full-text and vector search, generates conversation summaries and action items using LLMs, and provides a native macOS app and MCP server for Claude Code integration.

Quick Start (App)

  1. Download Bert.zip and unzip
  2. Move Bert.app to /Applications
  3. Grant Full Disk Access: System Settings > Privacy & Security > Full Disk Access > add Bert
  4. Launch Bert
  5. Open Settings (gear icon) and add your Anthropic or OpenAI API key
  6. Click Sync to import messages

The app bundles its own Node.js server — no dependencies required.

Features

  • Full-text search with filters (by contact, date range, group chat, sent by me)
  • Semantic search using local vector embeddings (HuggingFace nomic-embed-text-v1.5)
  • Hybrid search combining both (default)
  • AI agent for natural language questions — chains multiple search tools to synthesize answers
  • Conversation summaries generated by Claude or GPT
  • Action items extracted from recent conversations (unanswered questions, commitments, plans)
  • Thread view to see full message context around any result
  • Contact-aware typeahead for with:, sent_by:, and in: filters
  • MCP server for Claude Code integration (search, agent, actions, contacts)

Claude Code (MCP)

The MCP server lets Claude Code search your messages, ask natural language questions, and pull action items directly.

npm run mcp   # Start MCP server (stdio transport)

Register in .mcp.json:

{
  "mcpServers": {
    "imessage-agent": {
      "command": "npx",
      "args": ["tsx", "src/mcp-server.ts"],
      "cwd": "/path/to/Ann-Messages"
    }
  }
}

Exposed tools:

Tool Description
ask_agent Natural language question answering (chains search tools)
search_messages Structured search with mode, filters, date range
get_message_context Surrounding messages for a given message ID
get_actions Pending tasks and upcoming events
search_contacts Contact lookup with fuzzy matching

Development Setup

Prerequisites

  • macOS with Messages app
  • Node.js v20+
  • Full Disk Access for your terminal (System Settings > Privacy & Security > Full Disk Access)

Install & Run

npm install
npm run serve        # Start the API server on port 11488
npm run serve:reset  # Hard reset: wipe DB and re-ingest everything

Then open the Xcode project at Bert/Bert.xcodeproj and run, or use the CLI directly.

CLI Commands

# Incremental sync (new messages since last import)
npm start -- sync

# Full re-ingest from scratch
npm start -- resync

# Search from terminal
npm start -- search "dinner plans"
npm start -- search "birthday" --from-me --after 2024-06-01
npm start -- search "funny story" --mode semantic --context 3

# Generate embeddings for semantic search
npm start -- embed --batch-size 50

# Database stats
npm start -- status

Search Options

Flag Description
--mode text|semantic|hybrid Search mode (default: hybrid)
--from <contact> Filter by sender
--group-chat-name <name> Filter by group chat name
--after <YYYY-MM-DD> Messages after date
--before <YYYY-MM-DD> Messages before date
--from-me Only messages you sent
--to-me Only messages you received
--limit <n> Max results (default: 20)
--context <n> Surrounding messages (default: 0)

Building for Distribution

npm run bundle    # Bundle Node.js server into build/server/
npm run package   # Full pipeline: bundle → Xcode build → dist/Bert.zip

Architecture

src/
  server.ts               # HTTP API server (port 11488)
  mcp-server.ts           # MCP server for Claude Code integration
  index.ts                # CLI entry point
  config.ts               # Shared config (data directory)
  types.ts                # TypeScript interfaces
  progress.ts             # Sync progress tracking
  agent/
    engine.ts             # AI agent with tool-use chain for natural language queries
  commands/
    unified-sync.ts       # Core sync pipeline (incremental + hard reset)
    update-metadata.ts    # LLM-powered summaries + action extraction
    embed.ts              # Vector embedding generation
    copy-db.ts            # Copy chat.db locally
    ingest.ts             # Full re-ingest (hard reset alias)
    sync.ts               # Incremental sync
    resync.ts             # Wipe and re-ingest
    search.ts             # CLI search
    status.ts             # Database stats
  db/
    sqlite-reader.ts      # Read-only iMessage SQLite access
    pglite-client.ts      # Embedded Postgres (PGLite + pgvector)
    schema.sql            # Database schema
  etl/
    extract.ts            # Batch extract from SQLite
    transform.ts          # Timestamp parsing, attributedBody decoding
    load.ts               # Batch insert into PGLite
    link-preview.ts       # Link preview extraction
  search/
    fts.ts                # Full-text search (tsvector)
    vector.ts             # Vector similarity (pgvector)
    hybrid.ts             # RRF-combined search
    filters.ts            # WHERE clause builders
  embeddings/
    local.ts              # HuggingFace Transformers embeddings
  llm/
    query-parser.ts       # LLM interaction + provider routing
  contacts/
    address-book.ts       # macOS Contacts integration
    normalize.ts          # Contact name normalization
    search.ts             # Contact fuzzy search
  thread/                 # Thread view queries
  parsers/
    timestamps.ts         # iMessage timestamp conversion
  display/
    formatter.ts          # Terminal output formatting

Bert/                     # SwiftUI macOS app
  Bert/
    BertApp.swift         # App entry point + server lifecycle
    Services/
      ServerManager.swift         # Manages bundled Node.js server process
      SearchService.swift         # HTTP client for the API
      RemindersSyncManager.swift  # Reminders integration
    ViewModels/
      SearchViewModel.swift
    Views/
      ContentView.swift           # Tab-based layout
      SearchBarView.swift         # Search field + filters
      ResultsListView.swift
      ResultRowView.swift
      ChatMetadataPanelView.swift
      ActionsPanelView.swift
      EventsPanelView.swift
      TaskTriageView.swift
      AgentView.swift             # Natural language agent UI
      ThreadView.swift
      ContextMessagesView.swift
      LeaderboardView.swift       # Contact leaderboard
      DebugLogsView.swift
      SettingsView.swift
    Extensions/
      Date+Formatting.swift
    Models/               # Data types

scripts/
  bundle-server.sh        # Bundle Node.js + compiled server for embedding in app
  package-app.sh          # Full build + zip pipeline

Tech Stack

  • TypeScript + Node.js — API server, ETL pipeline, and MCP server
  • better-sqlite3 — read-only access to iMessage SQLite database
  • @electric-sql/pglite + pgvector — embedded Postgres for search
  • @huggingface/transformers — local vector embeddings (nomic-embed-text-v1.5)
  • @modelcontextprotocol/sdk — MCP server for Claude Code integration
  • Anthropic Claude / OpenAI GPT — conversation summaries, action extraction, and agent reasoning
  • SwiftUI — native macOS app
  • commander — CLI argument parsing

About

a simple Mac App to help me stay on top of my messages

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors