I've been deep in the AI tooling rabbit hole lately. Building stuff with Claude Code, Copilot, and other agents. And I kept hitting the same wall: these agents are incredibly capable, but they don't know my workflows. They don't know how my team likes to structure things, or the specific security checks we always run, or the weird edge cases we've learned the hard way.
Turns out you can actually teach them. And it's way simpler than I expected.
We'll build an Agent Skill from scratch—a portable, reusable package of instructions that any compatible agent can pick up and use. The spec lives at agentskills.io and it's refreshingly minimal.
This tutorial will cover:
- What Agent Skills actually are (and aren't)
- The folder structure and required files
- Writing effective SKILL.md files
- Adding scripts and resources
- Tips from real-world usage
Let's get into it.
What Even Is This?
Think of skills as "context on demand" for AI agents. Instead of cramming everything into a massive system prompt (which I was definitely doing before, and it was a mess), you package instructions into skills that agents load only when needed.
A skill is just a folder. At minimum, it contains a single file called SKILL.md. That's it. No build step, no compilation, no package.json. Just markdown with some YAML at the top.
When an agent encounters a task, it looks at the available skills, reads their names and descriptions, and decides which ones to activate. Only then does it load the full instructions. This progressive disclosure keeps things efficient.
What sold me: skills are portable. Write once and it works in Claude Code, GitHub Copilot, VS Code, OpenAI Codex, and others. No vendor lock-in.
The Stupidly Simple Structure
I overthought this at first. Turns out a skill is literally just:
my-skill/
├── SKILL.md # Required: instructions + metadata
├── scripts/ # Optional: executable code
├── references/ # Optional: detailed docs
└── assets/ # Optional: templates, examples
The only file you need is SKILL.md. Everything else is optional.
Let me show you what I actually built.
A Real Skill I Use: API Security Reviewer
I got tired of manually reminding Claude to check for the same security issues every time I asked it to review API code. So I made a skill for it.
mkdir api-security-reviewer
cd api-security-reviewer
Then create SKILL.md. The file has two parts: YAML frontmatter (metadata) and Markdown (the actual instructions).
Here's what mine looks like:
---
name: api-security-reviewer
description: Reviews API code for security vulnerabilities including auth issues, injection attacks, and data exposure. Use when reviewing backend code, APIs, or when security analysis is requested.
---
# API Security Review
You are a security-focused code reviewer. When this skill is activated, analyze code for the following vulnerability categories.
## Authentication & Authorization
Check for:
- Missing or weak authentication on endpoints
- Broken access control (users accessing resources they shouldn't)
- JWT issues: missing expiration, weak secrets, algorithm confusion
- Session management problems
## Injection Vulnerabilities
Look for:
- SQL injection (parameterized queries should be used)
- NoSQL injection
- Command injection
- LDAP injection
## Data Exposure
Flag:
- Sensitive data in logs
- Hardcoded secrets or API keys
- Overly verbose error messages
- Missing encryption for sensitive data at rest or in transit
## Output Format
For each finding, provide:
1. **Location**: File and line number
2. **Severity**: Critical / High / Medium / Low
3. **Issue**: Brief description
4. **Fix**: Concrete code example showing the fix
## Example
Given this code:
@app.route('/user/<id>')
def get_user(id):
query = f"SELECT * FROM users WHERE id = {id}"
return db.execute(query)
Output:
**Location**: app.py:3
**Severity**: Critical
**Issue**: SQL injection via string interpolation
**Fix**:
@app.route('/user/<id>')
def get_user(id):
query = "SELECT * FROM users WHERE id = ?"
return db.execute(query, (id,))
That's a complete, functional skill. Save it and you're done.
The first time I used this, Claude caught three issues I would've missed on a Friday afternoon code review. Worth the 20 minutes it took to write.
The Frontmatter: Don't Overthink It
I spent way too long reading about optional fields before realizing only two are required:
---
name: my-skill-name
description: What this skill does and when to use it.
---
name is lowercase with hyphens. Like a package name.
description is the important one—this is what the agent reads to decide if it should use your skill. I learned the hard way that vague descriptions are useless. "Helps with code" means your skill either loads when it shouldn't or doesn't load when it should. Be specific: "Use when reviewing backend code, APIs, or when security analysis is requested."
You can add optional stuff too:
---
name: my-skill-name
description: What this skill does.
license: MIT
metadata:
author: your-name
version: "1.0"
tags: ["security", "api", "review"]
---
But honestly? I usually skip the metadata. The agent doesn't really care.
When You Need Actual Code
Instructions alone don't always cut it. Sometimes you need executable scripts.
I added a dependency scanner to my security skill:
api-security-reviewer/
├── SKILL.md
└── scripts/
└── scan-dependencies.py
Then referenced it in SKILL.md:
## Dependency Scanning
Before manual review, run the [dependency scanner](./scripts/scan-dependencies.py) to check for known vulnerable packages.
The agent loads and runs the script when it decides it needs to. Pretty slick.
One gotcha: keep scripts self-contained. I assumed requests was installed everywhere and broke things. Now I always document dependencies at the top of each script.
Reference Docs for Complex Stuff
My security skill started getting long. Like, really long. I was hitting the recommended 500-line limit for SKILL.md.
Solution: move detailed docs to references/ and let the agent load them on demand.
api-security-reviewer/
├── SKILL.md
├── scripts/
│ └── scan-dependencies.py
└── references/
├── owasp-top-10.md
└── jwt-security.md
In SKILL.md, I just link to them:
For detailed JWT security patterns, see [JWT Security Guide](./references/jwt-security.md).
The agent only loads these when it actually needs the info. Keeps the token budget sane.
Stuff I Learned the Hard Way
Keep SKILL.md under 500 lines. I ignored this initially. Bad idea. Split content into references.
Token budget is real. The recommendation is under 5000 tokens for the full SKILL.md body. I check with wc -w SKILL.md and multiply by ~0.75 for a rough token estimate.
Test with actual tasks. I kept tweaking my skill based on where Claude got confused. The feedback loop is fast—change something, run a task, see what happens.
Don't skill everything. If your workflow is simple, you don't need this. I have maybe 4-5 skills I actually use. The rest were experiments that didn't stick.
The description field matters more than you think. This is what makes or breaks skill activation. I rewrote mine like three times before it worked reliably.
Where to Put Your Skills
For project-scoped skills in Claude Code:
your-repo/.claude/skills/my-skill/SKILL.md
For personal skills (available everywhere):
~/.claude/skills/my-skill/SKILL.md
Different agents have different conventions, but the skill format itself is the same.
Why I Wrote This
Honestly? Because I wish someone had written this when I started. The official docs are good but I learn better from "here's what I actually built and here's what broke."
But there's another reason. While building skills, I kept hitting the same wall: what happens when you make something genuinely valuable?
Right now, your options are open-source it (and hope for GitHub stars) or keep it private (and get nothing). There's no middle ground for creators who want to charge for their work without exposing their implementation.
So I built A2AX.
Private repos. You set the price. Creators keep up to 85%. That's it—no platform games, no "exposure" instead of money.
Early access is open if you're making skills worth selling.
Resources
If you want to go deeper:
- anthropics/skills has examples including the document creation skills that power Claude's file capabilities
- agentskills.io/specification is the full spec (you can read it in 5 minutes)
- The ecosystem supports Claude Code, GitHub Copilot, VS Code, OpenAI Codex, and more
That's it. A folder, a markdown file, some YAML. Now go teach your agent something new.
Top comments (1)
Nice! I wrote an article about why devs should start monetizing plugins… the same approach could easily apply to skills too.