> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mutagent.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Managed agents

> A managed agent is an agent you write as an agent.md folder with its own tools, skills and files, deploy to your workspace, and run on Helix Cloud by its address.

<Note>
  **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.
</Note>

For the platform model behind managed agents (agents, revisions, slots and runs), see
[Managed agents on the Platform](/platform/managed-agents/overview). To build one step by step, follow the
[Quickstart](/platform/managed-agents/quickstart); to write its tools, skills and
files, see [Tools, skills and files](/platform/managed-agents/tools-and-skills).

A managed agent is an agent you write as a folder, deploy to your workspace, and run on Helix Cloud
by its name:

```bash theme={null}
mutagent agent deploy invoice/agent.md --env prod
mutagent helix agent @invoice-pricing --env prod -p "Price three widget units."
```

This page assumes the setup in [Helix Cloud](/helix/cloud/overview): you are signed in, and the
workspace has an LLM provider and a model list.

## What a managed agent is

A managed agent is an address you pass to `mutagent helix agent`. It is not a separate runtime.

* `mutagent helix agent @invoice-pricing -p "…"` starts the same way as every Helix Cloud run. It gets
  the same sandbox, model checks, idle policy and `hs1_` session reference.
* The difference from a definition passed as text or with `--file`: before Helix starts, the server
  copies the agent's package into the sandbox. The package holds your prompt, tools, skills and files.

| Word | Meaning |
| - | - |
| Agent | One entry in the workspace's agent list, named by its slug. |
| Revision | One package that never changes: `v1`, `v2`, and so on. Deploying unchanged content does not make a new revision. |
| Slot | One agent in one Environment. Each slot has one active revision. The slot with no Environment is the default slot. |

| Address | Runs |
| - | - |
| `@invoice-pricing` | The slot's active revision. |
| `@invoice-pricing:v3` | Revision 3. |
| `@invoice-pricing:latest` | The newest validated revision, active or not. |

```mermaid theme={null}
flowchart LR
  F["agent.md folder"] --> C["mutagent agent check"]
  C --> D["mutagent agent deploy"]
  D --> R["Revision, active in its slot"]
  R --> H["mutagent helix agent @slug"]
  H --> S["Session hs1_"]
  classDef s fill:#140d22,stroke:#7E47D7,color:#ede7f8;
  class F,C,D,R,H,S s;
```

## The agent.md format

Every field, its type, default and validation rule is in the
[agent.md reference](/platform/managed-agents/agent-md).

An agent is a folder. `agent.md` is its entry file: YAML frontmatter, then a Markdown body. The body
is the standing prompt for every task. The task you pass when you run the agent is separate.

The entry file must be named `agent.md`, in lowercase.

### Base fields

These fields are a complete local definition. `mutagent helix agent --file` reads them.

| Field | Meaning |
| - | - |
| `name` | The agent's slug in the workspace. |
| `description` | One line on what the agent does. |
| `model` | `llm-provider/model`, for example `zai/glm-5.3`. Required to check or deploy. |
| `thinking` | The reasoning level passed to Helix. |
| `tools` | Built-in tool names for a local definition. |
| `disallowed_tools` | Built-in tool names the agent must not use. |
| `skills` | Skill names for a local definition. |

### The harness block

Deployment settings go in one optional `harness:` block. `mutagent agent check` and
`mutagent agent deploy` read it. `mutagent helix agent --file` ignores it.

