Methods
emisar speaks JSON-RPC 2.0 over MCP. Three methods matter to a client:
-
initialize— the MCP handshake; returns server capabilities and instructions. -
tools/list— the live action catalog as MCP tools, scoped to your key. Each runnable action is one tool, plus the meta tools below. -
tools/call— dispatch one action (or call a meta tool) by name with arguments.
The catalog is live, not static
tools/list
is a point-in-time snapshot. A tool being listed does
not
guarantee a runner is connected or its pack is trusted at call time — both are resolved
when you actually dispatch. When a call fails for a runner or catalog reason, re-call
tools/list
to refresh, then decide from the fresh list. Don't retry the same
failing call in a loop.
Calling an action
Each action tool takes its own declared, typed arguments, plus these emisar parameters:
| Parameter | Requirement | What it does |
|---|---|---|
| reason | Required | An operator-facing audit string — one short sentence on why. It's recorded on the run for a human to audit later. |
| <action args> | Per the action | The action's own typed arguments, re-validated against its declared schema on the runner. |
| runners | Required | The target runner(s) to fan out to — an array of names (or a single runner string). Always required: emisar never auto-targets, even when exactly one runner advertises the action, so every call names its host explicitly. |
| idempotency_key | Optional | Dedups a call you might retry, so the same intent runs once. (The bridge also mints a transport-level key automatically — see Idempotency.) |
| wait | Optional | Block until the run reaches a terminal state, up to a ~60s cap, and return its result. Otherwise the call returns once the run is dispatched; poll with wait_for_run. |
Meta tools
Alongside the action tools, tools/list includes a few helpers:
-
wait_for_run— block until a specific run reaches a terminal state (up to five minutes), then return its result; re-poll if it's still running. -
recent_runs— the account's recent runs, for picking up where a previous session left off. -
list_runbooks— the account's published runbooks (saved, ordered playbooks). -
get_runbook— one runbook's ordered steps. The cloud does not run a runbook for you: fetch it and dispatch each step yourself, in order, honoring each step's policy.
Idempotency
Idempotency has two layers, so a retried dispatch never double-executes a mutating action:
-
Transport
— the MCP bridge auto-mints an
Idempotency-Keyper call, covering transparent retries. -
Model intent
— the
idempotency_keyargument lets the model mark a call it might re-issue itself as the same intent.
Errors
When a dispatch is refused, the reason is specific. The three you'll meet most:
| Error | What it means | What to do |
|---|---|---|
| pack_untrusted | The runner advertises a pack version no operator has trusted yet, so the cloud refuses to run it. | A human trusts the pack on the Packs page. Retrying or reloading will not clear it. |
| pack_retired | The runner advertises a pack version a newer release retired (a critical fix superseded it), so the cloud refuses to run it. | Update the pack on the runner (emisar pack install <pack>), or an admin re-trusts the version on the Packs page. |
| No runner advertises <action> / Action not found | No currently-connected runner advertises this action — it's offline, the pack isn't loaded, or the pack isn't installed. | Re-call tools/list; if it's still missing, check the runner is online on the Runners page. |
| No runner in scope | The action exists, but no runner you're permitted to reach advertises it. | An access-grant issue — an admin widens your per-user runner scope. |
Every dispatch — allowed, approved, or denied — is recorded. See the audit trail for what's captured and how to stream it, and policies & approvals for what makes a call wait or deny.