Mistral Vibe · Code mode · Free reference
Mistral Vibe, on one page
Where skills load from, the four ways one fails without telling you, and the field that decides whether the agent ever opens it.
Nothing here is gated and nothing here is a download. Every claim about how skills load was read out of the installed Vibe 2.5.0 source on 20 September 2026, with the file and line beside it so you can check it rather than believe me. Behaviour described without a citation is guidance, not a source claim. A later version can make any of this wrong: the version is the ruler, and it is printed for that reason.
First: which Vibe are you in?
Vibe is three surfaces, and they do not share a skills system. Code is the CLI, the VS Code extension and remote sessions. Work is the web and mobile app, where Skills, Projects and scheduled tasks live. Chat is the turn-based tab carrying the old Le Chat features forward.
This page is Code. Everything below describes a skill as a directory on disk holding a SKILL.md, found by the CLI when it starts. Work Skills are built and stored inside the Work app instead, so none of the four failures below are failures you can hit there. If you are clicking in a browser rather than typing in a terminal, you are in Work, and this is the wrong page for you. Mistral documents the split here, checked 20 September 2026.
Where a skill can live
A skill is a directory holding a SKILL.md file. Three places are searched, and two of them are conditional.
| Path | Scope | Loads when |
|---|---|---|
| ~/.vibe/skills/ | User level | Always loaded. No trust check. Skills here follow you into every project on the machine. |
| ./.agents/skills/ | Project level | Trusted folders only. The portable Agent Skills location. Shared with other agents that adopt the spec. |
| ./.vibe/skills/ | Project level | Trusted folders only. The Vibe-specific location. Same trust requirement as .agents/skills. |
The trust check applies to the two project paths. A folder becomes trusted on first run, or by its entry in ~/.vibe/trusted_folders.toml, and the check walks up the parent directories. Clone a repository with skills in it into an untrusted folder and none of them load. The user-level path has no such gate, which is the asymmetry most people trip over when a skill works at home and not in the repo.
The four silent failures
Every one of these produces the same symptom: the skill is there, and the agent behaves as though it is not. None of them prints anything you will notice.
You nested the folder
The skill is on disk. It never appears.
Discovery lists the children of the skills directory once and looks for SKILL.md in each. It does not descend. A skill at .agents/skills/python/testing/SKILL.md is invisible, because python is a directory without a SKILL.md of its own.
Fix: Keep the tree flat. One directory per skill, SKILL.md directly inside it.
core/skills/manager.py:89-92
One capital letter in the name
The skill is on disk, correctly nested. It never appears.
The name field is validated against ^[a-z0-9]+(-[a-z0-9]+)*$ with a 64 character limit. PDF-Review fails. pdf_review fails. pdf-review loads.
Fix: Lower case, digits and single hyphens only. No underscores, no spaces, no leading or trailing hyphen.
core/skills/models.py:15-16
Nothing tells you it broke
A malformed skill behaves exactly like a skill you never wrote.
The loader catches Exception, writes a warning to the logger and returns None. That warning goes to a rotating log file, not to your terminal, and the default level is WARNING, so the session starts looking completely normal. No count of what loaded or what was skipped is emitted anywhere.
Fix: Do not read the absence of an error as success. Ask the agent to list the skills it can see and compare that list to your directory, or read ~/.vibe/logs/vibe.log.
core/skills/manager.py:102-104 with core/logger.py:40-50
Two skills, same name
A skill that worked yesterday quietly does something else today.
Names are one flat namespace across every search path, and the paths are searched in a fixed order: configured paths, then project, then user. First loaded wins. So a project skill shadows your personal one of the same name, and the personal version you have relied on for months stops being the one that runs the moment you cd into that repo. The skip is recorded with logger.debug, which sits below the default WARNING threshold, so by default it is not even written to the log file.
Fix: Namespace your own skills with a prefix. A collision costs an afternoon and a prefix costs nothing.
core/skills/manager.py:59-85
What the agent sees before it picks a skill
This is the part that changes how you write one. At session start the model is given three fields per skill, and the body of your SKILL.md is not among them:
<available_skills>
<skill>
<name>pdf-review</name>
<description>...</description>
<path>/path/to/SKILL.md</path>
</skill>
</available_skills>core/system_prompt.py:206-229
The instruction above that block tells the model to read the full SKILL.md file when a task matches a skill's description. The model does see the name and the path too, and it has the user's request in front of it. But the description is the only field you control that carries any meaning, it is capped at 1,024 characters, and the body is not loaded until after the choice is made. A skill with a beautiful body and a vague description will sit there unused for months.
Write the trigger, not the title
Weak: "Helps with code review." Nothing in that sentence matches a request a person would actually type.
Works: "Review a Python diff for missing error handling, untested branches and unsafe subprocess calls. Use when asked to review, critique or check a change before merge." It names the artefact, the checks and the words that trigger it.
Two things to know before you port a workflow
- There is a middleware pipeline, and you cannot reach it from config. Vibe 2.5.0 has a real interception layer: a ConversationMiddleware protocol with a before_turn method, a MiddlewarePipeline you can add to, and built-in members that cap turns, cap spend, auto-compact and enforce the read-only agent. What it does not have is a route into that pipeline from config.toml or from a skill. It is instantiated in Python, in the agent loop. So if you are porting a workflow whose policy lives in declarative pre-tool or post-tool hooks, that part does not port as configuration. Express the constraint with allowed-tools in the skill frontmatter and with the agent profile instead, or write Python.core/middleware.py:43-208, core/agent_loop.py:178
- There is no load report. The discovery routine returns a dictionary and emits no found, loaded or skipped summary. The number of skills you think are active is a number you have to verify yourself.core/skills/manager.py:69-85
How to actually see what happened
Logging is a rotating file handler writing to ~/.vibe/logs/vibe.log, and the default level is WARNING, so parse failures land there and duplicate skips do not land at all. Set LOG_LEVEL=DEBUG, start a session, and read the file. That is the only place the loader tells you the truth.core/logger.py:32-55, core/paths/_vibe_home.py:33
Skills, agents and prompts you can copy
Three public libraries, free, no account. They are laid out the way this page says to lay them out, which is the only reason they load.
awesome-mistral-vibe-skills
Skills in the flat layout Vibe actually discovers, with names that pass validation.
awesome-mistral-vibe-agents
Agent profiles as .vibe/agents TOML, with the permission posture written down.
awesome-mistral-vibe-prompts
Prompts that survive being handed to a coding agent instead of a chat window.
Kesslernity is where the deployment work gets written down, whichever assistant your organisation ended up with. The store is mostly Microsoft 365 Copilot today because that is what most enterprises are rolling out. The method is not.