Skills, commands and the merge: one mechanism, two names
Custom commands and skills are one mechanism now — a reusable procedure in a file. What merged, what didn't, and the axis that still matters: who invokes it.
The two names you keep tripping over
You created /deploy earlier, now your teammate calls it a "skill", the docs are confusing, the first tutorial says .claude/commands/, the newer one says .claude/skills/, and you're not sure if the file is still working.
The old file works and they're both a thing. Custom slash commands and skills were separate things at the beginning but naturally got merged into one thing which is — a procedure saved in a file that you can load in your session when needed, and the word "command" or "skill" is just a reflection of what docs you have read and when.
What actually merged
They've been merged.
At the beginning:
Custom command — was a prompt stored in a file. You were writing a set of instructions once and saving it in a file and invoking it using
/nameinstead of typing it, was user-initiated (no automatic invocation)Skill — was a bundle of a capability. A set of instructions with the option to include some files that the agent can load in a session when they think that's needed for a task
And then:
Custom command got a description which the model could understand so now there was an entry point from the model's perspective as well
Skill got a name which you can type so also an entry point from your perspective
So — two things at the beginning and they both became the same thing which is a procedure saved in a file that you can load in your session when needed. You can think about it as a command if you want or as a skill if you want, the word is just useful for communication between humans, doesn't matter which tool you use.
As an example:
The old file and the new file behave the same. Anthropic put it flatly in their docs: "Custom commands have been merged into skills. A file at
.claude/commands/deploy.mdand a skill at.claude/skills/deploy/SKILL.mdboth create/deployand work the same way."In Claude Code you can watch the seam in the flags — the
--disable-slash-commandsswitch describes itself as "Disable all skills", a single toggle for a single feature
This is how it looks across different tools:
Claude Code — supports both paths, the old file still works
Codex — has deprecated their previous custom prompt format and routes everything through skills
Cursor — in the middle of a migration process with a
/migrate-to-skillscommand to help you
Even though they're different in terms of implementation they all aim for the same thing which is skills.
The axis that still matters: who invokes it
There's one more difference which is not about the name but who can trigger it. There are two ways:
User-initiated — you type
/name, that's a gate which is closed until you type it and then it's opened onceModel-initiated — the model reads the description and decides that the time has come so they open it
That's what makes a difference between a "command" and a "skill", for example if you have /goals it basically forces the agent to state the goal before they act but it depends when you type it. Whereas if you have a skill, like a "goal-setting skill", the model can read that it's sth that sets the goals so they can invoke it when they think it's appropriate.
But it's usually good to keep things which are gates on your side (the user), like safety measures for example, if you were to make them model-initiated the model could open them in a wrong moment and defeat their purpose. On the other hand — if you have some procedures that are about sharing knowledge like migration conventions or PR description format it might make sense to make them model-initiated.
In most of the tools it's as simple as setting one frontmatter field, like disable-model-invocation. So it comes down to a design decision, not to a name.
SKILL.md became an open standard
The file standardised too — a skill is a SKILL.md which is a markdown file with a brief frontmatter and an Agent Skills open standard behind it (agentskills.io) which is referenced in the docs of Claude Code, Cursor and Gemini.
That's a really big thing as having such a standard lets you have a single place for all your skills which is .agents/skills/, so that they're available in Codex, Copilot, Cursor, Gemini and Kimi.
Just to give you some more context — Copilot and Cursor both read Claude Code's .claude/skills/, and Cursor also reads Codex's .codex/skills/. Write it once, multiple tools can consume it.
Not everything is standardised yet though, as every tool created their own command format at the beginning (Cursor's .cursor/commands/*.md or Gemini's ~/.gemini/commands/*.toml). Those are tool-specific and not portable, only skills are a thing that can travel. But that's the landscape — some local commands and the standardised skills everyone migrated to.
So this is how it actually looks behind the scenes, a single thing with two names (a command and a skill) which is:
A per-tool local command in a tool-specific format
And the standardised skill which everyone moved to
Where your tool keeps these, and what it calls them, is next.
In Claude Code
Skills are defined in the .claude/skills/<name>/SKILL.md files. The folder name is used as the invocation name so the deploy folder becomes /deploy. You can place skills either:
In the project's
.claude/skills/directory, to make them available to everybody who works with the projectIn your home
~/.claude/skills/to use them just for yourself
The old .claude/commands/deploy.md file still works — it does /deploy, just like the new version, so there are no compatibility issues, both approaches are identical. If you want to turn some command into a skill for the purpose of having a separate file with frontmatter (and possibly other files, next to the instructions), you move it into the .claude/skills/ directory.
You can make the new skill available only to the user by adding disable-model-invocation: true to its frontmatter. If that flag is set — it means the user is the only one who can run it, and its description stays out of context until they do. If you don't have it (or remove it) — Claude might invoke it on its own accord, if it thinks it's sensible. Generally — if it's some safety checkpoint, put it behind that gate (disable-model-invocation), if it's some general piece of knowledge that might be useful, let Claude know about it and make it model-invocable.
Lastly, just FYI — these skills are not Claude-specific, they're following the Agent Skills standard so they can be used with Copilot or Cursor; in fact both of them read the .claude/skills/ directory so you can have the same file in there and use it with all of them.
In Codex CLI
What Codex calls "skills" is a folder with a SKILL.md file inside it (with name and description in its frontmatter). The engine finds skills by walking up from the current working directory to the root of the repository looking for .agents/skills/, then the same from the user's home dir looking for ~/.agents/skills/ etc. There are also admin and bundled locations behind those.
You can't run a skill directly via the CLI (as in, there's no codex skill subcommand), you need to pick one from the /skills menu or type $ and reference its name. Codex might even choose a skill on its own if it finds a task that matches the description of some skill.
Codex is deprecating the previous mechanisms in favour of skills — custom prompts (Markdown files in ~/.codex/prompts/) with /prompts:<name> are being redirected to skills in the docs. All the plugin-provided commands are getting automatically converted into skills on install too, so moving forward, skills is the only way.
Just keep in mind:
If you have skills with identical names, they won't get merged in the picker — they'll both show up, so you'll need to use different names
Codex reloads skills live, but if a new skill isn't showing up, restart
There's also
/import, which pulls commands, MCP servers and settings across from Claude Code and Cursor
In GitHub Copilot CLI
This is how GitHub Copilot CLI handles the feature, it calls them skills and they are defined in SKILL.md files. You can manage them with the copilot skill subcommand (add, list, remove) or with /skills during a session.
The main thing about them is that the CLI searches for them in multiple places:
.github/skills/.agents/skills/.claude/skills/~/.agents/skills/~/.copilot/skills/
so anything you put there is found and used by it.
In terms of usage, it's not like that whenever you type the skill name it does something; once a new skill is added to the list, it can be utilised automatically. You can list the loaded skills with /env during a session and manage them with copilot skill or /skills.
If you already have Copilot for your organisation, the broadest surface to utilise skills for your teammates is .agents/skills/, because it's a tool that most of them are using anyway (Copilot CLI), and the skills put there can be easily used in other tools as well, as they read this directory.
In Cursor
Cursor's currently in the middle of a transition so both are visible. The first part is the older one — the command — which you define in a Markdown file under .cursor/commands and call by typing /name in the Agent, whereas the second part is the skill (which is what the current docs lead with) that's defined in a SKILL.md file with YAML frontmatter in either of those locations: .agents/skills or .cursor/skills, and can be called by typing /skill-name or @skill-name. The skills are also picked up from other tools' skills folders, like .claude/skills (from Claude Code) and .codex/skills (from Codex). Just to remember — there are two separate .cursor folders in terms of how the files are triggered:
commands + skills — these are called deliberately by the user
rules (
.cursor/rules,.mdcfiles) — these are getting fired automatically, either because they're constantly active or because they're picked by a glob pattern or by the agent
If you create an .md file under .cursor/rules, it'll get ignored unless you add the .mdc frontmatter, so it's important to remember about that. If you run the bundled /migrate-to-skills command, it'll transform your slash commands into skills and set disable-model-invocation: true for them, locking them to user invocation; the documentation suggests the CLI is able to consume .cursor/rules, but doesn't say anything about custom commands or user skills from there so treat those as editor-only for now.
In Gemini CLI
We can say there are two "things" in Gemini CLI — custom commands and skills. The custom commands are defined by TOML files stored either in the global folder ~/.gemini/commands or in .gemini/commands for every project, they must have a prompt field and (optionally) a description field and use the {{args}} placeholder to capture what follows after the command name; by creating nested directories you create namespaces, so you can invoke a file placed in ~/.gemini/commands/git/commit.toml as /git:commit. The skills are defined using SKILL.md files located in ~/.gemini/skills or in ~/.agents/skills for the platform-agnostic part of the standard, which Gemini's docs describe as the Agent Skills open standard (agentskills.io).
But for everything to work we need to resolve the platform-split first: as of 18th of June 2026 Gemini CLI doesn't serve Google AI Pro, Ultra or free versions anymore, so these users moved to Antigravity CLI. It now keeps running only for Google Cloud and paid Gemini or Gemini Enterprise Agent Platform API keys, which means that if you use it you can have the ~/.gemini/commands folder and if you use Antigravity — you don't; also these tools are not compatible with each other.
The thing is that in Antigravity there's no notion of TOML-based "custom commands" at all, it just has skills, and in this tool /name maps to a SKILL.md, so the only thing that carries across is the content of ~/.agents/skills and every file in ~/.gemini/commands needs to be converted into a skill.
In Kimi Code CLI
Kimi Code CLI calls these "skills", and you can define them as SKILL.md files inside their own folders or even as single .md files. These are auto-detected in the following locations:
project:
.kimi-code/skills/project:
.agents/skills/user:
~/.kimi-code/skills/user:
~/.agents/skills/
If you set --skills-dir it points to another location for a single run.
You can either call them with /skill:<name> followed by the task — /skill:git-commits fix the login race — or the model chooses a skill (which is actually just as first-class as running /skill) by looking at the best description and whenToUse for a given task; if you set disableModelInvocation, which is the same across the tools, then it leaves only the first option.
.agents/skills/ is the cross-tool standard, so these skills can also be run with Codex or Copilot. Claude Code's .claude/skills/ dir isn't supported natively but we ship /import-from-cc-codex which you can use to import them.
Btw if you're using this tool it's worth noting that there's no sandbox at OS level, so if you run a skill it can do anything in its shell steps based on the selected permission level, so be mindful of that — keep in mind that a project's .kimi-code/skills/ and .agents/skills/ are like scripts, you're running code from a repo you might not have vetted.
So which word do you use
Use "skill" to communicate about a reusable capability that comes with a description so that the model can invoke it themselves, use "command" if you refer to a /name that you type. They both point to the same thing which is a procedure saved in a file that you can load in your session when needed, just a word for convenience so we can communicate as humans.
Don't rewrite things that work just because you want to rewrite them, both Claude Code and Cursor support their previous local command format, and if you're satisfied with it — keep using it. But if:
You want to have a description so the model can invoke it
Or you want to attach some files with your instructions
Or you want to make it portable via
.agents/skills/
Then it makes sense to migrate, and the next two lessons are about what to put inside these files and how to control when they get invoked.