> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runtype.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runtype.com/_mcp/server.

# Agent skills

A Skill is a loadable context bundle with instructions and optional capability bindings. Your Agent loads the bundle only when a task needs it, instead of carrying all of its instructions in every system prompt. Use Skills for procedures such as a refund protocol, a brand-voice guide, or a data-export recipe.

> **Note**
>
> This page covers Runtype Agent Skills, which your deployed Agents load at runtime. For
> coding-agent skills that teach Claude Code, Cursor, and other editors how to build on Runtype, see
> [coding-agent skills](/user-guide/troubleshooting-faq/agent-skills). The two features use files
> named `SKILL.md`, but they're unrelated.

## How Skills work

Each Skill that you bind to an Agent appears to the model as a virtual tool named `skill:<slug>`, such as `skill:refund-protocol`. Runtype builds this tool from two manifest fields:

* `description`: Text that the model receives on every turn. It tells the model what the Skill does and when to load it. Write a trigger such as `Load when a user asks for a refund`.
* `body`: The full instruction sheet. Runtype returns it as the tool result when the model calls `skill:<slug>`.

## Skill manifest format

Skills follow Anthropic's `SKILL.md` format: YAML frontmatter followed by a Markdown body. Add Runtype-specific capability bindings under the `runtype:` key.

Use the following manifest to define a Skill with saved capability references:

**`SKILL.md`**

```markdown title="SKILL.md"
---
name: refund-protocol
description: Process customer refunds. Load when a user asks for a refund.
runtype:
  trustLevel: org
  capabilities:
    flowIds: [flow_YOUR_FLOW_ID]
    agentIds: [agent_YOUR_AGENT_ID]
    toolIds: [tool_YOUR_TOOL_ID]
    inlineTools: []
---

## Refund procedure

1. Verify the order ID.
2. Confirm that the item is within the return window.
3. Issue the refund and notify the customer.
```

Replace `flow_YOUR_FLOW_ID`, `agent_YOUR_AGENT_ID`, and `tool_YOUR_TOOL_ID` with the IDs of the Flows, Agents, and tools that you want the Skill to make available.

The manifest supports the following fields:

* `name`: A slug of up to 64 characters. Use lowercase letters, digits, `_`, and `-`, and start with a letter. You can't change the name after you create the Skill.
* `description`: Text of up to 1,024 characters that tells the model what the Skill does and when to load it.
* Markdown body: The instructions. The dashboard warns you when the body passes 50,000 characters, and Runtype rejects a body over 200,000 characters.
* `runtype.trustLevel`: A label for the Skill's source: `org`, `imported`, or `community`. Runtype sets it when you create the Skill, and later versions don't change it.
* `runtype.capabilities.flowIds`: IDs of saved Flows that your Agent can invoke after the Skill loads.
* `runtype.capabilities.agentIds`: IDs of saved Agents that your Agent can use as subagents after the Skill loads.
* `runtype.capabilities.toolIds`: IDs of saved tools that your Agent can use after the Skill loads.
* `runtype.capabilities.inlineTools`: Inline runtime tool definitions. Reference secrets only with `{{secret:NAME}}`, where `NAME` is the name of the secret.

At runtime, Runtype resolves each capability reference after checking the executing caller's permissions.

> **Warning**
>
> The API rejects manifests with `mcpServers` on import and save because their authentication fields
> can store literal credentials. Use `flowIds`, `agentIds`, `toolIds`, or `inlineTools` for Skill
> capabilities instead. Skills don't carry secrets of their own. Reference secrets only with
> `{{secret:NAME}}`.

## Create and bind a Skill

Create a Skill from the **Skills** page in the dashboard, with the Runtype API, or with the SDK. A Skill belongs to your organization account or personal account. From a coding agent, you can also use the Skill tools of the [Runtype MCP server](/developer-guides/integrations/runtype-mcp-server), such as `create_skill`, `bind_skill`, and `publish_skill_version`.

### Create a Skill in the dashboard

