# The exporter command line

Run your exports from Terminal, cron, backup tools and agents.

`exporter` is the Exporter Mac app run without a window. It uses the same connections, export folders, selection and settings you set up in the app, and it writes to the same export log. It works while the app is closed and it never prompts: anything missing stops the run with exit code 2 and one line saying what to do. macOS only.

## Install

1. Install Exporter from the Mac App Store ([download](https://exporter.dev/download)) and open it.
2. Connect an app (Apple Notes, Bear, Logseq, Contacts, Messages or Screen Time) or a Documents folder, and choose its export folder ([getting started](https://exporter.dev/docs/getting-started)). These grants can only be made in the app.
3. On the app's Command Line card, press "copy install command" and paste it once in Terminal.

The app is sandboxed and cannot write to your PATH, which is why the last step is a paste. The line installs `exporter` into `/opt/homebrew/bin` when that folder exists and belongs to you (no sudo), otherwise into `/usr/local/bin` with sudo. Pasting it again is safe; it replaces whatever was there. `exporter help install` prints the line for your Mac.

## Sources

`--source` takes one of these:

| source | also accepted | writes |
| --- | --- | --- |
| `apple` | `apple-notes`, `applenotes`, `notes` | markdown or html |
| `bear` | | markdown or html |
| `logseq` | | always markdown |
| `contacts` | `apple-contacts`, `addressbook` | always markdown |
| `messages` | `imessage`, `chats`, `conversations` | always markdown |
| `screentime` | `screen-time`, `usage` | always markdown, one file per day |
| `documents` | `docs`, `files`, `pdf` | the formats ticked on the Documents card |

## Formats

`--format` takes `markdown` (or `md`) or `html`; case does not matter. Anything else stops with `error: --format pdf: expected markdown | html` and exit 64.

- without it, `sync` writes each app in the format set on its card (Apple Notes and Bear each have their own) and `export` writes the setting of the app it exports; `exporter help sync` and `exporter help export` show the current ones
- Logseq, Contacts, Messages and Screen Time are always markdown, and Documents writes the formats ticked on its card, so for them `--format html` is ignored with a note: `note: logseq export is always markdown, so --format is ignored for this source.`
- Apple Notes writes one `.html` page per note ([the HTML format](https://exporter.dev/docs/notes#markdown-and-html)), attachments copied into `attachments/` next to it and linked, no front matter. Bear's HTML is the note's plain text inside a `<pre>`, with no styling, and attachment references left as Markdown text: the files are copied, not linked
- the MCP server reads only markdown files, so an export that is only HTML is invisible to it
- Apple Notes and Bear write one format per run; only Documents writes both in one sync. A run removes only old files of its own format, so switching leaves the other format's files in the folder. For both formats, give each its own folder:

```sh
exporter export --dest ~/Backups/notes-md   --format markdown
exporter export --dest ~/Backups/notes-html --format html
```

## sync

Runs the export you configured in the app, once, incrementally, into the app's export folders.

```sh
exporter sync [--source <source>]... [--format markdown|html] [--full] [--json] [--quiet]
```

| flag | what it does | default |
| --- | --- | --- |
| `--source <source>` | only this app, repeatable | every connected app; unconnected ones are skipped |
| `--format markdown\|html` | this run only, your app setting is unchanged. It lands in the same export folder as the other format; to keep both, export each to its own folder with `export --dest` | your app setting |
| `--full` | re-export everything. It removes only the files Exporter wrote before writing; anything else in the export folder stays | off |
| `--json` | a machine-readable summary | off |
| `--quiet`, `-q` | errors only | off |

```sh
exporter sync --source apple
```

```text
apple notes: exporting…
apple notes: 1204 of 1204 exported · 3 removed · 18.2s · markdown → /Users/me/Documents/notes
```

The summary line is `<source>: <succeeded> of <selected> exported`, then when present `N failed`, `N removed` (files of items that were deleted, renamed or moved), `N attachment issues`, then the duration, the format and the folder written.

If the app is running, `sync` exports nothing, exits 0 and prints `Exporter is running: real-time sync is live, the export root is already current.`

## export

A one-shot export to a folder of your choice, for snapshots and scripts. It runs fine while the app is open.

```sh
exporter export --dest <folder> [--source <source>] [--format markdown|html] [--organize folders|tags|smart] [--folder "Name"]... [--tag name]... [--dry-run] [--json] [--quiet]
```

| flag | what it does | default |
| --- | --- | --- |
| `--dest <folder>` | required. Must be inside a folder granted on the app's Command Line card ("add folder"). A grant on `~/Backups` covers every folder below it | none |
| `--source <source>` | the app to export | `apple` |
| `--format markdown\|html` | the format for this run | your app setting |
| `--organize folders\|tags\|smart` | Apple Notes only: how notes are laid out in folders | your app setting |
| `--folder "Name"` | only this Apple Notes folder, repeatable, name matched without case | the selection saved in the app |
| `--tag name` | only this tag, repeatable, Apple Notes or Bear | the selection saved in the app |
| `--dry-run` | print what would be exported, write nothing | off |
| `--json`, `--quiet` (`-q`) | as for sync | off |

With no `--folder` or `--tag`, Apple Notes and Bear export the selection saved in the app. Logseq exports the whole graph, Contacts every card, Messages every conversation, Screen Time every day; filters are ignored for them with a note.

```sh
exporter export --dest ~/Backups/notes-$(date +%F)
exporter export --dest ~/Backups/work --folder "Work" --format html
exporter export --dest ~/Backups/bear --source bear --tag journal
exporter export --dest ~/Backups/people --source contacts
exporter export --dest ~/Backups/papers --source documents
exporter export --dest ~/Backups/notes --dry-run
```

```text
would export 100 apple notes · markdown → /Users/me/Backups/notes
```

## list

```sh
exporter list sources|folders|tags|dests [--source apple|bear] [--json]
```

| list | what it shows | JSON |
| --- | --- | --- |
| `sources` | each app, connected or not, with its count. Documents is not listed | `[{"source": "apple", "connected": true, "notes": 1204}, {"source": "messages", "connected": true, "conversations": 1532}, {"source": "bear", "connected": false}]`, with `pages` for logseq, `contacts`, and `days` for `screen-time` |
| `folders` | Apple Notes folders with note counts, indented by depth. `--source bear` is an error (exit 64) | `[{"name": "Work", "notes": 42, "level": 0}]` |
| `tags` | tags with counts, Apple Notes by default, Bear with `--source bear` | `[{"name": "journal", "notes": 12}]` |
| `dests` | folders `export --dest` may write to, plus each app's export folder | `[{"path": "/Users/me/Backups", "kind": "granted"}]`, where `kind` is `granted`, `granted, volume not mounted` or `export root (apple-notes)` |

```sh
exporter list folders --json
```

```json
[{"name": "Work", "notes": 42, "level": 0}]
```

## status

```sh
exporter status [--json]
```

```text
apple notes    connected · last export 2026-09-11 03:00
bear           not connected
logseq         not connected
contacts       not connected
messages       connected · last export 2026-09-11 03:01
screen time    not connected
documents      not connected
root (apple-notes)  /Users/me/Documents/notes
root (messages)  /Users/me/Documents/messages
destinations   /Users/me/Backups
version        3.24 · free · 100 of 100 free notes used
messages       free · 10 of 10 free conversations used
app            not running
```

With `--json`: one object per app, named `apple-notes`, `bear`, `logseq`, `contacts`, `messages`, `screen-time`, `documents`, each `{"connected": true, "lastExport": "2026-09-11 03:00"}` (`null` when never exported); `destinations` (paths); `tier` (`full` or `free`, the Apple Notes unlock) and `freeNotesUsed`; `contactsTier` and `freeContactsUsed`; `messagesTier` and `freeConversationsUsed`; `screenTimeTier` and `freeDaysUsed`; `appRunning`. Times are local, `yyyy-MM-dd HH:mm`.

## log

The recent export runs, newest first: the same log the app shows, from every export folder and granted `--dest` folder. Dated folders created under a granted folder are not read; their record is in `<folder>/.exporter/`.

```sh
exporter log [--last N] [--json]
```

| flag | what it does | default |
| --- | --- | --- |
| `--last N` | how many runs | 10 |
| `--json` | one object per run | off |

```text
2026-09-11 03:00  apple-notes   1204/1204 exported  3 removed  clean  → /Users/me/Documents/notes
```

JSON: `[{"source", "finishedAt", "selected", "succeeded", "failed", "format", "status", "destination", "prunedFiles", "runError"}]`. `status` is `clean`, `warnings` (attachments missing) or `failures`.

## doctor

Checks that headless export will work and prints one line per check: `ok`, `FAIL` with a `fix:` line under it, `warn`, or `--` for information.

```sh
exporter doctor
```

It checks that each connected app's database is readable and its export folder writable, that every stored folder grant resolves, that every `--dest` folder is writable, the index, and the installed command. It ends with the version tier, whether the app is running, and the last crash if there was one. Exit 0 prints `all good.`, exit 2 prints `N problem(s) found.`

## report

Prints a diagnostic report (app version, macOS and hardware, connection state, recent runs, last crash; no note contents) and copies it to the clipboard.

```sh
exporter report [--send] [--email <addr>]
```

| flag | what it does | default |
| --- | --- | --- |
| `--send` | submits the report to us and prints `sent.`, or `offline: queued, will send on the next run or app launch.` | off |
| `--email <addr>` | adds your address so we can reply | none |

## help and version

- `exporter help [topic]`: topics `sync`, `export`, `list`, `status`, `log`, `doctor`, `report`, `cron`, `install`. Help for a command shows your current settings as the defaults
- `sync`, `export`, `list`, `log` and `report` also take `--help` or `-h`
- `exporter version` (or `--version`, `-v`) prints `exporter 3.24`
- `exporter` alone in a terminal prints the overview and exits 64

## JSON output

`--json` works on `sync`, `export`, `list`, `status` and `log`. Output is pretty-printed with sorted keys. For `sync` and `export` add `--quiet`: without it the progress and note lines are printed on stdout before the JSON. `export` prints one summary object, `sync` prints `{"runs": [...]}` with one per source:

```json
{
  "attachmentIssues" : 0,
  "durationSec" : 18.2,
  "failed" : 0,
  "format" : "markdown",
  "root" : "/Users/me/Documents/notes",
  "runError" : null,
  "selected" : 1204,
  "source" : "apple-notes",
  "status" : "clean",
  "succeeded" : 1204
}
```

While the app is running, `sync` prints its one line and no JSON. Errors go to stderr as `error: <what happened and what to do>`.

## Exit codes

| code | meaning |
| --- | --- |
| 0 | ok, including a run the free allowance cut short |
| 1 | export failures: an item failed, the run hit an error, or it selected items and wrote none |
| 2 | needs setup: app not connected, folder not granted, folder or tag not found, nothing to export; `doctor` found problems; the installed command is an old format or the app it points at is gone |
| 64 | usage: unknown command or flag, missing or bad value, `--folder` with Bear, `list folders --source bear`, `exporter` alone in a terminal |

## Where files land

`sync` writes to the export folder set for each app in Exporter, like `~/Documents/notes` or `~/Documents/messages`; `export` writes to `--dest`. A folder at your home level or one below it, like `~/Documents` itself, gets a per-app subfolder (`notes-export`, `messages-export` and so on), and a deeper folder is used as it is. The summary line (after the arrow) and the JSON `root` show the real folder.

Each export folder holds `.exporter/last-export.json` and `.exporter/last-export.md` (the last run) and `.exporter/history/` (the last 50 runs). Apple Notes, Contacts, Messages, Screen Time and Documents also keep `.exporter/files.json`, every file a run wrote: the next run removes only files listed there that no item produces any more (Screen Time never removes a day file). Bear and Logseq also remove the files of notes you deleted, renamed or retagged on the next run. Apple Notes and Logseq exports also get `bases/` with Obsidian views.

## Free allowance

The command line has the same allowances as the app:

| app | free |
| --- | --- |
| Apple Notes | 100 notes |
| Contacts | 100 contacts |
| Messages | the 10 most recent conversations |
| Screen Time | the 10 most recent days at the first sync, and only those: later days need the unlock |
| Documents | the 10 most recently modified documents |
| Bear and Logseq | unlimited |

Items already exported keep re-syncing free; the allowance only stops new ones. A run that reaches it still exports what it may, exits 0, and prints a note (not under `--quiet`):

```text
note: 42 note(s) skipped: free version limit (100 of 100 free notes). upgrade in the app to export everything.
note: 58 contact(s) skipped: free version limit (100 of 100 free contacts). unlock contacts in the app to export everything.
note: 1522 conversation(s) skipped: free version limit (10 of 10 free conversations). unlock messages in the app to export everything.
note: 11 day(s) skipped: free version limit (10 of 10 free days). unlock screen time in the app to archive every day.
note: 5 document(s) skipped: free version limit (10 of 10 free documents). unlock documents in the app to convert every one.
```

`status --json` carries the tier and used count for Apple Notes, Contacts, Messages and Screen Time. Each limited app unlocks with its own one-time in-app purchase inside Exporter, [priced per country](https://exporter.dev/pricing), no subscription and no web checkout. The command line reads the purchase on every run; if the App Store does not answer within 5 seconds, the run continues on the free allowance.

## Scheduling

`exporter help cron` prints these lines with the full path of the command on your Mac: use that, because cron's PATH may not include the install folder. In a crontab, escape `%` as `\%`:

```sh
0 3 * * * exporter sync
0 3 * * * exporter export --dest ~/Backups/notes-$(date +\%F)
```

For Carbon Copy Cloner and other backup tools, run `exporter sync` as a pre-flight script and branch on the exit code. The command stays attached for the whole export, even when macOS suspends it with no one logged in. While the app is running, with its window open or closed, `sync` is a no-op: real-time sync already keeps the folder current.

## MCP server

The app, not the command line, runs a local MCP server that lets Claude, Cursor, VS Code and other clients search and read your exports, at `http://localhost:8744/mcp`. [The MCP server page](https://exporter.dev/docs/mcp) covers everything about it, from starting it to its six tools.

## Troubleshooting

Run `exporter doctor` first; every failing check prints its fix. [Help](https://exporter.dev/docs/help) covers the app's messages too.

- `X is not authorized`: add the folder (or a parent) on the Command Line card, then re-run. `exporter list dests` shows what is granted
- `apple notes is not set up. open Exporter and connect Apple Notes + an export folder.` (the same for each app): connect it in Exporter
- `sync` prints that Exporter is running: nothing to do, the app keeps the folder current. Use `export --dest` for a separate copy
- `no notes were written. run "exporter doctor" to check folders and permissions.`: the run selected notes and wrote none; `doctor` checks the folders and permissions
- `bookmark broken`: the folder was moved, deleted, or its volume is not mounted. Choose it again in the app
- the installed command is an old format, or cron and backup tools see exit 19: paste the install command again
- the app moved since you installed the command: paste the install command again
- unlocked but the run says free: the purchase check waits at most 5 seconds, then continues on the free allowance. Run again
- a problem doctor cannot explain: `exporter report --send --email you@example.com`

## Related

- [MCP server](https://exporter.dev/docs/mcp): Connect Claude and other agents
- [For agents](https://exporter.dev/agents): Skills, command line and MCP for agents
- [Apple Notes](https://exporter.dev/docs/notes): Folders, fields, HTML and fixes
- [Changelog](https://exporter.dev/changelog): What changed in each version

---

human version: https://exporter.dev/docs/cli
every page: https://exporter.dev/llms.txt
