You wrote a good SKILL.md for Claude Code — a code-review playbook, a release-notes formatter, a "how we name migrations" guide. Here's the part that changed in 2026: you can drop that same folder into OpenAI's Codex CLI, Google's Gemini CLI, GitHub Copilot, and Cursor, and it just works. Agent Skills stopped being a Claude feature and became an open standard — published December 18, 2025 at agentskills.io, and by March more than thirty tools were reading the exact same files.
But "portable" has fine print. The SKILL.md body and its two frontmatter fields travel perfectly. Everything else — side files, scripts that touch the network, even the name you chose — can quietly not travel. This is the install path for each agent, and the three things that break the promise.
What actually travels#
A Skill is a folder with a SKILL.md: YAML frontmatter with two required fields, then a Markdown body of instructions.
---
name: release-notes
description: Draft release notes from merged PRs. Use when the user asks for
a changelog, release notes, or a "what shipped" summary for a version tag.
---
# Release Notes
## Steps
1. List merged PRs since the last tag.
2. Group by type: features, fixes, breaking changes.
3. Write one line per change, user-facing language, no PR numbers in the body.
Those two fields — name and description — are read identically by every runtime, and the description is the load-bearing one: it's the string each agent matches your request against to decide whether to fire the skill. Write it as what it does and when to use it, or the skill never triggers no matter which tool you're in. The Markdown body, and any reference files or scripts it points to, travel too — loaded on demand by progressive disclosure.
Where each agent looks#
Every tool reads a skills/ directory under its own config folder, and every tool accepts both a project-scoped and a global location. Same pattern, different prefix:
- Claude Code —
.claude/skills/in the repo, or~/.claude/skills/globally. - OpenAI Codex CLI —
.codex/skills/or~/.codex/skills/. Invoke explicitly with$skill-name, or browse with/skills. - Gemini CLI —
.gemini/skills/(or the neutral.agents/skills/alias), or~/.gemini/skills/. It also hasgemini skills install <git-url>to pull one from a repo. - GitHub Copilot —
.github/skills/in the repo; it also reads.claude/skillsand.agents/skills. Agent skills for Copilot code review went generally available at the end of July 2026. - Cursor —
.cursor/rules/in the repo, or~/.cursor/skills/globally; Cursor merges a skill with any.cursorrulesalready in the project.
The tell in that list: .agents/skills/ is emerging as the neutral home. Gemini CLI and Copilot both read it directly. Commit your skill there once and two agents find it with zero duplication — and for the tools that insist on their own path, symlink from that one source instead of maintaining copies that drift.
The three things that break portability#
1. Tool-specific side files. Codex reads an optional openai.yaml next to SKILL.md for Codex-only metadata — UI hints, MCP tool dependencies. It's genuinely useful in Codex and completely ignored everywhere else. Treat any side file as a bonus for one tool, never a dependency the skill needs to function.
2. Scripts that assume a runtime you don't have. A skill can bundle scripts, and the model runs them through bash. But the runtime differs sharply by surface: skills behave differently across Claude Code, the API, and claude.ai. On the Claude API, skills run in a sandboxed container with no network access and no runtime package installation — so a script that curls an endpoint or pip installs a dependency works in Claude Code (full network) and dies on the API. Gemini CLI, by contrast, adds the skill's directory to the agent's allowed file paths. If a script needs the network or a package, say so in the body and make the network-free path the default.
3. Reserved words in the name. This one bites silently. Claude requires the name field to be lowercase, hyphenated, 64 characters or fewer — and to not contain "claude" or "anthropic". Name your skill claude-reviewer and it loads fine in Cursor, Codex, and Gemini CLI, then Claude refuses it. Pick a tool-neutral name (code-reviewer, not claude-reviewer) and it clears every gate.
The decision#
Keep the SKILL.md pure: portable know-how in the body, a trigger-worthy description, a tool-neutral name, and no script that assumes a runtime some surface won't give it. Put the folder in .agents/skills/ as the single source of truth, and let each tool's own path point back to it. Do that and one skill really does run in all five agents.
And when the gap you're closing is access rather than know-how — a database, an API, a system with a permission boundary — that's not a skill at all. That's MCP, which sits at a different layer, and the two compose cleanly once you stop asking a playbook to do a protocol's job.



