Making a Python CLI AI Native With SKILL.md

🎯 TL;DR

This post shows how to make a Python CLI easier for Claude Code to use. I use a new tool called pokecli as the example and add a small SKILL.md that gives the agent a clear command guide.

The goal is not to change how the CLI works. It is to stop the agent from re-learning the same help text during the task. A good skill gives Claude Code a shorter path into the tool, with clear triggers, command groups, examples, and a small reference file when extra detail is needed.

Choose your path:


🤔 Why I Built This?

I recently gave an internal tech talk at work called Make Your CLI Tools AI-Native with SKILL.md. The feedback was a good signal that the idea landed, but it also made something clear: I needed a practical example people could inspect and reuse.

This post is that example.

I like CLIs that do one thing well, and pokecli is a good example of that. It has a clean command surface, clear output, and a workflow that feels natural in the terminal.

What I wanted to show is that you do not need to redesign a CLI to make it more useful for an AI agent. In many cases, the missing piece is a compact guide that tells the agent when to use the tool, which commands exist, and how to apply them safely.


📸 See It In Action

After installing pokecli and the respective skill, the end result is a small skill folder that Claude Code can load when a request matches the right trigger phrases:

pokecli-skill/
└── skills/
    └── pokecli/
        ├── SKILL.md
        └── references/
            ├── api-fields.md
            └── workflows.md

Once installed into ~/.claude/skills/pokecli, Claude Code gets a much clearer picture of how to use the tool:

  • When to reach for pokecli
  • Which commands belong to each resource
  • Which flags are shared across get commands
  • How to download sprites
  • How to inspect and clear the local cache

This is the same core idea used by Microsoft’s Playwright CLI ➡️ skill: keep the always-loaded trigger small, keep the main body focused, and push extra detail into reference files only when needed.


💡 The Problem (In 60 Seconds)

CLI help text is great for humans. The problem is not that an agent cannot use it. The problem is that the agent has to keep re-learning the same command surface during the task.

If an agent only sees raw help output, it still has to answer basic questions during the task:

  • Which resource groups exist?
  • Which commands support --no-cache?
  • Which output formats are available?
  • How do image downloads work?
  • Which cache commands are safe to run?

That means the model spends part of its context budget re-learning the tool instead of solving the user’s request.

This is the real value of a skill. It turns a CLI into a smaller, more direct interface for an agent.


✨ The Solution

A skill is a folder of Markdown instructions that teaches an AI agent how to use a tool or follow a workflow.

For Claude Code, a well-built skill usually has three layers:

  1. Frontmatter: the skill name, description, and allowed tools
  2. SKILL.md body: the command guide the agent reads when the skill triggers
  3. References: extra docs loaded only when the main file is not enough

This pattern matters because it keeps the default context small.

The frontmatter does the triggering work. The body gives the agent a short, practical command map. The references hold the field-level detail that only matters in a few cases.

That is the pattern I want to apply to pokecli.


🚀 Quick Start

Install the CLI with uv

Important This requires uv to be installed on your machine first. To install uv, you can follow the guide on the Astral site ➡️ .
uv tool install git+https://github.com/jebucaro/pokecli

You can later uninstall the tool running the following command.

uv tool uninstall pokecli

Install the Claude skill

pokecli install --skills

You could also copy the skill files into place by hand or do the same step with a small script. I added install --skills to make the example complete and easy to run.

Optional: local dev setup

git clone https://github.com/jebucaro/pokecli
cd pokecli
uv sync
uv run pokecli --help

pokecli still has a few obvious top-level command groups like pokemon, berry, item, move, image, and cache, but the current repo also ships many resource-specific commands that all follow the same contract. In practice, the important pattern for the skill is not the exact top-level count. It is that most resources support get <name_or_id> and list, while Pokemon adds extra navigation commands like moves, species, evolution, encounters, and forms.

Test the CLI before writing the skill

Add uv run before each command if you are testing locally with the dev setup

pokecli pokemon get pikachu
pokecli berry list --limit 5
pokecli image download pokemon 25 -o /tmp/pikachu.png
pokecli cache stats
Note The skill does not replace the CLI documentation. It gives Claude Code a smaller and more useful entry point into the same command surface.

