A Good Year for CLIs

My Christmas wish was for a more complete Datadog CLI:

a better version of dogshell that supports read/write, OAuth, and a more intuitive interface.

And the folks at Datadog shipped it! Pup is a Go Rust CLI for the Datadog API: 283+ subcommands, OAuth2, and output formatting designed for both humans and AI agents. It’s everything I wanted, and more.

What Pup Does

Designed for progressive disclosure:

# OAuth2 Authorization Code with PKCE, tokens stored to keychain or file.
pup auth login
pup monitors list --tags="team:api-platform"
pup metrics query --query="avg:system.cpu.user{*}"

The OAuth2 flow is a full implementation of the Authorization Code flow with PKCE (S256), including dynamic client registration, which is an impressive feature. For the Datadog endpoints that don’t yet support OAuth, pup falls back to API keys. This is such a superior experience to the usual token management, and I hope other organizations can follow this pattern.

I’ve been having a great time with pup, and new features are shipping every day. The Datadog MCP server is too opaque and magical for me to be 100% comfortable. Occassionally, it would surprise me by revealing it had write access that I didn’t even know I could grant. While I could follow along and hypothetically replay the API calls, I never would. With pup, you can see the exact commands in a way that’s refreshingly transparent.

The Rewrite

Three days ago, pup was completely rewritten in Rust. The authors benchmarked against the Go version, and it’s impressive.

MetricGoRustDelta
Binary size37.3 MB25.7 MB31% smaller
Startup (per invocation)9.3 ms7.8 ms16% faster
Peak RSS19.3 MB14.4 MB25% less memory

The most interesting part is at the bottom of the PR:

🤖 Generated with Claude Code

Almost all the commits are Co-Authored-By: Claude Sonnet 4.6. A complete rewrite with integration test coverage, CI pipeline, cross-compilation for native targets plus WASI and browser WASM. All done with an AI agent, which itself would be the primary audience of the tool.

Pup has first-class support for AI agents as consumers. It uses a table-driven AI agent detector in useragent.rs that sniffs environment variables for 11 different coding agents: Claude Code, Cursor, GitHub Copilot, etc. If detected, pup embeds the agent name in the User-Agent string and switches to structured JSON output with metadata and hints.

The WASM targets are worth noting. The same codebase compiles to native, WASI (for Wasmtime/Wasmer/Cloudflare Workers), and browser WASM with wasm-bindgen. The browser build uses localStorage for token persistence and exposes a PupClient JavaScript class with TypeScript definitions. I didn’t realize Cargo has such a nice multi-target compilation and feature flag system.

What Next?

Sentry also released their own CLI in January, and I hope more companies follow this path. The best CLIs will accommodate humans and agents without compromises.

Here are few more CLIs I would like to see this year:

  • Slack: I want a slack CLI with read functionality: slack channels list, slack conversations history, slack users list. I can sort of do this today by re-using the cookie-based credentials, but I want to slack auth login for granular, auditable, and revokable access.
  • PagerDuty: pd incidents list, pd oncall, pd acknowledge. A huge win for agents doing incident response alongside pup
  • Cloudflare: wrangler exists but is deployment-focused, not for observability/config querying
  • Your Own Infrastructure: Azure, AWS and GCP have decent CLI tools, and if you develop on a custom platform, it’s never been easier to ship a CLI for it. The benefits for both humans and agents can make it worth the effort.

Each of these tools should have:

  1. Progressive disclosure: <tool> gives a condensed help, and <tool> <subcommand> --help gives more details.
  2. Granular, revokable authorization: <tool> auth login, ideally with OAuth2 authorization code flow and dynamic client registration. Not all services can support DCR, and token-based authentication would be ok. Bonus points if I can audit the agent’s actions done on my behalf.
  3. JSON output setting: <tool> --output json, so the agent can compose them naturally through bash without MCP overhead.

It’s never been a better time to write a CLI for your API.