To create a Skill, follow these steps:

1. On the **Skills** page, click **New skill**.
2. Enter the Skill's slug, its description, and its instructions.
3. Click **Create and publish**. The Skill's page opens.

To keep the Skill unpublished, click **Save draft** instead of **Create and publish**.

To start from a file, click **Import SKILL.md** on the **New skill** page. Runtype creates a draft from the file. In the dashboard, this import is the only way to set a Skill's `trustLevel`, because later versions keep the value set at creation.

### Edit a Skill on its page

Every Skill has a page at **Skills** > the Skill's name. The page opens on the description and the instructions. Each field shows a live character count and an estimated token count.

The description warns you when it overlaps another Skill bound to the same Agent. Two similar descriptions make it unclear which Skill the model loads.

Edits don't change what your Agents run. Click **Save draft** to save your changes as a draft version. To make the draft the version that bound Agents load, click **Publish**. The button shows the version number that it publishes, such as **Publish v3**.

The rail beside the document has the following sections:

* **Versions**: Lists every version with its **Live** and **Draft** badges. A link such as **Compare with v2** shows a version's description, instructions, and capabilities next to the live version. **Restore** adds an older version's contents as a new draft, so earlier versions stay unchanged.
* **Agents**: Lists the Agents bound to this Skill. Each row follows the published version or pins a specific version. You can also turn each binding on or off, or detach it. To bind another Agent, click **Attach to an agent**.
* **Capabilities**: Lists the tools, Flows, and Agents that the Skill grants on load, each with the version that it first appeared in. To grant a capability, click **Add a tool**, **Add a flow**, or **Add an agent**. Capability edits save with the draft and take effect when you publish. A grant that's new since the live version is marked as needing approval at load time.

To replace the draft with a SKILL.md file, including its capability block, click **Import SKILL.md**. To download the current draft as SKILL.md, click **Export**. To delete the Skill, open **More skill actions** and click **Delete skill**.

### Bind a Skill in the Agent editor

Open the Agent and select **Skills** in the settings navigation to see every Skill bound to it. From there, you can do the following:

* Click **Add skill**, then pick a Skill from your account to bind it.
* Use the switch on a row to enable or disable a bound Skill without removing it.
* Click the unlink button on a row to remove the binding.

Bindings aren't part of the Agent draft. Each change saves as soon as you make it, and it applies to every version of the Agent, including the live version.

A binding that follows the published version doesn't load a draft. If the Skill has no published version, the row shows "Draft, not loaded until published". A binding pinned to a specific version loads that version, even if it's a draft.

> **Note**
>
> Claude-managed Agents don't load Runtype Skills and have no **Skills** section. For an External
> Agent, the **Skills** section lists the skills on its agent card, not Runtype Skills.

### Create and bind a Skill with the API

To create and bind a Skill through the API, follow these steps:

1. **Author the manifest.** Write `SKILL.md` with YAML frontmatter and a Markdown body.
2. **Create and publish the Skill.** Send a `POST` request to `/v1/skills` with `publish: true` and either a `markdown` string or `frontmatter` plus `body`.
3. **Bind the Skill to an Agent.** Send a `POST` request to `/v1/skills/bind` with `{ agentId, skillId }`. The `skill:<slug>` tool then appears in the Agent's tool list.
4. Optional: **Pin the binding.** To load one version instead of the published version, include `skillVersionId` in the bind request.
5. Optional: **Mention the tool in the system prompt.** Add `skill:<slug>` to the Agent's system prompt when you want to tell the model that the tool is available.

The following request creates and publishes a Skill from a structured manifest:

**`cURL`**

```bash title="cURL"
curl https://api.runtype.com/v1/skills \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "frontmatter": {
      "name": "refund-protocol",
      "description": "Process refunds when users ask."
    },
    "body": "Verify the order ID before issuing the refund.",
    "publish": true
  }'
```

Replace `YOUR_API_KEY` with a Runtype API key that has `SKILLS:WRITE` or `SKILLS:*` permission.

