How to Create a Custom Skill for Claude Code Using SKILL.md
To create a custom skill for Claude Code, create a folder under pm-{plugin}/skills/ containing a SKILL.md file with YAML front-matter defining name (matching the folder) and description, then run the validator to ensure compliance.
The phuryn/pm-skills repository provides a structured framework for extending Claude Code with custom skills through declarative SKILL.md files. This approach allows you to define reusable capabilities without modifying core plugin manifests or writing complex configuration code. Understanding how to create a custom skill for Claude Code using SKILL.md requires following specific architectural conventions defined in the repository's central documentation.
Understanding the Skill Architecture
Claude Code discovers skills automatically by scanning SKILL.md files located within each plugin's skills/ directory. Unlike traditional plugin development that requires manifest entries, this system uses filesystem conventions and front-matter validation to register new capabilities.
Plugin Layout Requirements
Every plugin in the repository follows the pm-{name} naming convention and contains a dedicated skills/ subtree. According to CLAUDE.md lines 13-30, the repository expects this structure:
pm-myplugin/
└─ skills/
└─ my-custom-skill/
└─ SKILL.md
The pm-{plugin}/.claude-plugin/plugin.json file defines the plugin itself, but you do not modify this manifest when adding individual skills. Skills exist as independent building blocks within the skills subdirectory.
The SKILL.md File Structure
A valid skill requires exactly one SKILL.md file per skill folder. As defined in CLAUDE.md lines 53-55, this file must contain:
- YAML front-matter with
nameanddescriptionfields - Free-form markdown content containing instructions, arguments, and examples
Step-by-Step Implementation Guide
Follow these steps to implement a new skill that Claude Code can discover and load automatically.
Step 1: Create the Directory Structure
Create a new folder under your plugin's skills/ directory. The folder name must match the skill identifier you intend to use:
mkdir -p pm-myplugin/skills/my-custom-skill
Step 2: Write the SKILL.md Front-Matter
Create SKILL.md with required YAML front-matter. The name field must exactly match the parent folder name, as enforced by the validator (see CLAUDE.md line 54):
---
name: my-custom-skill
description: "Brief one-liner that Claude uses to match trigger phrases and auto-load contexts."
---
The description field appears in Claude's skill list and drives auto-loading based on trigger phrases (see CLAUDE.md line 46).
Step 3: Add Skill Instructions
After the front-matter, add the instruction body that defines the skill's behavior:
# My Custom Skill
You are a specialist in analyzing project management workflows.
## Input Arguments
- `$PROJECT_PATH`: Path to the project directory (required)
- `$FOCUS_AREA`: Specific aspect to analyze (optional)
## Output
Provide a structured analysis with:
1. Current workflow bottlenecks
2. Recommended optimizations
3. Implementation priority
### Example Usage
/my-custom-skill $PROJECT_PATH="./src" $FOCUS_AREA="code-review"
Reference the review-resume skill in pm-toolkit/skills/review-resume/SKILL.md for a fully fleshed-out implementation example.
Step 4: Validate Your Skill
Run the repository-wide validator to check naming constraints and schema compliance:
python3 validate_plugins.py
As documented in CLAUDE.md lines 95-99, this script verifies that the front-matter name matches the folder name and validates other structural requirements. If you encounter a "Skill name does not match folder name" error, align the folder name with the name field in the YAML front-matter.
SKILL.md Front-Matter Constraints
The front-matter section follows strict validation rules. According to the source code analysis of CLAUDE.md:
- The
namefield is required and must equal the directory name exactly - The
descriptionfield is required and provides the auto-loading trigger context - No additional manifest entries are needed — skills do not appear in
plugin.json
These constraints ensure that Claude Code can scan pm-*/skills/ directories at runtime and correctly map trigger phrases to skill descriptions (see CLAUDE.md lines 46-56).
Validation and Troubleshooting
The validate_plugins.py script serves as the gatekeeper for skill integrity. It checks:
- Folder-to-name consistency
- Required front-matter fields
- File structure compliance
If validation fails, the error message indicates exactly which constraint was violated. Common issues include mismatched folder names or missing description fields. The validator ensures that only properly structured skills are available for Claude Code's discovery mechanism.
Summary
- Create a folder under
pm-{plugin}/skills/named after your skill - Write
SKILL.mdwith YAML front-matter containingname(matching folder) anddescription - Add instruction content in markdown format below the front-matter
- Do not modify
plugin.json— skills auto-discover based on filesystem structure - Run
python3 validate_plugins.pyto enforce naming and schema constraints - Reference
CLAUDE.mdfor architectural rules and validation requirements
Frequently Asked Questions
What happens if the skill name doesn't match the folder name?
The validator will reject the skill with a "Skill name does not match folder name" error. You must rename either the folder or the name field in the SKILL.md front-matter until they align exactly, as required by CLAUDE.md line 54.
Do I need to update plugin.json when adding a new skill?
No. Skills exist independently of the plugin manifest. The plugin.json file (located at pm-{plugin}/.claude-plugin/plugin.json) defines the plugin itself, but individual skills are discovered automatically by scanning SKILL.md files in the skills/ directory.
How does Claude Code know when to load my custom skill?
Claude Code scans every SKILL.md under pm-*/skills/ when the plugin loads. The description field in your front-matter is used for auto-loading based on trigger phrases, allowing Claude to match user queries to available skills without explicit commands.
Can I include optional arguments in my skill definition?
Yes. You can define optional input arguments using the $ARGUMENT_NAME syntax in your skill instructions. Mark them as optional in the documentation section, and Claude will handle cases where users omit these parameters during invocation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →