First Run
Start the Server
bun run startThis 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 facts4. 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 jobJobs 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 3s6. Server Ready
Once initialization is complete:
Melian running on http://127.0.0.1:3000Open 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 chatThis 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 devBun'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.