📦 Results

This is a condensed excerpt of the packaged SKILL.md pattern I ship with pokecli. The current repo version is longer because it now covers more resources, includes a decision tree, and points to both field-level and workflow references.

---
name: pokecli
description: Queries Pokémon, Berries, Items, Moves, Abilities, Types, Natures, evolution chains, species, egg groups, growth rates, machines (TM/HM), Pokemon forms, versions, version groups, regions, locations, location areas, generations, and pokedexes via the pokecli CLI. Use when the user needs to look up Pokémon stats, type matchups, abilities, natures, evolution chains, berries, items, moves, TMs, breeding compatibility, alternative forms, encounter locations, regional pokedexes, generation rosters, game versions, download sprites, or manage the local cache. Also use when the user mentions "pokecli", "pokedex", or "PokeAPI"
allowed-tools: Bash(pokecli:*)
---

# Pokémon Data Lookup with pokecli

## Quick start

```bash
pokecli pokemon get pikachu
pokecli type get fire
pokecli ability get intimidate
pokecli nature get modest
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. Evolve: Use `pokecli pokemon evolution <name>` to see the full evolution chain
4. Species: Use `pokecli pokemon species <name>` for Pokédex entries, capture rate, egg groups
5. Download: Use `pokecli image download pokemon <name> -o <path>` for sprites
6. 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.

**Uniform contract:** every resource supports `get <name_or_id>` and `list [--limit --offset]` with `--format table|json` and `--no-cache`. The Pokemon resource adds `moves`, `species`, and `evolution` sub-commands because each maps to a different API endpoint.

## Decision tree

Pick the right command for a given user intent. When in doubt, every resource supports `pokecli <resource> get <name_or_id>`.

| User intent                                        | Command                                             |
| -------------------------------------------------- | --------------------------------------------------- |
| Pokemon stats, types, abilities                    | `pokecli pokemon get <name>`                        |
| Moves a Pokemon can learn                          | `pokecli pokemon moves <name>`                      |
| Pokedex entry, egg groups, capture rate            | `pokecli pokemon species <name>`                    |
| Full evolution chain for a Pokemon                 | `pokecli pokemon evolution <name>`                  |
| Where can I catch this Pokemon?                    | `pokecli pokemon encounters <name>`                 |
| All varieties/forms (Mega, Alolan, Gmax)           | `pokecli pokemon forms <name>`                      |
| What does an ability do?                           | `pokecli ability get <name>`                        |
| What stats does a nature affect?                   | `pokecli nature get <name>`                         |
| Type matchups (weak/resists/immune)                | `pokecli type get <name>`                           |
| Berry profile / item description / move details    | `pokecli {berry,item,move} get <name>`              |
| What does an egg group mean? (breeding)            | `pokecli egg-group get <name>`                      |
| What growth rate does X use?                       | `pokecli growth-rate get <name>`                    |
| What does damage class X mean?                     | `pokecli move-damage-class get <name>`              |
| What does learn method X mean?                     | `pokecli move-learn-method get <name>`              |
| What does evolution trigger X mean?                | `pokecli evolution-trigger get <name>`              |
| What game is X (e.g. Pokemon Red)?                 | `pokecli version get <name>`                        |
| What versions belong to group X (e.g. red-blue)?   | `pokecli version-group get <name>`                  |
| What TM/HM is machine #N?                          | `pokecli machine get <id>`                          |
| Inspect a specific form/variety                    | `pokecli pokemon-form get <form-name>`              |
| All locations in a region                          | `pokecli region get <region>` (renders inline)      |
| What Pokemon live at this location?                | `pokecli location-area get <area>` (renders inline) |
| Sub-areas of a location                            | `pokecli location get <name>` (renders inline)      |
| Pokemon/moves introduced in Gen N                  | `pokecli generation get <gen>` (renders inline)     |
| Regional Pokedex listing (entry numbers + species) | `pokecli pokedex get <name>` (renders inline)       |
| Evolution chain by chain ID (not by Pokemon name)  | `pokecli evolution-chain get <id>`                  |
| Download a Pokemon sprite                          | `pokecli image download pokemon <name> -o <path>`   |
| Any resource not listed above                      | `pokecli <resource> get <name>` — uniform contract  |

## Multi-step workflows

For multi-resource recipes (regional encounter lookup, TM tracing, full Pokemon
profile assembly, decoding cross-reference fields), see `references/workflows.md`.

## Commands

### Pokemon

```bash
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
pokecli pokemon moves pikachu --move thunderbolt
pokecli pokemon moves pikachu --move thunderbolt --format json
pokecli pokemon moves eevee --method egg
pokecli pokemon moves charizard --method level-up
pokecli pokemon species pikachu
pokecli pokemon species mewtwo --format json
pokecli pokemon evolution eevee
pokecli pokemon evolution bulbasaur --format json
pokecli pokemon encounters pikachu
pokecli pokemon encounters 25 --format json
pokecli pokemon forms charizard
pokecli pokemon forms vulpix --format json
```

### Ability

```bash
pokecli ability get intimidate
pokecli ability get 22
pokecli ability get levitate --format json
pokecli ability list
pokecli ability list --limit 20 --offset 40
```

### Nature

```bash
pokecli nature get modest
pokecli nature get 3
pokecli nature get jolly --format json
pokecli nature list
pokecli nature list --limit 25
```

### Type

```bash
pokecli type get fire
pokecli type get 10
pokecli type get dragon --format json
pokecli type get ghost --no-cache
pokecli type list
```

### Berry

```bash
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

