Migrating a Claude Code skill from WebFetch to the new CircleCI CLI: lessons learned about tool and API design

genAI development   generative AI   harness engineering   idea to code   context engineering   developer experience   deployment pipeline   devops   automation   testing  

Contact me for information about consulting and training at your company.

The MEAP for Microservices Patterns 2nd edition is now available


One of the Claude Code skills in my idea-to-code plugin is debugging-ci-failures. It tells Claude Code how to watch and diagnose a failing CI build. Specifically, it instructs Claude Code to do the following five steps:

  1. Watch the build to completion
  2. Identify the failing job
  3. Fetch the failing step’s output
  4. Download the test artifacts
  5. Read the JUnit TEST-*.xml files to find the root cause

The skill supports two CI systems: GitHub Actions (via the gh CLI) and CircleCI. Until today, the CircleCI support used WebFetch — Claude Code’s built-in HTTP fetch tool — to access CircleCI’s REST API directly. That worked, but it was clumsy.

From WebFetch to CircleCI CLI

This post is about how I used Claude Code to migrate the skill from WebFetch to the new CircleCI CLI. The migration itself took a single one-line prompt — but that’s the least interesting part. Along the way, Claude Code discovered CLI features I didn’t know existed and found a shortcut I hadn’t thought to ask for. And by the end, a small skill update had turned into something more general: a lesson about how we should be designing tools for AI agents at all. I’ll come back to that. First, the hack the new CLI let me delete.

The WebFetch approach and its ugly workaround

Compared to the GitHub gh CLI, the existing CircleCI CLI was rather limited. As a result, the skill had to use WebFetch to access CircleCI’s REST API directly, which was rather inconvenient. Not only did Claude Code need to know the details of the REST API, but analyzing builds for private repositories required an API token, which was not something I wanted to expose to Claude Code.

Also, the Claude Code WebFetch tool caches responses for about 15 minutes, which is a problem when you are invoking an API. As a workaround, the skill had to append a cache-busting query parameter to every request:

WebFetch: https://circleci.com/api/v1.1/project/github/<org>/<repo>?limit=1&branch=<branch>&_ts=1

Note the &_ts=1 at the end. That’s not a CircleCI parameter — it’s a hack that forces WebFetch to treat each request as unique.

The new CircleCI CLI

I was excited to read Rob Zuber’s LinkedIn post announcing the new CircleCI CLI. A quick glance showed that it was roughly comparable to the gh CLI for GitHub Actions — it handled authentication, and hid the details of the REST API. What’s more, I discovered that changing the skill to use it was remarkably straightforward.

The prompt that started the migration

After I reorganized the skill so that GitHub Actions and CircleCI each had their own section, my next prompt was a single line:

For circleci some or all of the webfetch can be replaced by the new circleci CLI. For example, circleci run list — you can try on eventuate-foundation/eventuate-common.

Claude Code walked the CLI’s help tree (circleci --help, circleci run --help, circleci job --help, etc.), then ran commands against eventuate-foundation/eventuate-common to see the actual JSON shapes and behaviors before rewriting the skill.

Take a look at the Claude Code session and the resulting commit.

What the CLI replaces

The mapping turned out to be direct — the CLI has a purpose-built command for every step of the workflow:

Skill step Old (WebFetch + _ts hack) New (circleci CLI)
Watch a build Poll /build/<n>?_ts=N in a loop circleci run watch — blocks, exit code = outcome
Find the latest run WebFetch project endpoint circleci run list --branch <branch>
Get run + workflow + job status WebFetch, parse JSON circleci run get <run-id> --json
Find the failed step WebFetch ?include=steps, scan circleci job output list <job-id> --json --jq '.steps[] \| select(.exit_code != 0)'
Fetch the failed step’s output WebFetch /output/<idx>/0 circleci job output get <job-id> --step-num N
List artifacts WebFetch /artifacts circleci artifact <job-id> --json
Download artifacts WebFetch each URL individually circleci artifact <job-id> --output test-reports

Two of these are worth highlighting.

circleci run watch

circleci run watch replaces an entire polling loop with a blocking call whose exit code encodes the outcome:

  • 0 — all workflows succeeded
  • 1 — one or more workflows failed
  • 6 — cancelled
  • 8 — timed out

That’s a much better contract for an agent than “keep polling until status is no longer running, then check outcome.”

circleci job output get --condensed

Claude discovered that the circleci job output get command has a rather useful flag: --condensed:

Use –condensed to fetch a filtered version of stdout only, with noisy or repetitive lines removed server-side. This produces a much smaller payload suitable for feeding to an AI tool. When –condensed is set, output is always rendered through the plain-text renderer regardless of the terminal or –strip-ansi.

CircleCI has apparently added a first-class “give me the interesting lines, meant to be pasted into an LLM” mode to their CLI.

An unexpected shortcut

