09/Skills

What a Skill Is

SKILL.md packs: name + description + body; installing from the catalog, importing, enabling and disabling.


A skill is a single SKILL.md file: a required `name` and `description` in YAML frontmatter, followed by a markdown body. The body is the procedure — the steps, checklists and worked examples that say "here is how this job is done". What separates it from a system prompt is REUSE: a skill's CONTENT and WHERE it is injected are two separate records, so the same skill can be bound to three users and a group at once.

parse
SKILL.mdname + description + body
routerSkillis_active (kill switch)
Bindingscope + priority
Bindinganother scope
Matching request<skills> block
Content and binding are separate

#The SKILL.md contract

SKILL.md
---
name: incident-postmortem
description: "Writes a blameless postmortem from an incident timeline. Use when an incident is resolved and a written record is needed."
license: MIT
compatibility: "Any chat model"
allowed-tools: "read,search"
metadata:
  category: operations
homepage: https://example.internal/runbooks
---

# Incident postmortem

## Procedure

1. Rebuild the timeline before writing a single sentence of analysis.
2. ...
FieldRule
`name` (required)Lowercase letters, digits and hyphens only; at most 64 characters; cannot start or end with a hyphen; must NOT contain the words "anthropic" or "claude". Unique across the installation.
`description` (required)Cannot be empty, at most 1024 characters. This is the highest-leverage text you write: it is the field the model matches against the task, and in `metadata` mode it is the ONLY text injected. Make it say both what the skill does and WHEN to use it.
bodyThe markdown after the frontmatter. This is the part injected in `full` mode.
`license` / `compatibility`Optional; at most 255 and 500 characters respectively. Stored and written back on export; never injected.
`allowed-tools`Stored, NOT enforced — see the "Injection & Budget" page.
`metadata`The spec's string→string map (e.g. `category`). Not injected; it lives in the panel and in the export. Some real files write a nested map here instead (5 of the 48 top-starred community skills, measured 2026-08-24); such a block is NOT rejected and NOT coerced to strings — it is kept verbatim alongside the undefined keys and written back unchanged on export.
undefined keysFrontmatter keys the spec does not define (like `homepage` above) are stored separately, verbatim, and written back unchanged on export — they are not folded into `metadata`, and their type (list/number) is not mangled.
There is NO filesystem in the gateway. The `scripts/`, `references/` and `assets/` directories of an Agent Skills package are not supported here; the only thing carried across is the SKILL.md file itself.

#The ways to install a skill

Built-in catalogtemplate

The Marketplace tab of the Skills page lists 10 curated skills versioned alongside the code (code-review, commit-message, systematic-debugging, writing-tests-that-can-fail, sql-safety, api-endpoint-docs, refactor-planning, structured-extraction, security-review, incident-postmortem). "Install" makes a COPY: if the catalog entry later changes, the installed skill does not, and you can edit it freely after installing.

Community registryregistry

The Community half of the Marketplace searches SKILL.md files in public GitHub repositories through the skillsmp.com index. That install arrives DISABLED and the content is unreviewed — it has its own page: "The Community Registry".

Pasteimport

Paste the SKILL.md text directly; the frontmatter is parsed and validated with the same rules.

Import from URLimport

Give a SKILL.md URL. Because this is an SSRF surface, the limits are deliberately narrow — see the table below.

Write from scratchcustom

Fill in name, description, body, tags and the optional spec fields in the editor. Every skill converts back to a file with "Export as SKILL.md".

#The limits on URL import

Making the server fetch an address you supply is an SSRF surface: left unbounded it could read internal network addresses or a cloud metadata endpoint (`169.254.169.254`). Each limit below is pinned by its own test.

https only
An `http://` address is rejected with a 400 without any request leaving the machine.
host allowlist
Only `raw.githubusercontent.com`, `gist.githubusercontent.com` and `gitlab.com`. The match is EXACT: `raw.githubusercontent.com.evil.example` is rejected.
no cross-host redirect
Redirects are not followed automatically; each hop is handled manually and the request is refused if the HOST CHANGES (an https→http downgrade too). Otherwise an allowlisted host could puncture the allowlist with a single 302. At most 3 redirects are followed within the same host.
256 KB
The body cap is enforced WHILE streaming — a huge file is not buffered first and refused afterwards. If an over-cap `Content-Length` is declared, not a single byte is read.
10 s
A wall-clock deadline: 10 seconds in TOTAL, redirect chain included. (A socket timeout alone would let a source that leaks one byte every nine seconds reset the counter forever.)

Additionally: credentials embedded in the URL are refused, only port 443 is accepted, the URL must fit the audit-trail column (512 characters), and that check happens BEFORE any network call. If the source does not return 200, or the body is not a SKILL.md, the import fails — no half record is written.

#Two switches: enabling and disabling

SwitchWhereEffect
`is_active`On the skill row (the toggle in the Installed tab)A GLOBAL kill switch: while it is off, NONE of that skill's bindings run. This is how you take a skill out of service without dismantling its bindings.
`enabled`On the binding rowTurns off that one binding only; the skill's other targets are untouched.

Deleting a skill deletes its bindings with it at the database level (CASCADE) — no orphaned binding is left behind.