meetily-pro CLI
Install meetily-pro and use it to call the Meetily Gateway: global flags, token resolution, exit codes, and the full command tree.
A thin client, not a second implementation
meetily-pro has no business logic of its own. Every command resolves a server URL and a bearer token, sends one HTTP request to the Gateway, maps the outcome to an exit code, and prints the result. The default Gateway address is http://127.0.0.1:8420.
Before any command works beyond health, turn on Allow for the auto-created loopback key under Settings > Integrations > Apps & scripts - see Enable & connect. That loopback key ("Meetily's own", Read) is what the CLI uses; the token file already exists on disk, but like every key it stays "Not allowed yet" until you flip its Allow toggle.
Install
meetily-pro reaches your PATH through one command, install-cli, regardless of how you got the binary:
Standalone download
A single binary plus a SHA256SUMS file, built for one target triple.
In-bundle
The same binary ships inside the Meetily desktop app as a Tauri sidecar.
Get the binary. Either download the standalone build for your platform, or use the copy that already lives inside your installed Meetily app.
Run install-cli from that binary. install-cli is a local filesystem operation only - it never talks to the Gateway, and it always installs whichever binary you ran it from, so the standalone and in-bundle paths behave identically:
./meetily-pro install-cli # symlink into ~/.local/bin (unix default)
./meetily-pro install-cli --copy # copy the binary instead of symlinking
./meetily-pro install-cli --dir /usr/local/bin --forceConfirm it: open a new shell and run meetily-pro version.
Global flags and token resolution
These flags work with every subcommand, before or after it:
| Flag | Meaning |
|---|---|
--server <url> | Gateway URL. Overrides MEETILY_PRO_SERVER and the default http://127.0.0.1:8420. |
--token-file <path> | Read the bearer token from a file. This is the recommended way to pass a token - it never touches argv, process listings, or shell history. |
--json | Print the raw server JSON instead of the human-readable rendering. |
--timeout <secs> | Request timeout in seconds. Default 10. |
--quiet | Suppress non-essential (success/decorative) output. Errors still print. |
--token is retired
An older --token <value> flag is gone. The CLI no longer accepts it - use --token-file or the MEETILY_PRO_TOKEN environment variable instead.
How the token is resolved
--token-file, if passed.MEETILY_PRO_TOKEN environment variable.If --token-file points at a path that can't be read, the CLI prints a warning to stderr rather than silently falling through to the next option.
~/Library/Application Support/pro.meetily.ai/gateway-token%APPDATA%\pro.meetily.ai\gateway-token$XDG_DATA_HOME/pro.meetily.ai/gateway-tokenmeetily-pro health is the one command that needs no token at all. Every other command needs a token with the right scope, or the Gateway returns 401/403 - exit code 4 below.
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | Error - a non-2xx HTTP status other than 401/403, an invalid response body, or a CLI usage/parse error (bad flags, unknown subcommand). |
2 | Request timed out. |
3 | Could not connect to the server - connection refused/reset, or a DNS failure. |
4 | Denied - the Gateway returned 401 or 403: a missing token, or a token without the required scope. |
--help and --version exit 0. A 200 response with an empty body (several write/control endpoints return one) is parsed as JSON null, not treated as a parse error.
Scopes
Meetily has four scopes: read, record, write, and delete. There is no admin scope.
Unless a command below says otherwise: a GET route needs read, and a route that creates, changes, or removes data needs write. Recording control needs record instead of write, and deleting a meeting needs delete instead of write.
Commands
Read commands print a human-readable rendering by default, or the raw JSON with --json. Write and control commands do the same for their response body (often null).
| Command | Route | Scope |
|---|---|---|
meetily-pro health | GET /health | None |
meetily-pro doctor | Offline self-diagnostic - no Gateway call | None |
meetily-pro version | Prints the CLI's own version - no server call | None |
meetily-pro whoami | GET /v1/whoami | read |
meetily-pro search "<query>" | GET /v1/search?q= | read |
doctor checks the resolved server URL, whether the loopback token file exists and is readable, whether a token resolves at all, and does a best-effort reachability ping. It exits 0 unless it finds a real fault, such as a token file that exists but isn't a readable regular file.
| Command | Route | Scope |
|---|---|---|
meetily-pro meetings list [--limit N] [--offset N] | GET /v1/meetings | read |
meetily-pro meetings get <id> | GET /v1/meetings/:id | read |
meetily-pro meetings export <id> [--format json|md|txt] | GET /v1/meetings/:id/export | read |
meetily-pro meetings rename <id> --title "T" | PATCH /v1/meetings/:id | write |
meetily-pro meetings delete <id> | DELETE /v1/meetings/:id | delete |
meetily-pro meetings speaker-labels <id> --labels '<json>' | PUT /v1/meetings/:id/speaker-labels | write |
export defaults to json if --format is omitted. --labels takes a JSON object string, for example '{"Speaker 1":"Alice"}'.
meetings delete has no undo
This permanently deletes the meeting. There is no confirmation prompt - the CLI sends the request as soon as you run it. It needs the delete scope, which is granted separately from write and is never handed to a paired device.
| Command | Route | Scope |
|---|---|---|
meetily-pro transcript get <id> | GET /v1/meetings/:id/transcript | read |
| Command | Route | Scope |
|---|---|---|
meetily-pro summary get <id> | GET /v1/meetings/:id/summary | read |
meetily-pro summary set <id> --text "T" | --file <path> | PUT /v1/meetings/:id/summary | write |
meetily-pro summary regenerate <id> [--model] [--model-name] [--template-id] [--language] | POST /v1/meetings/:id/summary/regenerate | write |
summary set requires exactly one of --text or --file. summary regenerate's flags are all optional and fall back to the app's stored config when omitted.
Both commands overwrite, with no undo
summary set replaces the stored summary outright with whatever you pass; the previous summary is gone. summary regenerate makes a real LLM call against the meeting's transcript - it can take noticeable time, may consume compute or API cost depending on your configured provider, and replaces the existing summary when it completes.
| Command | Route | Scope |
|---|---|---|
meetily-pro jobs list | GET /v1/jobs | read |
meetily-pro jobs diarization --meeting-id <id> [--speaker-count N] | POST /v1/jobs/diarization | write |
meetily-pro jobs cancel <id> | POST /v1/jobs/:id/cancel | write |
meetily-pro jobs pause <id> | POST /v1/jobs/:id/pause | write |
meetily-pro jobs resume <id> | POST /v1/jobs/:id/resume | write |
meetily-pro jobs retry <id> | POST /v1/jobs/:id/retry | write |
Omit --speaker-count on jobs diarization for auto mode.
| Command | Route | Scope |
|---|---|---|
meetily-pro config get <section> | GET /v1/config/:section | read |
meetily-pro config set <section> --json-body '<json>' | --file <path> | PUT /v1/config/:section | write |
Valid sections: vad, diarization, speaker-identification, meeting-detection, global-shortcut, audio-player, custom-words, initial-prompt. Any other section name 404s. config set requires exactly one of --json-body or --file.
--json-body, not --json
This is --json-body, since the global --json output flag is inherited into every subcommand and already means something else there. --json-body carries the request payload; the global --json still controls how the response is printed.
config set replaces immediately
There's no dry-run or diff preview - the named section changes on the running app as soon as the request lands. Run config get <section> first if you want to compare before overwriting.
| Command | Route | Scope |
|---|---|---|
meetily-pro devices list | GET /v1/devices | read |
meetily-pro models list | GET /v1/models | read |
| Command | Route | Scope |
|---|---|---|
meetily-pro recording start [--meeting-name] [--mic] [--system] | POST /v1/recording/start | record |
meetily-pro recording stop | POST /v1/recording/stop | record |
meetily-pro recording pause | POST /v1/recording/pause | record |
meetily-pro recording resume | POST /v1/recording/resume | record |
recording start's request body takes meeting_name, mic_device_name, and system_device_name, all optional. There is no consent_attested field - sending one returns 400.
These control real audio capture
recording start begins recording microphone and/or system audio immediately; recording stop ends and finalizes it. Run these deliberately, not experimentally, especially against a Gateway on someone else's machine.
| Command | Route | Scope |
|---|---|---|
meetily-pro install-cli [--dir <path>] [--force] [--copy] | Local filesystem only - no Gateway call | None |
See Install above.
| Command | Route | Scope |
|---|---|---|
meetily-pro pair <host> [--client-name <name>] [--scopes <read,record,write,delete>] [--fingerprint <sha256>] | POST {host}/v1/pair/request, then polls GET {host}/v1/pair/:id | None - pairing bootstraps a token, so it needs none to start |
host is used directly, not --server / MEETILY_PRO_SERVER. Pass --fingerprint <sha256> to pre-pin an out-of-band-verified certificate before the first request (the safer path, covered in Pairing & remote access); omit it and the CLI pins the server's certificate trust-on-first-use on approval. Either way it persists that fingerprint to the local paired-fingerprint store, so a later command against --server <host> pins that connection instead of failing closed against the self-signed certificate. It prints the minted token once, for you to export as MEETILY_PRO_TOKEN - it deliberately does not write the token to disk.
meetily-pro mcp runs a Model Context Protocol server over stdio instead of making a single Gateway call. See MCP server for its commands, exposed tools, and security model.
Examples
meetily-pro whoamiPrints the identity and scopes attached to the resolved token. Add --json to get the raw response instead of the human-readable rendering.
meetily-pro meetings listLists meetings using the same pagination the desktop app uses. Add --limit and --offset to page through a large list.
What the CLI does not have
- No
schemacommand. There's nomeetily-pro schemaforGET /openapi.json. Fetch that route directly with curl if you need the manifest. - No
--wait/ SSE support.recording --waitis not wired into the CLI. The long-poll wait endpoints (GET /v1/jobs/:id/wait,GET /v1/recording/wait) have no CLI equivalent - use curl with-N, or reach them through the MCP server'swait_for_job/wait_for_recordingtools. - No
webhookscommand. Webhook registration, listing, deletion, and delivery logs are HTTP-only from the CLI's perspective. - No
pairingsadmin command. Listing or revoking existing pairings is HTTP-only; requesting and completing a new pairing is covered bymeetily-pro pairabove. - No recording-state read command.
GET /v1/recording(the current recording state) has no CLI subcommand - only the four control verbs underrecordingexist. Reach it with curl, or with the MCP server'sget_recording_statetool.
Last updated on
Governance & administration
The flags that gate the API, how to lock it down for a whole fleet, the kill switch, and what turning the API off actually means.
MCP server
Connect an MCP-compatible AI assistant to a running Meetily desktop app: tools, resources, prompts, and the security model behind them.
