You have built a new CLI. You watch Claude Code call --help a few times, and something becomes obvious: the agent is not confused by the tool. It is re-learning the same command surface on every task because there is no compact guide telling it where to start.
That is the problem a SKILL.md solves. It does not change the CLI. It gives the agent a shorter path into the same commands it would eventually figure out on its own.
What a skill is
A skill is a folder of Markdown instructions that Claude Code loads when a request matches a set of trigger phrases. For a CLI, a well-built skill has three layers:
- Frontmatter - the name, a description with trigger phrases, and an allowed-tools list
- Body - a focused command guide the agent reads once the skill fires
- References - extra docs the agent can consult when the main file is not enough
Each layer has a job. The frontmatter decides when the skill loads. The body decides what the agent does first. The references keep the main file short without losing detail.
Meet pokecli
pokecli is a Python CLI I built specifically so this article had a real, inspectable example: an actual tool with actual commands that you can install, run, and then study the skill alongside. The goal was not to build the most impressive CLI. The goal was to have something concrete enough to show the pattern end to end.
It queries Pokemon, berries, items, and moves, downloads sprites, and manages a local cache. Six top-level command groups, predictable output, and a clean structure that maps well into a skill body.
Install it with uv:
uv tool install git+https://github.com/jebucaro/pokecli
Then install the bundled skill into ~/.claude/skills/pokecli:
pokecli install --skills
What install --skills does
The skill files ship inside the installed package as package data. The command does not reach out to GitHub or generate anything. It reads the files bundled in the wheel and writes them to the right place on your machine.
In Python, that flow looks like this:
import shutil
from importlib import resources
from pathlib import Path
def install_skills():
skills_dest = Path.home() / ".claude" / "skills" / "pokecli"
skills_dest.mkdir(parents=True, exist_ok=True)
ref_dest = skills_dest / "references"
ref_dest.mkdir(exist_ok=True)
# Read files bundled as package data and write them to the destination
pkg = resources.files("pokecli.skills")
(skills_dest / "SKILL.md").write_text(
(pkg / "SKILL.md").read_text(encoding="utf-8")
)
(ref_dest / "api-fields.md").write_text(
(pkg / "references" / "api-fields.md").read_text(encoding="utf-8")
)
To make the skill files available as package data, declare them in pyproject.toml:
[tool.hatch.build.targets.wheel]
include = ["src/pokecli/skills/**"]
The key point is that the user does not need the repo checked out. The installed tool already carries the skill files. install --skills is just the command that puts them where Claude Code can find them.
Layer 1: The frontmatter trigger
The frontmatter is the part Claude reads all the time. It answers two questions fast: what does this skill do, and when should it load?
---
name: pokecli
description: Queries Pokémon, Berries, Items, and Moves data via the pokecli CLI. Use when the user needs to look up Pokémon stats, berries, items, or moves, download sprites, or manage the local cache. Also use when the user mentions "pokecli", "pokedex", or "PokeAPI"
allowed-tools: Bash(pokecli:*)
---
The description includes both the tool purpose and the phrases a user might actually say: pokedex, Pokemon stats, PokeAPI, download sprites. These are the real trigger words. A description that only describes the tool category without listing those phrases will miss requests.
The name should match the folder name so Claude can find the skill consistently.
Layer 2: The command guide
The body should read like a cheat sheet, not a tutorial. Short sections, command groups that mirror the CLI, examples you can copy and run.
pokecli has six top-level command groups: pokemon, berry, item, move, image, and cache. The skill body mirrors that structure:
pokecli pokemon get pikachu
pokecli berry get oran
pokecli item get master-ball
pokecli move get thunderbolt
## Core workflow
1. Query: Use `pokecli <resource> get <name_or_id>` to fetch details
2. Browse: Use `pokecli <resource> list` to paginate through all entries
3. Download: Use `pokecli image download pokemon <name> -o <path>` for sprites
4. Cache: Use `pokecli cache stats` and `pokecli cache clear` to manage local data
The agent does not need to know every flag before it starts. A quick start block and a workflow summary are enough for most requests. The rest of the command groups follow the same pattern: a few representative examples per group.
Layer 3: Reference files
Some questions do not belong in the main SKILL.md. What does base_experience mean for a Pokemon? Which sprite variants are usually available? Which fields are most useful when comparing moves?
That kind of detail goes in a separate file:
.claude/
└── skills/
└── pokecli/
├── SKILL.md
└── references/
└── api-fields.md
The main skill stays short and loads fast. The reference file is there when Claude needs the deeper detail. This keeps the skill easier to trigger and easier to maintain over time.
The allowed-tools line
This line matters more than it looks:
allowed-tools: Bash(pokecli:*)
It tells Claude Code that this skill is allowed to run pokecli commands, but not arbitrary shell commands. That is a useful boundary. The skill is not just a convenience layer; it also scopes what the agent can do when it fires.
Does it trigger correctly?
Before shipping a skill, test both sides of the trigger. These prompts should fire it:
- "Look up Pikachu's stats"
- "Show me berry data from PokeAPI"
- "Download a sprite for Charizard"
- "Compare Thunderbolt and Flamethrower"
These should not:
- "Help me write a Python class"
- "What is the weather today?"
- "Create a spreadsheet"
If a prompt that should trigger the skill does not, the description is missing the right phrase. Add it. If a prompt that should not trigger the skill does fire, the description is too broad. Narrow it.
This is a session where I asked Claude Code three different prompts. In none of them did I explicitly mention pokecli. Claude discovered the tool and how to use it entirely from the installed skill.
- "Look up Pikachu's stats"
- "Compare Thunderbolt and Flamethrower"
- "Download a sprite for Charizard"
The full version of this article goes deeper into the install flow, a side-by-side comparison with the Playwright CLI skill, a build-it-yourself challenge, and a walkthrough of the pokecli repo structure. You can find it at jonathanbucaro.com.
The key idea stays the same either way. You do not need to redesign a CLI to make it work well with an AI agent. In most cases, the missing piece is a compact guide that tells the agent when to reach for the tool and which commands to use first.
Pokémon and Pokémon character names are trademarks of Nintendo.



Top comments (0)