Skip to Content
Polyant is open source under AGPL-3.0 — star us on GitHub.
ReferenceSkill Frontmatter

Skill Frontmatter Reference

On this page

This page is the field reference for a skill’s operator-facing metadata: required per-skill environment variables, required tools, and ancillary scripts. The skill’s body is the prompt content injected into the supervisor system prompt when the skill is loaded.

Read this as a field contract, not as a file format. The engine does not parse a --- block out of a skill’s body today: parseFrontmatter() exists in packages/engine/src/utils/frontmatter.ts but nothing in the runtime calls it. The fields below are supplied as structured values - through the admin panel’s skill form, through the create/update API, or inside a catalogue bundle - and the engine stores them itself. Writing them as YAML at the top of the body puts text in the prompt and sets nothing.

Where each field ends up: name, description and category are columns on the skills row; requiredEnv and requiredTools are written to the skill_versions.metadata jsonb column; scripts is its own skill_versions column.

Supported fields

FieldTypeRequiredNotes
namestringyesDisplay name. The slug is derived from it server-side - lowercased, with every character outside a-z0-9- replaced by -. There is no slug field to override it with, and the slug is immutable afterwards. Unique per organization.
descriptionstringnoOne-line summary shown in the catalog UI and in tool descriptions when the skill is auto-loaded.
categorystringnoFree-form grouping for the catalog (e.g. operations, marketing). Defaults to general. Set on the skill itself, from the form or the create call - it is not per version.
requiredEnvarray of strings or objectsnoPer-skill environment variables the operator must populate via PUT /api/instances/:slug/skills/:name/env.
requiredToolsarray of stringsnoTool names exactly as registered: camelCase for a built-in tool (httpRequest), <namespace>:<tool> for a plugin tool (hubspot:contact, github:issue). They are auto-enabled on any agent that turns the skill on. A tool the organization cannot use is rejected on save, not warned about, and so is a tool’s old name from before it moved into a plugin (hubspotContact).
scriptsarray of script objectsnoInline scripts shipped with the skill. Each entry: { file, description, content }. Catalogue-bundle only - the standard create and update calls do not accept it, so a skill authored through the form or the API carries no scripts.

requiredEnv entry shape

Two forms are accepted, mixed in the same array:

requiredEnv: - GITHUB_TOKEN # shorthand (string) - sensitive=true assumed - name: GITHUB_OWNER # full form description: GitHub owner / org used in API calls sensitive: false

Normalised by normalizeRequiredEnv():

FieldTypeDefaultNotes
namestring-Env var name. Always required.
descriptionstring-Optional help text shown in the admin UI under the input field.
sensitivebooleantrueWhen true, the value is masked in the UI, encrypted at rest and exposed by readSkill only as {{skill_env.<skill>.<KEY>}}. Set false only for configuration that may remain visible.

Runtime handling

Values are scoped per agent and skill. For a sensitive entry, readSkill returns the opaque placeholder {{skill_env.<skill>.<KEY>}}; the runtime resolves it immediately before an eligible in-process tool executes, while the engine records the placeholder in tool and audit arguments. Non-sensitive entries may be returned inline. runSkillScript receives configured values only in the child process environment at execution time. A tool that returns a resolved value, or a script that prints one, can still expose it in its result.

scripts entry shape

FieldTypeNotes
filestringLogical filename (used for display / extraction).
descriptionstringOne-line summary of what the script does.
contentstringFull script body. No size limit beyond the text column maximum.

Fields explicitly NOT supported

These are common mis-spellings or assumptions from other ecosystems. Nothing consumes them:

Mistaken fieldUse instead
version(none - versions are auto-incremented server-side on every PUT /api/organizations/:orgSlug/skills/:name)
requiredSecretsrequiredEnv
dependsOnToolsrequiredTools
language(unused - set it in the body)
tags(unused - use category)
author(not parsed)

The parser stores any unknown keys it sees in the raw metadata jsonb but they are never surfaced through the API or UI - treat them as dropped.

Full example

Shown as YAML because it reads well as one block, and because a catalogue bundle carries the same field names. Remember that this is not a file you paste into the skill body: name, description and category go in the form’s own fields, requiredEnv and requiredTools in theirs, and scripts only through a bundle.

--- name: Issue Triage Workflow description: Standard triage flow for incoming GitHub issues - label, route, escalate category: operations requiredEnv: - TRIAGE_API_TOKEN - name: TRIAGE_QUEUE_URL description: Endpoint of the queue the tickets are read from sensitive: false - name: TRIAGE_SLACK_CHANNEL description: Slack channel where escalations are announced (#ops-triage) sensitive: false requiredTools: - httpRequest - searchKnowledge - slackPostMessage scripts: - file: extract-metadata.py description: Pull issue title / labels / reporter into a structured record content: | import sys, json data = json.loads(sys.stdin.read()) print(json.dumps({"title": data["title"], "labels": [l["name"] for l in data["labels"]]})) --- # Issue Triage When a new ticket comes in, follow these steps: 1. Fetch the ticket from the queue with `httpRequest`. 2. Classify it against the runbooks with `searchKnowledge`. 3. If the classification is `severity:high`, post to `#ops-triage` via `slackPostMessage`. 4. Reply with the runbook step if one matches.

The body (everything after the closing ---) is the prompt content that gets injected into the supervisor when the skill is loaded - either auto-loaded via the auto-load flag, or surfaced through readSkill.

Last updated on