```bash
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

```bash
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
```

### Egg Group

```bash
pokecli egg-group get monster
pokecli egg-group get human-like
pokecli egg-group get 1 --format json
pokecli egg-group list
```

### Growth Rate

```bash
pokecli growth-rate get medium-slow
pokecli growth-rate get slow
pokecli growth-rate get 1 --format json
pokecli growth-rate list
```

### Evolution Trigger

```bash
pokecli evolution-trigger get level-up
pokecli evolution-trigger get use-item
pokecli evolution-trigger get 1 --format json
pokecli evolution-trigger list
```

### Move Damage Class

```bash
pokecli move-damage-class get physical
pokecli move-damage-class get special
pokecli move-damage-class get status --format json
pokecli move-damage-class list
```

### Move Learn Method

```bash
pokecli move-learn-method get level-up
pokecli move-learn-method get machine
pokecli move-learn-method get egg --format json
pokecli move-learn-method list
```

### Version

```bash
pokecli version get red
pokecli version get sword
pokecli version get 1 --format json
pokecli version list
```

### Version Group

```bash
pokecli version-group get red-blue
pokecli version-group get sword-shield
pokecli version-group get 1 --format json
pokecli version-group list
```

### Machine (TM/HM)

```bash
pokecli machine get 1
pokecli machine get 100 --format json
pokecli machine list --limit 50
```

### Pokemon Form

```bash
pokecli pokemon-form get charizard-mega-x
pokecli pokemon-form get vulpix-alola
pokecli pokemon-form get pikachu-gmax --format json
pokecli pokemon-form list --limit 50
```

### Region

```bash
pokecli region get kanto
pokecli region get hoenn --format json
pokecli region list
```

The `get` output includes the region's full list of child locations inline.

### Location

```bash
pokecli location get pallet-town
pokecli location get kanto-route-1
pokecli location get celadon-city --format json
pokecli location list --limit 50
```

The `get` output includes the location's sub-areas inline.

### Location Area

```bash
pokecli location-area get kanto-route-1-area
pokecli location-area get trophy-garden-area --format json
pokecli location-area list --limit 50
```

The `get` output includes the full Pokemon encounter table for the area
(pokemon × version × method × chance × levels).

### Generation

```bash
pokecli generation get generation-i
pokecli generation get generation-iii --format json
pokecli generation list
```

The `get` output includes counts and full lists of Pokemon species and moves
introduced in that generation.

### Pokedex

```bash
pokecli pokedex get kanto
pokecli pokedex get national --format json
pokecli pokedex list
```

The `get` output includes the full numbered entries list for the pokedex.

### Evolution Chain

```bash
pokecli evolution-chain get 67
pokecli evolution-chain get 1 --format json
pokecli evolution-chain list --limit 50
```

Reuses the same tree rendering as `pokecli pokemon evolution`, but accepts a
chain ID directly (useful when you already have one from another response).

### Image Download

```bash
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

