Writing actions
Action file format
One action is one Markdown file. YAML frontmatter declares the contract; the body tells the agent what to do.
---name: create-userdescription: Create a user account.mcpTools: - Postgres: - insertcustomTools: - hashPassword - sendEmailargs: - name: email type: string required: true - name: plan type: string default: freeoutput: type: object items: - name: id type: string - name: welcomeSent type: boolean---Hash the password, insert the user, thensend the welcome email.Frontmatter fields
| Field | Type | Notes |
|---|---|---|
name | string | The action key and the generated filename. Must start with a letter and contain only letters, digits, - or _. |
description | string | Shown as JSDoc on the generated args interface. |
mcpTools | [{ Server: [tool, …] }] | MCP tools the agent may call. Each server name must match a key under tools.mcpServers in your config. |
customTools | [toolName, …] | In-process tools the agent may call. Each name must match a key under tools.custom. |
args | { name, type, required?, default?, description? }[] | type is one of string, number, boolean, object, array. An arg with a default is optional for the caller and filled in before the agent runs. |
output | { type, items? } | type: object → items are the object's fields. type: array → items are one element's fields. Primitive types need no items. |
Output shapes
output decides what action() resolves to. Three shapes cover everything.
An object
output: type: object items: - name: id type: string description: The new user's id.Resolves to { id: string }.
An array
output: type: array items: - name: id type: string - name: email type: stringUnder type: array, items describes a single element — so this resolves to { id: string; email: string }[].
A primitive
output: type: stringPrimitives need no items.
Arguments
required: truemakes an argument mandatory for the caller.defaultmakes it optional. The default is filled in before the agent runs, so the agent always sees a value.descriptionis carried into the generated types, where your editor will show it.
Arguments are validated at runtime against the generated input schema. An action called with a bad payload fails before it reaches the model, and the error names each failing field.
Declaring tools
Both tool fields are allowlists — an action can call what it names and nothing else. mcpTools references servers under tools.mcpServers; customTools references keys under tools.custom.
mcpTools: - Postgres: - insert - selectcustomTools: - hashPassword - sendEmailThe body
Everything after the closing --- becomes the task instruction passed to the agent for that action. Keep it specific: the shared system prompt in MDLANG.md is the place for behaviour that applies to every action.