DEV Community

Cover image for Teach Claude Code how to use your CLI with SKILLS.md
Jonathan Búcaro
Jonathan Búcaro

Posted on • Originally published at jonathanbucaro.com

Teach Claude Code how to use your CLI with SKILLS.md

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:

  1. Frontmatter - the name, a description with trigger phrases, and an allowed-tools list
  2. Body - a focused command guide the agent reads once the skill fires
  3. 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 command tool running the help command

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
Enter fullscreen mode Exit fullscreen mode

pokecli installation with uv

Then install the bundled skill into ~/.claude/skills/pokecli:

pokecli install --skills
Enter fullscreen mode Exit fullscreen mode

installing pokecli 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")
    )
Enter fullscreen mode Exit fullscreen mode

To make the skill files available as package data, declare them in pyproject.toml:

[tool.hatch.build.targets.wheel]
include = ["src/pokecli/skills/**"]
Enter fullscreen mode Exit fullscreen mode

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:*)
---
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
## 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:*)
Enter fullscreen mode Exit fullscreen mode

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"
Using pokecli with Claude Code
You

Look up Pikachu's stats

Agent
You

Base directory for this skill: [REDACTED]/.claude/skills/pokecli

Pokémon Data Lookup with pokecli

Quick start

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

Responses are cached locally after the first request. Use --no-cache to force a fresh fetch.

Commands

Pokemon

pokecli pokemon get pikachu
pokecli pokemon get 25
pokecli pokemon get charizard --format json
pokecli pokemon get bulbasaur --no-cache
pokecli pokemon list
pokecli pokemon list --limit 50
pokecli pokemon list --limit 20 --offset 40
pokecli pokemon moves charmander
pokecli pokemon moves 4 --format json

Berry

pokecli berry get cheri
pokecli berry get 1
pokecli berry get oran --format json
pokecli berry list
pokecli berry list --limit 10
pokecli berry list --limit 10 --offset 20

Item

pokecli item get potion
pokecli item get 1
pokecli item get master-ball --format json
pokecli item list
pokecli item list --limit 30
pokecli item list --limit 30 --offset 60

Move

pokecli move get thunderbolt
pokecli move get 24
pokecli move get surf --format json
pokecli move get flamethrower --no-cache
pokecli move list
pokecli move list --limit 40
pokecli move list --limit 20 --offset 100

Image Download

pokecli image download pokemon pikachu -o pikachu.png
pokecli image download pokemon pikachu -o pikachu_shiny.png --variant front_shiny
pokecli image download pokemon 6 -o charizard_back.png --variant back_default
pokecli image download pokemon 133 -o /tmp/eevee.png

Sprite variants: front_default, front_shiny, back_default, back_shiny, front_female, front_shiny_female

Cache Management

pokecli cache stats
pokecli cache clear
pokecli cache clear --resource pokemon
pokecli cache clear --resource item

Global options

Option Description
--no-cache Bypass local cache, fetch fresh from PokeAPI
--format table Rich formatted table output (default)
--format json Raw JSON with syntax highlighting

Example: Compare two Pokémon

pokecli pokemon get charizard
pokecli pokemon get blastoise

Example: Browse and then inspect

pokecli move list --limit 10
pokecli move get pound

Example: Download all starters

pokecli image download pokemon bulbasaur -o bulbasaur.png
pokecli image download pokemon charmander -o charmander.png
pokecli image download pokemon squirtle -o squirtle.png

Example: Look up moves a Pokémon can learn

pokecli pokemon moves pikachu
pokecli pokemon moves charizard --format json

Troubleshooting

For detailed command reference and data field descriptions, consult references/api-fields.md.

ARGUMENTS: Pikachu stats

Agent
Agent

Here are Pikachu's base stats:

Stat Value
HP 35
Attack 55
Defense 40
Sp. Attack 50
Sp. Defense 50
Speed 90

Pikachu is a pure Electric type with decent Speed being its standout stat. Its abilities are Static (may paralyze on contact) and the hidden ability Lightning Rod (draws Electric moves, raises Sp. Atk).

You

Compare Thunderbolt and Flamethrower

Agent
Agent
Agent

They're nearly identical moves — just different types and status effects:

Thunderbolt Flamethrower
Type Electric Fire
Category Special Special
Power 90 90
Accuracy 100% 100%
PP 15 15
Effect 10% Paralyze 10% Burn

The only meaningful differences:
- Paralysis (Thunderbolt) halves the target's Speed and has a chance to skip turns — generally considered the stronger status
- Burn (Flamethrower) deals chip damage each turn and halves the target's Attack (less useful against special attackers)

Both are among the most reliable moves in the game. Choice between them comes down to type coverage needed on your team.

You

Download a sprite for Charizard

Agent
Agent

Charizard's sprite has been saved to charizard.png in your current directory ([REDACTED]/development/pokecli/charizard.png).

If you want other variants, options include: front_shiny, back_default, back_shiny, front_female, front_shiny_female.


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.


Photo by Jay on Unsplash

Pokémon and Pokémon character names are trademarks of Nintendo.

Top comments (0)