Writing Your First Skill
This tutorial walks you through creating a skill, testing it locally, and publishing it to the Skola marketplace.
A skill is a Markdown file that instructs an AI agent how to perform a specific task. It lives in .claude/skills/<name>/ and is picked up automatically by Claude Code.
1. Scaffold the skill
skola create skill my-skill
You'll be prompted for a name, description, author, and tags. Skola creates:
my-skill/
├── SKILL.md ← the actual skill instructions
└── metadata.yaml ← registry metadata
Including agent configurations (optional)
If your skill provides recommended settings for AI agents (Claude, OpenCode, Cursor, Codex), include the --with-config flag:
skola create skill my-skill --with-config
This adds a configs.yaml file with a template. Edit it to define agent-specific configurations like hooks or settings.
2. Write the skill content
Open my-skill/SKILL.md. Replace the placeholder content with real instructions.
A good skill answers three questions: - When should the agent use this? (trigger phrases / preconditions) - What steps should it follow? (numbered, concrete) - What's the expected output? (success criteria)
Using context variables
If your skill needs team-specific values (Jira keys, repo names, Slack channels), use {{VARIABLE_NAME}} placeholders:
## Step 3: Create a Jira ticket
Use the Jira CLI to create a ticket in project {{JIRA_PROJECT_KEY}}:
```bash
acli jira create --project {{JIRA_PROJECT_KEY}} ...
Then declare those variables in `metadata.yaml`:
```yaml
context:
variables:
JIRA_PROJECT_KEY:
description: "Your team's Jira project key"
example: "AN"
required: true
When someone installs the skill, Skola will prompt them for each value and substitute it in.
Agent configurations (configs.yaml)
If your skill needs agent-specific settings (like Claude hooks or OpenCode config), create a configs.yaml file:
agents:
claude:
hooks:
PostToolUse:
- matcher: "mcp__{{CI_PLATFORM}}__get_logs"
hooks:
- type: command
command: "cat > /tmp/mcp_log.json"
Template variables ({{VAR}}) in configs.yaml are rendered with the user's context values. When users install your skill, they'll be prompted to apply these configurations to their agents.
Supported agents: claude, opencode, cursor, codex
3. Test locally
Install your skill from the local directory to verify it works:
# From the directory containing my-skill/
skola install skill/my-skill --dir .
This renders the templates with your values and writes the resolved files to .claude/skills/my-skill/.
Open the installed SKILL.md and confirm the variables were substituted correctly.
4. Validate before publishing
skola publish skill/my-skill --help
Run the validation without the actual PR step by checking the output of skola doctor and reviewing:
metadata.yamlhasname,description,author,tagsSKILL.mdis not empty boilerplate- All context variables have
descriptionandexample
5. Publish to the marketplace
skola publish skill/my-skill
This:
1. Validates your metadata
2. Forks the marketplace repo (if needed)
3. Creates a branch add-skill-my-skill
4. Copies your files into skills/my-skill/
5. Opens a PR with an auto-generated description
You'll get a PR URL. Share it with the reviewer in Slack.
6. After it merges
The CI pipeline automatically regenerates registry.yaml. Within minutes, anyone on the team can install your skill:
skola install skill/my-skill
Tips for great skills
| Do | Don't |
|---|---|
| Use numbered steps | Write vague instructions |
| Include example commands | Hardcode team-specific values |
| List preconditions clearly | Skip the "trigger phrases" section |
Use {{VARIABLE}} for anything env-specific |
Assume the repo name or Jira key |
| Keep it focused on one workflow | Bundle 3 unrelated workflows in one skill |
Example: minimal skill
---
name: hello-world
description: "A minimal example skill."
---
# Hello World
### Trigger phrases
- "run hello world"
## Step 1: Print a greeting
```bash
echo "Hello, world!"
Expected output
The string "Hello, world!" printed to the terminal. ```
That's it — a skill can be this simple. Start small, iterate.
