Skip to content

Routines and setup

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

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 extension, 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 extension 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 extension’s current version, so prompts can point to files in it, such as playbooks;
  • the extension’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 extension up with the Set up button in its header. It appears when the extension 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 extension, 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 extension 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 extension.

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.