Skip to main content
OpenBunny is composed of four components that can be deployed in different configurations depending on your needs.

System diagram

┌─────────────────────────────────────────────────────┐
│      Messaging channels (Slack, WhatsApp, etc.)     │
└────────────────────┬────────────────────────────────┘


        ┌────────────────────────────┐
        │   Service (Node.js)        │
        │  :3100 REST API + MCP      │
        │                            │
        │  Channel listeners         │
        │  LLM agent loop            │
        │  Task / contact management │
        │  Hybrid search (QMD)       │
        │  Scheduler                 │
        └────┬──────────────┬────────┘
             │              │
    BACKEND= │              │ BACKEND=
    local    │              │ remote
             ▼              ▼
     ┌─────────────┐  ┌──────────────────┐
     │  SQLite     │  │  Cloud (Next.js) │
     │             │  │  :3000           │
     │ Tasks       │  │                  │
     │ Contacts    │  │  Web UI          │
     │ Messages    │  │  Supabase API    │
     │ Reminders   │  │  RLS policies    │
     └──────┬──────┘  │  Multi-tenant    │
            │         └──────┬───────────┘
            │                │
            ▼                ▼
     ┌──────────────┐   ┌────────────────┐
     │  Client      │   │  Mobile        │
     │  (Next.js)   │   │  (Expo RN)     │
     │  :3000       │   │                │
     │              │   │  Offline-first │
     │  Kanban UI   │   │  Push notifs   │
     │  Tasks       │   │  Sync engine   │
     │  Contacts    │   │                │
     └──────────────┘   └────────────────┘

Component roles

Service

The core engine that does all the work. It connects to messaging channels, runs the LLM agent to process conversations, and manages tasks, contacts, and reminders. Exposes a REST API on port 3100 and an MCP server for tool integration. The service operates in two modes controlled by the BACKEND environment variable:
  • local — stores everything in SQLite
  • remote — stores messages locally in SQLite but proxies task and contact operations to the cloud API

Cloud

A multi-tenant Next.js application backed by Supabase PostgreSQL. Provides a web dashboard with Kanban board, team management, API token authentication, and push notifications. Row Level Security (RLS) policies enforce data isolation between teams.

Client

A lightweight Next.js frontend that connects directly to the service REST API. No database, no authentication — designed for local use. Provides a Kanban board, task detail views, contact management, and reminder scheduling.

Mobile

An Expo React Native app with offline-first architecture. Uses a local SQLite database with a sync engine to push and pull data from the cloud. Supports push notifications via APNs and FCM.

Deployment modes

Fully local

All data stays on your machine. The service uses SQLite for everything and the client provides the UI.
ComponentRuns onStorage
Servicelocalhost:3100SQLite
Clientlocalhost:3000None (proxies to service)
Best for individual users who want privacy and simplicity.

Hybrid

The service runs locally (or on a VPS) for channel processing, but tasks and contacts are stored in the cloud for team access.
ComponentRuns onStorage
Servicelocalhost / VPSSQLite (messages only)
CloudVercel / remoteSupabase PostgreSQL
MobileUser devicesLocal SQLite + cloud sync
Best for teams that want shared task management with local channel processing.

Fully remote

Everything runs on servers. Users interact through the cloud web UI or mobile app.
ComponentRuns onStorage
ServiceVPS / serverSQLite (messages only)
CloudVercel / remoteSupabase PostgreSQL
MobileUser devicesLocal SQLite + cloud sync
Best for production deployments that need to run 24/7.

Data flow

  1. Channel listeners receive messages from Slack, WhatsApp, iMessage, Telegram, or Gmail
  2. Messages are stored in the conversations and messages tables
  3. The scheduler runs every 60 seconds, checking for conversations that have been quiet for the debounce period (default 5 minutes)
  4. Qualifying conversations are claimed and sent to the LLM agent
  5. The agent analyzes the conversation context and uses tools to create/update tasks, manage contacts, and search for duplicates
  6. Tasks and contacts are persisted to the configured backend (SQLite or cloud API)
  7. The reminder engine periodically reviews open tasks and sends notifications when due

Tech stack

LayerServiceCloudClientMobile
RuntimeNode.js 22+Next.js 16Next.js 15Expo 55
FrameworkHonoReact 19React 19React Native
DatabaseSQLiteSupabase PGNoneExpo SQLite
AuthAPI tokensSupabase AuthNoneSupabase OTP
SearchQMD (BM25 + semantic)Supabase FTSNoneLocal SQLite