You wrote a good skill. A SKILL.md that turns your agent into a competent code reviewer, or a release-notes writer, or a thing that knows your team's deploy process cold. It works. You use it every day in Claude Code.
Then you open Codex to try something. Or a teammate lives in Cursor. Or you want the same behavior in Gemini CLI for the free eval calls. And you assume you're starting from scratch.
You're not. Since December 2025, the SKILL.md format has been an open standard, governed at agentskills.io. Anthropic created it, then handed it to a spec that 20-plus agent products now read. A skill you wrote for Claude Code runs in Codex, Gemini CLI, Copilot, Cursor, OpenClaw, Windsurf, and more, usually with zero changes.
Here's the part most people miss: skills are filesystem-based, not API-based. A skill is just a folder with a SKILL.md inside. Any agent that can read a directory and parse markdown can run it. There's no SDK to integrate, no endpoint to call. You drop the folder where the tool looks, and it shows up.
The only two things the standard actually requires
The spec is deliberately tiny. Your SKILL.md needs YAML frontmatter with exactly two required fields:
name— lowercase letters, numbers, and hyphens, max 64 characters, must match the folder namedescription— max 1024 characters, and this is the one that matters
Everything else (license, compatibility, metadata, allowed-tools) is optional. The body below the frontmatter is plain markdown with no format rules. That is the whole standard.
And here's the single highest-leverage line in the file: if your skill doesn't trigger, it is almost never the instructions. It's the description. The agent reads only the name and description at startup (this is progressive disclosure), then decides whether to load the rest. A vague description means the skill never fires. "Helps with PDFs" is useless. "Extracts text and tables from PDFs, fills forms, merges files. Use when the user mentions PDFs, forms, or document extraction" gets loaded at the right moment, every time. Write the description for the agent that has to decide whether you're relevant, not for a human reading a README.
Where each tool looks
The format is identical everywhere. What differs is the directory each tool scans:
Agent | Personal (all projects) | Project (committed to repo) |
|---|---|---|
Claude Code |
|
|
Gemini CLI |
|
|
Codex CLI |
|
|
Copilot CLI |
|
|
OpenClaw |
|
|
Cursor | (project only) |
|
Unified alias |
|
|
Two locations per tool: a personal one in your home directory, available in every project, and a project one you commit to the repo, shared with your team. Commit the project folder to version control and everyone who clones the repo gets the same agent behavior automatically. That is the whole pitch. Write the context once, stop re-pasting it into chat every morning.
Note that last row. Several tools now also read a unified .agents/skills/ (and ~/.agents/skills/) path, so you can target one folder instead of copying to five.
Where portability actually breaks
"Write once, run everywhere" is true for the core format. It is not true for everything. Here is where skills stop being portable, and how to keep yours clean:
Platform-specific frontmatter. Claude Code adds
context: fork. Codex adds anopenai.yamlsidecar. These are extensions, not the standard. A tool that doesn't understand a field should ignore it, but don't build your skill's behavior around one. Keep the required fields standard and treat the rest as nice-to-have.Hardcoded absolute paths.
/Users/yourname/...works on your machine and nowhere else. Use relative paths from the skill root. The spec is explicit: referencescripts/extract.py, not an absolute path, and keep references one level deep.Tool names that don't exist everywhere.
allowed-toolsis experimental and support varies. If your skill assumes a tool named exactly one way, it breaks on a platform that names it differently. Put the requirement incompatibilityinstead of assuming it.Runtime behavior you can't see. Same file, different execution. Session snapshotting, tool permissions, and invocation modes differ between platforms. A skill that works in Claude Code will very likely work in Codex, but test it before you bet a workflow on it.
The fix for all four is the same discipline: stick to the core format, keep paths relative, and declare environment requirements in compatibility rather than baking them into the logic.
The compound move
If you've been building skills for one tool, you already have a portable asset library. You just didn't know it. Audit your ~/.claude/skills/ folder, fix the four issues above, and copy the good ones to ~/.agents/skills/. Now they follow you across every agent you touch.
The model you run is rented and it changes every few months. Your skills are yours, and now they outlive whatever tool you happen to be using this quarter. That's the shift worth internalizing.
The Blueprint below is a SKILL.md written to be portable from line one. Copy it, drop it into two different tools, and watch the same behavior show up in both.
A portable SKILL.md (works in every skills-compatible agent)
Copy this into a folder named commit-writer/ as SKILL.md. Drop the folder in any path from the table above (~/.claude/skills/commit-writer/, ~/.codex/skills/commit-writer/, or the unified ~/.agents/skills/commit-writer/). No edits needed between tools. It uses only git and a shell, which every coding agent has, and it has zero hardcoded paths or platform-specific fields.
---
name: commit-writer
description: Writes clear, Conventional-Commits-formatted git commit messages from staged changes. Use when the user wants to commit, asks for a commit message, or says "commit", "write a commit", or "commit message".
license: MIT
compatibility: Requires git and a shell tool.
metadata:
author: agenticsmith
version: "1.0"
---
# Commit writer
Generate a Conventional Commits message from the currently staged
changes, then show it for approval before committing.
## Steps
1. Run `git diff --staged` to see what is actually staged. If nothing
is staged, run `git status` and tell the user there is nothing to
commit. Do not stage files yourself.
2. Read the diff and pick the change type: feat, fix, refactor, docs,
test, or chore.
3. Write the message as:
type(scope): imperative summary under 72 chars
- bullet explaining what changed and why, not how
- second bullet if the change touches more than one area
4. Keep the summary line under 72 characters. Imperative mood
("add", not "added").
5. Show the proposed message. Do NOT run `git commit` until the
user confirms.
## Rules
- Never invent changes that are not in the diff.
- Never commit without explicit confirmation.
- If the diff spans unrelated changes, suggest splitting into
separate commits instead of writing one vague message.Why this one travels well: the required fields are standard, the description is loaded with trigger keywords so it actually fires, the only dependency is declared in compatibility, and there is not a single absolute path. That is the template. Anything you write that follows these four habits is portable by default.
Tool review: gh skill (GitHub CLI)
What it does: As of GitHub CLI v2.90.0 (released April 16, 2026), gh skill adds five subcommands: install, preview, search, update, and publish. It solves the most annoying part of cross-tool skills: remembering where each agent looks. gh skill install detects the active agent and drops the skill into the right directory automatically, whether that's .claude/skills, .github/skills, .agents/skills, or the home-directory equivalent.
Setup difficulty: Trivial if you already have GitHub CLI. Run gh --version, confirm you're on 2.90.0 or later, and you're done. Supported hosts at launch include Claude Code, Copilot, Cursor, Codex, Gemini CLI, and Antigravity.
Verdict: This is the missing package manager for skills. gh skill preview before you install is the feature that matters most: it lets you read what a skill actually does before it lands in a directory your agent executes from. Use it every time.
Watch out for: Skills run in the same context as your agent, with full file and shell access. gh skill install from an untrusted source is the same risk as curl | bash. Preview first, read the body, and never auto-install from a registry you don't trust. The convenience is real, and so is the attack surface.
Rating: Install it.
Own your skills, rent your models
Here's a quiet shift that matters more than any model release this quarter.
For two years, the thing you invested in was prompts, and prompts were trapped wherever you typed them. Now the thing you invest in is skills, and skills are portable, version-controlled folders that run in every agent that adopts the standard. That's a different relationship to your own work.
The model is a commodity. You'll swap it out three times this year and barely notice. But a well-written skill that you've refined across a dozen real tasks is an asset you own, and it now follows you across tools instead of dying inside one.
Build skills, not prompts. Keep them portable. The tool you use next year will thank you.
See you next week.
Michael
