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.
agent.md, holds YAML frontmatter and a Markdown body.
mutagent agent check validates the folder, mutagent agent pack builds the package from it, and
mutagent agent deploy uploads that package as a revision. This page describes every field the
compiler accepts and every rule it applies.
For the platform model (agents, revisions, slots and runs), see
Managed agents. For running an agent, see
Helix Cloud: managed agents.
The folder
deploy, the parts end up in three places:
- Archive. The declared parts are built into one package archive: your source, the bundled tools, the skill folders and the files. Other files in the folder are not included.
-
Revision. The archive is stored as a revision,
v1,v2and so on, which never changes. Deploying the same content again reuses that revision. -
Slot. The revision becomes the active revision of the slot named by
--env. Each run in that Environment copies the active revision into its sandbox. -
Only what
agent.mddeclares is packaged: tool modules and the files they import,package.json, skill folders and the paths inharness.files. Other files in the folder are ignored. -
You can pass the folder or its
agent.mdtocheck,pack,deployandrun. -
The entry file must be named
agent.md, in lowercase. A folder with two case variants of the name is refused.
agent.md
- The file must begin with a
---line, and the frontmatter must end with a---line. - The frontmatter is exactly one YAML document.
- The body is the agent’s standing instructions for every task. It must not be empty. The task you pass when you run the agent is separate.
- The body is not parsed for configuration. A
---line inside the body is part of the instructions.
YAML rules
Base fields
These top-level fields are a complete local agent definition.mutagent helix agent --file reads
them. For a managed agent, name, description, model and thinking apply; tools and skills
do not grant anything, and disallowed_tools only removes tools. A managed agent gets exactly what
the harness block declares.
name
The agent’s slug in the workspace.deploy creates the agent with this slug, or adds a revision to the
agent that already has it. You run the agent as @<name>.
description
One line on what the agent does. It is not part of the agent’s instructions.model
The model the agent always uses, asmutagent helix models lists it. The workspace default model is
never used for a managed agent.
checkrefuses a value without an LLM provider and a model ID (MODEL_FORMAT).deploy,activateand every run refuse a model that is not in the workspace model list (422), or whose LLM provider the workspace has not configured (428).- The API key comes from the workspace’s LLM provider when the sandbox starts.
deploynever uploads a local key.
thinking
The reasoning level passed to Helix with the model.tools, disallowed_tools, skills
The local brief.mutagent helix agent --file reads them.
toolsandskillsgrant nothing. Declare tools inharness.toolsand skills inharness.skills.disallowed_toolsremoves names fromharness.tools.builtin. It cannot add a tool.
The harness block
harness: holds the deployment settings. It is optional. mutagent agent check, pack, deploy and
run read it; mutagent helix agent --file ignores it. Unknown keys inside it are refused.
Every path is relative to the agent folder and follows the path rules.
harness.tools.builtin
The Helix built-in tools the agent gets. No other built-in tool is granted.checkdoes not validate the names against Helix’s tool list.- Names listed in
disallowed_toolsare removed. - When the agent starts, the tools Helix activates must equal the built-in tools plus the tool module names. If they differ, the run stops. See At run.
harness.tools.modules
Your own tools, written in TypeScript or JavaScript. A Python function is not a tool format, andagent.md has no field for MCP servers.
namemust be unique across modules (DUPLICATE_TOOL), and must not also be a built-in tool name (TOOL_COLLISION).- The export must be a tool written with
defineTool, and itsnamemust equal the declaredname. This is checked when the agent starts, not bycheck. - The compiler bundles every module and the files it imports into one Helix extension. You do not write a Helix extension.
- A folder with tool modules must contain
package.json. See package.json.
What a tool module can import
A module that does not parse is refused (
TOOL_SYNTAX). check reads the imports without running
any tool code.
Writing a tool
The last argument of
execute, context, holds:
Reading a name that
harness.bindings.secrets does not declare throws an error.
harness.skills
Skill folders to package. Each folder holds aSKILL.md and the files it uses.
- Each path must be a folder (
SOURCE_NOT_DIRECTORY) that contains aSKILL.md(SKILL_MANIFEST). - Every file in the folder is packaged, except
node_modulesand.gitfolders. - Skills require
readinharness.tools.builtin(SKILL_REQUIRES_READ): the agent reads a skill’s files with it. - When the agent starts, Helix loads each skill from the package.
- A skill is guidance the agent reads, not a tool it calls. Say in the body when the agent should read it, for example “For every invoice request, read the invoice-pricing skill first”.
harness.files
Other files to package, such as data your tools read.- Each path is a file or a folder. A folder is packaged with every file in it, except
node_modulesand.gitfolders. - A tool reads them under
context.paths.assetRoot, at the same relative path:join(context.paths.assetRoot, "assets/catalog.json"). - A path that already starts with
files/is not placed underfiles/again. A tool readsfiles/catalog.jsonatjoin(context.paths.assetRoot, "catalog.json").
harness.bindings.secrets
Secret names the agent’s tools read throughcontext.bindings.
requireddefaults totrue.deployandactivaterefuse any required binding with 422AGENT_REQUIRED_BINDINGS_UNSUPPORTED, listing the names. Setrequired: falseon every binding.- Declared bindings are not added to the sandbox by name yet, so
optionalSecretreturnsundefined. Put the value in the slot’s Environment instead; its variables and secrets are loaded into the sandbox on every run.
harness.runtime.mode
The run mode when the run command names none.-p "<task>" always runs headless, and --rpc always runs interactive.
harness.runtime.scaffold
The Helix scaffold the agent runs in.standard is the only accepted value and the default.
Path rules
These rules apply to every path inharness.tools.modules, harness.skills and harness.files, and
to every file a tool module imports.
package.json
Required whenharness.tools.modules is set.
- It must be a JSON object (
PACKAGE_JSON). dependencies,devDependencies,optionalDependenciesandpeerDependenciesmust be absent or empty (DEPENDENCIES_UNSUPPORTED).- A
bun.lockorbun.lockbin the folder is packaged with it. - Set
"type": "module"for ES module tools, as the example does. The compiler does not check it.
mutagent agent check
check compiles the folder and validates it on your machine. It sends no request, needs no sign-in,
makes no model call and runs no tool code. It needs Bun 1.3.14.
It applies every rule on this page, builds the package in memory, and reports the result. With
--json it prints status: valid, the name, the three digests, the archive size, the package
manifest and the launch settings, or diagnostics naming each problem and its file. It exits 0 when
the folder is valid and 1 on a refusal.
Refusals about the entry file:
Tool modules are bundled during
check. A bundling error is refused with TOOL_BUILD.
A valid check shows that the folder compiles. It does not show that the model follows your
instructions or skills. Run a task with mutagent agent run and read the answer and the tool calls
before you deploy.
mutagent agent pack
pack builds the same package as check and writes it to --output. Nothing is uploaded.
--outputmust be outside the agent folder (AGENT_OUTPUT_IS_SOURCE). An existing file is replaced only with--force(AGENT_OUTPUT_EXISTS).- The archive is a gzip-compressed tar file. The same source, compiled with the same compiler and Bun versions, produces the same archive.
- With
--jsonit prints three digests, each writtensha256:and 64 hex characters. Without--json, its card shows the artifact digest.
deploy builds the package the same way; you do not need to run pack first.
What the package contains
Deploy refuses an archive larger than 16 MiB, or one whose files total more than 64 MiB when
extracted.
How the platform uses each field
At deploy and activate
Unchanged content reuses its existing revision.
At run
- The platform checks the model again, and the slot’s Environment and the sandbox provider, before any sandbox starts.
- It starts the sandbox with the workspace’s LLM provider keys and the Environment, copies the package in, and checks its digest.
- It starts Helix with
generated/agent.mdas the prompt,modelandthinking, the allowed tools (harness.tools.builtinplus the tool module names), each skill inharness.skills, and the bundled tools.harness.filesare undercontext.paths.assetRoot. - When the session starts, the bundled tools register and report a registration receipt within 15 seconds. The receipt must show every declared tool module registered, the active tools equal to the allowed tools, the package’s artifact digest and revision, and the declared bindings available. Otherwise the run stops with 422 and its sandbox is stopped.
- The task is sent (headless) or the session opens (interactive), and the run returns its receipt.
The complete example
This agent prices invoices. It reads a pricing policy from a skill and calls a tool that reads a product catalog.harness.tools.builtin: [read]grantsread, which the skill needs.harness.tools.modulesregisterscalculate_invoicefrom the default export oftools/calculate-invoice.ts.harness.skillspackagesskills/invoice-pricingwith itsSKILL.mdandpolicy.json.harness.filespackagesassets/catalog.json. The tool reads it atjoin(context.paths.assetRoot, "assets/catalog.json").harness.runtime.mode: headlessmakes a run without-por--rpca refusal, so run it with a task.
totalCents: 4164 and catalogVersion: catalog-v1, and
the answer ends with cobalt-orchard.
Deployment
Deploy, activate, run, retire and archive.
mutagent agent
Every
mutagent agent command and its flags.