# How to Create and Publish a Custom Skill for Claude Code: A Complete Guide

> Learn to create and publish custom Skills for Claude Code using SKILL md files and Python implementations. Follow this guide from the anthropics cwc workshops repository to build reusable code bundles.

- Repository: [Anthropic/cwc-workshops](https://github.com/anthropics/cwc-workshops)
- Tags: how-to-guide
- Published: 2026-07-18

---

**Custom Skills for Claude Code are reusable code bundles defined by a [`SKILL.md`](https://github.com/anthropics/cwc-workshops/blob/main/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`](https://github.com/anthropics/cwc-workshops/blob/main/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`](https://github.com/anthropics/cwc-workshops/blob/main/research-desk/skills/edgartools/SKILL.md) – A Skill for SEC filing analysis
- [`agent-battle/skills/mining/SKILL.md`](https://github.com/anthropics/cwc-workshops/blob/main/agent-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`](https://github.com/anthropics/cwc-workshops/blob/main/SKILL.md) – The metadata and documentation file
- Optional implementation files (e.g., [`impl.py`](https://github.com/anthropics/cwc-workshops/blob/main/impl.py), [`utils.py`](https://github.com/anthropics/cwc-workshops/blob/main/utils.py))

Example layout:

```text
research-desk/
└── skills/
    └── edgartools/
        ├── SKILL.md          # Required metadata

        └── sec_parser.py     # Optional implementation

```

## Step 2: Define the SKILL.md Metadata

The [`SKILL.md`](https://github.com/anthropics/cwc-workshops/blob/main/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`](https://github.com/anthropics/cwc-workshops/blob/main/research-desk/skills/edgartools/SKILL.md), the front-matter should look like this:

```markdown
---
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:

```python

# 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:
1. Locate the `edgartools` directory by reading [`SKILL.md`](https://github.com/anthropics/cwc-workshops/blob/main/SKILL.md)
2. Import the associated Python modules
3. Execute the logic with the provided `ticker` argument
4. 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`](https://github.com/anthropics/cwc-workshops/blob/main/SKILL.md).

## Step 5: Publish and Distribute Your Skill

Once testing passes, commit the Skill directory to your repository:

```bash
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`](https://github.com/anthropics/cwc-workshops/blob/main/skills/github-releases/SKILL.md)

```markdown
---
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`](https://github.com/anthropics/cwc-workshops/blob/main/skills/github-releases/releases.py)

```python
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.md`](https://github.com/anthropics/cwc-workshops/blob/main/SKILL.md) file** with YAML front-matter containing `name` and `description` fields
- **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-name` followed 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`](https://github.com/anthropics/cwc-workshops/blob/main/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`](https://github.com/anthropics/cwc-workshops/blob/main/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`](https://github.com/anthropics/cwc-workshops/blob/main/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.