Back to Guides
Workflow11 minUpdated Sep 19, 2026

Where Agent Skills Go: Claude Code, Cursor, Codex, Copilot

An agent skill is a folder whose name matches the name field in its SKILL.md, and each client reads it from a directory that client owns. Claude Code reads project skills from .claude/skills/ and personal skills from ~/.claude/skills/, while Cursor reads .agents/skills/ or .cursor/skills/ in a project and the same two names under your home directory.

TL;DR

A skill is a folder whose name matches the name field in SKILL.md. Claude Code reads .claude/skills/ in a project and ~/.claude/skills/ for every project. Cursor reads .agents/skills/ and .cursor/skills/. Codex, Copilot, Gemini CLI and OpenCode all read .agents/skills/, which makes it the shared location. Claude Code is the one client that does not.

Try it on your own script

Paste your draft below. You get your hook, structure, and pacing scores, a script-level attention-risk map, and the single biggest issue quoted from your own lines. Free, no login.

Free · No login · See a sample audit first if you prefer.

Key Takeaways

  • An agent skill is a folder whose name matches the name field in its SKILL.md, and each client reads it from a directory that client owns
  • Claude Code reads .claude/skills/<name>/SKILL.md in a project and ~/.claude/skills/<name>/SKILL.md in every one
  • Cursor reads .agents/skills/ or .cursor/skills/ in a project, and the same two under your home directory
  • Codex, Copilot, Gemini CLI and OpenCode all read .agents/skills/, which makes it the shared location, and Claude Code is the one client that does not
  • Claude Code 2.1.272 ran a skill placed in .claude/skills/ and answered Unknown command for a skill placed only in .agents/skills/, measured on 19 September 2026
  • The Agent Skills specification caps a skill name at 64 characters, caps the description at 1,024 characters, and requires the name to match the parent directory

Key Statistics

  • •The Agent Skills specification caps a skill name at 64 characters, caps the description at 1,024 characters, requires the name to match the parent directory, and recommends a SKILL.md under 500 lines (agentskills.io specification, read 19 September 2026).
  • •Codex limits the initial skill list to 2 percent of the model context window, or 8,000 characters when the context window is unknown, and shortens descriptions before it drops skills (OpenAI Codex skills documentation, read 19 September 2026).
  • •Claude Code truncates the combined description and when_to_use text at 1,536 characters in the skill listing (Claude Code skills documentation, read 19 September 2026).
  • •Claude Code 2.1.272 ran a skill placed in .claude/skills/ and answered Unknown command for a skill placed only in .agents/skills/, measured on 19 September 2026 in a scratch project on macOS.
  • •The Prepublish channel skill generator caps the skill name at 48 characters because that name becomes the frontmatter name, the zip top-level folder and the download filename stem (prepublish-be/internal/domain/entity/channel_skill_render.go).

Where Agent Skills Go: Claude Code, Cursor, Codex, Copilot

An agent skill is a folder whose name matches the name field in its SKILL.md, and each client reads it from a directory that client owns. Claude Code reads .claude/skills/<name>/SKILL.md in a project and ~/.claude/skills/<name>/SKILL.md in every one. Cursor reads .agents/skills/ or .cursor/skills/ in a project, and the same two under your home directory.

Where do agent skills go in Claude Code and Cursor?

Both clients split skills into project scope and personal scope, and both use the folder name as the identity of the skill. The Agent Skills specification requires the name field to match the parent directory name, and Cursor restates that rule in its own documentation.

Claude Code adds three scopes the other clients do not have. A plugin carries skills in its own skills/ folder and namespaces them as /plugin-name:skill-name. Enterprise skills load from .claude/skills/ inside the managed settings directory. Skills enabled on a claude.ai account download into ~/.claude/skills/synced/, which is why synced is a reserved folder name that Claude Code skips.

Personal scope also differs by client, and that is where a directory which works locally stops working elsewhere. Cursor keeps ~/.cursor/skills/ on the machine until you turn on Sync Skills for Cloud Agents, and it copies neither ~/.agents/skills/ nor unsynced local skills to Cloud Agents, remote SSH sessions or self-hosted workers. Claude Code keeps ~/.claude/skills/ out of Cowork, cloud sessions and routines, which read the skills enabled on your account instead.

The directory matrix for seven clients

Agent Skills clients disagree about directories, which is why a skill written for one client often sits unread in another. Each client name below links to the page the row is drawn from, and every page was read on 19 September 2026.

