Agent Skills provide a portable content format, not a portable runtime contract. A standards-compliant SKILL.md can still be undiscoverable, invoke differently, or fail when its tools and permissions change. This guide separates those risks across Codex, Claude Code, Gemini CLI, and GitHub Copilot using official documentation available on July 22, 2026.
Reading time: 11 minutes · Approximately 2,200 words · Documentation comparison, not an all-version device test
TL;DR
- The Agent Skills specification standardizes the structure inside a skill directory. It does not mandate where every client must search for that directory.
- Keep
nameanddescriptionin the portable core. Treatlicense,compatibility, andmetadataas optional, and assumeallowed-toolsis experimental across implementations. .agents/skillsis a useful implementation convention, not a path guaranteed by the specification. Codex, Gemini CLI, and Copilot document support for it; Claude Code does not.- Test compatibility in four layers: content, discovery, invocation, and runtime. Passing the first layer proves almost nothing about the fourth.
Scope: What the Standard Actually Standardizes
The Agent Skills specification defines a skill as a directory containing SKILL.md, with optional scripts, references, assets, and other resources. Its frontmatter has two required fields:
---
name: dependency-review
description: Review a dependency change for provenance, risk, and policy compliance. Use when a pull request adds or updates packages.
---
The standard also defines optional license, compatibility, and metadata fields. allowed-tools is optional and explicitly experimental, so support may vary by implementation. The Markdown body is intentionally flexible.
That is a meaningful common base. It lets authors package instructions and supporting files in a recognizable shape. It does not standardize client installation paths, directory traversal, name collision rules, automatic activation thresholds, slash command behavior, permission prompts, tool names, sandboxing, or dependency availability.
The official client implementation guide reinforces this boundary. It explains how an agent can discover, expose, and load skills, but does not prescribe one universal filesystem location. .agents/skills has become a valuable convention among implementations. It is not a normative requirement of the format.
This article is therefore a documentation matrix, not a claim that every product version was exercised on every operating system. Product behavior can change after July 22, 2026, and enterprise policy can narrow what the default client permits.
Official Compatibility Matrix as of July 22, 2026
| Client | Documented project discovery | Documented user or system discovery | Invocation model | Client-specific surface |
|---|---|---|---|---|
| OpenAI Codex | .agents/skills searched from the current working directory up to the repository root |
$HOME/.agents/skills, /etc/codex/skills |
Relevant skills can be selected from descriptions; explicit mention is also possible | agents/openai.yaml adds Codex-facing metadata and dependencies |
| Claude Code | .claude/skills/<name>/SKILL.md; plugin skills; .claude/skills inside added directories |
~/.claude/skills/<name>/SKILL.md |
Automatic selection or direct /skill-name invocation |
Invocation controls, argument hints, model selection, subagent context, hooks, and dynamic context |
| Gemini CLI | .gemini/skills or .agents/skills in the workspace |
~/.gemini/skills or ~/.agents/skills |
Matches by description, then asks for activation consent; /skills manages state |
Built-in and extension tiers, precedence, enable/disable, install, and link commands |
| GitHub Copilot | .github/skills, .claude/skills, or .agents/skills |
~/.copilot/skills or ~/.agents/skills |
Copilot selects relevant skills from prompt and description; CLI also supports direct invocation | license and allowed-tools; behavior spans cloud agent, code review, CLI, app, and IDE agent mode |
The Codex skills documentation describes repository traversal from the current working directory toward the repository root, plus user and administrator locations. That traversal rule matters in monorepos because the same process may see different skills when launched from different subdirectories. Codex also uses agents/openai.yaml for product-specific presentation and dependency metadata. The file is an extension around the skill, not part of the minimum cross-client contract.
Claude Code's skills documentation documents .claude/skills and ~/.claude/skills, automatic and explicit invocation, and a much richer set of frontmatter controls. Its current documented search paths do not include .agents/skills. A request to add shared paths, anthropics/claude-code issue #56193, was closed as not planned. That issue is not a permanent product promise, but it corroborates the documentation snapshot.
Gemini CLI's creation guide explicitly treats .agents/skills as an alias for .gemini/skills at both workspace and user scope. Its management guide also documents precedence and activation consent. Discovery does not mean immediate execution: the user must approve activation and resource access whenever the skill triggers.
The documented workspace depth is also different. Gemini CLI describes the skill directories in the current workspace, while Codex explicitly describes walking from the current working directory toward the repository root. Teams should not assume that a nested launch directory exposes the same project skills in both clients.
GitHub Copilot's skills guide accepts the broadest documented set of project aliases in this comparison. It also warns that pre-approving shell or bash through allowed-tools removes a confirmation step and can expose the environment to malicious instructions or prompt injection.
The Four-Layer Compatibility Model
The useful question is not “Does this client support Agent Skills?” It is “At which layer does compatibility stop?”
| Layer | What must remain equivalent | Typical false positive |
|---|---|---|
| 1. Content portability | SKILL.md parses; required fields and relative resources are valid |
A validator passes, so the team declares migration complete |
| 2. Discovery portability | The client finds the intended skill at the intended scope and resolves collisions predictably | The directory exists, but the client never scans it from this working directory |
| 3. Invocation equivalence | Explicit calls, automatic matching, arguments, confirmation, and context loading behave as intended | One client auto-activates while another requires a slash command or consent |
| 4. Runtime equivalence | Tools, permissions, environment variables, network, binaries, sandbox, and outputs are equivalent | Instructions load, but a named tool is absent or a script lacks access |
Layer 1 is the open-format achievement. Layers 2 through 4 belong to the harness.
This distinction mirrors the interface problem discussed in MCP vs CLI for AI agents. A common description of an operation does not guarantee a common execution environment. It also fits the broader Harness Engineering principle: the model is only one component, while discovery, tools, feedback, and constraints determine whether a workflow is reliable.
What Is Portable, and What Is Not
The strongest portable core is deliberately small:
- A directory name and standards-compliant
name. - A concrete
descriptionstating both capability and trigger conditions. - Markdown instructions that avoid product-specific invocation syntax.
- Relative links to
scripts/,references/, andassets/. - Scripts with explicit interpreters, checked dependencies, stable input and output, and non-zero failure exits.
- Environment requirements declared in
compatibilitywhen they materially affect execution.
Optional fields can remain portable when used conservatively. license communicates reuse terms. metadata can carry namespaced string values. compatibility can state that Python, Git, network access, or another dependency is required. None guarantees that a client will enforce the requirement.
Treat these elements as adapters or documented assumptions:
- Search paths and precedence.
- Claude Code fields such as
disable-model-invocation,user-invocable,argument-hint,model,context,agent, and hooks. - Codex-specific
agents/openai.yamlmetadata. - Gemini CLI activation consent and skill management state.
- Copilot-specific tool labels and differences among cloud, CLI, review, app, and IDE surfaces.
- Tool names such as
Bash,shell,Read, or product-specific MCP tools. - Network access, workspace trust, sandbox mode, secrets, installed packages, and operating-system behavior.
One subtle trap is permissive parsing. Claude Code may accept fields or defaults that differ from the open specification. A skill can work there while failing a stricter validator elsewhere. For a multi-client source, author to the standard's minimum requirements even when one client is more lenient.
A Single-Source Distribution Layout
Do not hand-edit four independent copies. Keep one canonical skill and generate client views from it.
agent-skills/
├── src/
│ └── dependency-review/
│ ├── SKILL.md
│ ├── scripts/
│ ├── references/
│ ├── assets/
│ └── agents/
│ └── openai.yaml
├── adapters/
│ └── claude-code/
│ └── dependency-review.frontmatter.yaml
├── fixtures/
│ └── dependency-review/
│ ├── prompt-explicit.txt
│ ├── prompt-implicit.txt
│ └── expected.json
└── dist/
├── .agents/skills/dependency-review/
└── .claude/skills/dependency-review/
The canonical SKILL.md should contain only standard fields. Codex's agents/openai.yaml can remain an optional file because the standard permits additional resources. If a team genuinely needs Claude-only frontmatter, a build step can merge the overlay into the Claude distribution. Generated files should carry a source checksum and a “do not edit” notice.
Use copies by default in releases because symlinks are not equally reliable across package managers, archives, Windows environments, and remote agents. A local development command may create links for speed, but CI should build clean copies, validate both distributions, and fail when generated content differs from the canonical source.
Build a Four-Layer Test Fixture
A useful fixture is intentionally boring. It should prove the harness contract without depending on a large task or subjective model quality.
Create a compatibility-probe skill that has standard-only frontmatter, references assets/marker.txt, includes a read-only script that prints fixed JSON, defines one explicit and one natural-language trigger, and makes no network or filesystem changes.
Run the same checks in each client:
C1 Parse: Does the standard validator accept the source?
C2 Discover: Is the intended copy visible from project and user scope?
C3 Explicit: Can a user invoke it by the documented mechanism?
C4 Implicit: Does the natural-language prompt select it reliably?
C5 Resources: Can it read the marker by a relative path?
C6 Runtime: Can it execute the safe script with the expected permission flow?
C7 Failure: Does a missing dependency stop clearly rather than hallucinate success?
C8 Collision: Which copy wins when project and user skills share a name?
Record client version, operating system, launch directory, policy profile, and invocation mode. Do not collapse the result into one “supported” boolean. A useful report looks like content=pass, discovery=pass, invocation=conditional, runtime=fail, with evidence attached.
Run the fixture in CI whenever the canonical skill, adapter, installer, or client baseline changes. It is a contract test for the harness, not a model benchmark.
Security Boundary: A Skill Is Executable Trust
A skill may look like documentation, but its instructions can cause file reads, shell execution, network calls, and secret access. Installation is therefore a trust decision.
Review the whole directory, not only SKILL.md. Pin remote sources to a commit or release, verify checksums, scan bundled scripts, and maintain an allowlist of interpreters and dependencies. Treat updates as code changes with review and provenance.
Do not use allowed-tools as a portable sandbox policy. The field is experimental, and clients interpret permissions differently. Claude Code describes it as pre-approval rather than a restriction on all other tools. Copilot warns that pre-approving shell access can remove a critical confirmation boundary. Enforce deny rules, workspace isolation, network policy, and secrets scope in the host harness.
The safe division of responsibility is simple: the skill declares what it needs; the harness decides what it may receive. A migrated skill should never broaden its own authority because the target client uses a different tool vocabulary.
FAQ
Can one SKILL.md work unchanged in all four clients?
Yes, if it uses the standard core, is installed in every client's documented path, and depends only on capabilities available everywhere. That proves content reuse, not equivalent activation or runtime behavior.
Is .agents/skills the universal Agent Skills directory?
No. It is a convention supported by Codex, Gemini CLI, and Copilot in the documentation reviewed here. The specification does not mandate it, and Claude Code currently documents .claude/skills instead.
Should a shared skill include allowed-tools?
Only when every target client has been tested and the security effect is understood. Since the field is experimental and permission semantics differ, shared skills are often safer when tool policy stays in client-specific harness configuration.
Do I need separate repositories for each coding agent?
Usually not. Keep one source directory, small client overlays, generated distributions, and a compatibility fixture. Split repositories only when runtime dependencies or release ownership are genuinely different.
What is the minimum migration test?
Validate the source, confirm discovery from the real launch directory, test explicit and implicit invocation, load one relative resource, run one harmless script, and observe one controlled failure. That sequence touches all four layers.
Conclusion and Next Action
Agent Skills solve a real portability problem, but only at the content layer. The durable engineering move is to preserve a standards-only core, isolate client extensions, distribute into documented paths, and test the harness contract rather than trusting a compatibility label.
For your next action, create one read-only compatibility-probe fixture this week and run it across the exact Codex, Claude Code, Gemini CLI, and Copilot surfaces your team supports. Publish the four-layer result internally before migrating a production skill.