> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anysite.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Protocol

> Structured JSON output, exit codes, error codes, and discovery for AI agent integration

## Overview

Anysite CLI is **agent-native** — it auto-detects when stdout is a pipe or subprocess (non-TTY) and switches all output to structured JSON. No flags, no configuration. AI agents like Claude Code, n8n, Make, and custom scripts get machine-readable responses out of the box.

Every command returns:

* A **JSON envelope** with `ok`, `result`/`error`, `hints`, and `meta`
* **Exit codes** for programmatic flow control
* **Error codes** with `retryable` flag and `suggestions`
* **Next-step hints** so agents discover follow-up commands without documentation

## Auto-Detection

| Context                    | Default Output           | Override                      |
| -------------------------- | ------------------------ | ----------------------------- |
| Terminal (TTY)             | Human-readable Rich text | `--json` to force JSON        |
| Pipe / subprocess (no TTY) | Structured JSON envelope | `--human` to force human text |

```bash theme={null}
# In terminal — human-readable output (default)
anysite api /api/linkedin/user user=satyanadella

# In terminal — force JSON output
anysite api /api/linkedin/user user=satyanadella --json

# In pipe — JSON automatically
anysite api /api/linkedin/user user=satyanadella | jq '.result.name'

# In pipe — force human output
anysite api /api/linkedin/user user=satyanadella --human | less
```

The `--non-interactive` flag disables interactive prompts (confirmations, selections). It is auto-enabled when stdin is not a TTY.

## JSON Envelope

### Success Response

```json theme={null}
{
  "ok": true,
  "result": {
    "name": "Satya Nadella",
    "headline": "Chairman and CEO at Microsoft",
    "follower_count": 12500000
  },
  "hints": [
    {
      "action": "Get posts",
      "command": "anysite api /api/linkedin/user/posts user=satyanadella"
    },
    {
      "action": "Save to database",
      "command": "anysite db insert mydb --table profiles --stdin"
    }
  ],
  "meta": {
    "version": "0.3.0",
    "command": "anysite api /api/linkedin/user"
  }
}
```

### Error Response

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "AUTH_FAILED",
    "message": "Authentication failed: invalid or expired API key",
    "retryable": false,
    "suggestions": [
      "Set API key: anysite config set api_key <key>",
      "Or set environment variable: export ANYSITE_API_KEY=<key>"
    ]
  },
  "meta": {
    "version": "0.3.0",
    "command": "anysite api /api/linkedin/user"
  }
}
```

Always check the `ok` field first. Use `error.code` for programmatic handling, `error.retryable` to decide whether to retry, and `error.suggestions` for recovery steps.

## Exit Codes

| Code | Meaning               | When                                           |
| ---- | --------------------- | ---------------------------------------------- |
| 0    | Success               | Command completed successfully                 |
| 1    | General error         | Unhandled error, server error                  |
| 2    | Usage error           | Invalid arguments, missing required parameters |
| 3    | Authentication failed | Invalid or expired API key                     |
| 4    | Resource not found    | Endpoint, connection, or source not found      |
| 5    | Network error         | Connection failure, timeout, rate limit        |

```bash theme={null}
anysite api /api/linkedin/user user=satyanadella
case $? in
  0) echo "Success" ;;
  3) echo "Check your API key" ;;
  5) echo "Network issue, retrying..." ;;
  *) echo "Error: exit code $?" ;;
