Anatomy of a skill
A skill is a folder with a small contract: a manifest that describes it, a prompt that instructs the agent, and — when it does real work — a scripts directory with its dependencies. This page details every file and the two manifest schemas you'll come across.
Folder structure
my-skill/
├── SKILL.yaml # local manifest (or skill.yaml — lowercase works too)
├── SKILL.md # the prompt: instructions for the agent
├── requirements.txt # Python dependencies (if there are scripts)
└── scripts/ # executable code
├── render.py
└── helpers.py
When a skill is distributed as a ZIP for Skill Studio, the filenames change (the manifest becomes manifest.yaml and the prompt becomes prompt.md) — see the Import via ZIP section. The two schemas describe the same skill; the difference is the entry point (local client vs. publishing to the Platform).
The two manifest schemas
| Schema | File | When | Key fields |
|---|---|---|---|
| Local | SKILL.yaml / skill.yaml | Skill running locally (Desktop/TUI/VS Code). | name, version, description, entrypoint, permissions, arguments[], required_env, execution_mode. |
| Platform | manifest.yaml | Packaged as a ZIP to import/publish in Skill Studio. | schema_version: 1, skill_key, name, version, description, entrypoint, inputs[]/outputs[], permissions, env.secrets[], execution_mode. |
Bundled skills carry the local skill.yaml; Skill Studio canonicalizes to manifest.yaml (schema_version 1) on publish. You don't need to keep both on hand — pick the schema for the path you're going to use.
The local schema (SKILL.yaml)
The three required fields are name, version and description — if any of them is missing, the skill won't appear in the list. The remaining fields are optional:
| Field | Type | Purpose |
|---|---|---|
name | string | The skill's identifier (required). |
display_name | string | Friendly label. |
version | string | Semver version, e.g. "2.0" (required). |
description | string | What the skill does (required; helps the model decide to invoke it). |
entrypoint | string | Main script, e.g. scripts/render.py. |
permissions | object | network: none|outbound|full and filesystem: none|outputs_only|full. |
arguments[] | list | Parameters: name, type, description, required, default, choices. |
outputs[] | list | Generated artifacts: name, content_type, primary. |
required_env[] | list | Names of secrets Imaginne injects before running. See Env-secrets. |
execution_mode | string | local_plain (default) or local_protected. See Execution modes. |
dependencies / commands | lists | Documentation metadata for the loader. |
The Platform schema (manifest.yaml)
This is the canonical schema for ZIP and publishing. Required: schema_version: 1, skill_key, name. The skill_key follows the regex ^[a-z0-9][a-z0-9-]{1,98}[a-z0-9]$ (lowercase, digits, and hyphens).
| Field | Type | Purpose |
|---|---|---|
schema_version | int | Must be 1. |
skill_key | string | The skill's unique key within the org (regex above). |
name | string | Internal name (required). |
display_name | string | Label shown in the console. |
version | string | Semver version (becomes the published version). |
description | string | The skill's description. |
entrypoint | string | Script or prompt.md for prompt-only skills. |
inputs[] / outputs[] | lists | type, description, required, enum. |
permissions | object | network: none|outbound|full, filesystem: none|outputs_only|full. |
docs.summary | string | Summary file (usually SKILL.md). |
env.secrets[] | list | { name, secret_ref, required }. See Env-secrets. |
execution_mode | string | local_plain (default) or local_protected. |
remote_server is rejectedThe value execution_mode: remote_server (and the legacy mode: remote_server) is refused on import and on publish. The skill runtime is always local; remote channels only relay. See Remote session.
A complete real-world example
The bundled docx skill creates, reads, and edits Word documents. Here is an excerpt of the real SKILL.yaml (local):
schema_version: 1
skill_key: docx
name: docx_skill
display_name: "DOCX (Microsoft Word)"
version: "2.0"
entrypoint: scripts/docx_create.py
permissions:
network: none
filesystem: outputs_only
outputs:
- name: output.docx
content_type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
primary: true
commands:
- name: docx_create
script: scripts/docx_create.py
usage: "python scripts/docx_create.py input.md output.docx [--scheme NAME]"
- name: docx_edit
script: scripts/docx_edit.py
usage: "python scripts/docx_edit.py input.docx output.docx <op> [args...]"
dependencies:
- python-docx
- lxml
- Pillow
Note the choices: permissions.network: none (it generates the document without touching the network), filesystem: outputs_only (it only writes to outputs/) and commands with the exact entry point the agent calls.
The prompt (SKILL.md)
SKILL.md is what the agent reads to learn how to use the skill: when to invoke it, which script to call, the format of the arguments, and the common errors. It's the single most important component for the quality of the result. Best practices observed in the bundled skills:
- Say what NOT to fabricate. "Don't make up data; if an input is missing, ask in plain text and stop."
- Pin the output discipline. Every final file goes into
outputs/(theOUTPUTS_DIRvariable). - Document the exact entry point. Show the command line, not the theory.
- List the useful errors (e.g.
ImportError, "path outsideOUTPUTS_DIR") so the agent can recover.
Scripts and dependencies
scripts/holds the executable code (Python is the common case). The scripts receive the manifest's arguments and write tooutputs/.requirements.txtlists the Python dependencies, one per line:
python-docx
lxml
Pillow
outputs/ disciplineScripts must write only to OUTPUTS_DIR (default outputs/). Relative paths are joined under OUTPUTS_DIR; an absolute path is accepted only if it's already inside it. Helper files (debug.py, check_env.py) should not be created — they leak as artifacts into the chat.
See also
Was this page helpful?
Report a problem on this pageDo not send passwords, keys, tokens, or customer data.