Concepts

Actions

An action is a named, deterministic capability. Automation action steps call them directly. Agents see selected actions as tools during a turn. Either way, it's one bounded call with a defined input and output: no LLM loop, no implicit retries inside, no surprise side effects.

If automations are "what should happen," actions are "what code to run."

The kinds

KindWhere it runsCreates a job?
workerYour worker process (over the worker WebSocket).Yes.
serverThe Mobius backend. Provider integrations live here.No.
controlThe Mobius runtime itself. Rare, built-in only.No.

Server actions are the platform-provided integrations: slack.post_message, github.add_label, linear.create_issue, and so on. Worker actions are how you plug your own code, your own network, and your own secrets into a run.

When do I need a worker action?

If you can answer "yes" to any of these, the action belongs on a worker:

  • It needs to reach something behind your firewall.
  • It needs a secret that should never live in Mobius.
  • It runs a custom model (Ollama, an internal serving stack).
  • It needs to scale separately from the Mobius backend.

If none of those apply and Mobius already integrates with the provider, use the server action. Don't run a worker just to call Slack.

Registering a worker action

A worker action declares a name, input/output schemas (JSON Schema), and annotations. The annotations matter:

AnnotationMeaning
idempotentSafe to retry. The runtime will.
destructiveShould require explicit confirmation when exposed to agents.
read_onlyNo external side effects.

Mark destructive things destructive and read-only things read_only. The runtime treats agents differently based on these, and the audit log surfaces them.

From the CLI:

mobius actions create --file actions/summarize.yaml
mobius catalog list-actions
mobius catalog get-action summarize-document
mobius actions update summarize-document --file actions/summarize.yaml
mobius actions rotate-secret summarize-document   # rotate signing secret

Action names starting with mobius. or with a known provider prefix (slack., github., linear., ...) are reserved. Custom names should be lowercase and project-local.

Using actions in an automation

steps:
  - name: summarize
    type: action
    action: summarize-document
    with:
      doc_id: "{{ .inputs.doc_id }}"
 
  - name: notify
    type: action
    action: slack.post_message
    with:
      channel: "#ops"
      text: "Summary ready for {{ .inputs.doc_id }}."

The runtime dispatches one job per worker action (the summarize-document step) and calls the server action directly inside Mobius (the slack.post_message step). You don't need to do anything special at the spec layer to mark which is which; the action's kind in the catalog decides.

One-shot invocation

You can call an action without an automation. Useful for CI hooks, debugging, and bootstrap glue:

mobius actions invoke slack.post_message \
  --input '{"channel":"#ops","text":"deploy started"}'
 
mobius actions list-invocations --limit 20
  • Workers execute worker actions.
  • Jobs are the transport records the worker claims.
  • Integrations hold the credentials server actions use.
  • Runs surface every action call in the event stream and the audit log.