ClientProject directoryPersonal directoryHow the client discovers the skillReads other clients' directories
Claude Code.claude/skills/<name>/SKILL.md~/.claude/skills/<name>/SKILL.mdScans those locations at startup, including parents up to the repository root, then watches them for editsNo (measured 19 September 2026)
Cursor.agents/skills/ or .cursor/skills/~/.agents/skills/ or ~/.cursor/skills/Walks the skills root recursively at startup; a nested project directory scopes its skills to the files below itYes: .claude/skills/, .codex/skills/, ~/.claude/skills/, ~/.codex/skills/
Codex CLI.agents/skills/ in the working directory, in each parent, and at the repository root$HOME/.agents/skills, with admin scope at /etc/codex/skillsScans from the working directory up to the repository root, then lists name, description and path in the promptNot documented
GitHub Copilot.github/skills/, .claude/skills/ or .agents/skills/~/.copilot/skills/ or ~/.agents/skills/Loads repository and personal skills into the cloud agent, code review, the Copilot CLI and IDE agent modeYes: .claude/skills/ and .agents/skills/
Gemini CLI.gemini/skills/ or the .agents/skills/ alias~/.gemini/skills/ or the ~/.agents/skills/ aliasScans discovery tiers; the model calls activate_skill, and you approve a consent prompt before the body loadsYes, through the .agents/skills/ alias
OpenCode.opencode/skills/, plus .claude/skills/ and .agents/skills/~/.config/opencode/skills/, ~/.claude/skills/, ~/.agents/skills/Walks up from the working directory to the git worktree, then lists skills in the skill tool descriptionYes: the .claude and .agents paths
Claude appsNo directory. Upload a zip, then enable the skill in Customize, then SkillsNot applicable: the skill belongs to your accountServer side. The zip must hold the skill folder at its root, not loose filesNo

Two rows need a note the table cannot hold. Anthropic's help centre article writes the filename in lowercase as skill.md and caps the description at 200 characters, while the platform documentation and the specification say SKILL.md and 1,024. The rows above follow the platform documentation. The Codex row covers the ChatGPT desktop app as well, because OpenAI ships skills into both products from the same .agents/skills locations.

The .agents/skills/ path is the nearest thing to a shared location, and Gemini CLI explains why it exists: the alias is documented as an interoperable path that stays compatible across different AI tools. Five of the seven rows above read it. Claude Code is the holdout, so a repository that mixes clients needs a .claude/skills/ entry beside the shared one rather than instead of it.

How to verify a skill loaded in each client

Each row below is the check that client documents. Listing a skill and using the skill are different questions, and only one of them has a command.

ClientCommand or stepWhat a pass looks like
Claude CodeType /name, or open the /skills menuThe body runs; an unloaded name answers Unknown command: /name. /skill-doctor reports each skill's context cost and usage (v2.1.252 or later)
CursorOpen Customize in the sidebar, then SkillsDiscovered skills appear beside rules. Typing / in Agent chat also finds the skill
Codex CLIRun /skills, or type $The skill appears in the selector. ~/.codex/config.toml can disable one with a [[skills.config]] entry without deleting the file
GitHub Copilotgh skill list, on GitHub CLI 2.90.0 or laterInstalled skills are listed, and gh skill preview OWNER/REPOSITORY SKILL renders one before install
Gemini CLI/skills list in a session, or gemini skills list --all from the terminalThe skill appears with its tier, and activation shows a consent prompt naming the directory it may read
OpenCodeopencode debug skillPrints every discovered skill as JSON with its name, description and absolute path
Claude appsEnable the skill, then send a prompt that should match itAnthropic's guidance says to review the thinking to confirm the skill loaded, then iterate on the description

GitHub documents no list command for the cloud agent, so the only check there is whether Copilot applies the skill when your prompt matches its description. Anthropic documents the same gap for claude.ai, which is why that row ends in a prompt test.

Measured: what two clients did on 19 September 2026

Documentation pages describe intent, and clients enforce less than they describe. I built one scratch project on macOS, placed the same SKILL.md files in different directories, and ran two clients against it. Claude Code was version 2.1.272 and OpenCode was version 1.18.23.

Claude Code ran a skill from .claude/skills/hello/ when it was invoked as /hello, and answered Unknown command: /agentsonly for a skill that existed only in .agents/skills/. A control invocation of /nosuchskill in the same project returned the same message, so that message separates a failed load from a successful one. A symlink at .claude/skills/linked pointing into .agents/skills/agentsonly/ then worked, which means Claude Code takes the invocation name from the entry in its own directory while reading the file from the target. Codex documents following symlinked skill folders as well, and the other clients' pages do not say.

OpenCode listed skills from a project .agents/skills/ directory, a project .claude/skills/ directory and a home ~/.agents/skills/ directory, each with its path on disk. It also listed a skill whose name field said not-mismatch inside a folder called mismatch, under the frontmatter name, so the match rule its own documentation states was not enforced at discovery in that version. Every run happened on macOS, in one project, against project-level paths.