The following TypeScript code creates, publishes, and binds a Skill with the SDK:

**`TypeScript`**

```typescript title="TypeScript"
import { Runtype } from '@runtypelabs/sdk'

Runtype.configure({ apiKey: process.env.RUNTYPE_API_KEY })

const { skill } = await Runtype.skills.create({ markdown: skillMarkdown, publish: true })
await Runtype.skills.bind({ agentId: 'YOUR_AGENT_ID', skillId: skill.id })
```

Replace the following:

* `skillMarkdown`: A string that holds your complete `SKILL.md` document.
* `YOUR_AGENT_ID`: The ID of the Agent to bind the Skill to.

`POST /v1/skills/import` also takes a complete `SKILL.md` document, but it always creates a draft with `trustLevel: imported`. To keep the manifest's trust level or publish in one call, send the document as `markdown` to `POST /v1/skills`.

The Skills API checks the following permissions:

* `SKILLS:READ` covers read operations.
* `SKILLS:WRITE` covers write operations, including publishing, binding, and proposal review.
* `SKILLS:*` grants both.
* `GET /v1/skills/{id}/bindings` returns each bound Agent's name and type, so it also needs `AGENTS:READ`.

Skills that you author through the dashboard, the API, or the SDK don't enter a review queue.

### Update, publish, and remove a Skill with the API

Use the following endpoints to manage a Skill after you create it:

* `PUT /v1/skills/{id}`: Adds a new draft version from an updated manifest. Pass `publish: true` to publish it in the same call.
* `GET /v1/skills/{id}/versions`: Lists the Skill's versions.
* `POST /v1/skills/{id}/versions/{versionId}/publish`: Makes that version the one that bound Agents load.
* `DELETE /v1/skills/bindings/{bindingId}`: Removes one binding.
* `DELETE /v1/skills/{id}`: Deletes the Skill, its versions, and its bindings on every Agent.

A `PUT` request doesn't change the live version unless you pass `publish: true` or call the publish endpoint. The API returns `400` for an invalid manifest or a changed `name`, and `422` for an unsupported capability such as `mcpServers`.

### Manage Skills as code

To keep a Skill in your repository and converge it from CI, define it with `defineSkill` and call `Runtype.skills.ensure`:

**`TypeScript`**

```typescript title="TypeScript"
import { Runtype, defineSkill } from '@runtypelabs/sdk'

const refundProtocol = defineSkill({
  name: 'refund-protocol',
  manifest: {
    frontmatter: {
      name: 'refund-protocol',
      description: 'Process customer refunds. Load when a user asks for a refund.',
    },
    runtype: { trustLevel: 'org' },
    body: '## Refund procedure\n\n1. Verify the order ID.',
  },
})

await Runtype.skills.ensure(refundProtocol, { release: 'publish' })
```

