name: miro-cli description: "Hand-authored Cobra CLI for the Miro REST API." author: "Olga Safonova" license: "Apache-2.0" argument-hint: "<command> [args]" allowed-tools: "Read Bash" metadata: openclaw: requires: bins: - miro-cli
Miro Developer Platform — miro-cli
Prerequisites: Install the CLI
This skill drives the miro-cli binary. You must verify the CLI is installed before invoking any command from this skill. If it is missing, install it first:
- Install from source:
go install github.com/olgasafonova/miro-cli/cmd/miro-cli@latest - Verify:
miro-cli --help(andmiro-cli --versionto record the build; a source/go installbuild reportsdev, a release reports its tag). - Ensure
$GOPATH/bin(or$HOME/go/bin) is on$PATH.
Alternatively, install via Homebrew (brew install olgasafonova/tap/miro-cli) or download a pre-built binary from the latest release.
If --help reports "command not found" after install, the install step did not put the binary on $PATH. Do not proceed with skill commands until verification succeeds.
Miro Developer Platform concepts
- New to the Miro Developer Platform? Interested in learning more about platform concepts?? Read our introduction page and familiarize yourself with the Miro Developer Platform capabilities in a few minutes.
Getting started with the Miro REST API
- Quickstart (video): try the REST API in less than 3 minutes.
- Quickstart (article): get started and try the REST API in less than 3 minutes.
Miro REST API tutorials
Check out our how-to articles with step-by-step instructions and code examples so you can:
Miro App Examples
Clone our Miro App Examples repository to get inspiration, customize, and explore apps built on top of Miro's Developer Platform 2.0.
Command Reference
miro-cli is organized into resource groups. Each group is a subcommand tree;
run miro-cli <group> --help for the exact verbs and flags of that group, and
miro-cli <group> <verb> --help for a single command. The groups are:
| Group | What it covers |
|-------|----------------|
| boards | Create, copy, get, update, delete boards; also boards diagram (render a sequence/flowchart from text) |
| items | Generic board items: get, list, update, delete, and bulk update/delete via --ids-file / --patches-file (pass - to read the JSON payload from stdin, e.g. ... \| miro items bulk-delete --ids-file -) |
| stickies | Sticky notes |
| shapes | Shapes |
| texts | Text items |
| cards | Card items |
| appcards | App card items |
| frames | Frames |
| images | Image items |
| embeds | Embedded URLs |
| documents | Document items |
| connectors | Connectors (lines/arrows between items) |
| tags | Tags and tag assignment |
| groups | Item groups |
| mindmap | Mind-map nodes |
| codewidgets | Code widget items |
| members | Board members and sharing roles |
| boards share | Invite members to a board (gated by the share allowlist — see Security) |
| exports | Board export jobs |
| audit | Organization audit events (last 90 days; Enterprise) |
| sync | Mirror boards/items into a local SQLite store for offline use |
| query | Run read-only SQL / FTS5 search against the local store built by sync |
The authoritative command list is the binary itself. When unsure whether a verb
exists, run miro-cli <group> --help rather than guessing.
Finding the right command
- Reading/searching offline or repeatedly →
miro-cli synconce, thenmiro-cli query "<SQL>"(FTS5 full-text search is available). - One-off live read → the matching resource group's
get/listverb. - Mutating a board → the resource group's
create/update/deleteverb; destructive verbs require--yes(or--agent).
Auth Setup
miro-cli authenticates with a Miro access token, resolved in this order:
--token <value>flag$MIRO_ACCESS_TOKENenvironment variable
If neither is set, commands that hit the API exit with a config error (exit code 10). There is no interactive login.
Check the setup directly with miro-cli auth status:
miro-cli auth status --json # {token_present, source, verified, status}, no network
miro-cli auth status --verify --json # also confirms the token works right now
Exit codes: 0 token present (and valid, with --verify), 10 no token,
4 token rejected. Under --verify, status reports ok,
invalid_or_expired, or insufficient_scope so you can tell a bad token from
a scope problem. Prefer this over probing with a read command.
Agent Mode and agent-facing flags
These global flags are available on every command:
--agent— agent mode. Expands to--jsonand--yes(forces JSON output and skips destructive-operation confirmations). Nothing else.--json— force JSON output (the default when stdout is piped).--dry-run— print the request the command would send, then exit without calling the API.--yes— skip confirmation prompts on destructive operations.--idempotent— treat already-exists as success on create, and already-gone as success on delete.--select <fields>— comma-separated list of top-level field names to keep in JSON output. It filters the top-level object; when the output is a JSON array, the same top-level filter is applied to each element. It does not descend into nested objects via dotted paths.--rate-limit,--concurrency,--cache-ttl,--no-cache,--store-path— tuning for throughput, the GET response cache, and the local store location.
Example:
miro-cli boards get --agent --select id,name
Output shape
Commands print the API result as JSON directly to stdout — there is no meta/
results envelope to unwrap; parse the value itself. When stdout is a terminal,
a short human-readable summary may be written to stderr, so piped and
--agent consumers receive clean JSON on stdout.
Security: board sharing is allowlist-gated
miro-cli boards share grants a third party access to a board, so it is gated
by a fail-closed allowlist. With no allowlist configured, every share attempt is
refused.
MIRO_SHARE_ALLOWED_DOMAINS— comma-separated list of recipient email domains permitted to receive invitations.MIRO_SHARE_ALLOWED_EMAILS— comma-separated list of exact addresses. When set (even to an empty value), it is authoritative: only the listed addresses pass and the domain allowlist is ignored entirely. This is a strict tightening, not a widening — a permitted domain cannot rescue an unlisted address.
Exit codes
| Code | Meaning | |------|---------| | 0 | Success | | 2 | Usage error | | 3 | Not found (HTTP 404) | | 4 | Auth error (HTTP 401 / 403) | | 5 | Other API error | | 7 | Rate limited (HTTP 429) | | 10 | Config error (e.g. missing token) |
Next.js App Router Expert
Development
A skill that turns Claude into a Next.js App Router expert.
README Generator
Development
Creates professional and comprehensive README.md files for your projects.
API Documentation Writer
Development
Generates comprehensive API documentation in OpenAPI/Swagger format.