The symlink result is the one that matters for a team, because it means one authored copy can serve a client that reads .agents/skills/ and a client that does not.

Sharing skills with a team

Commit the skill directory. A skill checked into a repository is the one distribution method every client in the matrix supports, and each client picks the folder up from its own path without an install step.

Author the file once in .agents/skills/<name>/, the path five of the seven clients read, and add a symlink at .claude/skills/<name> for Claude Code. That arrangement was measured above rather than assumed. Windows needs a different mechanism for symlinks, and no client in this matrix documents junction behaviour.

Claude Code writes the per-developer visibility choices from its /skills menu into .claude/settings.local.json, so that file belongs in .gitignore. Keep personal skill directories out of the repository, and do not author a skill named synced, because Claude Code reserves that folder for account skills.

Portability breaks in three places. Claude Code accepts frontmatter fields that claude.ai and the Skills API reject with an error listing the allowed keys, so a skill meant for both surfaces should use the six specification fields only. Body features that only Claude Code implements, such as injecting shell output at load time, do nothing in claude.ai chat or through the API. Codex reads an optional agents/openai.yaml beside SKILL.md for display metadata and invocation policy, and the other clients ignore that file.

A skill is one shape of reusable capability, and an MCP server is the other. The server shape suits a capability that should run on a server rather than travel as a folder of instructions. Prepublish publishes it at the MCP server, with a remote endpoint, a local bridge through npx prepublish-mcp, and the same audit reachable by either route.

If you would rather not author the file, the channel skill generator writes a bundle in this layout: one SKILL.md plus a references/ folder, inside a zip whose root is the skill folder. The name it generates already satisfies the 64 character ceiling, and it is capped at 48 characters because that name becomes the frontmatter name, the zip top level and the download filename stem (prepublish-be/internal/domain/entity/channel_skill_render.go). Measured runs on 18 and 19 September 2026 produced a 9,623 byte SKILL.md for @maxinomics from 12 videos and 9 transcripts in 6 minutes 30 seconds.

Troubleshooting: the skill does not load or does not trigger

Each row is a documented rule rather than a guess, and most of them come from the specification's validation rules or from a client that enforces them.

SymptomCauseFix
The skill does not trigger on its ownMatching runs on the description, so a description without the words a user would type gives the model nothing to match. disable-model-invocation: true removes automatic invocation in Claude Code and Cursor, and Cursor's paths field hides a skill from work outside its globsPut the trigger words in the first sentence of the description, then invoke the skill explicitly to separate a load failure from a match failure
The frontmatter fails validationClaude Code reads frontmatter only when the opening --- is the first line, and treats the whole file as content otherwise. A claude.ai or Skills API upload rejects a field outside the specification and names the allowed properties. A name over 64 characters or a description over 1,024 fails the specificationRun skills-ref validate ./my-skill from the specification's reference library, keep to the six specification fields on anything you upload, and check for a blank line above the ---
The name does not match the directoryThe specification requires name to match the parent directory, Cursor and OpenCode document the same rule, and Copilot says the name typically matches. Claude Code takes the invocation name from the directory and treats the field as a display labelRename the folder or the field, and pick a name that works as the frontmatter name, the zip top-level folder and the download filename stem
The description is too vague for the agent to matchThe description is the only text loaded before activation, so it carries the whole matching decision. Claude Code truncates the combined description and when_to_use text at 1,536 characters, and Codex shortens descriptions first when the skill list passes its budgetWrite what the skill does and when to use it, in that order, then generate should-trigger and should-not-trigger prompts and measure the hit rate
The file is too longThe body loads on activation and stays in context for the turn. The specification recommends under 5,000 tokens and 500 lines, and Claude Code keeps only the first 5,000 tokens of each skill when it re-attaches them after auto-compaction, inside a combined 25,000 token budgetMove detail into references/ and link each file from the body, one level deep. Codex counts its list budget against every installed skill, so a large library costs context whether or not a skill runs

Limits: directories move, and some of these claims are documentation-only

Everything here describes what seven vendors documented on 19 September 2026. Directories in this area have moved before and will move again. Claude Code merged custom commands into skills and still loads .claude/commands/ for older setups. Gemini CLI tells unpaid tier and Google One users that Antigravity CLI replaced it on 18 June 2026, while the skills page I read carries an April 2026 date. gh skill is in public preview and needs GitHub CLI 2.90.0 or later. The Copilot and Codex pages carry no visible last-updated date at all, so the only date attached to those rows is the day I read them.

