AI Agents
Arslan
ArslanOct 2, 2026

Learn how to turn any CLI into an Agent Skill with SKILL.md, workflow instructions, progressive disclosure, testing, and secure credential handling.

How to Turn a CLI Into an Agent Skill

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:

  1. Make the CLI agent-ready: non-interactive, machine-readable, with clear exit codes.
  2. Write the description: the text the agent uses to decide whether to load the skill.
  3. Write three to seven workflows: the tasks agents actually perform.
  4. Move reference docs and scripts out of the body: load them only on demand.
  5. 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:

text
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 window

SKILL.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 "needs gh on 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.

RequirementWhy agents need itIf you don't own the CLI
Non-interactive mode (--yes, --no-input)Agents can't answer prompts; the call hangsDocument 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 proseWrap the command and convert output in scripts/
Data on stdout, messages on stderrLogs don't pollute parsed resultsRedirect stderr in the documented command
Meaningful exit codesThe agent can branch on success or failureList the codes and their meaning in the skill
--dry-run for writesThe agent can preview destructive changesTell the agent to run a read-only command first
Output limits (--limit, --out <file>)Large output floods the context windowWrite 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:

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

markdown
---
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.

SymptomLikely causeFix
Skill never loadsname doesn't match the folder nameRename the folder or the name field so they match
Loads on some prompts, misses othersDescription lacks the user's wordsAdd the missing trigger nouns and phrases
Edits have no effectNew top-level skills directory not loaded yetRun /reload-skills or restart the session
Wrong skill firesTwo descriptions overlapAdd "Do not use for…" boundaries to both
Works in the main agent, not in subagentsSubagent starts with fresh context and hasn't loaded the skillPreload it with the subagent's skills field, and keep the Skill tool enabled
Skill fires, then the command failsCLI not on PATH or not authenticatedAdd 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:

bash
npm install -g olostep-cli
olostep init   # signs you in, installs the skills, and configures the MCP server

The 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:

markdown
---
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:

json
{
  "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.

FactorPlain CLICLI + agent skillMCP server
Needs shell accessYesYesNo
Agent knows when to use itOnly if toldYes, via the descriptionYes, via tool definitions
Context cost before useNone, until the agent runs --helpAbout 100 tokens of metadata per skill (per the spec)Depends on how the client loads tool definitions
Credential handlingInherits the shellInherits the shellManaged by the server
Best fitHumans and scriptsCoding agents in a terminalChat 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 as OLOSTEP_API_KEY or GH_TOKEN.
  • Use scoped keys: give the agent a token with only the permissions its workflows need.
  • Gate destructive commands: require --dry-run or 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.

About the Author

Arslan Ali

Co-Founder, Olostep · San Francisco, CA

Arslan is the co-founder of Olostep, a web data infrastructure platform that helps developers and teams access, extract, and structure web data at scale. He works closely on the product and technology behind Olostep, with a focus on building reliable infrastructure for web scraping, search APIs, and structured web data.

Read more