Hands-on · 4 guides

Guides

Short, practical, in order. Each guide assumes you've read the previous one and links back to the exact spec fields and CLI commands it uses.

01 / Beginner · 10 min

Writing your first skill

You need the skill CLI (install) and ten minutes. We'll scaffold a hackernews-top skill that fetches the current front page stories.

  1. Scaffold. skill init hackernews-top --template http creates the project. Open skill.json — every field is documented in the spec.
  2. Name it like a slug. Lowercase, hyphens, no spaces: "hackernews-top" is valid, "HackerNews Top" is not. The validator rejects anything else — run skill validate early and often.
  3. Describe the contract, not the implementation. inputs gets one optional integer, limit (default 10). outputs gets a stories array of objects with title, url, score. If a caller can't construct a valid request from your schemas alone, the schemas are wrong.
  4. Ask for the least permission that works. This skill only needs ["net.http"]. Resist exec — shells are for later skills, and privileged scopes send your publish into manual review.
  5. Write one example before any code. Add an entry to examples[] with a realistic input and the output you expect. It becomes your first test fixture in guide 02.
  6. Validate. skill validate should print VALID — 0 errors. Fix what it flags; the messages name the exact field and rule.
Done when: skill validate --strict exits 0. Strict mode treats warnings as errors — the bar your CI should hold.
02 / Intermediate · 15 min

Testing skills locally

skill test runs your skill in a local sandbox that enforces the same permissions and runtime limits the marketplace will. A green local run predicts a green publish run — with one caveat: your machine is not the marketplace's machine, so keep tests hermetic.

  1. Run the harness. skill test executes each examples[] entry and diffs actual vs. expected output. Start here before writing custom tests.
  2. Isolate one example. skill test --example "limit respected" runs a single case while you iterate. Fast loops beat full suites during development.
  3. Bless outputs deliberately. When behavior changes on purpose, skill test --update rewrites expected outputs. Review the diff like code review — --update can bless a bug as easily as a fix.
  4. Test the permission boundary. Temporarily remove a permission from the manifest and re-run: the sandbox should deny the access your skill secretly depended on. If the test still passes, the permission was unnecessary — delete it.
  5. Pin the runtime. If your skill needs more than defaults, set runtime.timeout_ms / memory_mb explicitly and test with --timeout overrides to find the real floor. Hosts cap at 5 minutes / 2048 MB.
  6. Mind the network. Live HTTP in tests is flaky. Prefer recorded fixtures for unit runs; keep one live smoke test marked clearly, and don't let CI depend on a third party's uptime.
Exit codes matter. skill test exits 1 on any failure — wire it straight into CI after skill validate --strict. See exit codes.
03 / Intermediate · 10 min

Versioning and changelogs

Skill versions are semver, and the marketplace treats them as a contract with every installed user. Get the semantics right and upgrades stay boring.

  1. PATCH (1.2.3 → 1.2.4): bug fixes and doc tweaks that don't change the input/output contract. Safe to auto-update.
  2. MINOR (1.2.4 → 1.3.0): new optional inputs, new output fields, new examples. Backward compatible — old callers keep working.
  3. MAJOR (1.3.0 → 2.0.0): renamed or removed fields, new required inputs, changed output shapes, added permissions. Callers must opt in.
  4. Pre-releases for the brave. 2.0.0-beta.1 installs only with --pre. Use them for breaking changes you want tested before the major lands. Publish with skill publish --pre.
  5. Keep a changelog. One CHANGELOG.md per skill, newest on top, one section per version with Added / Changed / Fixed bullets. Pass it to skill publish --changelog CHANGELOG.md and it becomes your release notes.
  6. Never rewrite a published version. If 1.2.0 is broken, ship 1.2.1. Registries are append-only; mutating a tag breaks every lockfile downstream.
CHANGELOG.md — format
## [1.3.0] - 2026-09-18
### Added
- Optional `days` input to bound the story window (default: 1)
### Fixed
- `score` is now always an integer; was occasionally a string

## [1.2.0] - 2026-09-02
### Added
- Initial marketplace release
04 / Pre-flight · 5 min

Publishing checklist

Run through this list before skill publish. Every item maps to a real rejection reason we've seen.

  • skill validate --strict exits 0 — no errors and no warnings.
  • skill test passes on a clean checkout (not just your working tree).
  • description reads well in a card: 20–280 chars, no marketing fluff, says what it does.
  • permissions is minimal — you ran the permission-boundary test from guide 02.
  • license is set to a real SPDX id. Unset means UNLICENSED (private).
  • examples[] has at least one entry with a descriptive name.
  • version was bumped per semver and the changelog has a matching section.
  • skill publish --dry-run succeeds — validate, test, and pack all green.
  • ☐ If you added exec, fs.write, or env.write: expect manual review (1–3 business days) and say why in the changelog.
Then ship: skill publish --changelog CHANGELOG.md. Watch the output URL — that's your listing. Share it.

Next: run your manifest through the validator or read the CLI reference.