Some cells rest on documentation alone, and the table says so rather than filling the gap. Codex does not document whether it reads .claude/skills/. Cursor, Copilot, Gemini CLI, OpenCode and Claude apps do not state whether they follow a symlinked skill folder, and only Claude Code and Codex document that they do. My OpenCode measurement came from one version on one operating system. The default filesystem on macOS is case-insensitive, so a lowercase skill.md was the same file as SKILL.md, and I did not test filename casing anywhere else.

Version gates sit under individual behaviours, and they matter when a step does not work on your machine. /skill-doctor needs Claude Code v2.1.252 or later. Syncing account skills in the terminal needs v2.1.273 or later. Cursor copies personal skills to Cloud Agents only after you turn sync on.

Re-check four things after a client upgrade. Confirm the directory still matches the matrix, because a compatibility path can be dropped as quietly as it was added. Re-run one explicit invocation per client, since that separates discovery from matching. Confirm the frontmatter fields you use still load in the client that is not yours. Re-read the documentation pages, because each carries its own last-updated date, and a directory claim is only as current as the page that made it.

Frequently asked questions

Do agent skills work in both Claude Code and Cursor without changes?

Mostly. Claude Code and Cursor both read the specification fields name and description, and both read a SKILL.md body. The differences sit in the extensions each client adds. Claude Code accepts context, agent, model and allowed-tools; Cursor has its own paths, icon and color fields. A skill written with only the six specification fields loads in both, and the same file uploads to claude.ai without an unexpected-key error.

Where do agent skills go in Claude Code?

Claude Code reads project skills from .claude/skills/<name>/SKILL.md and personal skills from ~/.claude/skills/<name>/SKILL.md. It also reads a nested .claude/skills/ below the directory where the session started, but only after Claude reads or edits a file there. A plugin carries skills in its own skills/ folder, and skills enabled on your claude.ai account sync into ~/.claude/skills/synced/. All of that comes from the Claude Code skills documentation read on 19 September 2026.

Where does Cursor look for skills?

Cursor loads project skills from .agents/skills/ and .cursor/skills/, and user-level skills from ~/.agents/skills/ and ~/.cursor/skills/. It walks those roots recursively, so a skill group filed inside a category folder still works, and it picks up a nested .cursor/skills/ anywhere in the repository, scoped to files under that folder. Cursor also loads .claude/skills/, .codex/skills/, ~/.claude/skills/ and ~/.codex/skills/ for compatibility.

Is there one directory every client reads?

.agents/skills/ is the closest thing. Cursor, Codex, GitHub Copilot, Gemini CLI and OpenCode all read it, across project and personal scope. Claude Code does not. A project skill that existed only in .agents/skills/ answered Unknown command when invoked in Claude Code 2.1.272 on 19 September 2026. The arrangement that works is one authored copy in .agents/skills/ plus a symlink into .claude/skills/, which Claude Code followed in the same test.

What happens when the frontmatter name does not match the folder?

The specification requires a match, and Cursor and OpenCode both document that requirement. Claude Code is looser: the invocation name comes from the directory, and the name field is a display label, so /hello comes from a folder called hello whatever the field says. A run of OpenCode 1.18.23 on 19 September 2026 listed a skill whose field said not-mismatch inside .agents/skills/mismatch/, so that rule was not enforced at discovery there.

How do I confirm that a skill loaded?

Invoke it by name and read what happens. In Claude Code, typing /name runs the body, and a missing skill answers Unknown command: /name, which I measured on version 2.1.272 on 19 September 2026. Cursor lists discovered skills under Customize, then Skills. Codex takes /skills, or a dollar sign to mention a skill. Gemini CLI takes /skills list. OpenCode prints every discovered skill and its path through opencode debug skill. GitHub CLI lists installed skills with gh skill list.

Why does a skill not trigger automatically?

Automatic invocation rests on the description, so a vague one produces no match. Setting disable-model-invocation true removes a skill from automatic invocation entirely, in Claude Code and in Cursor. Cursor can also scope a skill with paths so it appears only for matching files. Codex shortens descriptions first when the skill list passes its budget and may omit skills from the initial list, so the trigger words belong in the first sentence.

Which skill files should I commit to a repository, and what should I ignore?

Commit the skill directories, because they are the shared artifact: .agents/skills/, .claude/skills/, .github/skills/, .cursor/skills/, .gemini/skills/ or .opencode/skills/. Ignore per-developer state instead. Claude Code writes the /skills visibility choices into .claude/settings.local.json, which should stay on one machine. Keep personal skills out of the repository, and do not author a skill named synced, because Claude Code reserves that folder for skills from your account.

Related Guides

Free tools to put this into practice

Want to see how this reads on real channels? Browse the channel breakdowns. Each one compares script patterns across a channel's own higher-viewed and lower-viewed uploads, quoted from the transcripts.

See where your next script leaks viewers

Paste your script, get your scores and the biggest leak for free. No login.