# Command-line tool

Install the oleafly command on Windows, macOS or Linux, build and check projects from a terminal or CI, sync with an online LaTeX service, and connect coding agents through its MCP server and skill.

Oleafly comes with `oleafly`, a command-line tool that works on the same projects as the app. Build or check a paper from a terminal, a script or CI. Give a coding agent a reliable way into your project. Sync with an online LaTeX service or an Oleafly server, or run the Oleafly agent without opening the app.

It ships inside the app on every platform. This page covers the commands in Oleafly 0.4.8 and later. Earlier versions had fewer, so pin your Oleafly version in scripts that depend on it.

## Install

| System | Where the app keeps it | Put `oleafly` on your PATH |
|---|---|---|
| Windows | `oleafly-cli.exe` next to the app, in `%LOCALAPPDATA%\Oleafly` for the setup program or `C:\Program Files\Oleafly` for the MSI package | **Install** on the **Terminal command** row in **Settings → General** copies it to `%LOCALAPPDATA%\Oleafly\bin\oleafly.exe` and adds that folder to your PATH |
| macOS | `Oleafly.app/Contents/MacOS/oleafly-cli` | **Install** on the **Terminal command** row links `oleafly` into `/usr/local/bin` when you can write there, otherwise into `~/.local/bin` |
| Linux packages (.deb, .rpm) | `/usr/bin/oleafly-cli` | Nothing to do: the package installs `/usr/bin/oleafly` |
| Linux AppImage | Inside the AppImage | **Install** copies it to `~/.local/bin/oleafly` |

Programs that Oleafly starts, such as its own terminal and the CLI agents, always find `oleafly` on their PATH, even before you install it. The `OLEAFLY_CLI` variable holds its full path.

### Windows

1. Open **Settings → General** and choose **Install** on the **Terminal command** row.
2. Open a new PowerShell or Command Prompt window. Windows that were already open keep the old PATH.
3. Check that it works:

```powershell
Get-Command oleafly
oleafly version
```

**Remove** on the same row deletes the copy and takes the folder off your PATH again. When Oleafly updates, it refreshes the copy the next time it starts.

### macOS

Move Oleafly to your Applications folder first. A copy that runs from the disk image shows "Move Oleafly to your Applications folder first" instead of **Install**.

The command is a link to the app, so updating Oleafly updates the command too. If the folder isn't on your PATH, the row shows the line to add to your shell profile. Check it with `command -v oleafly`.

### Linux

The .deb and .rpm packages put `oleafly` on your PATH when you install them. `oleafly` with nothing after it opens the app.

The AppImage needs a copy, because the files inside an AppImage go away when it quits. After you replace the AppImage with a newer one, the row offers **Update**. If `~/.local/bin` isn't on your PATH, the row shows the line to add.

### Check that it works

`oleafly version` prints the app version and the engines the command would use. `oleafly doctor` checks the engines, the app, Git, the terminal command and your MCP clients, and prints a fix for anything missing. It works outside a project too.

## Build a project

`oleafly .` opens the current folder in the app. Every other command works on the folder you're in; `-C` followed by a path points it somewhere else.

```sh
cd ~/papers/thesis
oleafly init --engine typst
oleafly build
oleafly log --diagnostics
oleafly -C ~/papers/review --json build
```

- `oleafly init` makes the current folder a project. `--engine` takes `tectonic`, `latexmk`, `typst` or `markdown`.
- `oleafly new` followed by a folder and `--template` and a template id creates a project from a template. `oleafly templates list --all` lists the templates.
- `oleafly build` uses the project's engine and settings, the same way the app does: the Tectonic, Typst and Pandoc that come with Oleafly, or the LaTeX you installed. `--main` builds another document of the project, `--compiler` picks the LaTeX compiler for latexmk projects, `-o` copies the PDF somewhere else and `--timeout` sets the limit in seconds.
- A folder you opened in place in the app builds with the engine and main document you chose there, into the app's own build folder.
- The app and the command never build the same project at once: the second one waits for the first. A failed build keeps the last good PDF.
- `oleafly watch` rebuilds every time you save. `oleafly log --diagnostics` lists errors and warnings with file and line, and `oleafly clean` removes the build output.

