Coding agents that work in a terminal can already run shell commands. What they lack is know-how: which of your CLI's commands to use, which flags matter, and what to do when a call fails. An agent skill gives them that know-how without rewriting the tool.
What It Means to Turn a CLI Into an Agent Skill
You turn a CLI into an agent skill by writing a SKILL.md file that tells the agent when to use the CLI, which commands to run for common tasks, and where to find deeper docs. The CLI itself does not change. The skill is a small instruction layer that sits next to it.
According to Anthropic's Agent Skills announcement, "Skills are folders that include instructions, scripts, and resources that Claude can load when needed." Anthropic introduced skills on October 16, 2025, and published Agent Skills as an open standard on December 18, 2025.
A CLI (command-line interface) is any program you run from a terminal, such as gh, kubectl, ffmpeg or a vendor tool. If you want the Claude-specific install details, see how Claude Code skills work.
The method in this guide has five steps:
- Make the CLI agent-ready: non-interactive, machine-readable, with clear exit codes.
- Write the description: the text the agent uses to decide whether to load the skill.
- Write three to seven workflows: the tasks agents actually perform.
- Move reference docs and scripts out of the body: load them only on demand.
- Install and test: confirm the skill fires on the right prompts.
How Agent Skills Load: SKILL.md and Progressive Disclosure
An agent skill is a folder with one required file, SKILL.md, plus optional scripts/, references/ and assets/ folders. The agent reads it in stages, so a skill costs very little context until a task needs it.
This staged loading is called progressive disclosure. It explains most of the design decisions in the steps below.
The Skill Folder Layout
A skill that wraps a CLI usually looks like this:
my-cli/
├── SKILL.md # required: frontmatter + instructions
├── references/
│ └── commands.md # full command reference, loaded on demand
└── scripts/
└── summarize.sh # helper that runs outside the context windowSKILL.md starts with YAML frontmatter. The Agent Skills specification defines the loading tiers: "Metadata (~100 tokens): The name and description fields are loaded at startup for all skills". The same spec sets these field rules:
name: required, 1–64 characters, lowercase letters, numbers and hyphens only. It must match the parent folder name.description: required, 1–1024 characters. It should say what the skill does and when to use it.compatibility: optional, up to 500 characters, for environment requirements such as "needsghon PATH".allowed-tools: optional and marked experimental. Support varies between agents.
Why On-Demand Loading Matters
The skill body loads only when the skill activates. The spec recommends keeping it under 5,000 tokens and under 500 lines, with longer material moved to separate files.
This matters because many MCP clients load every tool definition upfront. In one worked example, Anthropic's code execution with MCP post reports, "This reduces the token usage from 150,000 tokens to 2,000 tokens—a time and cost saving of 98.7%."
That figure comes from a single MCP workflow, not from a skills benchmark. It does show why loading instructions only when needed protects the agent's context window.
Step 1: Make the CLI Agent-Ready
A skill cannot fix a CLI that hangs on a prompt or prints output the agent can't parse. Before writing SKILL.md, check that the CLI can run headless and return predictable results.
Terminal work is still hard for agents. The Terminal-Bench 2.0 paper tested 89 real-world terminal tasks and reports, "We show that frontier models and agents score less than 65% on the benchmark". A clean CLI contract removes one common source of failure.
| Requirement | Why agents need it | If you don't own the CLI |
|---|---|---|
Non-interactive mode (--yes, --no-input) | Agents can't answer prompts; the call hangs | Document the flag in the skill, or pipe yes in a wrapper script |
Machine-readable output (--json) | The agent can filter with jq instead of reading prose | Wrap the command and convert output in scripts/ |
| Data on stdout, messages on stderr | Logs don't pollute parsed results | Redirect stderr in the documented command |
| Meaningful exit codes | The agent can branch on success or failure | List the codes and their meaning in the skill |
--dry-run for writes | The agent can preview destructive changes | Tell the agent to run a read-only command first |
Output limits (--limit, --out <file>) | Large output floods the context window | Write output to a file and read only the summary |
These requirements follow general CLI conventions, since no agent-specific standard defines them. The GitHub CLI exit codes page lists 0 for success, 1 for failure and 4 when authentication is required. The Claude Code non-interactive mode docs describe JSON output and exit codes so scripts can branch on the result.
If you own the CLI, fix these in the tool. If you're wrapping a third-party CLI, record the safe flags and workarounds in the skill itself.
Step 2: Write a Description the Agent Will Match
The description is the only part of a skill the agent sees when choosing which skill to load. If it's vague, the skill never fires, no matter how good the body is.
A strong description has four parts:
- What it does: name the CLI and the job it performs.
- When to use it: the user requests or situations that should trigger it.
- Trigger nouns: the words users actually type, such as "PR", "pull request" or "CI run".
- When not to use it: a boundary that prevents overlap with other skills.
Compare two versions for GitHub's gh CLI:
# Weak: no trigger words, no boundary
description: Helps with GitHub.
# Strong: job, triggers, and boundary
description: >-
Manage GitHub pull requests, issues, and CI runs with the gh CLI.
Use when the user asks to open, review, merge, or check the status
of a PR, triage issues, or inspect failing GitHub Actions. Do not use
for local git operations like commit or rebase.Keep descriptions distinct across installed skills. Two skills that both claim "GitHub tasks" compete for the same prompts.
Step 3: Write Three to Seven Workflows, Not the Whole Manual
The skill body should cover the three to seven tasks agents actually do with the CLI, not every subcommand. Mirroring the full --help tree in Markdown recreates the context bloat that skills exist to avoid.
Each workflow needs the exact command, the shape of the output, and the gotchas a new user would hit. Here is a template you can copy:
---
name: gh-prs
description: >-
Manage GitHub pull requests and CI runs with the gh CLI. Use when the
user asks to open, review, merge, or check a PR or a failing Actions
run. Do not use for local git commits or rebases.
compatibility: Requires gh 2.x on PATH, authenticated via GH_TOKEN.
---
# GitHub PRs with gh
## Before you start
- Run `gh auth status`. If it exits non-zero, stop and ask the user to authenticate.
## Workflow 1: Check PR status
```bash
gh pr view --json state,mergeable,statusCheckRollup
```
- Output is JSON. Filter with `jq '.statusCheckRollup[] | select(.conclusion=="FAILURE")'`.
## Workflow 2: Open a PR
```bash
gh pr create --title "" --body "" --base main
```
- Pass `--title` and `--body` to skip those prompts, and push the branch first (or pass `--head`) to avoid the push prompt.
## Workflow 3: Read a failing CI log
```bash
gh run view --log-failed
```
- Logs can be long. Pipe to `tail -n 100` first.
## More commands
See references/commands.md for the full command list.Every workflow names a command that runs without prompts, says what comes back, and warns about one failure mode. That pattern makes the skill more predictable for the agent.
The gh pr view manual documents --json <fields> for JSON output. The gh pr create manual says --title and --body skip the title and body prompts, though an unpushed branch can still trigger a push prompt.
Setting GH_TOKEN avoids auth prompts, according to the gh environment variables page. Per the gh auth status manual, plain gh auth status exits 1 on auth issues, so the "Before you start" check works. With --json, the same command always exits 0. The --log-failed flag shows logs for failed steps, per the gh run view manual.
Step 4: Move Reference Docs and Scripts Out of the Body
Anything the agent needs only occasionally belongs in references/ or scripts/, not in SKILL.md. The agent opens these files only when a workflow points to them.
Use each folder for a different job:
references/commands.md: the full command and flag reference, for rare tasks.scripts/: multi-step logic such as pagination, parsing or retries. The agent runs the script and reads only its output.assets/: templates or config files the CLI needs.
You don't have to write the reference file by hand. If the CLI has a public docs site, you can crawl a documentation site and save the pages as Markdown. Then trim the result to the commands your workflows reference.
Step 5: Install the Skill and Test That It Fires
Install the skill by placing its folder in the agent's skills directory. The Claude Code skills documentation puts project skills in .claude/skills/<name>/SKILL.md and personal skills in ~/.claude/skills/<name>/SKILL.md.
Claude Code picks up edits to existing skill folders within the current session; if you create a new top-level skills directory, run /reload-skills.
Other agents use their own folders. The OpenAI Codex skills documentation says Codex reads skills from .agents/skills and builds on the open Agent Skills standard.
Then test the trigger with two short prompt lists:
- Should fire: "Is PR 482 ready to merge?", "Why did CI fail on my branch?", "Open a PR for this fix."
- Should not fire: "Commit these changes.", "Rebase onto main.", "Explain this function."
Run each prompt in a fresh session and record whether the skill loaded. If a "should fire" prompt misses, add its key nouns to the description.
Troubleshooting a Skill That Won't Trigger
Trigger failures usually come from the description or the install location, not the CLI.
| Symptom | Likely cause | Fix |
|---|---|---|
| Skill never loads | name doesn't match the folder name | Rename the folder or the name field so they match |
| Loads on some prompts, misses others | Description lacks the user's words | Add the missing trigger nouns and phrases |
| Edits have no effect | New top-level skills directory not loaded yet | Run /reload-skills or restart the session |
| Wrong skill fires | Two descriptions overlap | Add "Do not use for…" boundaries to both |
| Works in the main agent, not in subagents | Subagent starts with fresh context and hasn't loaded the skill | Preload it with the subagent's skills field, and keep the Skill tool enabled |
| Skill fires, then the command fails | CLI not on PATH or not authenticated | Add a "Before you start" check, such as gh auth status |
The Claude Code subagents documentation says subagents start with fresh context, preload skills named in their skills field, and can invoke others through the Skill tool.
Worked Example: The Olostep CLI as a Web-Research Skill
Olostep follows this exact pattern for web data. The Olostep CLI (olostep-cli) covers search, answers, map, scrape, crawl and batch scraping. According to the Olostep CLI reference, its data commands print JSON to stdout, with progress on stderr.
Install the CLI and skills with two commands:
npm install -g olostep-cli
olostep init # signs you in, installs the skills, and configures the MCP serverThe same CLI reference recommends olostep init as the next step after install. The Olostep agent integration guide covers the other setup paths.
The Olostep skills documentation says olostep add skills installs all 13 SKILL.md skills. They go into a shared store at ~/.agents/skills and are symlinked or copied into each agent's folder. One copy can serve many agents, including Cursor, Claude, Codex, Windsurf and Continue.
Here is a simplified version of the scrape skill:
---
name: scrape
description: >-
Scrape a single webpage and extract its content as clean markdown,
HTML, JSON, or text using Olostep. Use when the user shares a URL and
wants its content read, summarized, or extracted.
---
# Scrape a page with Olostep
## Before you start
- Check that `OLOSTEP_API_KEY` is set or that `olostep login` has run.
## Workflow: Read a page as Markdown
```bash
olostep scrape "https://example.com/pricing" --formats markdown
```
- Output is JSON. The page content is in `result.markdown_content`.
- Formats you did not request come back as null.The skill calls the Olostep scrape endpoint, which returns the page as clean Markdown, HTML or structured JSON. A trimmed response looks like this:
{
"id": "scrape_6h89o8u1kt",
"result": {
"markdown_content": "# Pricing\n\nStarter plan ...",
"html_content": null
}
}The example also shows how to split agent output by format. Use JSON for control data the agent filters, such as IDs, status and fields.
Use Markdown for content the model reads, such as a scraped page. Markdown keeps the page readable for the model without the HTML markup.
Agent Skill vs MCP Server vs Plain CLI
An agent skill and an MCP server solve different problems, and you can ship both. A skill gives an agent with shell access the know-how to use a CLI. An MCP server exposes tools to clients that have no shell.
If you need a refresher, here is what the Model Context Protocol is.
| Factor | Plain CLI | CLI + agent skill | MCP server |
|---|---|---|---|
| Needs shell access | Yes | Yes | No |
| Agent knows when to use it | Only if told | Yes, via the description | Yes, via tool definitions |
| Context cost before use | None, until the agent runs --help | About 100 tokens of metadata per skill (per the spec) | Depends on how the client loads tool definitions |
| Credential handling | Inherits the shell | Inherits the shell | Managed by the server |
| Best fit | Humans and scripts | Coding agents in a terminal | Chat apps, IDE clients, shared team setups |
Olostep runs both surfaces. The Olostep MCP server serves MCP clients, and the skills serve terminal agents. As Olostep's docs put it, "the MCP server gives the agent the live tools, the skills give it the know-how for when and how to use them."
Agent adoption was still uneven in 2025, so keep the CLI usable by humans and scripts as well. According to Stack Overflow 2025 AI agents data, "A majority of developers (52%) either don't use agents or stick to simpler AI tools, and a significant portion (38%) have no plans to adopt them."
Security and Credentials When an Agent Runs Your CLI
A CLI run by an agent inherits every credential in that shell. Treat a skill as code that can act on your behalf.
Apply these rules before you share a skill:
- Keep secrets out of
SKILL.md: read keys from environment variables such asOLOSTEP_API_KEYorGH_TOKEN. - Use scoped keys: give the agent a token with only the permissions its workflows need.
- Gate destructive commands: require
--dry-runor a read-only check before any write. - Restrict tools where supported: use
allowed-tools, keeping in mind that support varies by agent. - Vet third-party skills: skills can run scripts. Read every file before you install one.
For a checklist on reviewing downloaded skills, see this guide to vetting third-party agent skills.
Frequently Asked Questions
What is a SKILL.md file?
A SKILL.md file is the required file in an agent skill folder. It holds YAML frontmatter (name and description) followed by Markdown instructions that the agent loads when the skill activates.
Do I need to own the CLI to make a skill for it?
No. You can write a skill for any CLI installed on the machine and document safe flags and workarounds in the skill or a wrapper script.
Where do I put skills in Claude Code?
Put project skills in .claude/skills/<name>/ and personal skills in ~/.claude/skills/<name>/. Run /reload-skills if you created a new skills directory.
Does one skill work across different agents?
Agent Skills is an open standard, so a spec-compliant skill folder can be reused by skills-compatible agents. The VS Code Agent Skills documentation notes that supported locations and optional features vary by agent.
Should CLI output for agents be JSON or Markdown?
Use JSON for control data the agent filters and Markdown for long content the model reads. A single skill can use both.
Why isn't my skill triggering?
Common causes are a vague description, a name that doesn't match the folder, or the skill sitting in a folder the agent doesn't scan.
Should I build a skill or an MCP server?
Build a skill when your users run agents in a terminal, and an MCP server when they use clients without shell access. You can also ship both.
Do I need scripts, or is SKILL.md enough?
SKILL.md alone is enough for simple CLIs. Add scripts when a task needs multi-step parsing, pagination or retries that would otherwise fill the context window.
Next Steps
Turning a CLI into an agent skill takes five steps: make the CLI agent-ready, write a description that matches real prompts, document three to seven workflows, move reference material out of the body, and test that the skill fires.
Start with the CLI your agent misuses most. If your agents need live web data, olostep init installs a working set of skills you can read and adapt.



