Melian

First Run

The first words spoken beneath the boughs.

Start the Server

bun run start

This compiles and starts Melian's single Bun process, which hosts everything: the HTTP/WebSocket server, background job scheduler, iMessage poller, and all integrations.

What Happens on First Boot

Melian performs a series of initialization steps before accepting requests. Watch the startup log to confirm each one:

1. Qdrant Connection

Melian connects to Qdrant at the configured URL and checks for the required collections. If archival_memory or knowledge collections are missing, it creates them with the correct vector dimensions and distance metric (Cosine).

[melian] Qdrant connected at http://localhost:6333
[melian] Collection "archival_memory" created (dims=768, distance=Cosine)
[melian] Collection "knowledge" ready (existing)

2. SQLite Databases

Six SQLite databases are created if they don't exist. They live in the data directory (~/Library/Application Support/melian/ on macOS):

Database Purpose
recall.db Conversation history, core memory facts, thread metadata
jobs.db Job definitions, run history, output logs
email-cache.db Indexed email headers and cached bodies
calendar-cache.db Event cache for Google Calendar
attention.db Attention pipeline: seeds, classifiers, routing decisions
imessage-state.db iMessage read-state tracking (last-seen ROWID per contact)

Migrations run automatically using bun:sqlite. No manual schema setup is needed.

3. Core Memory

Core memory is initialized as an empty fact store on the first run. The system prompt is constructed each conversation turn by reading all stored facts from recall.db. On a fresh install, there are zero facts. Melian will begin accumulating them through conversation.

[melian] Core memory loaded: 0 facts

4. Seeded Jobs

The scheduler registers built-in recurring jobs on first boot if they don't already exist. Some are unconditional; others only appear when their integration is configured.

Always seeded:

Job Schedule Category Output
learning-review daily at 2:00am core log
integration-tests daily at 2:00am core log
self-healing daily at 2:30am core log
daily-morning-briefing daily at 7:00am core imessage+push
night-time-lights daily at 9pm home log

Seeded when email is configured:

Job Schedule Category Output
email-summary */30 6-22 * * * core log

Seeded when calendar is configured:

Job Schedule Category Output
calendar-briefing daily at {reminders.morning_briefing} core imessage+push

Seeded when tasks are configured (per tasks.yaml schedules):

Job Configured via Category
remarkable-task-sync sync.schedule tasks
task-followup followup.schedule tasks
daily-standup standup.schedule tasks
evening-checkin evening_checkin.schedule tasks
[JOB] Seeded learning-review job
[JOB] Seeded integration-tests job
[JOB] Seeded self-healing job
[JOB] Seeded daily-morning-briefing job
[JOB] Seeded night-time-lights job
[EMAIL] Seeded email-summary job
[CALENDAR] Seeded calendar-briefing job

Jobs that were previously disabled survive restarts; their enabled/disabled state is persisted in jobs.db.

5. iMessage Poller

If imessage.enabled is true and Full Disk Access is granted, the iMessage poller starts. It polls ~/Library/Messages/chat.db on a configurable interval (default: 3 seconds) and emits events for new incoming messages from configured contacts.

[IMESSAGE] Watching self-chat ... + 3 contact(s) every 3s

6. Server Ready

Once initialization is complete:

Melian running on http://127.0.0.1:3000

Open the Web UI

Navigate to http://localhost:3000 in your browser. The Nan Elmoth atmosphere loads, and you'll see the chat interface with an empty thread.

If this is the first time you've opened the UI from this browser, you'll be prompted to subscribe to web push notifications (optional). This enables the dashboard's PushBanner for real-time alerts without keeping the tab active.

First Conversation

Type a message and press Enter (or Shift+Enter for a newline). Melian will introduce herself and invite you to share context about yourself: your name, how you work, what you want her to handle. Everything she learns is stored as a core memory fact and prepended to every subsequent prompt.

A typical first exchange:

You: Hello

Melian: Welcome. I am Melian. I dwell here in the quiet of the forest, ready to listen. What shall I know about you?

Subsequent turns will be faster as the conversation history and core memory grow.

CLI Mode

If you prefer a terminal interface:

melian chat

This opens a readline-based REPL that sends messages to the same running server over the local API. All memory, tool use, and job integrations work identically. Only the presentation layer differs.

For one-shot questions without a REPL:

melian ask "What's on my calendar today?"

The CLI also provides commands for jobs, email, calendar, memory, analytics, and more. See the CLI Reference for the full command list.

Development Mode

For local development with hot reload (HMR on the frontend, automatic server restart on backend changes):

bun run dev

Bun's --watch flag is used for the server process, and the frontend is served with HMR enabled. React fast-refresh handles component-level updates without losing conversation state.