# Creating Skills
This guide covers how to create and structure [Agent Skills](https://docs.anthropic.com/en/docs/agents-and-tools/agent-skills/overview) for SkillPort.
## Quick Start
```bash
# Add the template skill
skillport add template
# Edit the template
# ~/.skillport/skills/template/SKILL.md
```
Or create from scratch:
```bash
mkdir -p ~/.skillport/skills/my-skill
cat > ~/.skillport/skills/my-skill/SKILL.md << 'EOF'
---
name: my-skill
description: What this skill does (used for search)
---
# My Skill
Instructions for the AI agent go here.
EOF
```
## SKILL.md Format
Every skill requires a `SKILL.md` file with YAML frontmatter.
### Required Fields
```yaml
---
name: my-skill
description: Brief description of what this skill does
---
# My Skill
Detailed instructions for the AI agent.
```
| Field | Requirements |
|-------|--------------|
| `name` | Lowercase, hyphens only, max 64 chars, must match directory name |
| `description` | Non-empty, max 1024 chars, used for search |
### Optional Metadata
The `metadata` field follows the [Anthropic Agent Skills](https://docs.anthropic.com/en/docs/agents-and-tools/agent-skills/overview) specification. SkillPort uses `metadata.skillport` for:
- **Search** — `category` and `tags` improve search relevance
- **Filtering** — Control which skills each client sees (see [Configuration](configuration.md#client-based-skill-filtering))
- **Core Skills** — `alwaysApply: true` loads skills without searching
```yaml
---
name: code-review
description: Systematic code review checklist for pull requests
metadata:
skillport:
category: development
tags: [code-review, pr, quality]
alwaysApply: false
---
```
| Field | Description | Default |
|-------|-------------|---------|
| `category` | Grouping for filtering/search | none |
| `tags` | Keywords for search | `[]` |
| `alwaysApply` | Always load as Core Skill | `false` |
### Core Skills (alwaysApply)
Skills with `alwaysApply: true` are loaded into every conversation:
```yaml
---
name: team-standards
description: Our team's coding standards
metadata:
skillport:
alwaysApply: true
---
```
Use sparingly - these consume context in every conversation.
> **Tip:** Core Skills can be controlled per-client via `SKILLPORT_CORE_SKILLS_MODE`.
> See [Configuration](configuration.md#core-skills-control) for details.
## Directory Structure
```
my-skill/
├── SKILL.md # Required - Agent instructions
├── scripts/ # Optional - Executable scripts
│ ├── process.py
│ └── validate.sh
├── templates/ # Optional - Templates and configs
│ ├── config.yaml
│ └── example.json
└── README.md # Optional - Human documentation (not loaded)
```
### File Roles
| File/Directory | Purpose | Loaded by Agent? |
|----------------|---------|------------------|
| `SKILL.md` | Agent instructions | Yes (via `skillport show` or `load_skill`) |
| `scripts/` | Executable scripts | No (executed via path) |
| `templates/` | Templates, configs | Yes (via `read_skill_file` in HTTP/Remote mode) |
| `README.md` | Human docs, setup | No |
## Writing Effective Instructions
### Keep Instructions Concise
Target under 5,000 tokens. Use:
- Bullet points over paragraphs
- Step-by-step numbered lists
- Clear section headings
```markdown
# Code Review Skill
## When to Use
- Reviewing pull requests
- Checking code quality before merge
## Steps
1. Check for security issues
2. Verify error handling
3. Review naming conventions
4. Check test coverage
## Checklist
- [ ] No hardcoded secrets
- [ ] All errors handled
- [ ] Tests included
```
### Use Path-Based References
Reference files by path, don't inline code:
```markdown
# Good - Reference by path
Run the validation script:
```bash
python {path}/scripts/validate.py input.txt
```
# Avoid - Inline code wastes context
```python
def validate(input):
# 50 lines of code...
```
```
The `{path}` placeholder is replaced with the skill's directory path when loaded.
### Provide Context for Scripts
Explain what scripts do without showing the code:
```markdown
## Available Scripts
### scripts/extract.py
Extracts text from PDF files.
**Usage:**
```bash
python {path}/scripts/extract.py input.pdf --output text.txt
```
**Arguments:**
- `input.pdf` - Path to PDF file
- `--output` - Output file path (default: stdout)
```
## Skill Types
### Prompt-Only Skills
Instructions and guidelines without executable code.
```
checklist-skill/
├── SKILL.md # Instructions only
└── templates/
└── checklist.md # Optional template
```
**Use cases:**
- Code review checklists
- Writing guidelines
- Process documentation
### Script-Based Skills
Include executable scripts for automation.
```
pdf-processor/
├── SKILL.md
├── scripts/
│ └── extract.py # PEP 723 for dependencies
└── templates/
└── output.json
```
**Use cases:**
- File processing
- Data transformation
- API integrations
### PEP 723 for Dependencies
Scripts can declare dependencies inline:
```python
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "pypdf>=4.0",
# "requests",
# ]
# ///
import pypdf
import requests
def main():
...
```
When executed with `uv run script.py`, dependencies are automatically installed.
## Best Practices
### 1. Match Name to Directory
The `name` field must match the directory name:
```
✓ skills/code-review/SKILL.md → name: code-review
✗ skills/code-review/SKILL.md → name: review-code
```
Validate with: `skillport lint`
### 2. Write Searchable Descriptions
Descriptions are used for search. Include key terms:
```yaml
# Good - Searchable
description: Extract text content from PDF documents using Python
# Bad - Vague
description: PDF utility
```
### 3. Use Categories and Tags
Help users find your skill:
```yaml
metadata:
skillport:
category: data-processing
tags: [pdf, text-extraction, documents]
```
### 4. Separate Human and Agent Docs
- `SKILL.md` - For the AI agent (loaded into context)
- `README.md` - For humans (setup, examples, troubleshooting)
### 5. Test Before Sharing
```bash
# Validate structure
skillport lint my-skill
# Test in real conversation
# Ask: "Search for my-skill"
# Then: "Load and use my-skill"
```
## Examples
### Minimal Skill
```yaml
---
name: git-commit-style
description: Guidelines for writing good git commit messages
---
# Git Commit Style
## Format
```
<type>: <subject>
<body>
```
## Types
- feat: New feature
- fix: Bug fix
- docs: Documentation
- refactor: Code refactoring
```
### Full-Featured Skill
```yaml
---
name: pdf-extractor
description: Extract text and metadata from PDF documents
metadata:
skillport:
category: data-processing
tags: [pdf, text-extraction, documents]
---
# PDF Extractor
## Overview
Extract text content from PDF files with metadata preservation.
## Usage
### Basic Extraction
```bash
python {path}/scripts/extract.py document.pdf
```
### With Options
```bash
python {path}/scripts/extract.py document.pdf \
--output text.txt \
--include-metadata \
--pages 1-10
```
## Output Format
See `{path}/templates/output.json` for the output schema.
## Limitations
- Scanned PDFs require OCR (not included)
- Max file size: 100MB
```
## Sharing Skills
### GitHub Repository
Structure for sharing multiple skills:
```
my-skills-repo/
├── README.md # Human docs for the collection
├── code-review/
│ └── SKILL.md
├── testing/
│ └── SKILL.md
└── documentation/
└── SKILL.md
```
Users install with:
```bash
skillport add https://github.com/user/my-skills-repo
```
### Single Skill Repository
```
pdf-extractor/
├── README.md # Human docs
├── SKILL.md # Agent instructions
└── scripts/
└── extract.py
```
Users install with:
```bash
skillport add https://github.com/user/pdf-extractor
```
## See Also
- [CLI Reference](cli.md) — Command documentation
- [Configuration](configuration.md) — Categories, filtering, search options
- [Design Philosophy](philosophy.md) — Why skills work this way