Designing a hierarchical skill directory
A design guide for building a hierarchical skill directory — the Agent Skills open standard, and how different agent tools implement it.
The challenge
Creating agent skills one at a time is straightforward. However, as your team adds more skills for writing, code review, data tasks, deployment, evaluation, and operations, managing them becomes harder. The main challenge moves from just writing a solid SKILL.md to making sure agents can find the right skill without loading every instruction, reference file, and template all at once.
This guide treats a skill directory like a routing system. We’ll start by looking at the open SKILL.md standard, then explain what it covers and how teams often add their own catalog patterns. This matters because most tools already support built-in skill discovery, but using a structured CATALOG.md or INDEX.md gives teams more control if they need it.
Our goal is practical: to figure out when native discovery is enough, when building a custom hierarchy makes sense, and how to organize descriptions, folders, references, and project instructions so agents can always find what they need.
The baseline
The Agent Skills open standard at agentskills.io, published by Anthropic on 18 December 2025, sets out the SKILL.md format, a three-level progressive-disclosure model, and the scripts, references, and assets layout. (Anthropic Engineering, agentskills.io/specification)
Of the eight major agent platforms and coding environments covered here, seven use the core SKILL.md model. The only exception is Google Jules.
Another, less strict convention for project instructions is called AGENTS.md. Most of the tools reviewed here can read AGENTS.md directly. Claude Code uses a similar file named CLAUDE.md, but it can also use instructions from AGENTS.md by importing or symlinking the file.
The table shows how the agent platforms and coding environments compare to the core SKILL.md model:
| Tool | Implements the SKILL.md standard? | Notes |
|---|---|---|
| Claude Code | Yes — and is a superset | Created the format; adds many optional frontmatter fields |
| Claude Cowork | Yes — inherits Claude Code | No separate spec; same engine inside Claude Desktop |
| OpenAI Codex | Yes — “builds on the open standard” | Adds an agents/openai.yaml UI file |
| Cursor | Yes — explicit adoption | Reads .claude/ and .codex/ skill dirs for compatibility |
| Windsurf | Yes — explicitly cites agentskills.io | — |
| GitHub Copilot | Yes — “an open standard (agentskills.io)“ | Beware: a separate “skillsets” feature is unrelated |
| Google Antigravity | Yes — “Skills are an open standard” | Gemini-specific paths |
| Google Jules | No — no skills concept at all | Uses AGENTS.md + setup scripts only |
The routing
A skill directory is a list of main skills and sub-skills. It helps an agent find the right skill without having to remember everything at once. By showing only basic details that can be explored further, it keeps things simple.
This method is known as progressive disclosure. The rest of this guide will explain the idea, show what is standard and what is custom, give a clear folder design, and describe the rules and limits for eight different tools.
The main idea is the same for all the tools reviewed. Every tool that can use skills, except Jules, uses progressive disclosure to keep context use low.
Progressive disclosure
This process has three main stages:
- Discovery: When the agent starts, it only loads the name and description of each installed skill from the YAML frontmatter. Nothing else is loaded at this point.
- Activation: If a task matches a skill’s description, the agent loads the full
SKILL.mdcontent for that skill. - Execution: The agent follows the instructions and loads scripts, templates, or reference documents only when they are needed.
The benefit is that you can register hundreds of skills without any context penalty. (agentskills.io/specification, Claude Platform Docs)
The table presents three levels of the standard and their budgets:
| Level | What loads | When | Rough size |
|---|---|---|---|
| 1 — Metadata | name + description | Always, at startup | ~100 tokens per skill |
| 2 — Instructions | The body of SKILL.md | On activation (task matches) | < 5,000 tokens (recommended) |
| 3 — Resources | scripts/, references/, assets/ | On demand, during execution | Effectively unbounded |
- Confirmed in Claude Code, Codex, Cursor, Windsurf, Copilot, and Antigravity. The documented standard includes three levels. You can add a custom four-step layer, such as catalog, category, sub-skill, and resources. This will not compete with the official standard.
- For Claude Code, once you use a skill, its
SKILL.mdfile stays in context for the rest of the session and is not re-read each turn. When auto-compaction happens, invoked skills are re-attached, keeping the first 5,000 tokens from each, up to a total of about 25,000 tokens. (Claude Code Skills)
The standard skill structure
Each skill is organized in the same way:
skill-name/
├── SKILL.md # REQUIRED: YAML frontmatter (name + description) + markdown instructions
├── scripts/ # optional: executable code for deterministic steps
├── references/ # optional: detailed docs loaded only when needed
└── assets/ # optional: templates, schemas, data files
Frontmatter limits:
name: Use lowercase letters, numbers, and hyphens. The name should be 64 characters or fewer, not start or end with a hyphen, and not contain consecutive hyphens (--). It must match the parent directory name.description: This field cannot be empty and should be no longer than 1,024 characters. It must explain what the skill does and when to use it.- Optional standard fields include:
license,compatibility(up to 500 characters),metadata, andallowed-tools(experimental).
- All tools listed here—Claude, Codex, Cursor, Windsurf, Copilot, and Antigravity—enforce a 64-character limit for names and a 1,024-character limit for descriptions.
- The reserved words “anthropic” and “claude” are only restricted in Anthropic products. This rule is not part of the open specification, and tools like Codex and Cursor do not enforce it. According to the open specification, the
namemust match the directory name. Cursor, Copilot, and Codex enforce this rule. In Claude Code, however,nameis optional and will default to the folder name if not specified.- In practice, the naming of
references/andassets/is flexible, while onlyscripts/is used consistently across all tools. Anthropic’s product documentation often uses flat files likeREFERENCE.mdorFORMS.md, or areference/directory. Antigravity uses directories such asscripts/,examples/, andresources/, while Copilot usesscripts/andexamples/. The names mentioned above are considered the standard’s canonical names, but they are not strictly required.- Each tool may include extra files or fields. For example, Codex can add an optional
agents/openai.yamlfile for UI metadata and invocation policy. Claude Code supports several optional frontmatter fields, such aswhen_to_use,allowed-tools,model,context: fork,paths, andhooks. Copilot adds fields likeuser-invocable,disable-model-invocation, and an experimentalcontext: fork.- If the
namefield contains an invalid character in Copilot, the skill will fail to load without any error message.
A recommended directory design
A tree that keeps the catalog thin and lets the agent drill down:
CATALOG.md ← Level 0: always in context (~1 line per CATEGORY)
│
├── documents/
│ ├── INDEX.md ← Level 1: category overview (~1 line per sub-skill)
│ ├── docx/
│ │ ├── SKILL.md ← Level 2: actual instructions (< 5,000 tokens)
│ │ └── references/ ← Level 3: deep docs, scripts, templates
│ ├── pdf/SKILL.md
│ └── xlsx/SKILL.md
│
├── data/
│ ├── INDEX.md
│ └── analysis/SKILL.md
│
└── code/
├── INDEX.md
└── review/SKILL.md
Flow: the agent reads CATALOG.md, matches a category and opens its INDEX.md, matches a sub-skill and loads its SKILL.md, then loads references/ and scripts/ only when executing.
The design extends the golden truth.
The open standard includes SKILL.md, progressive disclosure, and optional folders like scripts/, references/, and assets/. It does not cover sub-skills, skill categories, or formats like CATALOG.md or INDEX.md. Creating a catalog-to-category-to-skill-to-resources drill-down is a valid custom extension, especially when you control the routing layer.
Currently, no tool supports a CATALOG.md with category-based INDEX.md drill-down by default. Instead, platforms create the discovery interface automatically by loading each skill’s metadata. There are two possible approaches from here.
Path A – Native discovery (recommended). Add skills to the tool’s skill directory so it can automatically load their details. Use “Categories” as a naming and description rule. For example, start every document skill’s description with “Document processing –”. The location of the skill directory depends on the tool you are using:
| Tool | Where skills live |
|---|---|
| Claude Code / Cowork | .claude/skills/<name>/SKILL.md (+ plugin skills, namespaced plugin:skill) |
| OpenAI Codex | .agents/skills/ (scanned CWD → repo root), ~/.agents/skills/, /etc/codex/skills, system |
| Cursor | .agents/skills/, .cursor/skills/, ~/.agents/skills/, ~/.cursor/skills/ (+ reads .claude/, .codex/) |
| Windsurf | .windsurf/skills/, ~/.codeium/windsurf/skills/ (+ .agents/, .claude/) |
| GitHub Copilot | .github/skills/, .claude/skills/, .agents/skills/, ~/.copilot/skills/ |
| Google Antigravity | .agents/skills/, ~/.gemini/config/skills/ |
| Google Jules | — (no skills) |
Path B: Custom catalog (explicit drill-down). Create CATALOG.md or INDEX.md as actual routing files only if you are using a custom agent or harness that requires strict control over preloaded content. In this setup, you manage the routing logic yourself.
The types of nesting tools support, that are the closest to categories:
- Cursor lets you use nested skill folders to group by category, team, or domain. The category folder is just for organization, and discovery checks all folders in the tree. This is the closest match to categories.
- Claude Code works with nested
.claude/skills/folders and handles naming conflicts by using the directory, likeapps/web:deploy. This is namespacing, not a true category system. - Codex scans
.agents/skillsstarting from the current working directory up to the root of the repository. - In both Claude Code and Codex, plugins are the main way to package and group skills above the individual level.
In all cases, the rule stays the same: top-level files are only used for routing, not for carrying instructions.
Project instructions: AGENTS.md vs CLAUDE.md
In addition to skills, each tool includes an instructions file that is always available for the project context. The new standard for this across different tools is called AGENTS.md.
| Tool | Always-on instructions file | AGENTS.md? |
|---|---|---|
| Claude Code | CLAUDE.md (≤ ~200 lines advised; @import up to 4 hops) | No — must @import or symlink it; /init can fold it in |
| Claude Cowork | Global + per-folder instructions (Claude can self-edit) | Via the Claude Code path |
| OpenAI Codex | AGENTS.md (global + per-dir, merged root→CWD; 32 KiB default cap) | Yes |
| Cursor | .cursor/rules/*.mdc (4 activation types) or AGENTS.md (nested supported) | Yes |
| Windsurf | .windsurf/rules/*.md (12,000 chars/file; global rules 6,000) | Yes (root = always-on, subdir = glob) |
| GitHub Copilot | .github/copilot-instructions.md + .instructions.md (applyTo glob) | Yes (+ reads CLAUDE.md, GEMINI.md) |
| Google Antigravity | GEMINI.md + .agents/rules/ (12,000 chars/file) | Yes |
| Google Jules | AGENTS.md (its only customization surface) + setup scripts | Yes |
AGENTS.mdis the main standard for project instructions, and six out of eight tools read it directly. Claude Code usesCLAUDE.mdby default, but it can also import or link toAGENTS.mdto use the same instructions.- There is a clear difference between skills and instructions. Facts needed in every session should go in
CLAUDE.mdorAGENTS.md. Multi-step procedures that load only when needed should be added as skills. Claude Code explains this directly.- Rules systems work differently from skills. Cursor “rules” and Windsurf “rules” use a “model decision” mode that matches the description, a type of mini progressive disclosure. However, these are not skills and do not include scripts or assets in the same way. Windsurf sets strict character limits (12,000 per file, 6,000 global), while the skills standard only gives line and token recommendations.
Design guidelines
Rule 1: One skill, one job. Each skill should cover just one task or area. Avoid catch-all skills.
- This is a universal rule. Every tool’s best-practices guide says to keep skills focused and to split up large skills.
Rule 2: The description is the routing key. The agent discovers skills before seeing how they work. Clearly state what the skill does and when to use it, using specific trigger words. Write in the third person and be assertive, since agents often miss triggers.
- This rule is universal and strongly emphasized. Codex says to “front-load the key use case and trigger words so [it] can still match the skill if descriptions are shortened.” Anthropic recommends writing in the third person and considers descriptions the most important field.
Rule 3: Keep the catalog tiny. The preloaded index should be short, with only one or two lines for each entry.
- OpenAI Codex: The initial list is limited to 2% of the context window (measured in tokens), or 8,000 characters if the window size is unknown. If you exceed this, shorten descriptions first, then remove skills with a warning. This limit is hardcoded and not configurable (feature request #19679 is still open as of June 2026).
- Claude Code: The listing budget is about 1% of the context window by default and can be adjusted (
skillListingBudgetFraction, for example,0.02means 2%). Each entry is limited to 1,536 characters (maxSkillDescriptionChars). The least-used skills are dropped first. You can check this with/doctor.- Cursor, Windsurf, Copilot, and Antigravity do not publish a specific numeric catalog cap. They use the same preload-metadata and load-on-demand approach. Using about 1–2% of the context window, as in Codex and Claude, is a safe guideline for all tools.
- Key point: Place the most important trigger words at the beginning of each description so they are not lost if the text is shortened.
Rule 4: Decide what to take away from the agent. Anything that must stay consistent across runs should go in a script, template, or strict rule, not in prose for the model to interpret.
- This is supported by the standard, which says to “use scripts for deterministic reliability,” and by Antigravity, which advises to “use scripts as black boxes; run with
--helprather than reading the source.”
Rule 5: Write a constitution, not a suggestion. The more specific your SKILL.md is, the less room there is for improvisation.
- This matches Anthropic’s advice that “concise is key / the context window is a public good” and Copilot’s focus on “non-obvious rules.”
Rule 6 — Match instruction freedom to task risk (degrees of freedom). High freedom (open-ended, e.g. code review) → text guidance; medium (preferred-but-flexible, e.g. a runbook) → pseudocode or parameterized scripts; low (fragile or catastrophic, e.g. DB migrations) → exact scripts, “do not modify.”
- This rule comes directly from Anthropic’s best-practices document and is the most widely cited guideline.
Rule 7: Say when to activate, not just what to do. For auto-triggering, the description (and optionally a “when to use” line) must give the agent clear criteria to match.
- This is a universal rule. Both Codex and Anthropic say to include all “when to use” information in the description, since the body loads only after triggering.
Rule 8: Use relative paths, never hardcoded absolute ones. This keeps skills portable.
- This is a universal rule. The standard requires forward slashes, and Copilot needs extra files to be referenced with relative Markdown links, or they “won’t be picked up.”
Rule 9: Keep the reference graph one hop deep. Every reference file should be directly linked from SKILL.md. Avoid chains like SKILL.md → advanced.md → details.md, since the agent may only read part of deeper files. For files with more than about 100 lines, add a table of contents.
- This rule is stated in the best practices for Anthropic, Codex, and Cursor.
Size budgets
| Item | Limit | Source / scope |
|---|---|---|
name | ≤ 64 chars | Golden truth (all tools) |
description | ≤ 1,024 chars | Golden truth (all tools) |
CATALOG.md / INDEX.md entry | 1–2 lines each | Custom layer |
| Preloaded index total | ~1–2% of context (Codex: 2% / 8,000 chars; Claude Code: ~1% default, configurable) | Codex and Claude Code; others unquantified |
| Per-entry listing cap | 1,536 chars | Claude Code (maxSkillDescriptionChars) |
SKILL.md body | < 5,000 tokens and < 500 lines | Golden truth (recommendation) |
| Cursor rule file | < 500 lines | Cursor |
| Windsurf rule file | 12,000 chars (global 6,000) | Windsurf (hard cap) |
| Antigravity rule/workflow file | 12,000 chars | Antigravity (hard cap) |
| Copilot cloud custom-agent prompt | 30,000 chars | Copilot |
references/, scripts/, assets/ | Effectively unbounded | Golden truth |
The skill limits are recommendations in the standard but become hard caps in some rule systems (Windsurf, Antigravity). A generous skill budget does not transfer to a tool’s rules files.
Why this works
Loading every skill at once is not just wasteful — it degrades the agent: attention dilution (instruction-following drops), wasted tokens, and pattern conflation (skills bleed together). Progressive disclosure loads only what’s relevant, when it’s relevant — “just-in-time intelligence.” Hierarchical retrieval (coarse category → fine sub-skill) is the same principle applied to finding the skill.
Across the tools: Universally endorsed rationale. Copilot states it directly: “this three-level loading system means you can install many skills without consuming context.” No tool disputes it.
Risks and mitigations
| Risk | Mitigation | Cross-tool note |
|---|---|---|
| Catalog grows fat and gets truncated, hiding skills | Cap entries at 1–2 lines; front-load trigger words | Codex truncates then omits skills with a warning; Claude Code drops least-used first |
| Agent under-triggers a skill | ”Pushy,” third-person, what + when descriptions | Explicitly recommended by Anthropic and Codex |
| Sub-skills overlap or conflate | Single responsibility; mutually distinct descriptions | Universal |
| Deep reference chains read only partially | One-hop reference graph | Standard rule |
| Inconsistent output across runs | Move invariants into scripts and templates | Standard + Antigravity “black box scripts” |
| Broken portability | Relative paths only | Copilot fails silently otherwise |
| Building a custom catalog the platform already provides | Use native discovery unless self-hosting a harness | Directory design, Path A |
| Assuming one tool’s limits apply everywhere | Check each tool: Windsurf and Antigravity 12k-char rule caps; Codex 2% hardcoded | See size budgets |
Relying on AGENTS.md in Claude Code | Import or symlink it from CLAUDE.md, or use CLAUDE.md directly | Claude Code uses CLAUDE.md natively |
| Expecting skills in Jules | Jules has none — use AGENTS.md + setup scripts | The baseline |
Implementation checklist
- Pick the target tool(s) and confirm their skill directory location in the directory-design table. To target several, place skills in
.agents/skills/— the path most tools read in common. - Inventory capabilities; group into ~5–9 categories.
- Choose native discovery (Path A) vs. custom catalog (Path B). Default to native.
- List each sub-skill as a one-line entry; encode “categories” in description prefixes when using native discovery.
- For each skill, create
skill-name/SKILL.md:name≤ 64 chars matching the folder, a what-and-whendescription≤ 1,024 chars (third person, trigger words first), body < 500 lines / 5,000 tokens. - Push deterministic steps into
scripts/, deep docs intoreferences/, templates intoassets/— each one hop fromSKILL.md. - Add an
AGENTS.mdfor always-on project facts (and aCLAUDE.mdor@importfor Claude Code). - Test discovery with realistic tasks; tighten descriptions where the agent mis-routes or under-triggers. (Claude Code:
/doctor; Codex: watch for the budget warning.) - Iterate; build skills incrementally to fill observed gaps.
Summary
Keep the catalog ultra-thin, let the agent drill down on demand, scope each skill to one job, and make every description carry its own routing weight. Build on the agentskills.io standard rather than a parallel one, and treat the category and sub-skill drill-down as a deliberate custom layer on top.
Sources
The open standard:
- Agent Skills open standard — agentskills.io · Specification
- Equipping agents for the real world with Agent Skills — Anthropic Engineering
Claude Code / Cowork:
- Agent Skills overview — Claude Platform Docs · Best practices
- Skills — Claude Code Docs · Memory / CLAUDE.md · Subagents
- Get started with Cowork · Use plugins in Claude/Cowork
OpenAI Codex:
- Agent Skills — Codex · AGENTS.md guide · openai/skills repo · Issue #19679 (2% budget configurability)
Cursor:
Windsurf:
GitHub Copilot:
- Agent Skills (VS Code) · Custom instructions · Prompt files · About Agent Skills (GitHub) · Skillsets (distinct concept)
Google Antigravity:
Google Jules: