Normative reference · SDF v1 · engine v0.4.0

Skill Definition Format v1

A skill is a single JSON document — the manifest. It declares the skill's identity, its input/output contract, the capabilities it needs, and how to run it. Hosts (marketplaces, agent runtimes, the CLI) read this document and nothing else to decide whether a skill is installable, runnable, and safe.

Conformance rule. Anything marked REQUIRED must be present and valid or the definition fails validation. OPTIONAL fields may be omitted — but several carry strong recommendations noted below.

#Top-level fields

FieldTypeReq.Description
namestringREQUIREDLowercase slug identifying the skill. ^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$, max 64 chars.
versionstringREQUIREDSemver 2.0.0, no leading v. Example: "1.2.0".
descriptionstringREQUIREDHuman-readable summary. Recommended 20–280 characters.
inputsobjectREQUIREDSchema object describing accepted input. See schemas.
outputsobjectREQUIREDSchema object describing produced output. See schemas.
permissionsstring[]OPTIONALCapability tokens the skill needs. Omitted = [] (fully sandboxed).
runtimeobjectOPTIONALEngine version, timeouts, memory, env vars. See runtime.
examplesobject[]OPTIONALInput/output pairs. Recommended — doubles as test fixtures.
authorstringOPTIONALAuthor or org name. Recommended for listings.
licensestringOPTIONALSPDX identifier, e.g. "MIT". Defaults to UNLICENSED on publish.
tagsstring[]OPTIONALSearch keywords, lowercase. Max 10.

#Identity: name, version, description

##name

The skill's slug. Lowercase ASCII letters, digits, and single hyphens; must start and end with an alphanumeric; max 64 characters. Names are namespaced per publisher on marketplaces, so acme/web-search and you/web-search can coexist — the bare name here is the unqualified slug.

name — valid vs invalid
// valid
"web-search"      // ✓
"pdf2md"          // ✓ digits fine
"a"               // ✓ single char ok

// invalid — validator rejects these
"Web-Search"      // ✗ uppercase
"web_search"      // ✗ underscore
"-web-search"     // ✗ leading hyphen
"web--search"     // ✗ double hyphen

##version

Strict semver 2.0.0: MAJOR.MINOR.PATCH with optional pre-release and build metadata. No leading v — that's a display convention, not part of the version. Pre-release versions (e.g. 2.0.0-beta.1) install only with an explicit --pre flag. Versions below 0.1.0 are treated as drafts and hidden from marketplace search.

##description

One or two sentences a human would read in a listing. Must be non-blank. Under 20 characters or over 280 triggers a warning: short descriptions rank poorly, long ones get truncated in cards.

#Schemas: inputs & outputs

Both fields are schema objects in a JSON-Schema-like dialect. The shape is always:

schema shape
{
  "type": "object",          // conventional; enforced by convention, not by type error
  "required": ["query"],       // every entry MUST exist in properties — else error
  "properties": {
    "query": {
      "type": "string",       // required per property (warning if missing)
      "description": "The search query.",
      "minLength": 1
    },
    "limit": {
      "type": "integer",
      "default": 5,            // applied by hosts when the caller omits the field
      "minimum": 1, "maximum": 50
    },
    "format": {
      "type": "string",
      "enum": ["json", "markdown"]  // must be a non-empty array
    },
    "filters": {
      "type": "array",
      "items": { "type": "string" }  // warning if omitted on arrays
    }
  }
}

##Allowed property types

TypeJSON valueNotes
string"text"Supports minLength, maxLength, pattern (ECMA regex), format.
number3.14Any JSON number. minimum / maximum supported.
integer42Must have no fractional part at runtime.
booleantrue
array[…]Declare items; minItems / maxItems supported.
object{…}May nest properties recursively.
nullnullExplicit nullability marker.

Unknown type strings are errors (there is no guessing). A required entry that names a property not declared in properties is an error. Missing type on a property is a warning.

#Permissions

Capabilities are deny-by-default. A skill that doesn't declare permissions runs fully sandboxed: no network, no filesystem, no subprocesses. Declare only what you need — least privilege isn't just good hygiene, it determines your review lane on publish.

