Skills
Skills are folders of plain-text instructions the agent can call by name to do a specific task, each with its own instructions and its own limited set of allowed tools.
A skill is a folder of plain-text instructions that teaches the agent how to do a specific task, so you can extend what the agent can do without changing Fermix itself. Each skill is a directory containing a SKILL.md file with YAML-style frontmatter (a small settings block at the top of the file, between --- lines) and a system prompt body (the instructions handed to the model when the skill runs). A skill is not a provider-visible tool: it appears as a named entry in the runtime prompt’s skill catalog, and the agent invokes it only through the built-in skill tools (skill_view to read it, skill_run to delegate to it).
Skills differ from built-in tools in that they carry user-authored instructions and an explicit tool boundary, and they differ from plugins in that they contain no executable code, no manifest, and require no signing. A skill is plain text.
Discovery roots
The skill registry discovers skills from three roots on startup:
| Root | Path | Trust |
|---|---|---|
| Bundled | Inside the Fermix release (priv/skills) |
:operator |
| Local | ~/.fermix/skills |
:operator |
| Plugin | Skill dirs of enabled plugins | :guest |
Paths shown assume the default data directory; the local and plugin roots follow FERMIX_HOME if you have moved it (see Configuration).
Bundled and local skills are operator-trusted because the operator either installed Fermix (bundled) or placed the skill in their own directory (local). Plugin-loaded skills receive :guest trust, which restricts them to a read-only surface by default. Any skill path that does not resolve under one of the three known roots also falls back to :guest.
On a fresh install, the bundled skills are seeded into ~/.fermix/skills so they are immediately editable. Seeding runs only when the local skills directory is empty, so an existing install is never overwritten.
A skill that fails to load (bad frontmatter, missing name, name collision with an existing capability) is logged and skipped. The remaining skills load normally; discovery errors are never fatal.
SKILL.md format
Every skill directory must contain a SKILL.md file. The file opens with a YAML-style frontmatter block, followed by the skill’s system prompt in Markdown.
---
name: summarize_emails
description: Summarize unread emails in plain English.
allowed_tools: ["gmail_search_messages", "gmail_get_message"]
provider: anthropic
model: claude-sonnet-4-6
temperature: 0.3
max_iterations: 20
timeout_seconds: 120
---
# What this skill does
Summarize the user's unread emails concisely...
Recognized frontmatter keys:
| Key | Required | Description |
|---|---|---|
name |
Yes | Unique skill identifier: letters, digits, underscore, or hyphen, max 64 characters. Must not collide with any registered capability name. |
description |
Yes | One-line description shown in skill_list output and the runtime prompt catalog. |
allowed_tools |
No | JSON array of tool names available to the skill’s sub-agent (the separate agent run that executes the skill). [] means none; omitting the key inherits the trust-level default. |
policy |
No | Explicit capability-class override for the skill’s tool surface: any of read_only, read_write, exec, network, external_api. Desktop control (gui_control) can never be granted to a skill. |
provider |
No | Provider for the skill’s sub-agent run (a configured provider name such as anthropic or openai). When omitted, the run inherits the provider chain of the turn that invoked it. |
model |
No | Model override for the skill’s sub-agent run. A skill that pins provider/model runs only on that route, with no fallback. |
temperature |
No | Sampling temperature for the skill’s model call. |
max_iterations |
No | Iteration cap for the skill’s sub-agent loop (default 25). |
timeout_seconds |
No | Wall-clock timeout for a skill_run call (default 300 seconds). |
Unrecognized keys are ignored, but trust: is not one of them: a trust: line is rejected — the skill fails validation and is skipped at discovery, with a warning in the log naming it. Trust comes only from where the skill lives on disk (see Trust and tool boundaries); it can never be declared in frontmatter.
When a skill run times out, the external commands it spawned are terminated with it: each command Fermix runs is placed in its own OS process group, and Fermix kills the whole group — the command and every process it started — on timeout, on crash, and on daemon shutdown. A skill that shells out to python or node cannot leave orphaned subprocesses running.
The body after the closing --- is the system prompt. It is passed verbatim as the sub-agent’s system message when the skill is dispatched via skill_run. Keep the body under 64 KB (65,536 bytes): skill_view refuses to load anything larger, so the agent could no longer read the skill. Split long reference material into separate files inside the skill directory and point to them from the body.
Bundled skills
Fermix ships two bundled skills:
| Name | Description |
|---|---|
self-knowledge |
Describes Fermix’s own capabilities, agent loop, providers, channels, jobs, memory, sandbox, plugins, and configuration surfaces. |
browser-guidance |
Operating guidance for the browser tool: tool routing, the operating loop, action semantics, tab and ref hygiene, and stop conditions. |
Both are seeded into ~/.fermix/skills on a fresh install, so you can inspect or edit them locally.
Skill tools
Five built-in tools expose the skill surface to the agent:
| Tool | Description |
|---|---|
skill_list |
List installed skills with their names and descriptions. |
skill_view |
Show a skill’s full system prompt and metadata. |
skill_run |
Run a skill by name as a bounded sub-agent. Recursion depth is capped at 4. Every run writes a journal entry (a small record of how the run ended) under ~/.fermix/journals/. |
skill_create |
Scaffold a new skill under ~/.fermix/skills with a starter SKILL.md and an eval directory (evals are optional test cases that check the skill behaves as intended). |
skill_reload |
Re-scan all skill directories and refresh the running agent in place, reporting added, removed, and changed skill names plus any load errors. No daemon restart required (the daemon is the long-running Fermix background process). |
The CLI also provides fermix skills list, fermix skills view NAME, and fermix skills reload, each accepting --json for machine-readable output.
Creating a skill
Use skill_create from any chat channel or fermix ask:
{
"name": "summarize_emails",
"description": "Summarize unread emails in plain English."
}
skill_create accepts only name and description. It scaffolds ~/.fermix/skills/summarize_emails/SKILL.md (with allowed_tools: [] and a placeholder body) and a starter evals/evals.json file. Edit the SKILL.md to add your system prompt and adjust allowed_tools. You can also create the directory and SKILL.md manually without the tool.
After creating or editing a skill, run skill_reload (or fermix skills reload from the CLI) to pick up the change without restarting the daemon. The reload result doubles as validation: it lists added, removed, and changed skills plus a load error for any skill whose file failed to parse.
Picking up changes
Skill file changes do not apply automatically. To apply them:
- Edit
~/.fermix/skills/<name>/SKILL.md. - Run
skill_reload(in chat) orfermix skills reload(CLI) to refresh the registry in place. - Check the reload output: it reports added, removed, and changed skill names, and a load error for any skill that failed to parse (bad frontmatter, missing
name, name collision).
If you prefer a full restart: fermix restart. The registry re-scans all roots on restart and re-registers skills from scratch. A skill that collides with an existing capability name is skipped on every load attempt until the collision is resolved.
Trust and tool boundaries
The allowed_tools key is the primary confinement mechanism. It narrows the set of capabilities the skill’s sub-agent may call:
[]: the skill cannot call any tools.["browser", "web_fetch"]: the skill can only call those two tools.- Omitted: the skill inherits the trust-level default for its root (operator or guest).
Plugin skills load at :guest trust regardless of what allowed_tools specifies. A guest skill that names a tool outside the guest surface is rejected at run time, not silently granted. You cannot widen a plugin skill’s trust by editing its SKILL.md — the registry stamps trust from the skill’s on-disk location, never from its frontmatter.
Skill trust classifies where the skill file came from and bounds what its sub-agent may touch. It is separate from sender trust on a channel: skills are an operator surface, so a guest sender (someone authorized to chat but who is not the owner) sees no skill catalog and cannot run skills at all. See Ingress and trust.
When a skill is bound to a scheduled job via skill_name, the job’s own allowed_tools policy is intersected with the skill’s. Neither side can widen past the other.
Plugin skills
Plugins can ship their own skills inside the plugin package. A plugin’s skills are discovered only while the plugin is enabled, and they always load at :guest trust. Skills from catalog plugins you install live under the plugin’s directory in ~/.fermix/plugins; the bundled Google Workspace plugins (Gmail, Google Calendar, Google Drive) ship inside Fermix itself, and each carries a skill that documents its tool surface — the agent opens these with skill_view when dispatching work through those integrations.
Related pages
- Capabilities and tools: built-in tools including the skill tools
- Tool reference: full schema and failure modes for
skill_create,skill_list,skill_run,skill_view, andskill_reload - Scheduled jobs: binding a skill to a job with
skill_name - MCP: MCP tools (registered as
mcp_<server>_<tool>) available asallowed_toolsvalues