Skip to content

Blogclaude-code

How to share one skills repo between Claude Code and Codex

One skills repo can serve Claude Code and Codex through links, not copies. Measured on a working 102-skill repo: scoping each skill to its projects cut the always-loaded listing from 22,617 characters to a median of 7,080, and routers keep the rest on demand.

3hship6 min read

Share

Contents

A skills repo for Claude Code and Codex is one folder of skills plus links into each tool, and the part that decides what it costs is scope. On a working repo of 102 skills, scoping each skill to its projects cut the always-loaded listing from 22,617 characters to a median of 7,080.

The rest of this is the setup in the order that pays off: one source, short descriptions, routers that load references on demand, a scope per skill, explicit-only invocation, and one placement step with a check. Sizes are counted in characters from the repo’s files, because both tools state their limits in characters.

1. Lay out one repo for both tools

A skill is a folder with a SKILL.md file: a name and a description in YAML frontmatter, then instructions. Claude Code and Codex read the same format, so one folder serves both. They differ in where they look:

Tool User root Project root Also reads
Claude Code ~/.claude/skills .claude/skills Nested .claude/skills in subfolders, plugins, a managed enterprise location
Codex $HOME/.agents/skills .agents/skills, from the working directory up to the repo root /etc/codex/skills for admins, a bundled system set

Keep every skill in one repo and put only links in those roots. Codex follows symlinked skill folders, and a link keeps one source to edit. A copy in a root drifts from the source the first time one of them changes.

The repo measured here separates three things: authored skills under skills/<name>/, third-party skills vendored in their own folder, and a manifest for everything else. A skill folder holds SKILL.md, an optional references/ folder, an optional bin/ for command entrypoints it owns, and an optional agents/openai.yaml for Codex.

skills/<name>/
├── SKILL.md
├── references/ # loaded on demand
├── bin/ # optional command entrypoints
└── agents/openai.yaml # optional, Codex-only policy

2. Write a description that triggers and stays short

The listing is the name and description of every skill a session can see. It is in context from the first message, whether or not a skill is used, so it is the one cost every session pays.

Both tools cap it. Claude Code truncates description plus when_to_use at 1,536 characters per skill. Codex limits its initial list to 2 percent of the context window, or 8,000 characters when the window is unknown, and shortens descriptions first when a list runs over.

In the measured repo, descriptions average 212 characters (median 216), and the longest is 296. All sit under a house limit of 300 and far under the Claude Code cut. The repo’s rule is to state what activates the skill and name a nearby request that does not, as in the blog-post skill: “Use for drafting, rewriting or reviewing a post and citation-check failures; skip unrelated copywriting.”

3. Keep SKILL.md a router and load the rest on demand

The docs describe three levels of loading, called progressive disclosure. The same skill from the measured repo, split by what loads when:

Part Loads blog-post skill
Description Every session 214 characters
SKILL.md body When the skill triggers 2,610 characters, 43 lines
Reference files When SKILL.md sends the task to one 38,219 characters in 7 files

The description and the body are about 7 percent of the skill’s text (2,824 of 41,043 characters). The rest waits until a task needs it. SKILL.md stays a router: shared purpose, the constraints that always apply, and a list that says which reference to read for which kind of task.

Across the repo, 93 skills have references. Their SKILL.md files total 219,310 characters and their reference files 2,092,321, so the bodies hold about 9 percent of that content. The largest SKILL.md is 4,998 characters, just under the repo’s limits of 5,000 characters and 200 lines. Claude Code’s own advice is to stay under 500 lines.

4. Scope each skill to the projects that need it

Trimming a description saves characters in every session. Scoping removes the whole entry from the sessions that never need it. Each skill in the measured repo declares metadata.scope as global or a comma-separated list of project folder names. The sync step links a scoped skill into that project’s own .claude/skills and Codex skills folder, not into the user root.

Of the 102 skills, 29 are global and 73 are scoped across 26 project folders. What a session sees, counted as name plus description:

Placement Skills in the session Listing characters
Every skill global 102 22,617
Largest project session 57 12,534
Median project session 31 7,080
Smallest project session 30 6,744
Global skills only 29 6,600

The median session carries 69 percent less listing than the all-global layout. The 29 global skills set the floor, which is why the repo’s rule is to keep the global list small and give a skill the narrowest scope it really has.

These counts cover name and description only. Codex also lists each skill’s file path, so its real listing is longer. Against Codex’s 8,000-character fallback, the median session fits and the all-global layout does not. How much room a real window gives is set by the window, and the largest project session, at 12,534 characters, is the next one to trim.

5. Make skills you call by name explicit-only

Some skills should run only when named. In Codex, agents/openai.yaml with policy.allow_implicit_invocation: false stops the model from picking the skill from a prompt, and an explicit $skill call still works. In the measured repo, 11 of the 102 skills are set this way.

Claude Code has its own switch: disable-model-invocation: true in the frontmatter leaves the description out of context and loads the skill only when invoked. The measured repo does not use it, since its frontmatter rules keep invocation policy out of SKILL.md.

6. Place the skills with one step and a check

Placement is the one step that is easy to get wrong by hand. The measured repo does it with a single sync command that links every skill from its source into the right root and replaces nothing by hand. A second command fails on a real directory in a root (a copy), a link to anything but the declared source, a name visible twice in one session, and any entry in ~/.agents/skills.

That last rule comes from a root mismatch. The documented Codex user root is $HOME/.agents/skills, and the measured repo places its Codex links in ~/.codex/skills instead, so a link in both roots would show the same skill twice. Pick one root per tool and make the check fail on the other.

Without that tool, the same two moves are a link per skill and a search for anything that is not a link:

Terminal window
# one skill, scoped to one project, linked for both tools
ln -s ~/skills/skills/pdf-forms ~/code/app/.claude/skills/pdf-forms
ln -s ~/skills/skills/pdf-forms ~/code/app/.agents/skills/pdf-forms
# copies: any real directory in a skills root
find ~/code/app/.claude/skills ~/code/app/.agents/skills -mindepth 1 -maxdepth 1 -type d

Both ran once in a temporary directory: the links resolved to the skill’s SKILL.md, and the find printed nothing until a real folder was added, then printed only that folder. Whether each tool then lists the skill is the part to confirm in the tool itself.

7. Repeat it

  1. Keep one source. Put every skill in the repo and link it into the roots. Never edit a copy.
  2. Cut each description. State what triggers the skill and what does not, under a character limit you set.
  3. Make SKILL.md a router. Move procedures to references/ and link each with the task it serves.
  4. Give each skill a scope. Start narrow and widen only when a second project needs it.
  5. Count the listing. Sum name and description for each project’s view, and trim the largest.
  6. Check the placement. Fail on copies, duplicate names and a second root.

Verdict

Scope did most of the work. With every one of 102 skills global, each session would carry 22,617 characters of listing. With scopes, the median session carries 7,080, 69 percent less, and the largest carries 12,534. Routers and short descriptions keep the other side small: for the blog-post skill, 2,824 characters load up front and 38,219 wait in reference files. The decision it changes is where a skill goes before how it is worded, since a skill that sits in a project’s folder costs every other project nothing.

Responses

Sign in to write a response

Keep reading