Skills inject domain-specific knowledge into the agent’s context. A skill is a markdown document with YAML frontmatter that gets included in the system prompt or per-turn context when its required capabilities are available.
Skill sources
Skills are discovered from multiple sources, in precedence order:
- Project (
.rkat/skills/) — highest precedence
- User (
~/.rkat/skills/)
- Git repositories — cloned to local cache, refreshed on TTL
- HTTP endpoints — fetched from remote skill servers
- Embedded (builtin skills from component crates)
A project skill with the same ID as a builtin skill overrides the builtin (first-source-wins).
Git sources
Configured in .rkat/skills.toml. Uses gitoxide (pure Rust, no git CLI dependency):
[[repositories]]
name = "company"
transport = "git"
url = "https://github.com/company/meerkat-skills.git"
git_ref = "main"
ref_type = "branch" # "branch", "tag", or "commit"
refresh_seconds = 300 # TTL for branch refs (tags/commits are immutable)
depth = 1 # shallow clone depth
# auth_token = "${GITHUB_TOKEN}" # optional, env vars expanded
HTTP sources
[[repositories]]
name = "remote"
transport = "http"
url = "https://skills.example.com/api"
# auth_bearer = "${SKILLS_API_KEY}"
cache_ttl_seconds = 300
Each skill is a markdown file with YAML frontmatter:
---
name: Shell Patterns
description: "Background job workflows: patterns and tips"
requires_capabilities: [builtins, shell]
---
# Shell Patterns
When running background jobs...
Frontmatter fields
| Field | Type | Required | Description |
|---|
name | String | Yes | Display name for the skill |
description | String | Yes | One-line description |
requires_capabilities | Vec<String> | No (default []) | Capability IDs that must be available |
The frontmatter is delimited by --- markers. The body (everything after the closing ---) is stored as the skill’s body field.
Capability gating
Skills are filtered by their requires_capabilities field before being shown or injected:
- A skill is included only if all its required capabilities are available in the current build/config.
- A skill with an empty
requires_capabilities list is always available.
Skill resolution
The resolver supports two reference formats:
- Slash-prefix ID:
/skill-id — matches against SkillDescriptor.id.
- Exact name match (case-insensitive):
"Shell Patterns" or "shell patterns" — matches against SkillDescriptor.name.
Resolution returns SkillError::NotFound if no match, or SkillError::Ambiguous if multiple skills match.
Resolution mode:
| Mode | Behavior |
|---|
Explicit | Only explicit /skill-id or exact name matches |
Rendering
The renderer produces two output formats:
Inventory section
Injection block
Generates a ## Available Skills section listing all available skills for the system prompt:## Available Skills
- `/task-workflow` -- How to use task_create/task_update/task_list for structured work tracking
- `/shell-patterns` -- Background job patterns with shell and job management tools
This section is injected into the system prompt via the extra_sections parameter of assemble_system_prompt() in meerkat/src/prompt_assembly.rs. Wraps the skill body in XML-style tags for per-turn injection:<skill name="Shell Patterns">
# Shell Patterns
When running background jobs...
</skill>
Size limits
MAX_INJECTION_BYTES is set to 32 KiB (32 * 1024 bytes). If an injection block exceeds this limit, it is truncated with a warning log.
Built-in skills
The following skills are embedded in component crates:
| ID | Name | Crate | Required capabilities |
|---|
hook-authoring | Hook Authoring | meerkat-hooks | hooks |
shell-patterns | Shell Patterns | meerkat-tools | builtins, shell |
task-workflow | Task Workflow | meerkat-tools | builtins |
sub-agent-orchestration | Sub-Agent Orchestration | meerkat-tools | sub_agents |
mcp-server-setup | MCP Server Setup | meerkat-mcp | (none) |
memory-retrieval | Memory Retrieval | meerkat-memory | memory_store |
session-management | Session Management | meerkat-session | session_store |
multi-agent-comms | Multi-Agent Comms | meerkat-comms | comms |
Configuration reference
| Setting | Default | Description |
|---|
skills.enabled | true | Enable skill loading |
skills.max_injection_bytes | 32768 (32 KiB) | Maximum size of injected skill content |
skills.inventory_threshold | 12 | Flat listing below, collection mode above |
Custom skills
Create a subdirectory under .rkat/skills/ with a SKILL.md file:.rkat/skills/
my-deployment/
SKILL.md
Example .rkat/skills/my-deployment/SKILL.md:---
name: Deployment Guide
description: Project-specific deployment procedures
requires_capabilities: []
---
# Deployment Guide
1. Run `make build` to create the release binary.
2. Deploy via `./deploy.sh production`.
Same structure under ~/.rkat/skills/. These are available across all projects but have lower precedence than project-level skills.
When skills are active and builtins are enabled, two tools are registered:
| Tool | Description |
|---|
browse_skills | List skill collections and search by name/description |
load_skill | Load a skill’s full instructions into the conversation |
In collection mode (when there are more than 12 skills), the system prompt shows collection summaries. The LLM can use browse_skills to explore collections and load_skill to activate specific skills.
Invoking skills
Skills can be activated in three ways:
1. Slash reference in user message
Include /skill-id at the start of a message:
/extraction/email Extract the sender from this email
The agent detects the reference, resolves the skill, and injects its body before running the LLM.
2. Programmatic skill_references (per-turn)
Pass skill_references in the API request to resolve and inject skills for a specific turn:
{
"method": "turn/start",
"params": {
"session_id": "...",
"prompt": "Extract emails from this text",
"skill_references": ["extraction/email"]
}
}
3. Preloading at session creation
Pass preload_skills to inject skills into the system prompt at session creation:
{
"method": "session/create",
"params": {
"prompt": "Hello!",
"preload_skills": ["extraction/email", "formatting/markdown"]
}
}
See the Python SDK and TypeScript SDK for SDK wrappers.
Configuration
Skills are configured in .rkat/skills.toml with user/project layering:
# ~/.config/rkat/skills.toml (user) or .rkat/skills.toml (project)
enabled = true
max_injection_bytes = 32768 # max size of injected skill content
inventory_threshold = 12 # flat listing below, collection mode above
[[repositories]]
name = "company"
transport = "git"
url = "https://github.com/company/skills.git"
Project settings override user settings when the project file exists. Repositories are merged (project repos take precedence over user repos with the same name).