| Key | Meaning |
| - | - |
| `harness.tools.builtin` | The built-in tools the managed agent gets. No other built-in tools are granted. |
| `harness.tools.modules` | Your tool modules. Each has `path` (a TypeScript file), `export` (the export to register; the default export when omitted) and `name` (the registered tool name). |
| `harness.skills` | Skill folder paths to package. Each folder holds a `SKILL.md` and its files. |
| `harness.files` | Other file paths to package. Only declared files are packaged. |
| `harness.bindings.secrets` | Secret names the agent declares, each with `name` and `required`. See [Not built yet](#not-built-yet). |
| `harness.runtime.mode` | `interactive` or `headless`: the run mode when the command names none. |
| `harness.runtime.scaffold` | The Helix scaffold: `standard`. |

Paths are relative to the agent folder. A path outside the folder is refused.

## A complete example

This agent prices invoices. It reads a pricing policy from a skill and calls a tool that reads a
product catalog.

```text theme={null}
invoice/
├── agent.md
├── package.json
├── tools/calculate-invoice.ts
├── skills/invoice-pricing/SKILL.md
├── skills/invoice-pricing/policy.json
└── assets/catalog.json
```

<CodeGroup>
  ```markdown agent.md theme={null}
  ---
  name: invoice-pricing
  description: Calculates invoices from a packaged pricing skill and catalog.
  model: zai/glm-5.3
  thinking: low
  harness:
    tools:
      builtin: [read]
      modules:
        - path: tools/calculate-invoice.ts
          name: calculate_invoice
    skills:
      - skills/invoice-pricing
    files:
      - assets/catalog.json
    runtime:
      mode: headless
  ---
  You are the invoice pricing agent. Every invoice request must follow the invoice-pricing skill.
  Read its SKILL.md and policy.json before calling calculate_invoice. Supply the calculator with
  the policy values and the requested SKU and quantity. Never calculate the total yourself.
  Report the tool's exact totalCents and catalogVersion, followed by the policy receiptWord.
  Do not claim success if a skill file or tool is unavailable.
  ```

  ```json package.json theme={null}
  { "name": "invoice-pricing-agent-source", "private": true, "type": "module" }
  ```

  ```markdown skills/invoice-pricing/SKILL.md theme={null}
  ---
  name: invoice-pricing
  description: Required policy for invoice pricing requests; read its policy before using the calculator.
  ---

  Read `policy.json` in this skill directory. Supply its `discountPercent` and `taxBasisPoints`
  to `calculate_invoice` together with the requested SKU and quantity. The tool reads the catalog
  from the packaged agent files, so do not invent a unit price. Include the exact `receiptWord`
  from this skill file after the returned cents total and catalog version.
  ```

  ```json skills/invoice-pricing/policy.json theme={null}
  { "discountPercent": 7, "taxBasisPoints": 825, "receiptWord": "cobalt-orchard" }
  ```

  ```json assets/catalog.json theme={null}
  { "version": "catalog-v1", "products": { "widget": 1379, "gadget": 2683 } }
  ```

  ```typescript tools/calculate-invoice.ts theme={null}
  import { readFile } from "node:fs/promises";
  import { join } from "node:path";
  import { defineTool, Type } from "@mutagent/agents/tools";

  interface InvoiceInput {
    sku: string;
    quantity: number;
    discountPercent: number;
    taxBasisPoints: number;
  }

  export default defineTool<InvoiceInput>({
    name: "calculate_invoice",
    label: "Calculate invoice",
    description: "Calculate exact invoice cents from the packaged product catalog and skill policy.",
    parameters: Type.Object({
      sku: Type.String(),
      quantity: Type.Integer({ minimum: 1, maximum: 100 }),
      discountPercent: Type.Integer({ minimum: 0, maximum: 100 }),
      taxBasisPoints: Type.Integer({ minimum: 0, maximum: 10_000 }),
    }, { additionalProperties: false }),
    async execute(_id, params, _signal, _onUpdate, context) {
      const catalogPath = join(context.paths.assetRoot, "assets/catalog.json");
      const catalog = JSON.parse(await readFile(catalogPath, "utf8")) as {
        version: string;
        products: Record<string, number>;
      };
      const unitCents = catalog.products[params.sku];
      if (unitCents === undefined) throw new Error(`Unknown product: ${params.sku}`);
      const subtotalCents = unitCents * params.quantity;
      const discountCents = Math.round(subtotalCents * params.discountPercent / 100);
      const netCents = subtotalCents - discountCents;
      const taxCents = Math.round(netCents * params.taxBasisPoints / 10_000);
      const result = {
        subtotalCents,
        discountCents,
        taxCents,
        totalCents: netCents + taxCents,
        catalogVersion: catalog.version,
      };
      return { content: [{ type: "text", text: JSON.stringify(result) }], details: result };
    },
  });
  ```
</CodeGroup>

With this folder, the task "Price three widget units." returns `totalCents: 4164` and
`catalogVersion: catalog-v1`, and the answer ends with `cobalt-orchard`.

Rules for tool modules:

* Write a tool with `defineTool` from `@mutagent/agents/tools`. The compiler bundles and registers
  it. You do not write a Helix extension.
* A tool can import relative files inside the agent folder, `node:` built-ins and
  `@mutagent/agents/tools`. Nothing else. Third-party npm dependencies are not installed.
* A tool reads packaged files through `context.paths.assetRoot`, never through a path on your
  machine.

## Check and run on your machine

| Command | What it does |
| - | - |
| `mutagent agent check <agent.md>` | Compiles and validates the folder. It makes no network request and no model call, and runs no tool code. |
| `mutagent agent pack <agent.md> --output <archive>` | Writes the package archive and prints its digests. The archive must be outside the agent folder. |
| `mutagent agent run <agent.md> "<task>"` | Compiles the folder and runs the task with the Helix binary on your machine. |

```bash theme={null}
mutagent agent check invoice/agent.md
mutagent agent pack invoice/agent.md --output invoice.tgz
mutagent agent run invoice/agent.md "Price three widget units."
```

* The compiler needs Bun 1.3.14 on your machine.
* `agent run` needs Helix installed on your machine, and the API key of the LLM provider named in
  `model`, in your local Helix login or your environment variables. Signing in to Mutagent does not give Helix
  a model key.
* `agent run` runs in a temporary copy of the compiled package on your machine. It does not run in a
  sandbox.
* `agent run` creates no agent, revision or slot in the workspace.

`agent run` takes a file path. A slug is refused: `agent run` tells you that a managed agent runs with
`mutagent helix agent @slug`.

## Deploy and activate

| Command | What it does |
| - | - |
| `mutagent agent deploy <agent.md> [--env <name>] [--no-activate]` | Compiles, uploads and validates a revision, and activates it in the slot. |
| `mutagent agent activate <slug> --revision v<N> [--env <name>]` | Makes revision N the slot's active revision. |
| `mutagent agent list` | Lists the workspace's managed agents and their slots. `--include-archived` adds archived ones. |
| `mutagent agent inspect <slug> [--env <name>]` | Shows the agent's revisions, the slot's active revision and the slot's live sessions. |
| `mutagent agent retire <slug> [--env <name>] --force` | Disables the slot. It takes no new runs; live sessions finish. Requires `--force`. |
| `mutagent agent activity <slug>` | Lists the agent's activity, newest first. |
| `mutagent agent versions <slug>` | Lists the agent's spec versions, newest first. |

```bash theme={null}
mutagent agent deploy invoice/agent.md --env prod
mutagent agent inspect invoice-pricing --env prod
```

### What deploy does

<Steps>
  <Step title="Compile">
    Compiles the folder on your machine, as `check` does. You do not need to run `pack` first.
  </Step>

  <Step title="Create or reuse the agent">
    Creates the agent named by `name`, or uses the existing agent with that slug.
  </Step>

  <Step title="Upload">
    Uploads the package, and the server verifies its digests. New content becomes the next revision.
    Unchanged content uses its existing revision.
  </Step>

  <Step title="Validate">
    Checks the revision before it can run:

    * `model` is in the workspace model list (`mutagent helix models`).
    * The Environment named by `--env` exists in the workspace.
    * Every secret in `harness.bindings.secrets` sets `required: false`. `required` defaults to `true`.
    * The sandbox provider can receive a package. See [Environments and slots](#environments-and-slots).
  </Step>

  <Step title="Activate">
    Activates the revision in the slot. With `--no-activate`, deploy stops after validation: the
    revision exists and `@slug:vN` or `@slug:latest` runs it, but `@slug` still runs the previous
    active revision.
  </Step>
</Steps>

### Update and roll back

To update, edit the folder and deploy again. New runs use the new active revision. A running session
keeps the revision it started with.

To roll back, activate an earlier revision:

```bash theme={null}
mutagent agent activate invoice-pricing --revision v2 --env prod
```

`activate` runs the same validation as deploy: the model and the Environment are checked again.

## Run a managed agent

```bash theme={null}
mutagent helix agent @<slug>[:v<N>|:latest] [--env <name>] -p "<task>"
mutagent helix agent @<slug>[:v<N>|:latest] [--env <name>] --rpc
```

```bash theme={null}
mutagent helix agent @invoice-pricing --env prod -p "Price three widget units."
mutagent helix agent @invoice-pricing:v2 --env prod --rpc
```

### Modes

| Mode | How you choose it | What it does |
| - | - | - |
| headless | `-p "<task>"`, or no mode flag when `agent.md` sets `harness.runtime.mode: headless` | Runs the model and tool calls for the task. Input closes after the task. `session attach` and `session signal` work; `session send` is refused. |
| interactive | `--rpc`, or no mode flag when `agent.md` sets no mode or `harness.runtime.mode: interactive` | A live session: JSON commands on stdin, events on stdout, and `session send` from any terminal. |

`-p` with no task text is refused with exit code 1 before any request is sent. If you pass neither
`-p` nor `--rpc` and the package sets `harness.runtime.mode: headless`, the run is refused with 422
before any sandbox starts, because a headless run needs a task.

### What happens on a run

<Steps>
  <Step title="Find the revision">
    The server finds the agent by slug, then the slot for `--env`, then the revision: the active one,
    the `vN` you named, or the newest validated one for `:latest`.
  </Step>

  <Step title="Check before any sandbox starts">
    It checks that the model is in the workspace model list, that the Environment exists, and that
    the sandbox provider can receive a package.
  </Step>

  <Step title="Start the sandbox">
    It starts a sandbox on the default sandbox provider, or on the one named by
    `--sandbox-provider`. The sandbox gets the workspace's LLM provider keys and the Environment's
    variables, as on every run.
  </Step>

  <Step title="Copy the package">
    It copies the revision's package into the sandbox and checks its digest.
  </Step>

  <Step title="Start the agent">
    It starts Helix with the package's prompt, tools and skills. The tool module reports the tools
    it registered. If they do not match `agent.md`, the run stops.
  </Step>

  <Step title="Return the receipt">
    It sends the task (headless) or opens the session (interactive) and returns one receipt.
  </Step>
</Steps>

### The receipt

The receipt includes:

| Field | Meaning |
| - | - |
| `reference` | The session reference, which starts with `hs1_`. |
| `sandboxId` | The sandbox the session runs in. |
| `agent.slug` | The agent that runs, for example `invoice-pricing`. |
| `agent.revision` | The revision number that runs, for example `2`. |
| `mode` | `headless` or `interactive`. |

The CLI prints the receipt as one JSON line on stderr, before any output from the agent. Keep the
reference: every session command takes it.

The receipt says the session started. It does not contain the task's result. Read the session's
events for the result.

## Sessions

A managed agent's session is addressed by its `hs1_` reference.

| Command | Use it to |
| - | - |
| `mutagent helix session ls` | List the workspace's sessions. The `AGENT` column shows `slug:vN`. The `ARM` column shows `agent`. |
| `mutagent helix session attach <reference> [--since <n>]` | Watch the session's events. Read-only. |
| `mutagent helix session send <reference> [--type prompt\|steer\|follow_up\|abort] "<text>"` | Send into an interactive session. |
| `mutagent helix session close-input <reference>` | Close the session's input. |
| `mutagent helix session signal <reference> [--type SIGTERM] --force` | Stop the session. The default is SIGINT. `--force` confirms the stop. |
| `mutagent helix session checkpoint <reference>` | Save a checkpoint now. |
| `mutagent helix session checkpoints <reference>` | List the checkpoints of the session's sandbox, newest first. |

A managed agent's sandbox follows the same idle policy as every sandbox: after 15 minutes with no
activity, a final checkpoint is saved and the sandbox stops. Restoring a managed agent's session is
not supported yet, so start a new run after an idle stop.

See [Sessions](/helix/cloud/sessions) for the session commands.

## Environments and slots

* A slot is one agent in one Environment. `--env prod` on `deploy`, `activate`, `inspect`, `retire`
  and `helix agent` names the same slot.
* `--env` is optional on every command. Without it, the command uses the default slot, which has no
  Environment.
* `--env <name>` must name an existing workspace Environment. `deploy` and `activate` check it.
* On a run, `--env <name>` also loads that Environment's variables and secrets into the sandbox, as
  on every run. See [Environments](/helix/cloud/environments).
* Each slot has its own active revision. `prod` can run `v2` while the default slot runs `v4`.
* If an Environment is deleted, a run addressed to its slot is refused with 404, naming the
  Environment. `mutagent agent inspect` still lists the slot.
* A run addressed to a retired slot is refused with 409 `MANAGED_AGENT_SLOT_RETIRED`, with a pinned
  revision or without.

```bash theme={null}
mutagent env ls
mutagent agent deploy invoice/agent.md --env prod
mutagent agent deploy invoice/agent.md
mutagent agent inspect invoice-pricing --env prod
mutagent agent inspect invoice-pricing
```

A slot does not record a sandbox provider. Each run uses the default sandbox provider, or the one
named by `--sandbox-provider`. Not every sandbox provider can receive a package yet. `deploy`,
`activate` and a run refuse a sandbox provider that cannot, and the message names the sandbox
provider.

## Models

* `model` is required in `agent.md`. `check` and `deploy` refuse a file without it.
* A managed agent always uses its own `model`. The workspace default model is not used.
* `deploy` and `activate` refuse a model that is not in the workspace model list
  (`mutagent helix models`).
* A run checks the model again before any sandbox starts. If the LLM provider was deactivated after
  deploy, the run is refused and no sandbox starts.
* The model's API key comes from the workspace's LLM provider and is added when the sandbox starts.
  `deploy` never uploads your local key.

## Refused

| Command | Condition | Result |
| - | - | - |
| `agent check`, `agent deploy` | `model` is missing. | Refused before any request. |
| `agent check`, `agent deploy` | The frontmatter has an `apiVersion`, `kind` or `metadata` key. | Refused before any request. The message names the [base fields](#base-fields) and the [harness block](#the-harness-block). |
| `agent check`, `agent deploy`, `agent pack` | A path outside the agent folder, a symlink, or an import outside the allowed set. | Refused before any request. |
| `agent pack` | `--output` is inside the agent folder. | Refused before any request. |
| `agent run` | The argument is a slug. | Refused: "use `mutagent helix agent @slug`". |
| `agent deploy`, `agent activate`, `helix agent @slug` | `model` is not in the workspace model list. | 422, naming the model list. |
| `agent deploy`, `agent activate`, `helix agent @slug` | `--env` names no Environment in the workspace. | 404. |
| `agent deploy`, `agent activate`, `helix agent @slug` | The sandbox provider cannot receive a package. | 422, naming the sandbox provider. |
| `agent deploy`, `agent activate` | A secret binding is required: `required` is `true` or not set. | 422 `AGENT_REQUIRED_BINDINGS_UNSUPPORTED`, listing the binding names. |
| `helix agent @slug` | No agent has that slug. | 404. |
| `helix agent @slug` | The slot has no active revision, `vN` does not exist or is not validated, or `:latest` finds no validated revision. | 422. |
| `agent activate`, `helix agent @slug` | The managed agent is archived. | 409 `MANAGED_AGENT_ARCHIVED`, before any sandbox starts. |
| `helix agent @slug` | The slot is retired. | 409 `MANAGED_AGENT_SLOT_RETIRED`, before any sandbox starts. |
| `helix agent @slug` | `-p` with no task text. | Exit code 1, before any request. |
| `helix agent @slug` | No `-p` and no `--rpc`, and the package's mode is headless. | 422, before any sandbox starts. |
| `helix agent @slug` | `--cwd` or another Helix flag. The package decides the prompt, tools, skills and model. | Refused before any request. |
| `helix session send` | The session is headless. | Refused. |
| `helix session restore` | The session belongs to a managed agent. | 409. |

The run refusals above happen before a sandbox starts. The tool registration check happens after the
sandbox starts; when it fails, the sandbox it started is stopped.

## Not built yet

| Not built yet | What to do now |
| - | - |
| Restoring a managed agent's session. | Start a new run. `session checkpoint` still saves a checkpoint. |
| Receiving a package on every sandbox provider. | Run on a sandbox provider that deploy and run accept. |
| Adding declared secret bindings to the sandbox by name. | Set `required: false`, or leave secrets out of `harness.bindings`. Put the value in the slot's Environment; it is loaded into the sandbox on every run. |
| Steering a headless run. | Use `--rpc` when you need to send into the session. |
| Permissions specific to deployments. | `mutagent agent` commands use your workspace sign-in. |

<CardGroup cols={2}>
  <Card title="mutagent agent" icon="terminal" href="/cli/commands/agent">
    Every `mutagent agent` command and its flags.
  </Card>

  <Card title="Sessions" icon="comments" href="/helix/cloud/sessions">
    Watch, send to, stop and checkpoint a session.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.