Write or revise a NodeTool skill: a user skill row through create_skill, or a shipped system skill under packages/system-skills. Use when instructions should persist across sessions.
Installs into .claude/skills of the current project.
Are you the author of Nodetool Skill Author?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/nodetool-ai-nodetool-skill-author)
---
name: nodetool-skill-author
description: "Write or revise a NodeTool skill: a user skill row through create_skill, or a shipped system skill under packages/system-skills. Use when instructions should persist across sessions."
featured: true
---
# Author a NodeTool skill
A skill is a named set of instructions an agent loads when its description
matches the task. Write one when the same direction would otherwise be repeated
every session. Do not write one for a single job: do the job.
## Which kind
| | User skill | System skill |
|---|---|---|
| Lives in | A row in the user's account | `packages/system-skills/<name>/SKILL.md` in the build |
| Written by | `create_skill`, `update_skill`, `delete_skill` | A file in a pull request |
| Scope | That user | Every install, on day one, with no seeding migration |
| Editable at runtime | Yes | No. Immutable, and the names are reserved so a user row cannot shadow one |
A repository skill under `.claude/skills/` is a third thing: it directs the
coding agent working on the NodeTool repository, not the agent inside the
product — the engineering loop, not a product surface. Its maintenance rules
are in a checkout's `.claude/README.md`, § Maintaining skills.
A skill that teaches a product surface is a system skill even when the coding
agent also wants it. `packages/system-skills/<name>` holds the one copy and
`.claude/skills/<name>` is a symlink to it, so the product and the repository
read the same document. Write a second copy under `.claude/skills/` and the
two drift; `npm run check:agents-docs` fails on one.
## The contract
Both kinds are the same document.
```markdown
---
name: my-skill
description: When to use this
---
The instructions.
```
- `name` is a lowercase slug, `a-z0-9-` only, at most 64 characters. It cannot
contain `anthropic` or `claude`. A user's names must be unique per user.
- `description` is one bounded line, at most 1024 characters, with no markup.
**It is the only part always in context**, so write it as *when to use this*,
not as what the skill contains. A description that does not name the trigger
means the skill never loads.
- `featured: true` is for a shipped skill only. It puts the skill in the
catalog that every turn carries. Every other shipped skill is found with
`list_skills({query})`, so feature a skill only when a turn needs it before
its first call: the entry point of a product surface, or a craft skill that
work on that surface always reads.
- The body must be non-empty. Frontmatter is parsed as scalar `key: value`
pairs, not full YAML, and the fence is the first `---` line after the opening
one, so a `---` rule inside the body survives.
- `##` headings split the body into sections a loader can fetch one at a time.
Use them for material an agent needs only at one step.
Confirm the parse by listing it back: `list_skills` shows name and description,
`load_skill {name}` returns the full instructions.
## Write it so it fires and so it holds
- **Lead with the result, then the loop.** The reader is mid-task and will act
on the first thing that looks like an instruction.
- **Name tools exactly.** A renamed tool in a skill is a failure a model cannot
recover from. Check each call against the live schema or the capability
registry before writing it.
- **State what a tool refuses**, not only what it accepts. Most skill failures
are a call made with a field the tool drops.
- **Point at the neighbour** rather than restating it. A craft skill quotes a
call, the contract skill owns it.
- **Do not add checkpoints or deliverables** the user did not ask for. An
example in a skill is an illustration, not a requirement on the next request.
## Shipping a system skill
One directory holding a `SKILL.md` whose frontmatter `name` matches the
directory. Nothing imports these files, so `packages/system-skills` is not a
workspace: `stageSystemSkills` in `scripts/bundle-backend.mjs` copies every
directory into `_skills/` beside the bundled `server.mjs`, and
`scripts/verify-backend-bundle.mjs` fails a build that misses one. A new
directory ships with no other change.
Discovery order is `_skills/` beside the bundle, else `packages/system-skills`
on the way up, else `NODETOOL_SYSTEM_SKILLS_DIR`. Only `SKILL.md` is read: a
skill ships as one document, so material that would have been a `references/`
file belongs in a `##` section of the body.
Symlink the new directory into `.claude/skills/<name>` when the repository's
coding agent should reach it too.
Two follow-ups a new system skill usually needs:
- Nothing, for the tool names: `packages/agents/tests/shipped-skill-names.test.ts`
reads every snake_case call out of every shipped skill and checks it against
the registry, so a new directory is covered as soon as it exists. A skill
whose body names timeline calls can also go in that test's `SKILL_NAMES`,
which matches them exactly against the capability specs and `edit_timeline`'s
op list.
- A skill that guides one model line goes in `MODEL_PROMPTING_SKILLS`
(`packages/agents/src/model-prompting-skills.ts`) so `find_model` attaches it
to a matching route. `packages/agents/tests/model-prompting-skills.test.ts`
checks that table against the skills on disk, the model ids the shipped
provider manifests name, and the capability registry.
## Reference
In a NodeTool checkout, these repository sources go further:
- `packages/system-skills/README.md` — the shipped set, and how one job
routes across it.
- `packages/agents/src/system-skills.ts` — loader and discovery rules.
- `packages/protocol/src/skill-document.ts` — the parser and the validators.