# Skills (/agent/skills)

A skill is a written procedure the agent can load when it's relevant - how to cut a release, how to
add a migration, how this project wants a new endpoint wired up.

The agent always sees each skill's **name and one-line purpose**. It reads the full text only when a
task calls for it, so a large library of skills doesn't crowd the context window.

## Where they live [#where-they-live]

Skills come from three places. On a name collision the earlier one wins:

```
1. ~/.jan/projects/<slug>/skills/        project: this project only
   ├── release/
   │   └── SKILL.md                       # folder form, can bundle scripts alongside
   └── add-migration.md                   # flat form
2. ~/.jan/projects/<slug>/plugins/<P>/    plugin skills, always named <P>:<name>
3. ~/.jan/skills/                         user: every project on this machine
4. jan                                    built-in onboarding skill
```

Put a skill in `~/.jan/skills/` to use it from every project. A project skill with the same name
**shadows** the user one in that project. Plugin skills never collide, because they're always
qualified as `<plugin>:<name>`. A project or user skill named `jan` replaces the built-in one.

Run `/skills` in the console to see every skill with its scope. A skill hidden by a
higher-precedence one is marked `shadowed by project`.

Skill folders can be symlinks in either scope, for example
`~/.jan/skills/review -> ~/my-skills/review`. Jan follows them. If the same folder is reached twice,
it's listed once. Dangling links and symlink loops are skipped.

The folder form is what new and imported skills are written as, and it lets a skill ship helper
scripts or templates next to its instructions. The format matches the wider SKILL.md ecosystem, so
skills written elsewhere generally work here.

The model sees skills rebuilt from disk on every run. To refresh the `/` popup after adding, editing,
or deleting one mid-session, including a user skill, run `/reload skills`. It reports what was
added, removed, or changed.

## Writing one [#writing-one]

A skill is markdown with a name and a description:

```markdown
---
name: release
description: Cut and publish a release
---

# Cutting a release

1. Confirm `main` is green in CI.
2. Bump the version in `Cargo.toml` and `package.json` - they must match.
3. Update `CHANGELOG.md`; group by feat/fix/chore.
4. Tag `v<version>` and push the tag. CI does the rest.

Never publish from a dirty working tree.
```

Keep it concise. A skill competes for the same attention as everything else in the prompt.

You can write the file yourself, or ask the agent to:

```
Write a skill for how we cut releases, based on what you see in CHANGELOG.md and the CI config
```

`skill_write` writes to the project by default. Ask for a user skill ("save this as a user skill")
and the agent passes `scope: "user"`, which writes to `~/.jan/skills/<name>/SKILL.md`.

## Who can invoke a skill [#who-can-invoke-a-skill]

A skill has two invocation sides, and frontmatter closes either one:

- **User-invoked** - you type `/release` (or `/skill:release`) in the console, or pick it from the
  slash popup.
- **Model-invoked** - the agent sees the skill's `description` in its catalog and can fire it on
  its own by loading it with `skill_read`.

By default both sides are open. `user-invocable: false` hides a skill from you; `disable-model-invocation: true`
hides it from the agent. See [Skill Invocation](/agent/skill-invocation) for the full
mechanics, the trade-offs, and when to use which.

Skills can also be installed as [plugins](/agent/plugins) - whole skill collections cloned
from a git repo or picked from a marketplace, invocable under `<plugin>:<skill>` names.

## Tools [#tools]

| Tool | Approval |
| --- | --- |
| `skill_list` | No |
| `skill_read` | No |
| `skill_write` (`scope`: `project` default, or `user`) | No, unless denied in `[tools]` |

`skill_list` and `skill_read` cover every scope above, including plugin skills
(`skill_read` accepts `<plugin>:<name>`, or the plain name when it's unique).

## Controlling which are active [#controlling-which-are-active]

```toml
[skills]
enabled = []        # empty means all skills are enabled
```

`enabled` is a whitelist across every scope. It matches a plain name, a qualified
`<plugin>:<name>`, or a plugin name, which enables all of that plugin's skills. Every enabled skill's
name and purpose goes into the system prompt, and the body loads on demand.

<Callout type="info">
Older scaffolds had an `inject = "always" | "relevance"` key. It was never read, and Jan removes
it from your `agent.toml` the next time the agent starts.
</Callout>

<Callout type="info">
[Jan Desktop's Cowork surface](/desktop/cowork) (`nightly` channel only) keeps its own skill
store under `<data folder>/agent-workspace/skills`. It layers the attached folder's project skills on
top of that store. It doesn't read `~/.jan/skills` yet.
</Callout>

## Skills, AGENTS.md, and memory [#skills-agentsmd-and-memory]

Three places that shape behaviour, easily confused:

| | Scope | Loaded |
| --- | --- | --- |
| [`AGENTS.md`](/agent/project-config#agentsmd) | Rules for everything the agent does here | Always |
| Skills | A specific procedure | On demand, when relevant |
| [Memory](/agent/memory) | Facts the agent learned | Recalled as needed |

Rule of thumb: if it applies to every task, it belongs in `AGENTS.md`. If it applies to one kind of
task, make it a skill.
