Creating Skills
A skill is a directory containing a SKILL.md file. The file uses YAML frontmatter for metadata and Markdown for the instructions the agent follows.
Directory Structure
your-skill-name/ # kebab-case folder name
├── SKILL.md # Required -- main skill file
├── credentials.json # Optional -- credential schema
├── index.js # Optional -- code-based tools (Tier 3)
├── scripts/ # Optional -- executable scripts
│ └── process.py
└── references/ # Optional -- detailed docs loaded on demand
└── api-guide.md
SKILL.md Frontmatter Reference
---
name: my-skill # Skill identifier (defaults to directory name)
description: "What this skill does. Use when the user asks to [trigger phrases]. Do NOT use for [negative triggers]."
always: true # Skip all eligibility checks (optional)
requires:
env: # Environment variables that must be set
- MY_API_KEY
bins: # CLI binaries that must be on PATH
- curl
- jq
config: # Config keys that must exist
- some.config.key
compatibility:
os: # Supported platforms (optional)
- darwin
- linux
- win32
install: # Installation options (optional, see below)
- kind: brew
formula: my-tool
bins: [my-tool]
os: [darwin, linux]
label: "Install via Homebrew"
tools: # HTTP template tools (Tier 2, see below)
- name: my_api_call
description: "What this tool does"
input:
query:
type: string
description: "Search query"
request:
url: "https://api.example.com/search?q={{query}}"
method: GET
headers:
Authorization: "Bearer {{credential:apiKey}}"
metadata:
emoji: ""
homepage: https://example.com
tags: [example, demo]
author: Your Name
gitUrl: https://github.com/user/skill-repo
---
The description field is the most important part -- it controls when the agent activates the skill. Include what the skill does, specific trigger phrases, and negative triggers to avoid overlap with other skills.
Tier 1: Text-Only Skills
The simplest skill type. The Markdown body contains instructions that teach the agent to use existing tools (bash, web fetch, file operations) in specific ways.
---
name: weather
description: "Get weather via wttr.in. Use when the user asks about weather."
requires:
bins:
- curl
---
# Weather
Get weather using curl and wttr.in.
## Commands
Current weather:
curl -s "wttr.in/Berlin?format=3"
Detailed forecast:
curl -s "wttr.in/Berlin"
The agent reads these instructions and uses bash to run the commands. No custom tools are registered.
Tier 2: HTTP Template Skills
Define API tools in the frontmatter tools array. Each tool becomes a callable tool for the agent with automatic HTTP execution.
Tool input fields support these types: string, number, boolean, object. Fields are required by default; set required: false to make them optional. Use enum for constrained values.
Request templates support three placeholder types:
| Placeholder | Source |
|---|---|
{{argName}} | Tool call arguments |
{{credential:fieldKey}} | Credential store values |
{{oauth2:accessToken}} | OAuth2 access token |
Placeholders work in the url, headers, and body fields. The method defaults to GET if omitted. Non-GET requests automatically receive a Content-Type: application/json header unless one is explicitly set.
HTTP tool responses are saved to the workspace's _temp/ directory as JSON or text files, with a summary returned to the agent.
Tier 3: Code-Based Skills
For full control, add an index.js file alongside SKILL.md. It must export a tools array:
export const tools = [
{
name: "my_custom_tool",
description: "Does something custom",
inputSchema: {
type: "object",
properties: {
input: { type: "string", description: "The input" },
},
required: ["input"],
},
async execute(args, context) {
// context.credentialStore -- access stored credentials
// context.skillName -- the skill's name
return { content: `Result: ${args.input}` };
// Return { content: "...", isError: true } for errors
},
},
];
Code tools are dynamically imported at runtime. They receive a context object with access to the credential store and skill name.
Credential Schema
Define required credentials in a credentials.json file:
{
"credentials": [
{
"id": "api",
"type": "api-key",
"name": "My API Key",
"description": "API key from example.com",
"fields": [
{
"key": "apiKey",
"label": "API Key",
"type": "secret",
"required": true,
"placeholder": "sk-..."
}
]
}
]
}
Field types: text, secret (masked input), url, email, model-select.
Credentials are stored with the key pattern skill.{skillName}.{credentialId}.{fieldKey}. The storeAs option overrides this prefix for sharing credentials across skills. The multiple flag enables named instances (e.g., multiple email accounts).
For OAuth2 credentials, add an oauth block instead of (or alongside) fields:
{
"id": "google",
"type": "oauth2",
"name": "Google Account",
"oauth": {
"authorizationUrl": "https://accounts.google.com/o/oauth2/v2/auth",
"tokenUrl": "https://oauth2.googleapis.com/token",
"scopes": ["https://www.googleapis.com/auth/gmail.modify"],
"refreshable": true
}
}
Installation Specs
The install array defines how to install required binaries. Each entry specifies a package manager and platform:
| Kind | Field | Description | Platforms |
|---|---|---|---|
brew | formula | Homebrew formula name | darwin, linux |
npm | package | npm global package | all |
go | module | Go module path | all |
uv | package | Python package via uv | all |
download | url | Direct binary download URL | varies |
winget | package | Windows Package Manager ID | win32 |
scoop | package | Scoop package name | win32 |
choco | package | Chocolatey package name | win32 |
Each spec can include:
bins-- Binaries provided by this install (for PATH verification).os-- Platforms this install option applies to. Omit for all platforms.label-- Human-readable label shown in the UI.id-- Unique identifier (auto-generated if omitted).
Install options are filtered by the current platform before being shown to the user.
OS Compatibility
Use the compatibility.os field to restrict a skill to specific platforms:
compatibility:
os:
- darwin # macOS
- linux
- win32 # Windows
If omitted, the skill is available on all platforms. If the current platform is not in the list, the skill is marked ineligible with a reason like "Requires OS: darwin (current: win32)".
Reference Documentation
Keep SKILL.md focused on core instructions. Place detailed API guides, examples, or reference material in a references/ subdirectory. Link to them from the skill body:
For detailed API examples, see `references/api-guide.md`.
Reference files are loaded on demand, minimizing token usage during normal operation.
Installing Skills from Git
Skills can be installed from Git repositories:
cortask skill install https://github.com/user/cortask-skill-name.git
The repository is cloned into the user skills directory. It must contain a SKILL.md file at the root. Installed Git skills are marked with a .origin file tracking the source URL.