PermissionGrantsReview
net.httpOutbound HTTPS requestsautomatic
net.websocketOutbound WebSocket connectionsautomatic
fs.readRead files under the skill workspaceautomatic
fs.writeWrite files under the skill workspacemanual
execSpawn subprocessesmanual
env.readRead environment variables declared in runtime.envautomatic
env.writeModify the process environmentmanual
clockWall-clock timeautomatic
randomCSPRNG randomnessautomatic
kv.read / kv.writeSkill-scoped key/value storeautomatic
Unknown tokens are warnings, not errors. The permission set is extensible per host — but a typo like "net.htp" grants nothing, so the linter flags anything outside the known list.

#Runtime requirements

Optional hints to the host about how to execute the skill. All fields optional; hosts apply their own caps (marketplace defaults: 5 min timeout, 2048 MB memory).

FieldTypeDescription
enginestringVersion range, e.g. "skill-engine>=0.4". Hosts refuse to run on incompatible engines.
timeout_msnumberMax wall-clock run time. Positive; warn above 300000.
memory_mbnumberMemory request. Positive; warn above 2048.
envstring[]Environment variable names the skill may read (with env.read). Use UPPER_SNAKE_CASE.

#Examples

An array of { name, input, output } objects. input and output must be objects. Examples are user documentation and machine fixtures: skill test runs each example's input and diffs the output. Give every example a descriptive name — unnamed examples draw a warning.

examples
"examples": [
  {
    "name": "basic query",
    "input": { "query": "agentskills spec", "limit": 3 },
    "output": { "results": [ … ], "took_ms": 812 }
  }
]

#Metadata: author, license, tags

Optional but recommended. author is a display string shown on listings. license should be an SPDX identifier (MIT, Apache-2.0); publishing without one marks the skill UNLICENSED (private). tags are lowercase search keywords, max 10.

#Full annotated example

skill.json — web-search v1.2.0
{
  "name": "web-search",            // slug — lowercase, hyphenated
  "version": "1.2.0",               // semver, no leading v
  "description": "Searches the public web and returns ranked results with titles, URLs, and snippets.",
  "author": "Acme Labs",
  "license": "MIT",
  "tags": ["web", "search", "research"],

  "inputs": {                            // what the caller provides
    "type": "object",
    "required": ["query"],
    "properties": {
      "query": { "type": "string", "minLength": 1 },
      "limit": { "type": "integer", "default": 5, "minimum": 1, "maximum": 50 }
    }
  },
  "outputs": {                           // what the skill returns
    "type": "object",
    "required": ["results"],
    "properties": {
      "results": {
        "type": "array",
        "items": { "type": "object" }
      }
    }
  },

  "permissions": ["net.http"],      // least privilege: only outbound HTTPS
  "runtime": {
    "engine": "skill-engine>=0.4",
    "timeout_ms": 15000,
    "memory_mb": 256
  },
  "examples": [
    {
      "name": "basic query",
      "input": { "query": "agentskills spec", "limit": 3 },
      "output": { "results": [], "took_ms": 812 }
    }
  ]
}

Paste this into the validator → — it passes with zero errors and zero warnings.

#Validation rules summary

SeverityRule
ERRORTop level is not a JSON object
ERRORMissing name, version, description, inputs, or outputs
ERRORname fails the slug pattern or exceeds 64 chars
ERRORversion is not semver 2.0.0 (or has a leading v)
ERRORdescription blank or not a string
ERRORinputs/outputs not objects; required names a missing property; unknown property type
ERRORpermissions/tags not arrays of strings; runtime not an object; bad timeout_ms/memory_mb
ERRORexamples entries missing input/output objects
WARNINGMissing author, license, examples, or property types
WARNINGdescription shorter than 20 or longer than 280 chars; version is 0.0.x; unknown permission tokens
WARNINGruntime exceeds host caps; duplicate permissions; non-UPPER_SNAKE env names

Exit codes follow the same split: the CLI's skill validate exits 0 on pass (even with warnings) and 1 on any error. See the CLI reference.