meridian CLI is a bash script that wraps macOS launchd, letting you manage all Meridian daemons without touching launchctl directly. After installation, the script is symlinked into /usr/local/bin/meridian (or ~/.local/bin/meridian) so you can call it from any directory.
Commands
meridian start
meridian start
| Label | Service |
|---|---|
com.meridiona.screenpipe | screenpipe ambient recorder |
com.meridiona.daemon | Meridian Rust ETL daemon (also runs the in-process PM worklog pipeline and the coding-agent indexer) |
com.meridiona.ui | Next.js dashboard at http://localhost:3000 |
com.meridiona.mlx-server | MLX inference server |
.plist file is missing, meridian start prints an error for that service and exits with a non-zero code. Run ./install.sh to reinstall missing plists.The PM worklog (Jira / GitHub / Linear) pipeline and the coding-agent indexer used to ship as their own LaunchAgents (
com.meridiona.jira-updater, com.meridiona.coding-agent-indexer). They now run inside com.meridiona.daemon, so meridian status only reports the four labels above.The Rust daemon TCP-connects to the MLX server at startup to verify it is reachable. If the MLX server is not running, the daemon exits immediately. Start all services together with
meridian start rather than launching them individually.meridian stop
meridian stop
mlx_lm.server processes that launchd does not track. The .plist files in ~/Library/LaunchAgents/ are left in place so meridian start can bring everything back up.Use this command before editing ~/.meridian/.env so the daemon picks up the new values on the next meridian start.meridian restart
meridian restart
meridian stop, waits one second, then runs meridian start. Use this after changing environment variables or rebuilding the daemon binary.meridian status
meridian status
- ✓ running (pid N) — service is up and has a PID
- ⊘ loaded but not running — launchd has the plist but the process is not active
- ✗ not installed — plist is missing; run
./install.sh
meridian status any time you are unsure whether the stack is up.meridian logs [target] [-f] [-n N]
meridian logs [target] [-f] [-n N]
~/.meridian/logs/. All arguments are optional.Valid targetsEach component has a normal log (everything) and a paired -error log (WARN/ERROR only) so you can grep for problems without scrolling past routine output.| Target | File |
|---|---|
daemon (default) | ~/.meridian/logs/daemon.log |
daemon-error | ~/.meridian/logs/daemon-error.log |
screenpipe | ~/.meridian/logs/screenpipe.log |
screenpipe-error | ~/.meridian/logs/screenpipe-error.log |
ui | ~/.meridian/logs/ui.log |
ui-error | ~/.meridian/logs/ui-error.log |
mlx-server | ~/.meridian/logs/mlx-server.log |
mlx-server-error | ~/.meridian/logs/mlx-server-error.log |
| Flag | Description |
|---|---|
-f | Follow (stream) the log in real time |
-n N | Show the last N lines (default: 100) |
meridian doctor [--fix] [--dry-run] [--porcelain]
meridian doctor [--fix] [--dry-run] [--porcelain]
meridian doctor always produces something useful.Run meridian doctor as the first diagnostic step whenever something seems wrong: a missed Jira sync, a blank dashboard, a misclassified session, or a daemon that looks alive but isn’t producing output. Every check is content-free — counts, timestamps, status codes, reachability — never screen content or ticket text.Check groups| Group | What it looks at |
|---|---|
system | macOS detected, disk free, .env present, required toolchains |
meridian daemon | ETL last-run status + freshness, frame cursor, summariser / classifier queue depth, subprocess-error sentinels |
screenpipe | binary on PATH, plist installed, process live, DB frames, frame freshness, blank-text rate (Screen Recording permission proxy), per-app accessibility share, WAL size |
mlx-server | /health reachability and backend, /info model-loaded readiness (liveness vs. readiness) |
jira | /myself auth (distinguishes 401 expired from 403 scope), ticket sync freshness, candidate-ticket completeness |
ui | launchd service up, .next built, / serves, a referenced _next/static asset fetches, serve mode (catches an output: 'standalone' build run with next start) |
mcp server | packages/meridian-mcp/dist/index.js built |
worklog | drafts awaiting review, hours stuck unprocessed, approved worklogs failing to post |
coding-agent | Claude Code and Codex CLI presence, JSONL session directories, ~/.claude/commands/session-summary.md skill file (without it, every Claude Code session falls back to MLX) |
observability | OpenObserve reachability (so telemetry doesn’t silently drop) |
config | cross-process contract — DB path agreement (MERIDIAN_DB vs. MERIDIAN_DB_PATH), settings-file split-brain, dead env vars like POLL_INTERVAL_SECS |
✓ ok, ⊘ warn, · info, or ✗ critical. Failing rows show a → remedy line with the exact command to fix them. The exit code is 0 on a clean run and 1 when any check is critical.Flags| Flag | Description |
|---|---|
--fix | Apply tiered repairs to the warnings the sweep finds — see below |
--dry-run | With --fix, plan the repairs without executing them |
--porcelain | Emit TSV rows instead of the rich table — for scripts and dashboards |
--fix repair tiers| Tier | Behaviour |
|---|---|
| auto | Safe + idempotent (e.g. restart a dead service) — run silently |
| guided | Shows the command and asks y/N before running (e.g. drain the summariser queue, re-classify sentinels, refresh Jira, rebuild UI). Defaults to No on non-interactive stdin so --fix never auto-runs a mutating action without a human. |
| manual | Only a human can do it (regenerate a token, align settings) — printed as instructions |
--fix is escalated: a content-free diagnostic bundle is written to ~/.meridian/ so you can share it with the team or hand it off to claude.ExamplesThe daemon also runs a subset of these checks (capture-layer / L1 only) as a startup preflight, logging warn/error to
daemon.log. The preflight is non-fatal — the daemon still runs — so always confirm with meridian doctor if you suspect a fault.meridian worklog-status [--day YYYY-MM-DD]
meridian worklog-status [--day YYYY-MM-DD]
drafted, approved, posted, rejected, failed), and a per-ticket table with the synthesised Jira comment for each row. Useful for a quick “what is the daemon about to post?” check before approving worklogs in the dashboard.This command is read-only — it never writes to the DB and never calls Jira / GitHub / Linear. It also skips daemon initialisation, so it’s safe to run while the daemon is up.Flags| Flag | Description |
|---|---|
--day YYYY-MM-DD | Report for the given day (default: today, in the daemon’s local timezone) |
meridian pm-worklog [--day YYYY-MM-DD]
meridian pm-worklog [--day YYYY-MM-DD]
drafted state — they are never auto-posted. Approve them in the dashboard (or run meridian worklog-post-approved) to send them to Jira / GitHub / Linear.Use this when you want to regenerate drafts for a past day, recover from a failed run, or kick the pipeline manually without waiting for the next daemon cycle. The daemon runs the same pipeline on a schedule, so under normal operation you do not need to call this command.Flags| Flag | Description |
|---|---|
--day YYYY-MM-DD | Day to process (default: today) |
meridian worklog-post-approved
meridian worklog-post-approved
approved are skipped.Examplemeridian coding-agent-install-skill
meridian coding-agent-install-skill
session-summary Claude Code slash-command file to ~/.claude/commands/session-summary.md so claude -p /session-summary resolves to the prompt Meridian uses to summarise coding-agent transcripts for the Jira worklog.Without this file, claude -p /session-summary returns Unknown command and the summariser silently falls back to the local MLX model for every Claude Code session — you lose subscription-claude quality on the transcript summaries that feed the worklog. Run this once per machine where Claude Code is installed.The command is idempotent (safe to re-run) and writes nothing if the file already exists. meridian doctor warns when the skill is missing, and meridian doctor --fix runs this command for you, so most users never need to invoke it directly.Examplemeridian config edit
meridian config edit
~/.meridian/.env in your $EDITOR (falls back to nano if $EDITOR is not set). This is the canonical way to update API keys, change the poll interval, or toggle classification without hunting for the file path.After saving, run meridian restart so the daemon picks up the new values.meridian permissions
meridian permissions
- Screen Recording — opens the System Settings pane; click
+, navigate to the screenpipe binary, add it, and toggle it on. - Accessibility — same steps.
- Microphone — screenpipe appears here only after it first requests mic access. Grant Screen Recording first if screenpipe is not listed yet.
meridian restart afterwards so screenpipe picks up the newly granted permissions.meridian update
meridian update
main in one step: git pull --ff-only, rebuilds the Rust daemon (cargo build --release), rebuilds the Next.js UI (npm run build), then restarts every daemon via meridian restart. Use it after a release announcement, or any time you want to pull upstream fixes without running each step by hand.This command only works in a source checkout (the directory contains a Cargo.toml). For production installs from npm, upgrade with:git pull --ff-only fails (local commits that haven’t been pushed, or a non-fast-forward), meridian update exits without rebuilding so you can resolve the conflict yourself; rerun meridian dev build and meridian restart afterwards.Examplemeridian uninstall
meridian uninstall
mlx_lm.server processes, and removes the meridian and meridian-daemon symlinks from /usr/local/bin/ and ~/.local/bin/.Your data at ~/.meridian/ is not removed. Delete it manually if you want to wipe everything:install.sh Flags
The installer (./install.sh) accepts flags that let you customise or automate the setup process.
--no-ui
Skip the Next.js dashboard build. Useful on headless machines or when you only need the daemon and MCP server.
--dry-run
Preview every action the installer would take without executing any of them. Helpful for auditing the setup on a new machine.
--no-daemon
Build all binaries but do not register any launchd agents. Use this if you want to manage service startup yourself.
--skip-permissions
Skip the interactive macOS permissions walkthrough. Useful when re-running the installer after permissions are already granted, or in scripted environments.
--skip-env
Skip all credential prompts entirely. Existing values in the
.env files are preserved. Use alongside --skip-permissions for fully non-interactive re-installs.--mlx
Install and register the persistent MLX inference server as a launchd daemon. Requires Apple Silicon. Enables faster, on-device session classification with no external API calls.