ANCC

Agent-Native CLI Convention. Build tools agents can use without plugins.

ANCC is a pattern for building CLI tools that agents can discover, install, configure, and compose. "Agent" here means any autonomous process with shell access — an LLM in a loop, a CI pipeline, a cron job. When a tool is deterministic and its interface is documented, the agent doesn't need to guess. It reads the spec, runs the command, parses the output.

Tools

Tools following this pattern.

chainwatch

AI agent execution control plane. Watch, contain, and audit autonomous agent runs.

noisepan

Signal extractor for noisy information streams.

entropia

Source credibility verifier.

Observed in practice

An autonomous agent encountered these tools and installed them without a plugin.

Given a goal and access to a shell, an agent discovered CLI tools from conversation context. It ran brew install ppiankov/tap/noisepan, then noisepan init to generate a config file, edited the config for its task, and executed noisepan pull --format json. When asked to upgrade the pipeline, the agent ran noisepan doctor and discovered entropia as a companion tool for source verification — then installed it too. No plugin framework. No SDK. No registry.

Why it matters

Concrete friction reduction.

Without ANCC

With ANCC

The Convention

Six requirements. A tool that meets all six is agent-native.

1. Single binary, zero runtime deps

Ship one binary. Install means copy a file. Homebrew, curl | tar, or go install. An agent that can run shell commands can install it.

2. Deterministic behavior

Same input, same output. No ambient state, no implicit config. Running tool analyze input.txt --format json twice produces identical output unless the input changes. An agent can verify its work by running the command again.

3. Structured output

Support --format json for machine consumption. Human-readable output is the default. JSON output is the agent interface.

4. One bounded job

Each tool does one thing. It runs, produces output, and exits. No interactive modes. If a service or daemon exists, it is controlled through bounded CLI commands — the ANCC interface is always a single invocation with a defined exit.

5. SKILL.md at repo root

A machine-readable file that tells an agent everything it needs: how to install, what commands exist, what flags they take, what the JSON output looks like, and what the tool does not do.

6. Init command

Running tool init produces a valid config file with sensible defaults. An agent runs init, reads the result, and adjusts from there.

Recommended: Doctor command

Not required, but powerful for tools that compose with others.

Running tool doctor checks the tool's own health — config validity, dependencies, connectivity — and surfaces companion tools it can compose with. An agent runs doctor to understand what's working, what's missing, and what else to install. Tools that operate in isolation don't need this. Tools that form pipelines benefit from it.

SKILL.md

The interface contract. Lives at the repo root.

SKILL.md is what makes a tool discoverable. An agent reads it to learn what a tool does, how to install it, and how to parse its output. A single markdown file that works for humans and machines.

# tool-name

One-line description of what this tool does.

## Install

```
brew install user/tap/tool-name
```

## Commands

### tool-name analyze

Analyzes input and produces a report.

**Flags:**
- `--format json` — output as JSON (default: human-readable)
- `--config path` — config file (default: ./tool-name.yaml)
- `--verbose` — show detailed progress

**JSON output:**
```json
{
  "status": "pass | fail | warn",
  "score": 0.0-1.0,
  "details": [{"item": "...", "result": "..."}]
}
```

**Exit codes:**
- 0: success
- 1: failure (bad input, missing config)
- 2: partial results (some checks passed)

## What this does NOT do

- Does not modify input files
- Does not make network requests unless configured
- Does not require authentication for local operation

## Parsing examples

```bash
# Get the status
tool-name analyze --format json | jq '.status'

# Filter failing items
tool-name analyze --format json | jq '.details[] | select(.result == "fail")'
```

Principle

ANCC names a pattern that already works. Tools present evidence and let you decide. The terminal worked before agents, and it works with them.