`ensure` creates the Skill, or adds a version when the content differs. It never deletes a Skill. If the Skill's last change came from the dashboard, the API, or the Runtype MCP server, `ensure` fails with a conflict error. To overwrite that change, pass `{ onConflict: 'overwrite' }`. With `release: 'publish'`, it also publishes the converged version. To fail a pull request check when the stored Skill differs from your definition, pass `{ expectNoChanges: true }`. To read the stored definition back, call `Runtype.skills.pull` with the Skill's name. `Runtype.skills.ensure` doesn't manage bindings. Bind the Skill with `Runtype.skills.bind`, or declare an Agent's complete set of Skills, with optional version pins, in the `skills` option of [`Runtype.agents.ensure`](/user-guide/agents/manage-agents-as-code#bind-skills).

## How Skills load at runtime

On the first load of a Skill in a turn, Runtype returns the body as the tool result. On the stream, the `skill:<slug>` tool's `tool_complete` event carries `result.kind: "skill_loaded"`, the Skill name, and the capabilities it activated. The load appears in the [execution log](/user-guide/logs/what-are-logs) as a tool call.

If a Skill adds tools that the Agent doesn't already have, the load pauses for approval before those tools activate. A Skill with no capabilities, or one whose capabilities the Agent already has, loads without this approval. For the places where you can answer an approval, see [Approvals on messaging surfaces](/user-guide/products-surfaces/approvals-on-messaging-surfaces).

Surfaces that can't collect an approval check every bound Skill before the run starts. If any bound Skill would add tools that the Agent lacks, they refuse the whole request, even if the model would never load that Skill. The chat widget and Client Chat return HTTP `501` with `APPROVAL_MODE_UNSUPPORTED`. Product Chat also returns `501`, and an MCP capability call fails with an error that names the Skill.

Runtype activates newly bound capabilities on the following turn. To let the Agent use them, turn on **Agent loop** and set **Max turns** to `2` or higher. Runtype starts a follow-up turn when a Skill adds tools, so leave room for that turn in **Max turns**. Knowledge-only Skills can load in one turn.

Runtype deduplicates repeat loads within a single turn. If the model calls the same `skill:<slug>` tool again in that turn, Runtype returns an `alreadyLoaded` result without the body or another capability activation. That repeat's `tool_complete` doesn't carry `result.kind: "skill_loaded"`. The model can load the Skill again in a later turn and receive the full body.

## Agent-proposed Skills

A running Agent can submit a Skill proposal with the **Propose Skill** built-in tool (`propose_skill`). To let an Agent propose Skills, add this tool to the Agent. For more information, see [Built-in tools](/user-guide/tools/built-in-tools).

The tool takes a `name`, a `description`, a `body`, and optional `capabilities`. It returns immediately and doesn't pause the current run. Its `tool_complete` event carries `result.kind: "skill_proposed"`, the proposed Skill name, and the outcome (`pending_approval` or `auto_published`).

Every proposal, including a text-only proposal, waits in the review queue until a person approves or rejects it. To review proposals, follow these steps:

1. On the **Skills** page, select the **Proposals** tab. A badge shows the number of pending proposals.
2. For each proposal, click **Approve** or **Reject**.

Through the API, list pending proposals with `GET /v1/skill-proposals`. Approve or reject one with `POST /v1/skill-proposals/{id}/approve` or `POST /v1/skill-proposals/{id}/reject`.

Approving a proposal publishes the Skill but doesn't bind it to an Agent. Bind it separately in the Agent editor's **Skills** section, from the Skill's page, or with `POST /v1/skills/bind`.

## Troubleshooting

This section covers the most common problems with Skills.

### The Agent never loads a Skill

If a Skill can't be resolved, the `skill:<slug>` tool doesn't appear, and Runtype leaves the Skill out of the Agent's tools without an error. Check the following:

* The binding is turned on.
* The Skill has a published version, or the binding pins a version.
* Every `flowIds` and `agentIds` entry in the loaded version still exists and is available to the account that runs the Agent.

If a single `flowIds` or `agentIds` entry fails to resolve, Runtype leaves out the whole Skill, not only that capability. A `toolIds` entry that doesn't exist or is inactive is different: Runtype skips that tool and still loads the Skill.

### Requests fail with HTTP 501

A bound Skill grants tools that the Agent doesn't already have, and the Surface can't collect an approval. To use the Skill on that Surface, add those tools to the Agent directly so that the Skill adds nothing new. Otherwise, turn off the binding for that Agent.

### The Agent loads the wrong Skill

Two bound Skills have similar descriptions. Open each Skill's page and check for the overlap warning under the description. Rewrite the descriptions so that each one names a distinct trigger.

## Next steps

Continue with these guides:

* [Agent tools](/user-guide/agents/agent-tools): Attach Flows, custom tools, external tools, MCP tools, and subagent tools to an Agent.
* [Creating and configuring agents](/user-guide/agents/creating-and-configuring-agents): Turn on **Agent loop** and configure **Max turns**.
* [What are Agents?](/user-guide/agents/what-are-agents): Learn how Agents use tools and system prompts.