esac
```

## Error Codes

<AccordionGroup>
  <Accordion title="API Errors">
    | Error Code         | Exit Code | Retryable | Trigger                    |
    | ------------------ | --------- | --------- | -------------------------- |
    | `AUTH_FAILED`      | 3         | No        | Invalid or expired API key |
    | `RATE_LIMIT`       | 5         | Yes       | Too many requests          |
    | `NOT_FOUND`        | 4         | No        | Resource not found         |
    | `VALIDATION_ERROR` | 2         | No        | Bad input parameters       |
    | `SERVER_ERROR`     | 1         | Yes       | API server error           |
    | `NETWORK_ERROR`    | 5         | Yes       | Connection failure         |
    | `TIMEOUT`          | 5         | Yes       | Request timeout            |
  </Accordion>

  <Accordion title="Database Errors">
    | Error Code             | Exit Code | Retryable | Trigger                            |
    | ---------------------- | --------- | --------- | ---------------------------------- |
    | `CONNECTION_NOT_FOUND` | 4         | No        | Database connection not configured |
  </Accordion>

  <Accordion title="Dataset Errors">
    | Error Code         | Exit Code | Retryable | Trigger                            |
    | ------------------ | --------- | --------- | ---------------------------------- |
    | `DATASET_ERROR`    | 1         | No        | Dataset operation failed           |
    | `SOURCE_NOT_FOUND` | 4         | No        | Source not found in dataset config |
  </Accordion>

  <Accordion title="LLM Errors">
    | Error Code           | Exit Code | Retryable | Trigger                     |
    | -------------------- | --------- | --------- | --------------------------- |
    | `CONFIG_ERROR`       | 2         | No        | LLM provider not configured |
    | `LLM_PROVIDER_ERROR` | 1         | Yes       | LLM provider failure        |
  </Accordion>
</AccordionGroup>

## Hints

Every command returns **next-step hints** — suggested follow-up commands based on what you just did. In JSON mode, hints appear in the `hints` array. In human mode, they are printed as dim text on stderr.

Agents use hints to discover follow-up actions without consulting documentation:

```bash theme={null}
# Collect hints from response
HINTS=$(anysite api /api/linkedin/user user=satyanadella | jq -r '.hints[].command')
echo "$HINTS"
# anysite api /api/linkedin/user/posts user=satyanadella
# anysite db insert mydb --table profiles --stdin
```

## Discovery Payload

Run `anysite` with no arguments in a pipe to get a full discovery payload describing all CLI capabilities:

```bash theme={null}
anysite | jq '.result'
```

The discovery payload includes:

| Field              | Description                                                                     |
| ------------------ | ------------------------------------------------------------------------------- |
| `commands`         | All available commands with descriptions and subcommands                        |
| `agent_protocol`   | How auto-JSON, `--json`, `--human`, `--non-interactive` work                    |
| `output_schema`    | Success and error envelope formats                                              |
| `exit_codes`       | Machine-readable exit code meanings                                             |
| `installed_extras` | Which optional packages are available (`data`, `llm`, `postgres`, `clickhouse`) |

This allows an agent to introspect the CLI on first run and plan its workflow without any prior knowledge.

## Built-in Guide

The CLI includes a comprehensive dataset configuration guide accessible via the command line:

```bash theme={null}
# Full configuration reference
anysite dataset guide

# Specific section
anysite dataset guide --section sources

# Complete example config
anysite dataset guide --example advanced

# List all available sections and examples
anysite dataset guide --list

# JSON output for agents
anysite dataset guide --json
```

<Tip>
  Agents can use `anysite dataset guide --json` to get a structured reference of all dataset pipeline features, source types, and configuration options.
</Tip>

## Integration Examples

### Pipe to jq

```bash theme={null}
# Extract a specific field
anysite api /api/linkedin/user user=satyanadella | jq '.result.follower_count'

# Process batch results
anysite api /api/linkedin/search/users keywords="CTO" count=10 --json | \
  jq -r '.result[] | [.name, .headline] | @csv'
```

### Shell Script with Error Handling

```bash theme={null}
#!/bin/bash
RESPONSE=$(anysite api /api/linkedin/user user="$1" 2>/dev/null)
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
  echo "$RESPONSE" | jq '.result'
elif [ $EXIT_CODE -eq 3 ]; then
  echo "Authentication failed. Check your API key."
  exit 1
elif [ $EXIT_CODE -eq 5 ]; then
  echo "Network error. Retrying in 5 seconds..."
  sleep 5
  anysite api /api/linkedin/user user="$1"
else
  ERROR=$(echo "$RESPONSE" | jq -r '.error.message')
  echo "Error: $ERROR"
  exit $EXIT_CODE
fi
```

### Agent Workflow

A typical AI agent workflow with the CLI:

```bash theme={null}
# 1. Discover CLI capabilities
anysite | jq '.result.commands'

# 2. Discover available endpoints
anysite describe --search "linkedin" --json

# 3. Inspect specific endpoint
anysite describe /api/linkedin/user --json

# 4. Execute and parse
RESULT=$(anysite api /api/linkedin/user user=satyanadella)
echo "$RESULT" | jq '.ok'     # true
echo "$RESULT" | jq '.hints'  # next steps
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Data Agent" icon="robot" href="/cli/agents/data-agent">
    AI agent for automated data collection using the agent protocol
  </Card>

  <Card title="Installation" icon="download" href="/cli/installation">
    Install the CLI and configure global options
  </Card>
</CardGroup>
