Agent DailyAgent Daily
tutorialintermediate

Building custom Skills for Claude Oct 2025 • Skills Create, deploy, and manage custom skills extending Claude with specialized organizational workflows.

cookbook
View original on cookbook

This cookbook guide teaches developers how to create, deploy, and manage custom skills for Claude that extend its capabilities with organization-specific workflows and domain knowledge. Custom skills are specialized expertise packages bundled as markdown files, scripts, and resources that codify organizational knowledge, ensure consistency, and automate complex workflows while maintaining privacy. The guide covers skill architecture, SKILL.md requirements, progressive disclosure for token optimization, and provides utility functions for skill management including creation, listing, and deletion.

Key Points

  • Custom skills are specialized expertise packages that codify organizational knowledge, ensure consistency across interactions, and automate multi-step workflows while keeping proprietary methods secure
  • Every skill requires a SKILL.md file with YAML frontmatter (name and description) and markdown instructions; additional .md files can be included for documentation, API references, examples, and troubleshooting
  • Skills can bundle multiple file types: markdown files for instructions, Python/JavaScript scripts for complex operations, templates for customization, and resource files for supporting data
  • Skills load in three progressive stages (metadata → instructions → resources) to optimize token usage, with instructions recommended to stay under 5,000 tokens
  • Use files_from_dir() utility to bundle skill files and client.beta.skills.create() to deploy skills with a display_title; skills remain private to your organization
  • Helper functions enable skill management: create_skill() for deployment, list_custom_skills() to view all custom skills, and delete_skill() to remove skills and versions
  • Skills support composability—multiple skills can be combined for complex tasks—and include version control for tracking changes and rolling back if needed
  • API workflow involves three steps: create skill from directory, use skill in messages via container parameter with skill_id and version, and reference skills during execution
  • Prerequisites include Anthropic API key with Skills beta access, Python environment with local SDK, and completion of foundational Skills notebook
  • Best practices include organizing complex documentation across multiple markdown files, using clear examples and constraints in SKILL.md, and leveraging progressive disclosure for token efficiency

Found this useful? Add it to a playbook for a step-by-step implementation guide.

Workflow Diagram

Start Process
Step A
Step B
Step C
Complete
Quality

Concepts

Artifacts (4)

Environment Setup Scriptpythonscript
import os
import sys
from pathlib import Path
from typing import Any

# Add parent directory for imports
sys.path.insert(0, str(Path.cwd().parent))

from anthropic import Anthropic
from anthropic.lib import files_from_dir
from dotenv import load_dotenv

# Load environment variables
load_dotenv(Path.cwd().parent / ".env")

API_KEY = os.getenv("ANTHROPIC_API_KEY")
MODEL = os.getenv("ANTHROPIC_MODEL", "claude-sonnet-4-6")

if not API_KEY:
    raise ValueError("ANTHROPIC_API_KEY not found. Copy ../.env.example to ../.env and add your API key.")

# Initialize client with Skills beta
client = Anthropic(
    api_key=API_KEY,
    default_headers={"anthropic-beta": "skills-2025-10-02"}
)

# Setup directories
SKILLS_DIR = Path.cwd().parent / "custom_skills"
OUTPUT_DIR = Path.cwd().parent / "outputs"
OUTPUT_DIR.mkdir(exist_ok=True)

print("✓ API key loaded")
print(f"✓ Using model: {MODEL}")
print(f"✓ Custom skills directory: {SKILLS_DIR}")
print(f"✓ Output directory: {OUTPUT_DIR}")
print("\n 📝 Skills beta header configured for skill management")
Skill Management Utility Functionspythonscript
from typing import Any
from anthropic import Anthropic
from anthropic.lib import files_from_dir

def create_skill(client: Anthropic, skill_path: str, display_title: str) -> dict[str, Any]:
    """
    Create a new custom skill from a directory.
    
    Args:
        client: Anthropic client instance
        skill_path: Path to skill directory
        display_title: Human-readable skill name
    
    Returns:
        Dictionary with skill_id, version, and metadata
    """
    try:
        skill = client.beta.skills.create(
            display_title=display_title,
            files=files_from_dir(skill_path)
        )
        return {
            "success": True,
            "skill_id": skill.id,
            "display_title": skill.display_title,
            "latest_version": skill.latest_version,
            "created_at": skill.created_at,
            "source": skill.source,
        }
    except Exception as e:
        return {"success": False, "error": str(e)}

def list_custom_skills(client: Anthropic) -> list[dict[str, Any]]:
    """
    List all custom skills in the workspace.
    
    Returns:
        List of skill dictionaries
    """
    try:
        skills_response = client.beta.skills.list(source="custom")
        skills = []
        for skill in skills_response.data:
            skills.append({
                "skill_id": skill.id,
                "display_title": skill.display_title,
                "latest_version": skill.latest_version,
                "created_at": skill.created_at,
                "updated_at": skill.updated_at,
            })
        return skills
    except Exception as e:
        print(f"Error listing skills: {e}")
        return []

def delete_skill(client: Anthropic, skill_id: str) -> bool:
    """
    Delete a custom skill and all its versions.
    
    Args:
        client: Anthropic client
        skill_id: ID of skill to delete
    
    Returns:
        True if successful, False otherwise
    """
    try:
        versions = client.beta.skills.versions.list(skill_id=skill_id)
        for version in versions.data:
            client.beta.skills.versions.delete(skill_id=skill_id, version=version.version)
        return True
    except Exception as e:
        print(f"Error deleting skill: {e}")
        return False
Skill Directory Structure Templatetemplate
skill_name/
├── SKILL.md                    # REQUIRED: Instructions with YAML frontmatter
├── REFERENCE.md                # Optional: API reference documentation
├── EXAMPLES.md                 # Optional: Usage examples
├── TROUBLESHOOTING.md          # Optional: Common issues and solutions
├── CHANGELOG.md                # Optional: Version history
├── scripts/                    # Optional: Executable code
│   ├── process.py
│   └── utils.js
└── resources/                  # Optional: Templates, data files
    └── template.xlsx

# SKILL.md Template
---
name: skill-name-lowercase
description: Brief description of what the skill does (max 1024 chars)
---

# Skill Title

## Overview
Clear guidance for Claude on how to use this skill.

## Usage Examples
- Example 1
- Example 2

## Constraints
- Constraint 1
- Constraint 2

## Best Practices
- Practice 1
- Practice 2
Skill Usage in Messagespythonconfig
# Create skill
skill = client.beta.skills.create(
    display_title="My Skill",
    files=files_from_dir("path/to/skill")
)

# Use in messages
response = client.beta.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    container={
        "skills": [{
            "type": "custom",
            "skill_id": skill.id,
            "version": "latest"
        }]
    },
    messages=[
        {
            "role": "user",
            "content": "Use my custom skill to..."
        }
    ]
)
Building custom Skills for Claude Oct 2025 • Skills Create, deploy, and manage custom skills extending Claude with specialized organizational workflows. | Agent Daily