Skills
Use skills to load reusable instructions and supporting resources into a session. This guide covers using skills,
Use skills to load reusable instructions and supporting resources into a session. This guide covers using skills, authoring their metadata and activation rules, and configuring optional validators.
Get started
Create a project skill from the project root, then start a new session so its automatic activation pool includes it:
mkdir -p .agents/skills/project-review
cat > .agents/skills/project-review/SKILL.md <<'EOF'
---
name: project-review
description: Review project changes with explicit evidence and validation limits.
domains: developer
rules:
- content(review)
---
Report each finding with its file path, the observed behavior, and the smallest correction.
Separate source inspection from checks you actually ran. Do not claim a test passed without its result.
EOF
octomind run developer:generalActivate it manually, or send a fresh request such as Review the current changes and report concrete findings.:
/skill
/skill project-reviewTyping /skill project-review again toggles it off. Manual activation does not require matching domains or rules.
How Skills Work
A skill is a directory containing a SKILL.md file (frontmatter metadata + instruction body). When activated, the
skill’s instruction body is injected into the session context, giving the AI domain-specific knowledge.
New to taps? Skills are most commonly distributed via taps. See Tap System for how to add one (for example, register your local tap with
octomind tap myorg/my-skills ./my-skills) before any tap skill becomes available.
Skill Locations
Octomind discovers skills in this order, with first-wins deduplication by frontmatter name:
- Taps (highest priority) —
<tap>/skills/<name>/SKILL.md - Project universal dir —
<workdir>/.agents/skills/<name>/SKILL.md - Global universal dir —
~/.config/agents/skills/<name>/SKILL.md - Agent plugins — skills below discovered plugin roots (
plugins/<plugin>/skills/<name>/SKILL.md) - Generated evolution skills — eligible machine-local trial/active artifacts, always lowest authority
A skill pack in either universal directory works without a tap. Plugin skills support listing and manual/env loading, but the automatic activation pool currently scans taps, universal directories, and generated bindings only.
Configuration
The shipped template provides this required [skills] section. All five fields are required in the resolved
configuration; edit the existing section rather than replacing the whole config with a partial snippet:
[skills]
auto_activation = true # enable/disable auto-activation via declarative rules
auto_validation = false # enable/disable auto-validation via validate scripts (default: false)
activation_timeout = 3 # reserved (rules are in-process, no timeout needed)
validation_timeout = 60 # seconds per script; 0 uses a one-hour timeout
max_retries = 3 # per-skill failure cap; 0 disables the capActivate skills
1. Environment variable — preload skills at session start:
OCTOMIND_SKILLS=project-review octomind run developer:general2. Auto-activation — skills with declarative rules: in frontmatter activate based on project context (e.g.,
Cargo.toml detected, user mentions "rust"). Auto-activation requires both a non-empty rules: list and a
domains: entry matching the current agent's role — rules: alone is not enough (skills without a matching domain are
never placed in the activation pool). Automatic user-input activation skips already-active skills; the runtime
capability intent path can also evaluate skill rules.
3. Manual — via the /skill command or the skill MCP tool:
/skill project-reviewFor the AI-facing skill MCP tool, use this arguments object:
{"action":"use","name":"project-review"}Skill Directory Structure
<name>/
SKILL.md # Required: metadata (frontmatter) + instructions (body)
validate # Optional: validation script (exit 0 = valid, stderr = error)
scripts/ # Optional: executable scripts the skill references
references/ # Optional: supplementary documentation
assets/ # Optional: templates, config files, resourcesWhen a skill is activated, immediate files in scripts/, references/, and assets/ (not nested descendants) are
listed (with their absolute paths) in a ## Skill Resources section appended to the injected skill block, so the AI can
open them on demand via shell/view.
SKILL.md Format
Frontmatter
---
name: programming-rust
description: "Rust conventions, idiomatic patterns, and cargo tooling. Auto-activates in Rust projects."
license: Apache-2.0
compatibility: "Requires cargo and rustc."
domains: developer
allowed-tools: shell text_editor
rules:
- file(Cargo.toml)
- content(rust)
- content(rust) file(Cargo.toml)
---Octomind's parser reads exactly these keys: name, description, compatibility, license, allowed-tools,
capabilities, domains, and rules. Any other key (including the AgentSkills-spec title) is silently ignored —
adding it does nothing. The skill is loaded only if both name and description are present; if either is missing,
the skill is skipped entirely.
| Field | Required | Description |
|---|---|---|
name | yes | Use a lowercase hyphenated name by convention. Used as the skill identifier. Must equal the directory name to be activatable by name (use/forget/auto-activation look up skills/<name>/ and verify the frontmatter name matches). The /skill and skill list views use the frontmatter name regardless of directory. |
description | yes | What the skill does and when to use it. |
capabilities | no | Capabilities to auto-load when skill activates. Space-delimited or ["git", "memory"]. |
domains | no | Agent categories for auto-activation scoping. Without this, skill is manual-only. |
allowed-tools | no | Space-delimited expected tool names, not permission grants. The MCP skill list/use results warn about missing tools; the slash-command list does not show that compatibility warning. |
license | no | License name (e.g., Apache-2.0). |
compatibility | no | Free-text environment requirements (shown by the MCP skill list). |
rules | no | Declarative activation rules. Each - line is an OR-group; space-separated checks within a line are AND. Empty = manual-only. |
The parser is a small line-oriented frontmatter reader, not a general YAML loader. Keep metadata on one line; use
space-separated values or inline arrays for domains and capabilities. Avoid inline comments on values: domains: developer # review would include extra domain tokens. Unknown keys are ignored; name/description lengths and naming
conventions are not validated.
Body
The body after frontmatter contains the instructions, as in the complete project-review example above. Keep actions
concrete and put longer supporting material in references/ for the agent to read when needed.
Declarative Activation Rules
The rules: field in SKILL.md frontmatter defines when a skill should auto-activate. Rules are evaluated in-process (no
script spawning) on each fresh user message that carries enough intent (see Activation Gating
below).
Logic
- Each
-line is an OR-group — if any group matches, the skill activates. - Space-separated checks within a line are AND — all must match for the group to activate.
- Empty
rules:(or omitted) = manual-only skill.
rules:
- content(rust) file(Cargo.toml)
- content(cargo) bin(cargo)Check Types
| Check | Syntax | Description |
|---|---|---|
file | file(pattern) | File or glob exists in working directory. Example: file(Cargo.toml), file(*.go) |
content | content(word) | Case-insensitive word-boundary match against user message. Example: content(rust) matches "rust" but not "thrust" |
grep | grep(pattern) or grep(pattern, glob) | Search file contents in working directory (respects .gitignore). Example: grep(fn main), grep(fn main, *.rs) |
env | env(VAR) or env(VAR=val) | Environment variable is set and non-empty, or equals a specific value. Example: env(CI), env(CI=true) |
match | match(regex) | Regex match against user message content. Example: match(\brust\b) |
bin | bin(name) | Executable is findable on PATH using the platform lookup rules. Example: bin(cargo), bin(node) |
session | session(pattern) | Case-insensitive substring match on current session name. Example: session(octomind) matches "260421-octomind-a1b2" |
workdir | workdir(pattern) | Case-insensitive substring match on working directory path. Example: workdir(rust) matches "/home/dev/rust-project" |
semantic | semantic(phrase) or semantic(phrase, threshold) | Local embedding cosine match of phrase against the user message (via muvon/octomind-embed). Fires when cosine ≥ threshold (default 0.45). Example: semantic(deploying to production) can match paraphrases when their computed score reaches the threshold. |
Evaluation Context
file,grep,workdir— evaluated against the project working directory.content,match,semantic— evaluated against the user's message text.env— evaluated against environment variables.bin— evaluated against the system PATH.session— evaluated against the current session name.- Already-active skills are skipped.
Activation Gating
Auto-activation does not run on every message — it is gated to avoid expensive false-positive MCP server loads:
- Intent gate — the user message must have at least 8 non-whitespace characters (after XML stripping). Short
acknowledgments like
try,ok,do it, orfix bugnever trigger any skill (or capability) auto-activation. - XML-block stripping —
<tag>...</tag>blocks (injected<skill>content,<validation>feedback, log pastes, system tags) are removed from the message before anycontent/match/semanticevaluation, so injected context cannot trigger false positives. - Semantic abstain-on-tie — when every matching rule group contains a
semantic(...)check, it must win by a margin of 0.08 cosine over the next-best semantic candidate across the activation pool; if two skills are near-tied, neither activates. A matching group containing no semantic check bypasses this margin gate; addingfile(...)to a semantic group does not bypass it.semanticchecks evaluate tofalsewhen the embedding model isn't ready.
Domain Scoping
The domains field limits which agents evaluate this skill's rules:
domains: developer devops- Matching uses the role base before
::developer:generalmatchesdomains: developer.domains: "*"matches any domain - Reduces the activation pool to relevant skills only
- Skills without
domainsare manual-only (backward compatible)
Environment Variable: OCTOMIND_SKILLS
Preload skills at session start. Values are comma-delimited exact skill names:
export OCTOMIND_SKILLS=project-review
octomind run developer:general- Skills are loaded at startup and marked as env-loaded; successful
/donecompression omits their injected blocks, while automatic compression preserves active skill blocks - Declarative rules are not evaluated for env-loaded skills
- Each name is validated against available skills across all locations (taps and the universal
.agents/skills/~/.config/agents/skillsdirs) - Unknown skill names are skipped with a warning
- No alias, substring, glob, or semantic lookup is applied to
OCTOMIND_SKILLS - Already-active skills are not re-injected
Validate Script
An optional executable script at <tap>/skills/<name>/validate checks the assistant response. Automatic validation
currently searches tap directories only: a validator in a universal directory or plugin is not run by this path. Enable
[skills].auto_validation to use it.
Protocol:
- Runs only on the final assistant message (end of turn)
- On Unix the script must be executable; Windows routes scripts through Git Bash
argv[1]="assistant"(always — the script receives the assistant's response)stdin= the assistant message content- Runs in the project working directory
- exit 0 = output is valid (also resets the per-skill retry counter)
- failure (retry + LLM feedback) requires non-zero exit AND non-empty captured output. The captured output is
stderr, or stdout when stderr is empty. A non-zero exit that produces no stderr/stdout output yields no feedback
and does not increment the retry counter — so don't write a silent
exit 1and expect the model to be corrected.
For example, in a local tap you own, install this validator for project-review. It checks that the response states its
validation limits and emits actionable feedback on failure:
mkdir -p my-skills/skills/project-review
cp .agents/skills/project-review/SKILL.md my-skills/skills/project-review/SKILL.md
cat > my-skills/skills/project-review/validate <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
if grep -qi 'validation' ; then
exit 0
fi
printf '%s\n' 'Include a validation statement saying what you inspected or ran.' >&2
exit 1
EOF
chmod +x my-skills/skills/project-review/validate
octomind tap myorg/my-skills ./my-skillsEnable validation in the existing config and start a new session:
[skills]
auto_validation = trueOCTOMIND_SKILLS=project-review octomind run developer:generalThe model gets another turn to fix the issue. Retries are capped by max_retries in [skills] config.
Capabilities Auto-Loading
When a skill declares capability names from your installed taps, for example:
capabilities: git memoryActivation then:
- Resolves the named capabilities and selected provider files from taps.
- Skips capabilities with missing required environment variables while still activating the skill body.
- Enables backing servers and records the servers loaded by the skill for later release.
Forgetting a skill decrements those server references. A shared server is disabled/removed when the last tracked
reference is released. This is separate from the capability tool’s four-entry LRU and does not run its domain gate or
dependency-only activation path. Plugin skills can also load the plugin’s mcp.json servers.
For installed memory/codesearch capabilities with these provider files, override the provider in config:
[capabilities]
memory = "octobrain"
codesearch = "octocode"For capability metadata, semantic routing, tap-qualified references, and OCTOMIND_CAPABILITIES, see Token
efficiency.
/skill Command
List or toggle skills interactively during a session:
| Command | Effect |
|---|---|
/skill | List active skills first, then alphabetical; 15 per page |
/skill 2 | Show page two, if present |
/skill *review* | Filter names/descriptions by a case-insensitive * pattern |
/skill project-review | Toggle the exact skill name |
/skill
/skill *review*
/skill project-reviewTab completion suggests available skill names after /skill .
skill MCP tool
The AI-facing skill tool exposes three actions: list, use, and forget. The list action accepts optional
pattern (substring filter on name/description), offset, and limit (default 20) parameters for pagination. Pass
one of these argument objects to the skill tool:
{"action":"list","pattern":"review","offset":0,"limit":20}{"action":"forget","name":"project-review"}Authoring Checklist
There is no shipped lint tool. When authoring a skill, verify by hand:
SKILL.mdhas valid frontmatter with bothnameanddescription(missing either silently drops the skill).- The frontmatter
namematches the skill's directory name (required foruse/forget/auto-activation). - If you ship a
validatescript, make it executable (chmod +x) — a non-executable script fails to spawn at end-of-turn. - A
validatescript that should correct the model must exit non-zero and write to stderr/stdout; a silentexit 1produces no feedback.
Common questions
Why did my rule not activate? Check that the skill is in a supported automatic location, its name matches the
directory, and its domains contain the role base or *. Restart after adding a skill, and send a request with at least
eight non-whitespace characters. Use /skill project-review to test manual loading independently.
Why did validation not run? It is disabled by default and the runner searches taps only. Check the executable bit on
Unix. validation_timeout = 0 means one hour in the current implementation, not an unlimited wait. Timeouts and spawn
errors are debug-logged; they do not generate model repair feedback.
/loglevel debug
/skill
Review the current changes and include a validation statement.
/loglevel infoWhy are tools missing after activation? allowed-tools does not install or authorize tools. Capability loading can
fail or skip missing required environment variables while the skill body still activates. Inspect the AI-facing skill
list/use result and your installed capability configuration.
Source reference
| Surface | Source |
|---|---|
| Metadata, discovery, and tool actions | src/mcp/runtime/skill.rs |
| Activation, env loading, and validators | src/mcp/runtime/skill_auto.rs |
| Slash command | src/session/chat/session/commands/skill.rs |
| Defaults and configuration | config-templates/default.toml, src/config/mod.rs |
| Compression boundary | src/session/chat/conversation_compression/mod.rs |