Claude skills vs Codex skills: paths, $ vs /, openai.yaml, and precedence
Claude Code and OpenAI Codex both run Agent Skills from the same SKILL.md, but they load from different directories, invoke with different syntax, and put agent-specific settings in different places. Every difference, with examples.
Contents
Claude Code and OpenAI Codex agree on what a skill is. Both implement the Agent Skills specification: a folder, a SKILL.md, name and description in YAML, instructions in Markdown, optional scripts/ and references/ and assets/. A skill published for one installs into the other with a single command, and the body does not change.
Where they disagree is in the plumbing around the file. Codex walks a different set of directories with a documented precedence order, uses $skill-name where Claude uses /skill-name, keeps its vendor-specific settings in a separate agents/openai.yaml file rather than in the frontmatter, and exposes a config file for disabling skills. Claude Code puts a dozen optional fields directly in the frontmatter, merges slash commands into skills, and lets a skill fork into a subagent. This article lays out every difference so you can write once and understand what each tool will do with the result.
Directory scanning and precedence
Codex loads skills from four scopes and documents their precedence:
| Order | Scope | Path |
|---|---|---|
| 1 | Repository | .agents/skills in the current directory, any parent, or the repo root |
| 2 | User | ~/.agents/skills |
| 3 | Admin | /etc/codex/skills |
| 4 | System | Skills bundled with Codex |
Codex follows symlinked skill folders, so a shared skills repository can be linked into ~/.agents/skills without copying.
Claude Code has its own set:
| Scope | Path | Notes |
|---|---|---|
| Enterprise | .claude/skills/ inside the managed settings directory | Admin-controlled |
| Personal | ~/.claude/skills/<name>/SKILL.md | Beats a project skill of the same name |
| Project | .claude/skills/<name>/SKILL.md | Loads from the start directory and every parent up to the repo root |
| Nested | <subdir>/.claude/skills/ | Loads once Claude reads or edits a file in that subtree |
| Plugin | <plugin>/skills/<name>/SKILL.md | Exposed as /plugin-name:skill-name |
| Synced | ~/.claude/skills/synced/ | Skills enabled on claude.ai, downloaded when CLAUDE_CODE_SYNC_SKILLS is set |
The two tools do not read each other’s directories. A repo that wants to serve both today either commits skills twice or uses a CLI that installs to both targets:
npm i -g skillmds
skillmd add anthropic/skill-creator # every agent detected on the machine
skillmd add anthropic/skill-creator -a codex # Codex only
skillmd add anthropic/skill-creator -a claude-code # Claude Code only
The Codex and Claude Code guides on SkillMD carry the exact paths.
Invocation syntax
| Action | Claude Code | Codex | ChatGPT |
|---|---|---|---|
| Automatic | By description | By description | By description |
| Explicit | /skill-name | $skill-name | @skill-name |
| Pass arguments | /skill-name arg1 arg2, read as $ARGUMENTS in the body | Free text after the mention | Free text after the mention |
| Stack several | Up to six inline skills in one message | One mention per skill | One mention per skill |
| Manual-only | disable-model-invocation: true in frontmatter | policy.allow_implicit_invocation: false in agents/openai.yaml | Same openai.yaml |
| Agent-only (hidden from you) | user-invocable: false | Not available | Not available |
The $ versus / distinction is more than cosmetic. In Claude Code, skills and slash commands are the same thing: a .claude/commands/deploy.md and a .claude/skills/deploy/SKILL.md both produce /deploy, and the skill wins if both exist. Codex reserves / for its own built-in commands and gives skills the $ sigil so the two namespaces never collide.
Where vendor-specific settings go
This is the deepest design difference between the two implementations.
Claude Code puts extensions in the frontmatter. Beyond the spec fields, Claude Code reads:
| Field | Purpose |
|---|---|
argument-hint | Autocomplete hint, e.g. [issue-number] |
disable-model-invocation | Manual-only |
user-invocable | Set false to hide from the / menu |
allowed-tools | Tools pre-approved for the invoking turn (clears on your next message) |
disallowed-tools | Tools removed while the skill is active |
model | Model override for the turn |
context: fork | Run the skill as a subagent |
agent | Which subagent type to fork into |
background | Whether a forked skill runs in the background (default) or blocks |
hooks | Hooks registered when the skill is invoked |
Claude also substitutes ${CLAUDE_SKILL_DIR} and ${CLAUDE_PROJECT_DIR} in both the body and in allowed-tools Bash rules, so a skill can pre-approve exactly the bundled script it tells the agent to run.
Codex puts extensions in a sidecar file. The SKILL.md frontmatter stays spec-clean, and an optional agents/openai.yaml inside the skill folder carries the rest:
interface:
display_name: "Release notes"
icon_small: "assets/icon-16.png"
icon_large: "assets/icon-64.png"
brand_color: "#0A84FF"
policy:
allow_implicit_invocation: false # default true
dependencies:
tools:
- type: mcp
value: github
The interface block controls how the skill appears in the ChatGPT and Codex UI. policy is the Codex equivalent of disable-model-invocation. dependencies.tools declares the MCP servers the skill expects, so the agent can tell you what is missing instead of failing mid-task.
The consequence for authors: a skill that uses Claude’s frontmatter extensions still loads in Codex (unknown keys are ignored), but the behavior those keys encode does not carry over. A context: fork skill runs inline in Codex. A disable-model-invocation: true skill is auto-invocable in Codex unless you also add the openai.yaml policy. If manual-only matters, set it in both places.
Context budget
Codex publishes its number: the initial skill listing is limited to at most 2% of the model’s context window, or 8,000 characters when the window size is unknown. If you install more skills than fit, some descriptions will not be shown to the model, and those skills will not trigger automatically.
Claude Code does not publish a fixed cap, but the same principle applies through progressive disclosure: only name and description load at startup. Both tools reward short, specific descriptions. Both recommend keeping the body under 500 lines.
Enabling, disabling, and removing
| Task | Claude Code | Codex |
|---|---|---|
| Stop automatic use, keep manual | disable-model-invocation: true | allow_implicit_invocation: false in openai.yaml |
| Disable without editing the skill | skillOverrides in settings ("user-invocable-only") | [[skills.config]] with enabled = false in ~/.codex/config.toml |
| Remove | Delete the folder; live change detection drops it from /skills in the current session | Delete the folder |
| Restrict which skills the model may call | Permission deny rules on the Skill tool | Config entries per skill |
Claude Code watches its skill directories and applies edits within the session. Codex rescans on startup.
Distribution
Claude Code distributes skills through plugins. A skill folder with a .claude-plugin/plugin.json loads as a plugin and can bundle agents, hooks, and MCP servers alongside skills. Skills enabled on claude.ai sync into Claude Code sessions, including Cowork and cloud sessions that never see your laptop’s ~/.claude/skills/.
Codex ships a $skill-installer skill for curated skills and packages skills as plugins for broader sharing. The openai/skills repository holds first-party examples, including the skill-creator skill Codex uses to write new skills.
Both are compatible with third-party registries. SkillMD lists 25,000+ skills with a safety review on each, tags which agents each author tested against, and installs to either tool with one command. Claude Code users can also add the hosted MCP server and install by asking:
claude mcp add skillmds -- npx -y skillmds
Writing one skill for both
A checklist that produces a skill both tools run identically:
- Use only spec fields in the frontmatter:
name,description,license, and optionallycompatibilityandmetadata. - Name the folder the same as
name, lowercase with hyphens, under 64 characters. - If the skill must be manual-only, add
disable-model-invocation: trueto the frontmatter andpolicy.allow_implicit_invocation: falseinagents/openai.yaml. - If the skill needs an MCP server, say so in the body for Claude and declare it under
dependencies.toolsfor Codex. - Reference bundled scripts by relative path from the skill root. Avoid
${CLAUDE_SKILL_DIR}in the body; it is Claude-only. - Keep the body under 500 lines and move long material to
references/. - Run
skillmd lintbefore committing.
The full multi-agent field table is in the compatibility matrix.
Summary table
| Dimension | Claude Code | OpenAI Codex |
|---|---|---|
| Spec | Agent Skills SKILL.md | Agent Skills SKILL.md |
| Project dir | .claude/skills (plus parents, nested, plugins) | .agents/skills (plus parents to repo root) |
| Personal dir | ~/.claude/skills | ~/.agents/skills |
| Admin dir | Managed settings directory | /etc/codex/skills |
| Precedence | Personal > project > bundled; skill > command; namespaced plugins | Repo > user > admin > system |
| Explicit invoke | /name, with $ARGUMENTS | $name (ChatGPT: @name) |
| Vendor settings | Frontmatter fields | agents/openai.yaml sidecar |
| Manual-only | disable-model-invocation | policy.allow_implicit_invocation: false |
| Subagent execution | context: fork | Not available |
| Tool pre-approval | allowed-tools (per turn) | Not available |
| MCP dependency declaration | In the body | dependencies.tools |
| Disable via config | skillOverrides | [[skills.config]] enabled = false |
| Context cap for listings | Not published | 2% of window or 8,000 chars |
| Live reload | Yes | Rescan on start |
| Cloud sync | claude.ai-enabled skills | Repo skills |
Further reading
Frequently asked questions
Do Claude Code skills work in OpenAI Codex?
Yes. Both implement the Agent Skills specification. A skill that uses name, description, and a Markdown body loads unchanged in Codex once it is in a directory Codex scans, such as .agents/skills. Claude-only frontmatter fields are ignored.
Where does Codex look for skills?
In order of precedence: .agents/skills in the working directory, its parents, or the repo root; ~/.agents/skills for personal skills; /etc/codex/skills for admin-installed skills; then built-in system skills.
How do I invoke a skill explicitly in Codex vs Claude Code?
Codex uses a dollar sign: $skill-name. ChatGPT uses an at sign: @skill-name. Claude Code uses a slash: /skill-name, and accepts arguments that the skill body reads as $ARGUMENTS.
What is agents/openai.yaml in a Codex skill?
An optional file inside the skill folder that holds Codex- and ChatGPT-specific settings: a display name, icons, and brand color for the UI, a policy that can disable implicit invocation, and declared MCP tool dependencies. It keeps vendor settings out of the shared SKILL.md frontmatter.
How do I turn off a skill in Codex without deleting it?
Add a [[skills.config]] entry with enabled = false to ~/.codex/config.toml. In Claude Code, set disable-model-invocation: true in the frontmatter to make it manual-only, or delete the skill folder to remove it.