Skip to content

Routines and setup

An app’s routines are declared in matter.json. A member routine exists for each member once they set the app up, on the computer they choose. Everything below works on the member’s own routines for the app.

const routines = await matter.routines.list()
// [{ id, key, title, enabled, deviceId, schedule, input, lastRunAt, nextRunAt, runs }]
const run = await matter.routines.run(
'research',
{ campaign: campaignId },
{ requestKey: `research:${campaignId}:${day}` },
)
// { ok, runId, threadId, queued }
const runs = await matter.routines.runs({ key: 'research', limit: 20 })
// [{ id, key, status, startedAt, finishedAt, outcome, error, threadId, requestKey, input }]
await matter.routines.setInput('research', { campaigns: ['Q4'] })
await matter.routines.setEnabled('research', false)
Call What it does
list() The member’s routines for the app, each with its last 10 runs.
run(key, input?, { requestKey? }) Starts a run now.
runs({ key?, ids?, requestKeys?, limit? }) Runs, newest first. The default limit is 50.
setInput(key, input) Sets the input every run of the routine gets.
setEnabled(key, on) Pauses or resumes the routine.

A routine the member hasn’t got fails with not_found: set the app up first.

A run’s input is the routine’s own input (from setInput or setup), with the input you pass to run on top. The agent gets it after the prompt, as JSON, under “Input for this run”. A run’s input is at most 16 KB.

A request key names a run for good. Running again with a key that already has a run gives back that run instead of starting another, so retries are safe. To run again on purpose, use a new key. Find runs by their keys with runs({ requestKeys }).

A routine runs concurrency runs at once (1 by default). Further runs are queued (queued: true), and start in order as runs finish. A paused routine doesn’t run.

A routine run is an agent thread on the member’s computer, working as the member:

  • its working directory is the app’s current version, so prompts can point to files in it, such as playbooks;
  • the app’s tools, as an MCP server;
  • the browser or Computer Use only if the routine needs them;
  • Matter’s own tools, for tasks, docs, the brief and the rest.

Runs report to the member’s brief only what needs them. Your pages show the rest.

Members set an app up with the Set up button in its header. It appears when the app has member routines the member hasn’t set up. Setting up creates their routines, on the computer they choose.

With "setup": "/setup" in matter.json, Set up opens that page of your app, so you can collect what the routines need. Your setup page finishes with matter.setup.create:

const device = await matter.device()
await matter.setup.create({
deviceId: device.id,
inputs: { research: { campaigns: ['Q4'] }, inbox: { folders: ['INBOX'] } },
})
Call What it does
setup.get() The member’s setup, { id, deviceId }, or null.
setup.create({ deviceId?, inputs? }) Sets the app up on this computer, or the computer deviceId names, with each routine’s input by key. Called again, it moves the setup and updates the inputs.
setup.remove() Removes the member’s setup, and deletes their routines for the app.

Without a setup route, Set up creates the routines directly, with no input. context().setup.thisDevice tells you whether the member’s routines run on this computer.