---
title: "CLI"
description: "Run Nuxt SEO Pro Site operations from a terminal, a script, or a coding agent."
canonical_url: "https://nuxtseo.com/docs/nuxt-seo-pro/guides/cli"
last_updated: "2026-09-23T04:46:46.136Z"
---

`@nuxtseo/cli` runs public Site operations from a terminal, a script, or a coding agent. It sends every request through `@nuxtseo/sdk`. It never calls MCP or a private route.

## Install

Install [Node.js](https://nodejs.org) 22 or newer.

```sh
npm install --global @nuxtseo/cli
nuxtseo --version
```

You can also run one command without a global install:

```sh
npx @nuxtseo/cli sites list
```

## First Site read

Set a Team API token through your shell or your CI secret store. Then list the Sites the token can reach:

```sh
export NUXTSEO_TOKEN='your-team-api-token'
nuxtseo sites list
```

Select a default Site and inspect a Page:

```sh
nuxtseo sites use site_123
nuxtseo page inspect https://example.com/about
```

For an automated read, keep the Site explicit and request JSON:

```sh
nuxtseo page inspect https://example.com/about \
  --site site_123 \
  --json
```

## Sign in

Run `nuxtseo login`. It prints a pairing code, opens your browser on the approval page, and waits. Check that the code in the browser matches the code in your terminal. Choose a role, then approve. The CLI receives a Team API token and stores it.

```sh
nuxtseo login               # pair through the browser
nuxtseo login --no-browser  # print the URL instead of opening it
nuxtseo login --with-token  # paste an existing token instead
```

The token is an ordinary Team API token labelled `CLI on <hostname>`{lang="html"}. It appears under Settings > API tokens and is revoked there like any other.

A pairing request stays open for ten minutes. Denying it creates nothing.

Token resolution order is:

1. `NUXTSEO_TOKEN`
2. The stored credential

Outside an interactive terminal, `login` reads a token from stdin instead of pairing, so CI keeps working. Tokens are never accepted as positional arguments or options.

The CLI validates the token with `GET /api/v1/account/token`, which reports the Team, the role, the granted scopes, and the expiry without reading a Site. `nuxtseo whoami` reads the same operation. It then stores the token in the OS keychain through the optional `@napi-rs/keyring` package. If keychain support is unavailable, the CLI warns on stderr and writes `~/.nuxtseo/auth.json` with mode `0600`.

`nuxtseo logout` removes the local credential. To stop a token working everywhere, revoke it in the dashboard. An environment token always wins, and `login` and `logout` never change it.

API host resolution order is:

1. `--api-url`
2. `NUXTSEO_API_URL`
3. The host stored by `nuxtseo config`
4. `https://nuxtseo.com`

## Site selection

Site scoped commands resolve a Site in this order:

1. `--site <site-id>`{lang="html"}
2. `NUXTSEO_SITE_ID`
3. The Site saved by `nuxtseo sites use <site-id>`{lang="html"}
4. The only accessible Site
5. A selection prompt when several Sites are available in a TTY

Scripts and agents should pass `--site`. Several Sites outside a TTY produce exit `5`. The CLI never guesses.

An explicit argument, environment value, or stored Site ID goes straight to the requested operation. It adds no `sites.list` request and needs no `sites:read` scope.

## JSON output

For a public API success, `--json` writes the complete protocol response envelope to stdout, followed by one newline. The CLI does not unwrap `data`, rename fields, rank results, or add local fields. Warnings and diagnostics go to stderr.

The [OpenAPI 3.1 document](/docs/api/openapi.json) holds the exact paths, request schemas, responses, scopes, and errors. Read it to predict an envelope before you call for it.

The SDK validates and parses the HTTP body before the CLI serializes it. The JSON value and the protocol structure are preserved. Whitespace and object key order from the wire are not a byte level guarantee.

If the server returns a valid protocol error body, `--json` writes that body to stdout and writes the readable recovery message to stderr.

Local outcomes have no server protocol body. With `--json`, commands such as bare `nuxtseo`, `config`, `logout`, and `sites use` emit a tagged CLI-owned JSON value with `schemaVersion: 1`. Local failures emit `CliError` with a stable code and exit code. These tags are separate from protocol envelopes.

`--help --json` returns the selected command, global options, arguments, and subcommands as `CliHelp`. Option names are strict. An unknown option exits `2` before authentication or network work.

## Automation controls

The CLI never prompts outside a TTY. `CI=1` or `--no-input` suppresses interactive mode inside a terminal session. `--json` also implies `--no-input`.

Mutations need confirmation. Pass `--yes` or `-y` in automation:

```sh
nuxtseo page scan https://example.com/about --site site_123 --yes --json
```

| Option                                     | Behaviour                                                                                                |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| `--no-input`                               | Disable every prompt even when stdin and stdout are TTYs                                                 |
| `--timeout-ms <milliseconds>`{lang="html"} | Apply one deadline to Site resolution, SDK retries, and the operation. Default `30000`, maximum `300000` |

A request timeout returns `CliError` code `request_timeout` and exits `6`. The error prints an exact retry command with a longer deadline. `SIGINT` and `SIGTERM` abort the active request and return exit `130`.

## Commands

```text
nuxtseo login
nuxtseo logout
nuxtseo whoami
nuxtseo config
nuxtseo sites list
nuxtseo sites use <site-id>
nuxtseo usage
nuxtseo actions list
nuxtseo actions show <action-id>
nuxtseo actions resolve <action-id>
nuxtseo backlinks recoverable
nuxtseo mentions list
nuxtseo page inspect <url>
nuxtseo page scan <url>
nuxtseo performance
nuxtseo analytics <view>
nuxtseo search status
nuxtseo search analytics <view>
nuxtseo search indexing <summary|urls>
nuxtseo search index-history
nuxtseo search inspect <url>
nuxtseo sitemaps list
nuxtseo sitemaps urls
nuxtseo sitemaps submit <sitemap-url>
nuxtseo sitemaps delete <sitemap-url>
nuxtseo research overview
nuxtseo research keywords <topic>
nuxtseo research serp <keyword>
nuxtseo research rankings <domain>
nuxtseo audit changes
nuxtseo audit link-opportunities
nuxtseo audit link-structure
nuxtseo audit content-decay
nuxtseo audit duplicates
nuxtseo content briefs list
nuxtseo content briefs show <brief-id>
nuxtseo content briefs create <keyword>
nuxtseo skill install
```

`search analytics` takes `pages`, `keywords`, `countries`, `devices`, `timeseries`, `page-detail`, `keyword-detail`, or `analysis`. `page-detail` needs `--page-url`, `keyword-detail` needs `--keyword`, and `analysis` needs `--preset`. The `brand-only` and `non-brand` presets also need `--brand-terms`. The CLI refuses a missing argument before it sends a request.

`analytics` takes `performance`, `top-pages`, `source-medium`, `key-events`, `countries`, `devices`, or `dimension`. The `dimension` view needs `--dimension`.

`search inspect` reads Google's own verdict for one URL. `page inspect` reads the Nuxt SEO observation store for the same URL.

Run bare `nuxtseo` in a terminal for a task based menu. It groups Site fixes, performance, research, content, and account setup. The menu prints the direct command it runs.

`search status` reads stored connection state. It never waits for Google.

`research keywords`, `research serp`, and `research rankings` can use the Team research allowance. Keyword responses report cache use in `evidence`. SERP and ranking responses report `cached: true`. A cached response uses no unit.

## Paging

The CLI fetches one page per invocation by default. It never merges responses.

| Command                 | Paging inputs                              | Default                  | `--all`          |
| ----------------------- | ------------------------------------------ | ------------------------ | ---------------- |
| `actions list`          | `--limit 1..25`, `--offset >=0`            | `--limit 10 --offset 0`  | yes              |
| `actions show`          | `--group-id`, `--cursor`, `--limit 1..100` | `--limit 50`             | no               |
| `page inspect`          | `--limit 1..200`, `--offset >=0`           | `--limit 100 --offset 0` | yes              |
| `backlinks recoverable` | `--limit 1..200`, `--offset >=0`           | `--limit 100 --offset 0` | yes              |
| `mentions list`         | `--limit 1..200`                           | `--limit 100`            | no               |
| `search analytics`      | `--limit 1..100`, `--page >=1`             | `--limit 25 --page 1`    | row views only   |
| `search indexing`       | `--limit 1..500`, `--offset >=0`           | `--limit 50 --offset 0`  | `urls` view only |
| `sitemaps urls`         | `--cursor`, `--limit 1..1000`              | `--limit 500`            | yes              |
| `content briefs list`   | `--limit 1..100`, `--offset >=0`           | `--limit 25 --offset 0`  | yes              |

Keep the server order for actions. For the next page, pass the offset or cursor the response reported. A cursor is opaque. Do not edit or infer one.

`--all` repeats the same operation until the server reports no more pages. It writes one complete envelope per page, newline delimited. The CLI never merges, unwraps, or re-ranks a page. The loop stops after 50 requests. If pages remain, the CLI exits `9` and stderr names the argument that resumes the read.

## Coding agents

The package ships an agent skill that teaches a coding agent how to drive the CLI. Install it with the CLI itself; a global install has no local `node_modules` to copy from.

```sh
nuxtseo skill install                 # ~/.claude/skills/nuxtseo-cli
nuxtseo skill install --agent codex   # ~/.codex/skills/nuxtseo-cli
nuxtseo skill install --target ./.claude/skills
```

The command reports the destination it wrote.

The skill covers the JSON contract, Site selection, paging, mutation consent, and what to do for each exit code.

## Exit codes and recovery

| Code  | Meaning                                                   | Typical recovery                                            |
| ----: | --------------------------------------------------------- | ----------------------------------------------------------- |
| `0`   | Success, including a closed stdout pipe                   | Continue                                                    |
| `2`   | Invalid input, or a mutation with no confirmation         | Fix the arguments. Use `--yes` for a deliberate mutation    |
| `3`   | Missing, invalid, or expired authentication               | Replace `NUXTSEO_TOKEN`, or run `nuxtseo login`             |
| `4`   | Forbidden, scope, or entitlement failure                  | Use a token with the required access, or change plan        |
| `5`   | Conflict, stale evidence, or an ambiguous Site            | Refresh the read. Pass `--site` when selection is ambiguous |
| `6`   | Rate, quota, provider, or request timeout                 | Read the retry metadata on stderr, then retry later         |
| `7`   | Local state, network, contract, or infrastructure failure | Fix the named path or network issue. Keep the request ID    |
| `8`   | Resource or accessible Site not found                     | Run `sites list`, then `sites use`, or pass `--site`        |
| `9`   | `--all` reached its 50 request cap                        | Resume with the argument stderr names                       |
| `130` | Interrupted or cancelled                                  | Confirm no mutation landed before you retry                 |

The CLI prints the exact server error code. Where the server supplies them, stderr also carries the request ID, the retry delay, the rate limit, the reset time, and structured details.

The CLI never falls back to MCP, a private route, or cached feature data.

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
