Apr 20, 2026

Build Your First Agent Skill: A Practical Walkthrough

Learn how to create a custom Agent Skill from scratch. Write a SKILL.md, test it locally, and publish it to GitHub for others to use.

#tutorial#skill-creation#SKILL.md#developer-tools

You have installed a few skills and they work. Now you want to create one for your own workflow. Maybe your team has a specific code review process, or you always format API responses the same way, or you have a deployment checklist you follow manually.

This tutorial walks through creating a real skill from scratch.

What You Will Build

A "release-notes" skill that generates structured release notes from git commit history. This is something most teams need and no one enjoys writing manually.

By the end, you will have a skill that:

  1. Reads git log for recent commits
  2. Categorizes them by type (feat, fix, refactor, etc.)
  3. Generates a Markdown release notes document
  4. Follows your team's formatting conventions

Step 1: Create the Skill Directory

Skills live in your local skills directory. For Claude Code:

mkdir -p ~/.claude/skills/release-notes
cd ~/.claude/skills/release-notes

Step 2: Write the SKILL.md

Create SKILL.md with this structure:

---
name: release-notes
description: Generate structured release notes from git commit history, categorized by change type
---

Then add the instructions in Markdown:

## Purpose

Generate release notes for the current repository based on recent git commits.

## When to activate

The user asks for release notes, changelog, or "what changed" for a version or time range.

## Instructions

1. Run `git log --oneline` to get recent commits. Default range: last 50 commits or since the last tag, whichever is smaller.

2. Categorize each commit by its prefix:
   - `feat:` or `feature:` → New Features
   - `fix:` or `bugfix:` → Bug Fixes
   - `refactor:` → Refactoring
   - `docs:` → Documentation
   - `test:` → Tests
   - `chore:` → Maintenance
   - No prefix → Other Changes

3. Group commits under these headings. Omit empty sections.

4. For each commit, include:
   - The commit message (without the prefix)
   - The commit hash (first 7 characters)
   - Do NOT include author names or dates unless specifically requested

5. Output format:

# Release Notes

## New Features
- Description of change (`abc1234`)
- Description of change (`def5678`)

## Bug Fixes
- Description of fix (`ghi9012`)

## Other Changes
- Description (`jkl3456`)

6. If the user specifies a version number, include it in the heading:
   `# Release Notes v1.2.0`

7. If the user asks for "full" release notes, include the commit body text below each entry.

## Important rules

- Do not fabricate commits. Only include what exists in git log.
- If the repo uses conventional commits, respect the format. If not, put everything under "Other Changes."
- Keep descriptions concise. Do not expand or interpret commit messages.

Save the file. That is the entire skill.

Step 3: Test the Skill

Open a git repository in Claude Code:

cd ~/my-project
claude

Ask:

Generate release notes for the last 2 weeks

Claude should activate the skill, run git log, categorize commits, and produce structured output.

If the output looks wrong, edit the SKILL.md instructions. The most common issue is the categorization logic being too strict or too loose. Adjust the prefix list to match your team's conventions.

Step 4: Add a Script (Optional)

If you want the skill to also run a script (for example, to generate a file automatically), add scripts/generate.sh:

#!/bin/bash
# Usage: generate.sh [since-tag] [version]
SINCE=${1:-$(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~50")}
VERSION=${2:-"$(date +%Y-%m-%d)"}

echo "# Release Notes $VERSION"
echo ""
git log "$SINCE"..HEAD --pretty=format:"- %s (%h)" | \
  sed 's/^- feat(\(.*\)):/- **\1**:/' | \
  sed 's/^- fix(\(.*\)): /- [\1] /'

Reference this script in the SKILL.md instructions:

## Scripts

- `scripts/generate.sh [since-tag] [version]` — generates a raw release notes file.
  Use this as a starting point, then refine with the full categorization instructions above.

Step 5: Publish to GitHub

If your skill is useful to others, publish it:

# Create a new GitHub repo
gh repo create my-org/release-notes-skill --public

# Push the skill
cd ~/.claude/skills/release-notes
git init && git add . && git commit -m "feat: initial release-notes skill"
git remote add origin git@github.com:my-org/release-notes-skill.git
git push -u origin main

Others can install it:

claude skill add --from-github my-org/release-notes-skill

What Makes a Good Skill

From building this one, you can see the pattern:

  1. One clear purpose. This skill generates release notes. Not release notes plus changelogs plus deployment notes.
  2. Explicit when-to-activate rules. The agent needs to know when to use this skill vs. others.
  3. Concrete output format. Show the exact format you want. Examples beat descriptions.
  4. Honest constraints. "Do not fabricate commits" prevents hallucination.
  5. Optional scripts. The SKILL.md instructions are the core. Scripts are a bonus, not a requirement.

Common Mistakes

  • Too many purposes. One skill should do one thing. If you find yourself writing "and also..." split it into two skills.
  • Vague instructions. "Generate nice release notes" is not actionable. "Group commits by prefix, output in this specific Markdown format" is.
  • Skipping the when-to-activate section. Without it, the agent either never uses the skill or uses it at the wrong time.

Ready to explore more skills? Check the SkillMap leaderboard for the latest curated collection.