After this, you'll be able to turn a repeatable 3-step workflow into a named skill the agent invokes consistently, and audit it for least-privilege.
Before you start
Before diving in, complete Read a Tool Schema Like the Model Does so your skill's description is written from the model's perspective, not your own.
The idea
Here is the before and after: Every session you finish a feature, you describe the same four steps to Claude: run the linter, check for stray TODOs, write a one-paragraph summary, generate a commit message. Every session Claude interprets those steps slightly differently. After you package them as a skill, you type 'run feature-wrap' and the same sequence runs every time, with no re-explanation.
A skill is a named file containing: a verb-phrase name, a one-sentence description of when to invoke it, a numbered step list with the tool or action for each step, a success condition the agent can check, and constraints on what it must not do. That is the whole format. The agent reads the file, executes the steps, verifies the success condition, and stops.
Validation before generation is the most important sequencing rule. A linter call costs roughly 500 to 2,000 tokens. A full code-generation call costs 10 to 50 times more. A skill that runs the linter first and only generates if it passes catches errors when they are cheap. The same error caught after generation costs 10x to fix.
For Claude Desktop users: skills live in your CLAUDE.md file or in a linked module file. Add the skill definition there and Claude reads it at session start. For Claude Code users: skills can also live in a dedicated skills/ directory and be invoked by name. Either way, Claude reads the skill definition and executes the steps without re-prompting.
Try it (25 min)
Watch out for
Paste this into Claude:
I want to package a workflow I do regularly into a named skill. Here is the workflow: [describe a 3-5 step process you do at least weekly, e.g. 'every time I finish a feature: run the linter, check for any TODO comments I left, summarize the change in one paragraph, and write a commit message']. Help me turn this into a skill definition. Write it as a structured skill file with: a name, a one-sentence description of when to invoke it, a numbered list of steps with the tool or action for each step, the success condition (how the agent knows the skill completed correctly), and any constraints (what the skill must NOT do). Then show me how I would invoke it.
What good looks like:
What a good response looks like:
Here is a complete skill definition for a feature-wrap workflow: ``` skill: feature-wrap description: Run after finishing a feature branch. Lint, check for TODOs, summarize changes, write commit message. steps: 1. Run linter via shell tool: `npm run lint`. If errors found, stop and report them. Do not proceed. 2. Search for TODO comments added in this session: `grep -rn 'TODO' src/ --include='*.ts'`. List any found. 3. Read git diff --staged and write a one-paragraph plain-English summary of what changed and why. 4. Write a conventional commit message (type(scope): description) based on the summary. success_condition: Linter exits 0, TODO list is empty or acknowledged, summary is written, commit message is ready. constraints: - Do NOT run git commit automatically. Present the message for user approval first. - Do NOT modify any files during this skill. Read and report only. ``` Invocation: say 'run feature-wrap' or 'invoke feature-wrap on my current changes'.
Go deeper (20 min)
Paste this into Claude:
Now audit your skill for least-privilege. Paste your skill definition and ask Claude: 'For each step in this skill, tell me: (1) What permissions does this step need? (2) Could the same step be done with read-only access instead of write access? (3) What is the blast radius if this step goes wrong? (4) Which steps should require human confirmation before proceeding?' Then revise the skill to add confirmation gates on any step with a blast radius larger than your own project files.
What good looks like:
What a good response looks like:
Least-privilege audit output for the feature-wrap skill: Step 1 (linter): needs shell execute. Read-only alternative: no, execution is required. Blast radius: none, linter does not write files. Gate: not needed. Step 2 (TODO grep): needs filesystem read. Could be read-only: yes. Blast radius: none. Gate: not needed. Step 3 (diff summary): needs git read. Could be read-only: yes. Blast radius: none. Gate: not needed. Step 4 (commit message): needs no permissions (output only). Blast radius: none if auto-commit is blocked by constraint. Revised constraint added: 'Step 4 must display the commit message and wait for explicit user confirmation before calling git commit. If the user does not confirm within the session, discard the message and stop.' Blast radius of entire skill: zero (read-only on all steps, no external writes, no API calls).
When this breaks
Claude can do it for you
Say to Claude: 'I want to package [workflow name] as a skill. Interview me about the steps I actually take when I do this manually. Then write the skill definition based on my answers and flag any steps that need a confirmation gate.' Claude Desktop users: once Claude writes the skill, say 'add this to my CLAUDE.md' and it will insert it automatically.
You can now
Produce a skill definition with a verb-phrase name, observable success condition, least-privilege per step, and run it twice on real work without re-explaining any step.
Key takeaways
A skill turns a repeatable workflow into a reliable one. Write the skill once, get consistent output every time, and audit the permissions before you scale it.