For Typst specifics, see [Typst projects](/docs/typst/#build-from-the-command-line).

## Use it from a coding agent

Coding agents work best with three things the command gives them: `oleafly context` for the project's map, `--json` for results they can read, and exit codes that say what went wrong. There are three ways to connect an agent.

### The oleafly-cli skill

Oleafly ships a skill called `oleafly-cli`. It teaches an agent the commands, the JSON output and the exit codes, and the loop that works best: read the context, edit, build, read the diagnostics, fix the first error.

In Oleafly's terminal and the CLI agents it starts, pick the skill like any other. For an agent you run on your own, turn on **Settings → AI Assistant → Skills → Share skills with other agents on this computer**. Oleafly then links its skills, `oleafly-cli` included, into the folders other coding agents read, such as `~/.claude/skills`, `~/.codex/skills` and `~/.agents/skills`. `oleafly skills path` prints where the skills are, for agents that read another folder.

### Connect an agent over MCP

`oleafly mcp` is an MCP server that talks over standard input and output. When the app has your project open, it passes calls on to the app's own [MCP server](/docs/mcp/), so the agent gets every app tool and your approval prompts. Otherwise it works on its own, with read tools (project status, the project map, files, search, logs, the doctor report, citation lookup) and `compile`. There is no URL or token to copy and no Node.js to install.

The quickest setup is `oleafly mcp config --client` followed by `claude-code`, `claude-desktop`, `codex`, `cursor` or `gemini`. It prints the entry for that client; add `--write` to have it added for you, with a backup of the client's file. Restart or reconnect the client afterwards. Inside a project it writes the project's settings; elsewhere it writes your user settings, with the command's full path, because apps you start from the desktop may not see your PATH.

#### Claude Code

```sh
claude mcp add --scope user oleafly -- oleafly mcp
```

Inside a project, `oleafly mcp config --client claude-code --write` adds the server to the project's `.mcp.json` instead.

#### Claude Desktop

Claude Desktop starts servers without a project folder, so its entry always works through the app: keep Oleafly open with your project. Use the full path to `oleafly`. On Windows, double every backslash in the path.

```json title="claude_desktop_config.json"
{
  "mcpServers": {
    "oleafly": {
      "command": "/usr/local/bin/oleafly",
      "args": ["mcp", "--bridge", "always"]
    }
  }
}
```

The file is in `~/Library/Application Support/Claude` on macOS and `%APPDATA%\Claude` on Windows.

#### Codex

```toml title="~/.codex/config.toml"
[mcp_servers.oleafly]
command = "oleafly"
args = ["mcp"]
tool_timeout_sec = 300
```

#### Cursor

Use `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` inside one project.

```json title="~/.cursor/mcp.json"
{
  "mcpServers": {
    "oleafly": {
      "command": "oleafly",
      "args": ["mcp"]
    }
  }
}
```

#### Gemini CLI

```json title="~/.gemini/settings.json"
{
  "mcpServers": {
    "oleafly": {
      "command": "oleafly",
      "args": ["mcp"],
      "timeout": 300000
    }
  }
}
```

### Give an agent the whole project

`oleafly context` maps the project: its files, outline, labels, citations, missing files, unresolved references and the last build's problems. `--format md` gives text to paste into a prompt; `--format json` gives the same map for a program.

## Check a paper before you submit

`oleafly check` runs the [Preflight checks](/docs/preflight/) on the project, with the same results as the Preflight panel: references, citations, labels, missing files, bibliography fields, figures and anonymity for blind review. Checks that need the compiled PDF use the last build.

`oleafly lint` runs the LaTeX and BibTeX checks and, in the builds that include it, spelling and grammar. `--fix` applies the fixes that are safe to apply.

Both take `--format human`, `json` or `sarif`, and `--exit-code` makes them exit with 9 when they find problems. SARIF works with code-scanning services such as GitHub's: write the report with `oleafly check --format sarif -o preflight.sarif`, upload it with the `upload-sarif` action, and each finding shows on its line in the pull request.

## Sync with an online LaTeX service

`oleafly remote` downloads projects from your online LaTeX service account and keeps a folder in sync with one, with the same merge the app uses.

### Sign in

Sign-ins live in the app's encrypted store, so a sign-in made in the app works on the command line and the other way round.

- `oleafly auth login online --with-token` saves a Git token from the service's account settings. Linking and syncing need one.
- `oleafly auth login online --from-browser firefox` copies your sign-in from a browser on this computer, for listing and downloading projects. Firefox works on every system; Chrome, Edge and Brave work on macOS. `--cookie-stdin` reads a session cookie instead.
- `oleafly auth login git --host https://gitlab.com` saves a token for a Git host.
- `oleafly auth status` lists every sign-in and where it came from, without showing any secret.
- `oleafly auth logout` removes a sign-in.

:::caution[Keep tokens out of your shell history]
Tokens go in on standard input, for example `oleafly auth login online --with-token < token.txt`, never as arguments. In a terminal, the command asks for them without showing what you type. `oleafly auth token` prints a saved token for scripts, so treat its output like a password.
:::

### Import and sync projects

```sh
oleafly remote list
oleafly remote import 64a1f0c2e5b7 --into ~/papers
cd ~/papers/thesis
oleafly remote link
oleafly remote sync
```

- `oleafly remote import` downloads projects into new folders. It works with any account.
- `oleafly remote link` connects a folder to its online project through the service's Git integration, which needs a Git token.
- `oleafly remote sync` merges online changes into the folder and sends yours. `--dry-run` shows what would change and `--no-push` merges without sending.
- When a file changed on both sides, the sync writes nothing and exits with 8. Run it again with `--resolve` and the file's path followed by `=local` or `=remote` for each file.
- `oleafly remote diff` shows what differs; with `--exit-code` it exits with 9 when files differ and 8 when they conflict. `--latexdiff --pdf` builds a marked-up PDF of your changes, using latexdiff from your TeX distribution.
- `oleafly remote status`, `oleafly remote unlink` and `oleafly remote open` show the link, remove it and open the project in your browser.

## Work with an Oleafly server

`oleafly server sign-in` followed by the server's address signs the command line in with a code you approve in your browser. The command line is its own device on the server, apart from the app.

- `oleafly server status` and `oleafly server projects` show your servers and shared projects.
- `oleafly server share` shows a project's link and turns link sharing and comments on or off.
- `oleafly server members` lists the people on a project and adds, removes or changes them. Only the owner can change sharing and members.
- `oleafly server comments` lists, adds, replies to and resolves comments. A comment that can't be sent right away is kept and sent the next time.

Sharing a project for the first time happens in the app. See [Live collaboration](/docs/collaboration/).

## Run the Oleafly agent from a terminal

`oleafly ask` answers a question about the project without changing anything. `oleafly agent run` does a task.

```sh
oleafly ask "Which sections cite Smith 2021?"
oleafly agent run --allow write "Fix the overfull boxes in chapter 3"
```

- The agent can always read the project. `--allow` adds `write`, `commands` or `network`, and it refuses anything you didn't allow. It never stops to ask a question.
- Changes go to a review folder in `.oleafly/agent-runs/` first. `oleafly agent apply` followed by that folder writes them into the project, and `--apply` on the run writes them straight away.
- The provider, model and effort come from the app's settings, or from `--provider`, `--model` and `--effort`. The key comes from the provider's own environment variable, such as `ANTHROPIC_API_KEY`, or from the app's encrypted store.
- `--json` prints one result when the run ends, and `--events` adds a JSON line for each event as it works.

### Keep research tasks running after you quit

Mark a [research task](/docs/research-tasks/) **Keep running when Oleafly is closed**. When you quit, a small background helper takes those tasks over and their experiment runs keep going. A step that needs your approval pauses the task and sends a notification. When you open Oleafly again, it takes the tasks back and shows what happened. Turn this off, or start the helper when you sign in, under **Settings → Research → Background tasks**. `oleafly daemon status` shows what the helper is doing.

## Command reference

Every command explains its options with `--help`. The full reference is in the repository: [docs/cli.md](https://github.com/Oleafly/Oleafly/blob/main/docs/cli.md).

### Projects and builds

| Command | What it does |
|---|---|
| `oleafly open` | Opens a folder in the app (`oleafly .` for the current one) |
| `oleafly init` | Makes the current folder a project |
| `oleafly new` | Creates a project, from a template if you name one |
| `oleafly templates` | Lists templates and shows one |
| `oleafly build` | Builds the project |
| `oleafly watch` | Rebuilds on every save |
| `oleafly clean` | Removes the build output |
| `oleafly log` | Shows the last build's log or its problems |
| `oleafly doctor` | Checks engines, the app and your setup |
| `oleafly version` | Shows the version and the engines in use |
| `oleafly project info` | Shows the project's settings |
| `oleafly projects list` | Lists the app's projects |
| `oleafly config` | Gets and sets project and app settings |

### Writing and references

| Command | What it does |
|---|---|
| `oleafly cite` | Prints BibTeX for a DOI, arXiv id, ISBN or PubMed id; `--add` adds it to the bibliography |
| `oleafly literature` | Searches OpenAlex, Semantic Scholar, Crossref, arXiv and PubMed |
| `oleafly bib check` | Finds entries that match no real record |
| `oleafly bib clean` | Fixes citation keys and removes duplicates; `--apply` writes the changes |
| `oleafly stats` | Counts words, headings, figures and equations |
| `oleafly synctex` | Maps a source line to the PDF and back |
| `oleafly export` | Exports the document to Word, HTML, Markdown, EPUB and more |
| `oleafly convert` | Converts one file to another format |
| `oleafly typst` | Lists, installs and removes Typst versions |
| `oleafly checkpoint` | Lists, compares and copies the app's checkpoints |

### Agents and automation

| Command | What it does |
|---|---|
| `oleafly context` | Maps the project for a person or an agent |
| `oleafly mcp` | Runs the MCP server; `mcp config` sets up a client |
| `oleafly skills` | Lists the skills and prints where they are |
| `oleafly ask` | Answers a question about the project |
| `oleafly agent` | Runs the Oleafly agent on a task |
| `oleafly daemon` | Runs and controls the helper that keeps tasks going |

### Checks

| Command | What it does |
|---|---|
| `oleafly check` | Runs the Preflight checks |
| `oleafly lint` | Runs the LaTeX, BibTeX, spelling and grammar checks |

### Accounts and sync

| Command | What it does |
|---|---|
| `oleafly auth` | Signs in to online LaTeX services, Oleafly servers and Git hosts |
| `oleafly remote` | Imports, links and syncs online projects |
| `oleafly server` | Works with Oleafly servers: projects, sharing, members, comments |

### Shell and help

| Command | What it does |
|---|---|
| `oleafly completions` | Prints shell completions for bash, zsh, fish, PowerShell or elvish |
| `oleafly man` | Prints the manual page |
| `oleafly help exit-codes` | Explains the exit codes |

### Options for every command

| Option | What it does |
|---|---|
| `-C` followed by a path | Runs the command on another project folder |
| `--json` | Prints one JSON result |
| `--events` | Prints progress as JSON lines before the result |
| `--quiet` | Prints only the result |
| `--log` | Shows `none`, the `tail` or the `full` compiler log |
| `--no-input` | Never asks a question |
| `--color` | Uses color `auto`, `always` or `never` |

## Output for scripts

### JSON output

With `--json`, every command prints one JSON object: `schema_version`, `ok`, `command`, the command's own fields and `warnings`. When a command fails, `error` holds a `kind`, a stable `code` and a `message`. When they help, it also has a `hint`, `details`, and `"retryable": true` if trying again may work. Check `schema_version` before you rely on a field.

```json
{
  "schema_version": 1,
  "type": "result",
  "ok": false,
  "command": "remote sync",
  "error": {
    "kind": "conflict",
    "code": "remote.conflicts",
    "message": "2 files changed both here and online.",
    "hint": "Pick a side with --resolve PATH=local or --resolve PATH=remote, then sync again.",
    "details": { "conflicts": ["main.tex", "refs.bib"] }
  },
  "warnings": []
}
```

`--events` adds one JSON line per progress event before the result.

### Exit codes

`oleafly help exit-codes` prints the same table.

| Code | Meaning |
|---|---|
| 0 | It worked |
| 1 | Something inside Oleafly went wrong |
| 2 | The command was used wrongly, or it needs `--yes` to go ahead |
| 3 | The project is missing or invalid, or a path points outside it |
| 4 | A tool or the Oleafly app it needs isn't installed |
| 5 | The build failed |
| 6 | You need to sign in |
| 7 | The network failed |
| 8 | Something else holds the project, or a sync has conflicts |
| 9 | A check found problems |
| 130 | You pressed Ctrl+C |

### Questions, color and logs

The command never asks a question without a terminal. `--no-input` turns questions off too, and so does a `CI` variable; a command that needs a yes then fails with exit code 2 and asks for `--yes`. `NO_COLOR` or `--color never` turns color off. Paths that would leave the project are refused.

### Environment variables

| Variable | Use |
|---|---|
| `OLEAFLY_DATA_DIR` | Oleafly's data folder, when it isn't `~/.oleafly` |
| `OLEAFLY_TECTONIC`, `OLEAFLY_LATEXMK`, `OLEAFLY_TYPST`, `OLEAFLY_PANDOC` | A compiler to use instead of the one Oleafly finds |
| `OLEAFLY_APP` | The Oleafly app that `oleafly open` starts |
| `OLEAFLY_ONLINE_GIT_TOKEN` | A Git token for the online LaTeX service, used instead of a saved one |
| `OLEAFLY_CLI` | Set by Oleafly for programs it starts: the command's full path |
| `CI` | When set, the command never asks a question |
| `NO_COLOR` | When set, output has no color |

## Troubleshooting

| What you see | What to try |
|---|---|
| `oleafly` isn't found | Open a new terminal. Then check with `Get-Command oleafly` on Windows or `command -v oleafly` on macOS and Linux, and add the line that Settings shows to your shell profile |
| `oleafly doctor` reports a missing engine | Install it with the command doctor prints, or open the project in the app once |
| An MCP client can't start the server | Run the configured command in a terminal, use the full path from `oleafly mcp config`, and run `oleafly doctor` |
| Exit code 6 | Run `oleafly auth status`, then sign in again |
| Exit code 8 during a sync | Run the sync again with `--resolve` for each file it lists |
| On macOS, Settings says "Move Oleafly to your Applications folder first" | Move the app, open it from Applications, then choose **Install** |

## Related pages

- [Typst projects](/docs/typst/#build-from-the-command-line)
- [Connect via MCP](/docs/mcp/)
- [CLI agents](/docs/cli-agents/)
- [Preflight checks](/docs/preflight/)
- [Research tasks](/docs/research-tasks/)
