How to Create and Publish a Custom Skill for Claude Code: A Complete Guide
Custom Skills for Claude Code are reusable code bundles defined by a SKILL.md file and optional Python implementations, stored in a skills directory and invoked via the /skill-name command.
Claude Code can be extended with modular capabilities that automate specific workflows. According to the anthropics/cwc-workshops repository, these custom Skills are self-contained directories that combine YAML metadata with executable scripts, allowing the assistant to perform complex tasks on demand.
What Defines a Claude Code Skill
A Skill is a portable extension that teaches Claude Code specific patterns or API integrations. Each Skill requires a SKILL.md file containing YAML front-matter that declares the name and description, plus optional implementation files that handle the actual execution logic. Claude Code discovers these Skills automatically when they are placed in repository-specific skills/ directories or the global .claude/skills/ folder.
Reference implementations in the source code demonstrate this structure clearly:
research-desk/skills/edgartools/SKILL.md– A Skill for SEC filing analysisagent-battle/skills/mining/SKILL.md– A data extraction Skill with functional Python code
Step 1: Structure Your Skill Directory
Create a dedicated folder for your Skill. If you want the Skill available only within a specific project, place it under your-project/skills/skill-name/. For global availability across all Claude Code sessions, store it in .claude/skills/skill-name/ in your home directory or repository root.
The directory must contain at minimum:
SKILL.md– The metadata and documentation file- Optional implementation files (e.g.,
impl.py,utils.py)
Example layout:
research-desk/
└── skills/
└── edgartools/
├── SKILL.md # Required metadata
└── sec_parser.py # Optional implementation
Step 2: Define the SKILL.md Metadata
The SKILL.md file must begin with a YAML front-matter block containing exactly two keys: name and description. This metadata tells Claude Code how to register and describe the Skill in the command palette.
Following the pattern seen in research-desk/skills/edgartools/SKILL.md, the front-matter should look like this:
---
name: edgartools
description: |
Fetch and parse SEC EDGAR filings for a given ticker symbol.
Returns structured financial data as markdown tables.
---
# edgartools
This Skill interfaces with the SEC EDGAR API to retrieve 10-K and 10-Q filings.
It expects a `ticker` argument and returns parsed financial metrics.
The name field determines the command users type to invoke the Skill (e.g., /edgartools). The description appears in the Skills panel and helps Claude Code understand when to suggest this Skill automatically.
Step 3: Implement the Skill Logic
Add a Python file containing the executable code. Claude Code imports this module when the Skill is invoked, so define a clear entry point function that accepts the arguments specified in your documentation.
Example implementation following the agent-battle/skills/mining/ pattern:
# mining.py
import requests
from typing import Dict
def run(ticker: str) -> str:
"""
Fetch latest mining statistics for a cryptocurrency.
Args:
ticker: The cryptocurrency symbol (e.g., 'BTC', 'ETH')
Returns:
Markdown formatted string with mining difficulty and hash rate.
"""
api_url = f"https://api.mining.com/v1/stats/{ticker}"
response = requests.get(api_url)
data = response.json()
return f"**{ticker} Mining Stats**\n- Difficulty: {data['difficulty']}\n- Hash Rate: {data['hashrate']} TH/s"
The function signature should match the arguments you expect users to pass via the command line. Claude Code handles the import and execution automatically.
Step 4: Test Your Skill Locally
Open Claude Code in the repository containing your Skill directory. In the chat interface, invoke the Skill using the forward-slash syntax:
/edgartools ticker=AAPL
Claude Code will:
- Locate the
edgartoolsdirectory by readingSKILL.md - Import the associated Python modules
- Execute the logic with the provided
tickerargument - Display the returned markdown output
If the Skill fails, check the Python traceback in the conversation history. Common issues include missing dependencies in the Skill's Python files or malformed YAML front-matter in SKILL.md.
Step 5: Publish and Distribute Your Skill
Once testing passes, commit the Skill directory to your repository:
git add research-desk/skills/edgartools/
git commit -m "Add edgartools Skill for SEC filing analysis"
git push origin main
For global reuse across multiple projects, copy the entire Skill directory to the .claude/skills/ folder in your home directory or the target repository root. This location takes precedence in Claude Code's discovery mechanism. After pushing to a shared repository, any Claude Code session opened on that branch will list the new Skill in the Skills panel and make it available via the / command prefix.
Complete Working Example
Here is a fully functional Skill based on the patterns in anthropics/cwc-workshops:
File: skills/github-releases/SKILL.md
---
name: github-releases
description: |
Fetch the latest GitHub release information for any public repository.
---
# github-releases
Returns the latest tag, release name, and publication date.
File: skills/github-releases/releases.py
import requests
def fetch_latest(repo: str) -> str:
"""Return latest release info for a GitHub repository."""
url = f"https://api.github.com/repos/{repo}/releases/latest"
data = requests.get(url).json()
tag = data.get("tag_name", "N/A")
name = data.get("name", "N/A")
published = data.get("published_at", "N/A")[:10] # YYYY-MM-DD
return f"| Repository | Tag | Date |\n|------------|-----|------|\n| {repo} | {tag} | {published} |"
Invocation:
/github-releases repo=anthropics/cwc-workshops
Summary
- Skills require a
SKILL.mdfile with YAML front-matter containingnameanddescriptionfields - Implementation files are optional but typically include Python scripts that define entry point functions
- Discovery locations include repository-specific
skills/directories and the global.claude/skills/folder - Invocation syntax uses
/skill-namefollowed by key=value arguments - Publishing involves committing to a repository or copying to the global Skills directory for cross-project availability
Frequently Asked Questions
What file format does the SKILL.md use?
The SKILL.md file uses standard Markdown with a YAML front-matter block at the top (delimited by ---). The front-matter must contain the name and description keys. This format is parsed by Claude Code to register the Skill in the command palette without executing any code.
Can Skills be written in languages other than Python?
While the examples in anthropics/cwc-workshops use Python for implementations, Claude Code primarily expects Python files for executable Skills. However, you can document external CLI tools in the SKILL.md description, and the Skill can invoke shell commands or subprocess calls to other languages if needed.
Where should I place Skills for global access?
Place Skill directories inside .claude/skills/ in your repository root or home directory. Claude Code searches this location first when loading Skills. Repository-specific Skills placed in skills/ subdirectories (like research-desk/skills/) are only available when Claude Code is opened in that specific repository.
How do I debug a Skill that fails to load?
Check the YAML front-matter syntax in SKILL.md for indentation errors or missing quotes. Ensure the name field contains no spaces. Verify that any Python implementation files have no import errors by testing them standalone with python impl.py. Claude Code displays Python tracebacks in the chat when Skill execution fails.
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 →