{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "agentskills:skill:1.0",
  "title": "Agent Skills SKILL.md frontmatter",
  "description": "Frontmatter for the Agent Skills open standard — the portable `SKILL.md` format published at agentskills.io and read by Claude, Codex, Gemini CLI, Copilot, Cursor and others. Six fields, two of them required. This is the one built-in that sets `additionalProperties: false`, and the reason is not strictness for its own sake: the tooling on the distribution path — `package_skill.py`, claude.ai skill uploads, the Skills API — fails with `Unexpected key(s) in SKILL.md frontmatter` rather than ignoring a field it does not know. A schema that tolerated unknown keys would pass exactly the file that cannot be shipped. Validate a skill you intend to distribute against this; validate a Claude Code-only skill against `anthropic:claude-skill:2.1`, which is the superset. One spec rule is out of reach here: `name` must also match the skill's parent directory name, which is a fact about the path rather than the front matter. The spec carries no version number of its own; `1.0` labels the format as published at https://agentskills.io/specification",
  "type": "object",
  "required": ["name", "description"],
  "additionalProperties": false,
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
      "description": "The skill's identifier, 1-64 characters. Lowercase letters, digits and hyphens only, with no leading, trailing or consecutive hyphen. Must also equal the name of the directory holding this `SKILL.md`, which no front matter check can see."
    },
    "description": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1024,
      "description": "What the skill does *and* when to use it, in at most 1024 characters. Agents load this at startup for every installed skill and decide from it alone whether to open the body, so keywords that name the triggering task belong here."
    },
    "license": {
      "type": "string",
      "minLength": 1,
      "description": "The license covering the skill: a license name such as `Apache-2.0`, or a pointer to a bundled file such as `Proprietary. LICENSE.txt has complete terms`."
    },
    "compatibility": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500,
      "description": "Environment requirements, in at most 500 characters — intended product, required system packages, network access. Most skills do not need this field."
    },
    "metadata": {
      "type": "object",
      "additionalProperties": { "type": "string" },
      "description": "Client-defined properties the spec does not cover. A map from string keys to **string** values: the spec's own example quotes `version: \"1.0\"` because unquoted it is a YAML float and this map takes strings. Claude Code's `metadata` is free-form by comparison, so a nested or numeric value passes there and fails here."
    },
    "allowed-tools": {
      "type": "string",
      "minLength": 1,
      "description": "Space-separated tools pre-approved to run, such as `Bash(git:*) Bash(jq:*) Read`. Marked experimental in the spec: support varies between agents, and the list form Claude Code also accepts is not part of the standard."
    }
  }
}