```bash
pokecli cache stats
pokecli cache clear
pokecli cache clear --resource pokemon
pokecli cache clear --resource ability
pokecli cache clear --resource nature
pokecli cache clear --resource type
pokecli cache clear --resource pokemon-species
pokecli cache clear --resource evolution-chain
pokecli cache clear --resource item
pokecli cache clear --resource machine
pokecli cache clear --resource egg-group
pokecli cache clear --resource version-group
```

Other cacheable resources: `move-damage-class`, `move-learn-method`, `growth-rate`, `evolution-trigger`, `version`, `pokemon-form`, `location`, `location-area`, `region`, `generation`, `pokedex`. Run `pokecli cache stats` for the full list.

## 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            |

> **For AI agents:** Prefer the default table output — it is plain text you can
> read directly. Use `--format json` only when you need to pipe the output to
> `jq` or a shell script. Raw JSON is not easier to process; it requires extra
> parsing steps that table output avoids entirely.

## `pokemon moves` options

| Option              | Description                                                       |
| ------------------- | ----------------------------------------------------------------- |
| `--move <name>`     | Filter to a specific move; exits 1 if the Pokémon cannot learn it |
| `--method <method>` | Filter by learn method: `level-up`, `machine`, `tutor`, `egg`     |

## Example: Compare two Pokémon

```bash
pokecli pokemon get charizard
pokecli pokemon get blastoise
```

## Example: Browse and then inspect

```bash
pokecli move list --limit 10
pokecli move get pound
```

## Example: Download all starters

```bash
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

```bash
# All moves with summary footer
pokecli pokemon moves pikachu

# Check if a Pokémon can learn a specific move (table)
pokecli pokemon moves pikachu --move thunderbolt

# Returns {"can_learn": true/false, "method": "...", "level": N} — useful for scripting
pokecli pokemon moves pikachu --move thunderbolt --format json

# Filter by learn method: level-up, machine, tutor, egg
pokecli pokemon moves eevee --method egg
pokecli pokemon moves charizard --method level-up --format json
```

**`--move` exit codes:** `0` if the Pokémon can learn the move, `1` if it cannot.

## Example: Look up type matchups

```bash
# What is fire weak to? What does it hit super effectively?
pokecli type get fire

# Full type chart as JSON
pokecli type get water --format json
```

## Example: Check a Pokémon's ability details

```bash
# Get the effect of an ability seen on a Pokémon
pokecli ability get intimidate
pokecli ability get levitate
```

## Example: Find the right nature for competitive play

```bash
# Which stat does modest boost/drop?
pokecli nature get modest

# Browse all 25 natures
pokecli nature list --limit 25
```

## Example: View a full evolution chain

```bash
# Branching evolution (Eevee has 8 evolutions)
pokecli pokemon evolution eevee

# Linear chain
pokecli pokemon evolution charmander

# Trade evolution
pokecli pokemon evolution haunter
```

## Example: Get a Pokémon's Pokédex entry and species data

```bash
# Capture rate, egg groups, flavor text, gender ratio
pokecli pokemon species bulbasaur

