Skip to main content

resonate-cli

Drive the Resonate server from the shell — start a server (`serve` / `dev`), create/resolve/search Durable Promises, create and delete cron schedules, manually invoke a function via `invoke`, walk a call-graph with `tree`, and inspect or recover tasks (`tasks`). Reach for this when the agent needs to poke a running Resonate server without writing SDK code: unblocking a stuck human-in-the-loop promise, triggering a workflow by hand to reproduce a bug, listing pending promises by tag, registering a one-off cron, or smoke-testing a deploy. Covers global flags, every subcommand and its flags as of `resonate 0.9.8`, configuration layering (`resonate.toml` + `RESONATE_*` env vars + flags), common recipes, and the small set of docs-vs-binary deltas an agent will trip on.

Jump to install

Source facts

Repository
resonatehq/resonate-skills
Last source activity
August 21, 2026 at 17:03
Detected SKILL.md language
English
Stars
6
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
resonate-cli
description
Drive the Resonate server from the shell — start a server (`serve` / `dev`), create/resolve/search Durable Promises, create and delete cron schedules, manually invoke a function via `invoke`, walk a call-graph with `tree`, and inspect or recover tasks (`tasks`). Reach for this when the agent needs to poke a running Resonate server without writing SDK code: unblocking a stuck human-in-the-loop promise, triggering a workflow by hand to reproduce a bug, listing pending promises by tag, registering a one-off cron, or smoke-testing a deploy. Covers global flags, every subcommand and its flags as of `resonate 0.9.8`, configuration layering (`resonate.toml` + `RESONATE_*` env vars + flags), common recipes, and the small set of docs-vs-binary deltas an agent will trip on.
# resonate-cli ## Overview The `resonate` binary is one program with three jobs: 1. **Run the Resonate server** — `resonate serve` (persistent storage) and `resonate dev` (in-memory, for development). 2. **Talk to a running server over HTTP** — every subcommand under `resonate promises`, `resonate schedules`, `resonate tasks`, plus the top-level `resonate invoke` and `resonate tree`. 3. **Expose an MCP shim** — `resonate mcp` is a stdio MCP server that wraps the same HTTP API for skill-aware agents (see `resonate-bash` for the durable-bash tool that ships through this shim). This skill is the agent's reference for #2 and #3 — when you need to interact with a Resonate server from a shell. For long-form server deployment, see [`resonate-server-deployment`](../resonate-server-deployment/SKILL.md) and [`resonate-server-deployment-cloud-run`](../resonate-server-deployment-cloud-run/SKILL.md). The CLI is the source of truth. The hosted docs occasionally drift — see [Docs-vs-binary deltas](#docs-vs-binary-deltas) below. When in doubt: `resonate <cmd> --help`. ## When to use this skill Reach for the CLI when **any** of the following is true: - You need to resolve, reject, or cancel a Durable Promise from outside any worker — typically to unblock a human-in-the-loop workflow, simulate a webhook callback, or recover a stuck process. - You need to inspect server state — `promises get`, `promises search`, `schedules search`, `tasks search`, `tree`. - You need to trigger a function manually — `invoke` creates the promise and routes it to a worker target, no client SDK required. - You need to register or remove a cron schedule. - You're scripting a smoke test against a running server. Prefer the SDK over the CLI in application code. The CLI is for operators, debuggers, and one-off tooling. Anything you'd commit as a workflow step should live in the SDK. ## Installation and version check ```shell brew install resonatehq/tap/resonate # macOS resonate --version # expect 0.9.8 or newer ``` Linux: download from [GitHub releases](https://github.com/resonatehq/resonate/releases) and put the binary on `$PATH`. All command surface in this skill is from `resonate 0.9.8`. Use `resonate <cmd> --help` to confirm against your installed version — the built-in help is always authoritative. ## Top-level command map ``` resonate ├── serve Start the production server (persistent storage) ├── dev Start the development server (in-memory) ├── promises Promise operations (CRUD + search + callbacks/listeners) ├── tasks Task operations (low-level; usually SDK-owned) ├── schedules Schedule operations (cron-driven promise creation) ├── invoke Invoke a function via a durable promise ├── tree Display the call-graph tree rooted at a promise ID └── mcp Start the Resonate MCP server (stdio transport) ``` ## Global flags Every client subcommand (`promises`, `tasks`, `schedules`, `invoke`, `tree`, `mcp`) accepts: | Flag | Description | Default | |---|---|---| | `-S`, `--server <URL>` | Resonate server URL | `http://localhost:8001` | | `-T`, `--token <TOKEN>` | JWT bearer token for authenticated servers | — | | `-h`, `--help` | Print help for this command | — | `resonate --version` and `resonate --help` work at the top level. There is **no** `--output json` flag in `resonate 0.9.8`, despite older docs mentioning one. Subcommand stdout is human-formatted; if you need structured output, call the HTTP API directly with `curl`. ## Server commands ### `resonate dev` — in-memory development server ```shell resonate dev ``` Storage defaults to `:memory:` (SQLite in-RAM), so every restart is a clean slate. Useful for local development and tests. Listens on: - HTTP API: `http://localhost:8001` - Prometheus metrics: `http://localhost:9090/metrics` - Health probe: `http://localhost:8001/health` (200 when healthy — note: it is `/health`, not `/healthz`) Common flags (full set: `resonate dev --help`): | Flag | Default | Notes | |---|---|---| | `--server-port <PORT>` | `8001` | HTTP API port | | `--server-host <HOST>` | `localhost` | Bind host | | `--server-cors-allow-origin <ORIGIN>` | — | Repeatable; `*` for permissive | | `--storage-sqlite-path <PATH>` | `:memory:` | Override for an on-disk SQLite file even in dev | | `--transports-bash-exec-enabled <BOOL>` | `false` | Enable the `bash://` transport used by the [`resonate-bash`](../resonate-bash/SKILL.md) MCP tool | | `--observability-metrics-port <PORT>` | `9090` | `0` disables the metrics endpoint | | `--level <LEVEL>` | `info` | `debug`, `info`, `warn`, `error` | `--transports-bash-exec-enabled` (and every `--transports-*-enabled` flag) requires an explicit `true` / `false`. A bare flag errors with `a value is required for '--transports-bash-exec-enabled <BOOL>'`. ### `resonate serve` — production server ```shell export RESONATE_STORAGE__POSTGRES__URL="$DATABASE_URL" # e.g. postgres://<user>:<password>@<host>:5432/resonate resonate serve --storage-type postgres ``` Same flag surface as `dev` plus storage and auth options. The full reference is `resonate serve --help`; the highlights: | Flag | Default | Notes | |---|---|---| | `--storage-type <sqlite\|postgres\|mysql>` | `sqlite` | **Must be set to `postgres` explicitly** — passing only `--storage-postgres-url` silently leaves the server on SQLite | | `--storage-postgres-url <URL>` | — | Required when `--storage-type postgres` | | `--storage-postgres-pool-size <N>` | `10` | | | `--storage-mysql-url <URL>` | — | MySQL is also supported | | `--storage-mysql-pool-size <N>` | `10` | | | `--auth-publickey <KEY>` | — | Path to PEM public key; enables JWT auth. Use the literal string `none` for unsigned mode | | `--auth-iss <ISS>` | — | Required JWT `iss` claim | | `--auth-aud <AUD>` | — | Required JWT `aud` claim | | `--tasks-lease-timeout <MS>` | `15000` | How long a claimed task lease holds before redispatch | | `--tasks-retry-timeout <MS>` | `30000` | Pending-task retry interval | | `--transports-http-push-enabled <BOOL>` | `true` | Outbound webhook delivery | | `--transports-http-push-auth-mode <none\|bearer\|gcp>` | `none` | Set to `gcp` for Cloud Run ID-token auth | | `--transports-http-poll-enabled <BOOL>` | `true` | SSE long-poll transport | | `--transports-gcps-enabled <BOOL>` | `false` | GCP Pub/Sub transport (`--transports-gcps-project` required) | | `--transports-bash-exec-enabled <BOOL>` | `false` | See [`resonate-bash`](../resonate-bash/SKILL.md) | | `--observability-otlp-endpoint <ENDPOINT>` | `localhost:4317` | OpenTelemetry OTLP target | | `--storage-sqlite-path <PATH>` | `resonate.db` | On-disk by default in `serve` (`:memory:` in `dev`) | **Storage gotcha:** `--storage-type` defaults to `sqlite`. If you set `--storage-postgres-url` alone, the server boots on SQLite and silently ignores the URL. Always pair them. `--storage-mysql-url` behaves differently: passing it alone **auto-switches** the storage type to `mysql` when the current type is `sqlite`, so the flag is sufficient on its own — but be explicit with `--storage-type mysql` anyway for clarity. **Health route:** `/health` returns 200 when the server is up. `/healthz` does not exist on Resonate — don't wire that into your readiness probes. ## `resonate promises` The most common subcommand tree. Every promise command takes `<ID>` as the trailing arg (or two IDs for callbacks/listeners) and respects the global `-S` / `-T` flags. ### `promises create <ID> --timeout <DURATION>` ```shell resonate promises create approval-456 --timeout 24h ``` | Flag | Description | |---|---| | `--timeout <DURATION>` *(required)* | Promise deadline relative to now, e.g. `30s`, `5m`, `1h`, `24h` | | `--param <JSON>` | Promise parameter, JSON-encoded: `--param '{"data":"hello"}'` | | `--tags <JSON>` | Tag object: `--tags '{"project":"checkout"}'`. Used by `search --tags` later | ### `promises get <ID>` ```shell resonate promises get order-123 ``` Returns state, timestamps, param, value, and tags. ### `promises resolve <ID> [--value <JSON>]` ```shell resonate promises resolve approval-456 --value '{"approved": true}' ``` The flag is `--value`, **not** `--data` (older docs sometimes show `--data` — the binary doesn't accept it). ### `promises reject <ID> [--value <JSON>]` Same shape as `resolve` — the JSON ends up in the `value` field with promise state `rejected`. ### `promises cancel <ID> [--value <JSON>]` Same shape; promise state becomes `rejected_canceled`. ### `promises search` ```shell resonate promises search --state pending --limit 20 resonate promises search --tags '{"project":"checkout"}' --limit 50 ``` | Flag | Description | |---|---| | `--state <STATE>` | One of `pending`, `resolved`, `rejected`, `rejected_canceled`, `rejected_timedout` | | `--tags <JSON>` | Match on tag subset, JSON object | | `--limit <N>` | Default `100` | | `--cursor <CURSOR>` | Pagination cursor returned by the previous page | `promises search` does **not** take a positional ID pattern — there is no `search "order-*"` form in `resonate 0.9.8`. Filter via `--tags` or paginate `--state` results client-side. ### `promises register-callback <AWAITED> <AWAITER>` Wires a server-side callback so that resolving `AWAITED` notifies the `AWAITER` promise. Rarely used from the CLI — most callers register callbacks via the SDK. ### `promises register-listener <AWAITED> <ADDRESS>` Registers a delivery address (e.g. `http://my-host/cb` or `poll://group@worker`) to be notified on settlement of `AWAITED`. Useful for ad-hoc webhook wiring during debugging. ## `resonate schedules` Cron-driven promise creation. Every cron tick stamps out a new promise from a template. ### `schedules create <ID> --cron <EXPR> --promise-id <TEMPLATE> --promise-timeout <DURATION>` ```shell resonate schedules create hourly-sync \ --cron "0 * * * *" \ --promise-id "sync-{{.timestamp}}" \ --promise-timeout 30m \ --promise-param '{"job":"sync"}' \ --promise-tags '{"system":"etl"}' ``` | Flag | Required | Description | |---|---|---| | `--cron <EXPR>` | yes | Standard 5-field cron, e.g. `"0 * * * *"` for hourly | | `--promise-id <TEMPLATE>` | yes | Promise ID template. `{{.timestamp}}` interpolates the tick's ms-since-epoch — use it to keep each tick's promise ID unique | | `--promise-timeout <DURATION>` | yes | Per-tick promise deadline, e.g. `30m`, `1h` | | `--promise-param <JSON>` | no | Param attached to every generated promise | | `--promise-tags <JSON>` | no | Tags attached to every generated promise | `--description` exists in older docs but not in `resonate 0.9.8`. Use `--promise-tags` to label. ### `schedules get <ID>` / `schedules search` / `schedules delete <ID>` ```shell resonate schedules search --limit 50 resonate schedules get hourly-sync resonate schedules delete hourly-sync ``` `schedules search` accepts `--tags` and `--limit`/`--cursor`. There is no positional pattern arg — same shape as `promises search`. ## `resonate invoke` ```shell resonate invoke <PROMISE_ID> --func <FUNC_NAME> [--arg <ARG> | --json-args <JSON_ARRAY>] ``` Creates a Durable Promise and routes it to a worker that has registered `FUNC_NAME`. The agent uses this to trigger workflows manually — for reproducing a bug, smoke-testing a worker after deploy, or kicking off one-off jobs. | Flag | Default | Description | |---|---|---|
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub