# Manifest reference

Source: https://docs.coderhelm.com/plugins/manifest-reference

Every field of plugin.yaml, with its type, default and rules. Rendered from the same JSON Schema that the validator uses.

> Coming soon: this page describes work that is not on main yet.

A plugin is described by one file, `plugin.yaml`, at the root of its repo. This page is generated from the manifest's JSON Schema, published at a stable URL:

```txt
https://docs.coderhelm.com/schema/plugin-manifest.v1.json
```

Point your editor at it for completion and inline errors. With the YAML extension for VS Code, put this comment on the first line:

```yaml title="plugin.yaml"
# yaml-language-server: $schema=https://docs.coderhelm.com/schema/plugin-manifest.v1.json
```

Check a plugin against it before you push with the validator: see [Test a plugin locally](/plugins/testing).

## Top-level fields [#top-level-fields]

The plugin.yaml file at the root of a CoderHelm plugin. A plugin is text plus approved tools: its behavior comes from its agents and skills, and this file declares what it may touch.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `name` | string | yes |  | The plugin's id. Lowercase letters, digits and `-`, optionally namespaced by publisher as `publisher/name`. Must match `^([a-z0-9][a-z0-9-]\{0,38\}/)?[a-z0-9][a-z0-9-]\{0,63\}$`. Example: `marketing`, `acme/marketing`. |
| `version` | string | yes |  | The plugin's version, in semantic versioning (`MAJOR.MINOR.PATCH`). Installs are pinned by content hash, so the version is a label for people; raise it whenever you publish. Must match `^(0\|[1-9][0-9]*)\.(0\|[1-9][0-9]*)\.(0\|[1-9][0-9]*)(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$`. Example: `1.2.0`. |
| `description` | string | yes |  | One line saying what the plugin does. Shown in the catalog and on the plugin's page. At most 240 characters. |
| `skills` | list of string | no | `["skills/*/SKILL.md"]` | Paths or globs of the plugin's skills, relative to the plugin's folder. Skills use the same SKILL.md format as skill repos and apply only to this plugin's runs. |
| `agents` | list of string | no | `["agents/*.md"]` | Paths or globs of the plugin's agents. Each agent file is Markdown with frontmatter; its body is the agent's instructions. |
| `settings` | list of objects | no | `[]` | Values each team fills in on the plugin's page. Values live with the team, never in the plugin. |
| `tools` | list of objects | no | `[]` | Every tool the plugin's agents may call. A tool that is not listed here does not exist for a plugin run. |
| `triggers` | list of objects | no | `[]` | What starts a run of the plugin, besides a person writing a brief on the plugin's page. |
| `outputs` | list of objects | no | `[]` | What a run produces. Drafts wait in the review queue; a publish output sends an approved draft out through a consequential tool. |
| `budget` | object | no |  | The plugin's own monthly token limit. The team can change it on the plugin's page, and the team's limits apply too. |

Fields not listed here are refused, so a typo fails loudly instead of being ignored.

## settings[] [#settings]

Values each team fills in on the plugin's page. Values live with the team, never in the plugin.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `key` | string | yes |  | The setting's name. Lowercase letters, digits and `_`, starting with a letter. Must match `^[a-z][a-z0-9_]\{0,63\}$`. |
| `type` | `string` \| `secret` \| `connection` | yes |  | `string` is a value the team types. `secret` is sealed, never shown again once saved, and never given to a model. `connection` asks the team to connect an account. |
| `provider` | string | no |  | For a `connection`: how the account is connected, such as `oauth2`. Example: `oauth2`. |
| `scopes` | list of string | no |  | For an OAuth connection: the scopes asked for. Adding a scope in a new version waits for an admin. |
| `sensitive` | boolean | no | `false` | Keep the value out of every prompt and never send it back to the dashboard. `secret` and `connection` settings are always sensitive. |

A `connection` setting needs `provider`. `secret` and `connection` settings are always sensitive.

## tools[] [#tools]

Every tool the plugin's agents may call. A tool that is not listed here does not exist for a plugin run.
Each entry is one of two shapes.

### Tools from an MCP server [#tools-from-an-mcp-server]

Tools from an MCP server the team has on its Connections page.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `ref` | string | yes |  | `mcp:\<id\>`: the connection's MCP server. Must match `^mcp:[a-z0-9][a-z0-9_-]*$`. Example: `mcp:sanity`. |
| `allow` | list of string | yes |  | Tool names, or `*` globs, from that server the plugin may call. Everything else on the server is hidden from the run. |
| `risk` | `read` \| `write` \| `consequential` | no | `"read"` | The highest risk among the allowed tools. |

### A built-in or plugin-defined tool [#a-built-in-or-plugin-defined-tool]

A built-in CoderHelm tool, or a tool the plugin defines.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `name` | string | yes |  | Lowercase letters, digits and `_`. Agents call the tool by this name. Must match `^[a-z][a-z0-9_]\{0,63\}$`. |
| `kind` | `builtin` \| `http` | yes |  | `builtin` is one of CoderHelm's own tools, such as reading release notes. `http` is a tool the plugin defines that calls an outside service with the team's connection. |
| `description` | string | no |  | When an agent should use the tool. At most 240 characters. |
| `risk` | `read` \| `write` \| `consequential` | yes |  | `read` only looks. `write` changes something a person can still review, such as a draft in a CMS. `consequential` reaches people or money (publish, send, post) and runs only after an approval. |

### Risk levels [#risk-levels]

`read` only looks. `write` changes something a person can still review, such as a draft in a CMS. `consequential` reaches people or money (publish, send, post) and runs only after an approval.

## triggers[] [#triggers]

What starts a run of the plugin, besides a person writing a brief on the plugin's page.

### `on: manual` [#on-manual]

A person starts a run from the plugin's page by filling in a short form.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `on` | `"manual"` | yes |  |  |
| `form` | map | no | `\{"brief":"text"\}` | The form's fields: `text` for a box to write in, or a list of choices to pick from. |

### `on: schedule` [#on-schedule]

Runs on a schedule.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `on` | `"schedule"` | yes |  |  |
| `cron` | string | yes |  | Five-field cron: minute, hour, day of month, month, day of week. Must match `^\S+( \S+)\{4\}$`. Example: `0 14 * * MON`. |

### `on: github.release` [#on-githubrelease]

Runs when a release is published on a GitHub repo the team connected. The run gets the release notes CoderHelm wrote.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `on` | `"github.release"` | yes |  |  |

## outputs[] [#outputs]

What a run produces. Drafts wait in the review queue; a publish output sends an approved draft out through a consequential tool.

### `type: draft` [#type-draft]

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `type` | `"draft"` | yes |  |  |
| `kinds` | list of `blog` \| `social` \| `email` \| `image` \| `action` | yes |  | The kinds of draft a run may save. `action` is a step to take, such as an update to a record, rather than something to read. |

### `type: publish` [#type-publish]

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `type` | `"publish"` | yes |  |  |
| `via` | string | yes |  | The name of a `consequential` tool from `tools` that sends an approved draft out. Must match `^[a-z][a-z0-9_]\{0,63\}$`. |
| `approval` | object | no |  | The approval a draft needs before it is published. The person who asked for a draft never approves it. |

#### approval [#approval]

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `role` | string | no |  | Who should approve, as a short name such as `marketing_editor`. The team lists the actual approvers on the plugin's page. Must match `^[a-z][a-z0-9_]\{0,63\}$`. |
| `min` | integer | no | `1` | How many different people must approve. |

## budget [#budget]

The plugin's own monthly token limit. The team can change it on the plugin's page, and the team's limits apply too.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `monthly_tokens` | integer | no |  | Tokens the plugin may use per month. Empty or 0 means no limit of its own. |