# Legendary check + habitat
pokecli pokemon species mewtwo
```

## Troubleshooting

For detailed command reference and data field descriptions, consult
`references/api-fields.md`. For multi-step recipes that chain commands across
resources, consult `references/workflows.md`.

And this is the folder layout Claude Code should end up loading:

.claude/
└── skills/
    └── pokecli/
        ├── SKILL.md
        └── references/
            ├── api-fields.md
            └── workflows.md

🏗️ How It Works

The nice part of this pattern is that it stays close to the tool itself. You are not inventing a new interface. You are reorganizing the CLI into an agent-friendly guide.

1. The Install Flow

For this example, the setup works like a normal tool install.

You install pokecli with uv tool install git+https://github.com/jebucaro/pokecli, then you run pokecli install --skills.

You could also install the skill files manually or with a small script. I added this command so the post could show a complete end-to-end example.

At that point, the CLI does not generate a new skill from scratch. It copies the skill files that already ship inside the installed package into the place Claude Code expects.

That matters because the user does not need the repo checked out locally. The installed tool already has what it needs. In practical terms, the flow is simple:

  1. uv installs the CLI as a runnable tool
  2. pokecli install --skills enters the install command group
  3. The command reads the packaged skill files
  4. It creates ~/.claude/skills/pokecli
  5. It writes SKILL.md, references/api-fields.md, and references/workflows.md

It keeps the setup short and keeps the implementation easy to explain.

2. YAML Frontmatter: The Trigger Layer

The frontmatter is the part Claude reads all the time.

For pokecli, it has to answer two questions fast:

  1. What does this skill do?
  2. When should Claude load it?

That is why the description needs both the tool purpose and the trigger phrases a user might actually say, such as pokedex, Pokemon stats, PokeAPI, or download sprites.

The name should match the folder name, and the allowed-tools entry should keep the skill scoped to pokecli commands.

3. allowed-tools: The Safety Layer

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 good default for a task-focused skill.

In other words, the skill is not just a convenience layer. It is also a boundary.

4. The Body: The Working Command Guide

The body should read like a cheat sheet for an agent.

That means:

  • short sections
  • command groups that mirror the CLI
  • examples that can be copied and run
  • no long theory in the middle of the command list

pokecli already gives us a clean top-level structure to mirror:

  • pokemon
  • berry
  • item
  • move
  • image
  • cache

Inside those groups, the skill can then show the operations that matter most, such as get, list, moves, download, stats, and clear.

5. References: Where Extra Detail Belongs

Not every question belongs in the main SKILL.md.

For example:

  • What does base_experience mean for a Pokemon?
  • What is berry firmness?
  • Which fields are most useful for comparing moves?
  • Which sprite variants are usually available?

That kind of detail belongs in references/api-fields.md. Multi-step recipes belong in references/workflows.md. The main skill stays short, and the deeper files are there when Claude needs them.

This keeps the skill easier to maintain and easier to trigger.


⚖️ Side-by-Side Comparison

I used Microsoft’s Playwright CLI ➡️ as the reference pattern for this pokecli skill.

The goal was not to copy the browser workflow. It was to reuse the same skill shape: a small trigger, a focused command guide, and extra detail moved into reference files. That is why this comparison matters.

Design ChoicePlaywright CLIpokecli
Main triggerbrowser automation tasksPokemon data lookup tasks
Tool scopeBash(playwright-cli:*)Bash(pokecli:*)
Quick start shapenavigate, click, type, pressget and list data, inspect Pokemon moves, download images
Workflownavigate, interact, re-snapshotquery, browse, inspect moves, download, cache
Command groupsbrowser actions and sessionscore groups plus uniform resource commands
Extra docsseparate skill referencesreferences/api-fields.md and references/workflows.md

The commands and use case change, but the structure stays the same. That is the useful part of the pattern.


✅ Testing Your Skill

Anthropic’s skill guidance ➡️ is helpful here: test both triggering and behavior.

Queries that should trigger the skill

  • “Look up Pikachu’s stats”
  • “Show me berry data from PokeAPI”
  • “Download a sprite for Charizard”
  • “Compare Thunderbolt and Flamethrower”
  • “Use pokecli to browse items”

Queries that should not trigger the skill

  • “Help me write a Python class”
  • “What is the weather today?”
  • “Create a spreadsheet”
  • “Summarize this meeting transcript”

Functional checks

pokecli pokemon get pikachu
pokecli pokemon moves pikachu
pokecli berry list --limit 5
pokecli item get master-ball --format json
pokecli move get thunderbolt
pokecli image download pokemon 25 -o /tmp/pika.png
pokecli cache clear --resource pokemon
pokecli cache stats

If these commands work, the skill examples are grounded in the actual tool.


🛠️ Challenge: Build One Yourself

If you want to push this one step further, try removing the ready-made pokecli skill and build your own.

This is a good test because it shows you what Claude can infer from the CLI alone, where it gets stuck, and what kind of guidance actually helps.

1. Move the shipped skill out of the way

If you installed the packaged skill earlier, remove it first so it does not get picked up (you can later add them again if you need them with the pokecli install --skills command.

rm -rf ~/.claude/skills/pokecli

2. Create a small project folder

Make a clean folder for the exercise and add the local skill path Claude will read.

mkdir -p pokecli-skill-lab/.claude/skills/pokecli
cd pokecli-skill-lab

Inside that folder, create ./.claude/skills/pokecli/SKILL.md.

3. Start with a small first draft

Do not try to write the perfect skill on the first pass. Start with the smallest useful version.

You already have the full implementation earlier in this post, so use that as your reference instead of repeating a second full draft here.

A solid first version should include:

  • frontmatter with name, description, and allowed-tools
  • a few quick start commands
  • command groups that match the CLI
  • a few examples Claude can copy and run
  • optional reference files for deeper details

4. Run Claude inside the project folder

Now start Claude from inside the folder so it can see the local skill.

claude

Once Claude is running, try prompts like these:

  • “Use pokecli to look up Pikachu’s stats”
  • “Browse berries with pokecli and show me five”
  • “Download a Charizard sprite with pokecli”
  • “Compare Thunderbolt and Flamethrower with pokecli”

Clear the context and try the same prompts but removing the explicit mention of pokecli.

5. Watch what Claude gets wrong

This is the useful part of the exercise.

If Claude misses a command group, add it. If it uses the wrong flags, add a working example. If it reaches for generic shell commands instead of pokecli, tighten the description and examples.

You are not trying to write a long document. You are trying to remove hesitation.

6. Tighten the skill one pass at a time

After a few prompts, your file will usually get better in obvious ways:

  • add trigger phrases you forgot the first time
  • add one or two examples for image download and pokemon moves
  • list shared flags like --format json and --no-cache
  • move deep field notes into a reference file only if you really need them

That feedback loop is the real lesson. The best SKILL.md is not the longest one. It is the one that gives Claude a short path to the right command.


🔎 Explore the Repo

One thing I like about this project is that the repo structure maps cleanly to the final skill.

At the CLI level, the Typer app still has a few obvious top-level command groups such as pokemon, berry, item, move, image, and cache, but the repo now also includes many resource-specific Typer apps that share the same interface.

That gives the skill two useful structures at once: recognizable command families for humans and a uniform get/list contract for agents. The command examples then fill in specialized operations such as moves, species, evolution, encounters, forms, download, stats, and clear.

At the behavior level, the project also gives us the right details to mention in the skill:

  • all get commands support --no-cache
  • all get commands support --format table|json
  • list commands use --limit and --offset
  • image downloads support --output and --variant
  • cache entries live under ~/.pokecli/cache.json

If you want to inspect the tool itself, start with these sources:

  • the project README in pokecli ➡️
  • the command modules under src/pokecli/commands/
  • the app entry point in src/pokecli/main.py

Key Takeaways

  1. A skill makes a CLI easier for Claude Code to use without changing the CLI itself.
  2. The frontmatter description is the most important line because it decides when the skill fires.
  3. allowed-tools gives the skill a clear safety boundary.
  4. The best skill body is a short command guide, not a long tutorial.
  5. Reference files help you keep the main SKILL.md small and focused.
  6. A clean CLI like pokecli is a strong candidate for this pattern because its command groups already map well into a skill.

Final Thoughts

This is the part I find most useful about skills: they do not ask you to rebuild your tooling for AI. They ask you to describe your tooling in a way the agent can use well.

If you already have a CLI with clear commands and predictable output, you are probably closer to an AI-native tool than you think. In many cases, the missing piece is not a new protocol. It is a good SKILL.md.

That is also why I wanted to turn the tech talk into a concrete example. The idea is easier to trust when you can point to a real CLI, a real skill file, and a workflow that maps cleanly from one to the other.


Photo by Jay ➡️ on Unsplash ➡️

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