While Claude Code studied the CLI’s commands, it found another one that isn’t strictly a WebFetch replacement — it’s an entirely new step Claude can try before downloading anything:

circleci testresult list <job-id>

By default, this command shows a job’s failed tests. It enables Claude Code to quickly identify the failing test without downloading any artifacts. The skill now tries testresult list first and falls back to downloading TEST-*.xml files only if that isn’t enough.

Why this matters beyond one skill

The bigger point isn’t about CircleCI or Claude Code specifically. There are a few broad lessons here:

  • Prefer tools to raw APIs
  • Design CLI tools to be discoverable
  • Design CLI tools for token-efficient output

Let’s look at each one.

Prefer tools to raw APIs

If your agent has to reach an external system through a general-purpose HTTP tool, it’s writing REST calls by hand, dealing with caching, composing URLs, and parsing JSON shapes. Every one of those steps is a place the agent can go wrong.

If instead the agent can reach the same system through a well-designed CLI, the CLI hides all of that. circleci run watch doesn’t need cache-busting. circleci artifact --output doesn’t need URL composition. circleci job output get --condensed doesn’t need the agent to figure out how to trim noise for an LLM — the vendor already did.

A CLI aimed at agents is a shorter path than the raw API, and shorter paths are more reliable. When you’re writing skills, prefer the CLI when one exists — and let the absence of one push you to open an issue with the vendor rather than to hand-craft another URL.

Design CLI tools to be discoverable in the era of shallow understanding

It’s also worth pointing out that Claude Code figured out how to use the CircleCI CLI without me telling it anything about the commands. It simply ran circleci --help, then circleci run --help, then circleci job --help, and so on, until it had a mental model of the CLI’s command tree. That was enough for it to determine the right commands and update the skill. If you are developing CLI tools, make sure they are discoverable in this way — the --help output is a first-class part of the interface, not just a convenience for humans.

Design CLI tools for token-efficient output

Finally, the --condensed flag is a great example of a CLI designed for an agent’s needs. Filtering noise server-side lowers token cost and keeps the agent’s context window focused on what matters — and the vendor knows which lines are noise better than any skill author does. Worth considering whenever you design an API or CLI tool.

About this article

Claude Code wrote the first draft of this post during the same session that made the change. The skill migration and the article came out of one conversation. First, I asked Claude to migrate the skill to the CircleCI CLI tool. After that, I told it to draft this post.

Need help with modernizing your architecture?

I help organizations modernize their architecture to enable fast flow and GenAI-powered software delivery. If you’re planning or struggling with a modernization effort, I can help.

Learn more about my modernization and architecture advisory work →


genAI development   generative AI   harness engineering   idea to code   context engineering   developer experience   deployment pipeline   devops   automation   testing  


Copyright © 2026 Chris Richardson • All rights reserved • Supported by Kong.

About Microservices.io

Microservices.io is created by Chris Richardson, software architect, creator of the original CloudFoundry.com, and author of Microservices Patterns. Chris helps organizations modernize their architecture to enable fast flow and GenAI-powered software delivery.

Need help modernizing your architecture?

Avoid the trap of creating a modern legacy system — a new architecture with the same old problems.
Contact me to discuss your modernization goals.

Get Help

Microservices Patterns, 2nd edition

I am very excited to announce that the MEAP for the second edition of my book, Microservices Patterns is now available!

Learn more

ASK CHRIS

?

Got a question about microservices?

Fill in this form. If I can, I'll write a blog post that answers your question.

NEED HELP?

I help organizations improve agility and competitiveness through better software architecture.

Learn more about my consulting engagements, and training workshops.

LEARN about microservices

Chris offers numerous other resources for learning the microservice architecture.

Get the book: Microservices Patterns

Read Chris Richardson's book:

Example microservices applications

Want to see an example? Check out Chris Richardson's example applications. See code

Virtual bootcamp: Distributed data patterns in a microservice architecture

My virtual bootcamp, distributed data patterns in a microservice architecture, is now open for enrollment!

It covers the key distributed data management patterns including Saga, API Composition, and CQRS.

It consists of video lectures, code labs, and a weekly ask-me-anything video conference repeated in multiple timezones.

The regular price is $395/person but use coupon OFFEFKCW to sign up for $95 (valid until Sept 30th, 2025). There are deeper discounts for buying multiple seats.

Learn more

Learn how to create a service template and microservice chassis

Take a look at my Manning LiveProject that teaches you how to develop a service template and microservice chassis.

Signup for the newsletter


BUILD microservices

Ready to start using the microservice architecture?

Consulting services

Engage Chris to create a microservices adoption roadmap and help you define your microservice architecture,


The Eventuate platform

Use the Eventuate.io platform to tackle distributed data management challenges in your microservices architecture.

Eventuate is Chris's latest startup. It makes it easy to use the Saga pattern to manage transactions and the CQRS pattern to implement queries.


Join the microservices google group