Skip to main content
Early access. Cloud sessions and managed agent runs are not open to every account yet: we are letting accounts in gradually while we test. They run in a cloud sandbox operated by Mutagent, so there is nothing to host. A sandbox with nothing to do for 15 minutes stops; send the session a message and it wakes up, delivers your message and carries on in the same conversation.
In this tutorial you build the invoice-pricing agent. It prices an invoice from a product catalog and a pricing policy. You write it, run it on your machine, deploy it to an Environment, run it on Helix Cloud, deploy a change, and roll the change back. It takes about 10 minutes. The agent has:

Before you start

Check each item. The command after it is the check. Steps 7 and 8 are optional. Without Helix on your machine, skip step 7; you can still deploy and run the agent on Helix Cloud.
For coding agents. Run every command from the folder that will contain invoice/. Add --json to every mutagent agent and mutagent env command: each prints one JSON object on stdout, and success is true exactly when the exit code is 0. mutagent helix agent is the exception: its output is Helix’s own, so read its exit code and stderr instead. Exit codes: 0 success, 1 failure (usage errors included), 2 key expired or invalid, 3 not signed in or no workspace.
1

Create the folder

Write invoice/package.json. An agent with tool modules needs it. It has no dependencies.
invoice/package.json
2

Write agent.md

agent.md holds the settings in YAML frontmatter and the agent’s instructions in the Markdown body. Write invoice/agent.md:
invoice/agent.md
  • name is the agent’s slug. You run it as @invoice-pricing.
  • model is the model the agent always uses. Replace zai/glm-5.3 with an id from mutagent helix models.
  • harness.tools.builtin: [read] gives the agent the read tool. It reads the skill with it.
  • harness.tools.modules, harness.skills and harness.files declare the three files you write next. Only declared files are packaged.
  • harness.runtime.mode: headless means a run needs a task.
3

Add the catalog file

Write invoice/assets/catalog.json. The tool reads prices from it.
invoice/assets/catalog.json
4

Write the tool

Write invoice/tools/calculate-invoice.ts:
invoice/tools/calculate-invoice.ts
  • name equals the name under harness.tools.modules.
  • parameters is the input the model must send.
  • The tool reads the catalog under context.paths.assetRoot, where the packaged files are.
  • You do not install @mutagent/agents. The compiler supplies it.
Tools, skills and files explains every field.
5

Write the skill

Write invoice/skills/invoice-pricing/SKILL.md:
invoice/skills/invoice-pricing/SKILL.md
Write the policy next to it, in invoice/skills/invoice-pricing/policy.json:
invoice/skills/invoice-pricing/policy.json
The model sees the skill’s name and description. It reads SKILL.md and policy.json with read. The folder now holds:
6

Check the folder

check compiles the folder and validates it. It sends no request and runs no tool code.
Success: exit code 0, and with --json the result has "status": "valid" and "name": "invoice-pricing".If check refuses the folder, it exits 1 and the message names the problem. Add --json to see the code and diagnostics, which name the file. Fix every diagnostic before you go on. Common refusals lists the frequent ones.
7

Run it on your machine

run builds the package and runs the task with Helix on your machine. It creates nothing in the workspace.
The wording of the answer changes between runs. The total is 4164 cents, the catalog is catalog-v1, and the answer includes cobalt-orchard.Success: exit code 0, and with --json the result has "status": "completed", "exitCode": 0, and the answer in text. If the card shows status failed, the command exits non-zero: run it again with --json and read diagnostics. A missing model key reads, for example, No API key found for zai.
8

Pack the agent (optional)

pack writes the package archive that deploy uploads. It uploads nothing. --output must be outside the agent folder.
You do not need pack to deploy. deploy builds the same package.
9

Create an Environment

A deploy targets a slot: the agent in one Environment. Create the Environment prod:
On every run in prod, the Environment’s variables and secrets are environment variables in the sandbox. This agent’s tool does not read any, so one variable is enough. A tool that needs a token reads it from here. See Secrets.Success: exit code 0, and with --json the result has "success": true and "created": true. If prod already exists, set adds the variable to it and keeps its other entries; created is then false.
10

Deploy

deploy builds the package, uploads it as revision v1, checks the model and the Environment, and makes v1 the active revision in prod.
Success: exit code 0. With --json, stdout holds one result with "slug": "invoice-pricing", "revision": 1, "activated": true, "environment": "prod", "activeRevision": 1 and an operationId; the status card goes to stderr. Revisions are numbers in JSON and v1 in messages. Keep the slug and the revision.A model that is not in the workspace model list is refused with MODEL_NOT_IN_LIST. An Environment that does not exist is refused with ENVIRONMENT_NOT_FOUND. A refused deploy writes nothing. See If it fails.
11

Run it on Helix Cloud

The platform starts a sandbox, copies revision v1 into it, and runs the task. The answer is printed on stdout:
The run’s receipt and progress are printed on stderr:
  • The first line is the receipt. reference is the session reference, which starts with hs1_. Every session command takes it. agent.revision is the revision that runs.
  • The [mutagent:agent-package] line is the registration receipt. status is verified: the tools that started equal the tools agent.md declares. See The registration receipt.
Success: the command exits with the session’s exit code, 0 when the task completed, and the answer is on stdout. A refusal before the sandbox starts is printed on stderr with the fix to run.
12

List the session

AGENT shows the slug and the revision. STATUS is ended because a headless run ends after its task.
13

Attach to the session

Replace <reference> with the hs1_ reference from the receipt or from session ls:
attach prints the session’s output from the start, then follows it until it ends. It is read-only. Ctrl-C detaches.
14

Change the agent and deploy revision v2

Change the discount in invoice/skills/invoice-pricing/policy.json from 7 to 10:
invoice/skills/invoice-pricing/policy.json
Check, then deploy again:
The content changed, so deploy stores revision v2 and makes it active in prod:
Run the same task:
The receipt shows "revision":2. The total is now 4030 cents: subtotal 4137, discount 414, tax 307.
  • Deploying unchanged content does not create a revision. It reuses the existing one.
  • A session that is still running keeps the revision it started with.
15

Roll back to v1

Make v1 the active revision in prod again:
Success: exit code 0, and with --json the result has "revision": 1 and "activeRevision": 1.activate checks the model and the Environment again, as deploy does. New runs in prod use v1 and return 4164 cents. Revision v2 still exists:
  • mutagent helix agent @invoice-pricing:v2 --env prod -p "…" runs v2 without activating it.
  • mutagent agent inspect invoice-pricing --env prod --json lists both revisions. In its deployment, activeRevision is 1.
  • To go forward again, run mutagent agent activate invoice-pricing --revision v2 --env prod.

If it fails

With --json, a failure is an object with "success": false, a code and a suggestedAction. Branch on the code. Errors and exit codes has the full list.

What you built

Tools, skills and files

Write more tools, use built-in tools, add skills, files and secrets.

Deployment

Deploy, activate, run, retire and archive, with what each step checks.

agent.md reference

Every field and every rule.

Sessions

Attach to, send to, signal and checkpoint a session.