Arcjet CLI
Arcjet is the AI agent runtime security platform. Discover the agents running in your organization, enforce policy across every action, prompt, and tool call, and keep the evidence to prove what happened. Detect prompt injection, authorize agent tool calls, redact PII, and block bots and abuse.
The Arcjet CLI (arcjet) manages your Arcjet account from a terminal. Use it to create sites and fetch their keys, manage remote rules, inspect requests and guard decisions, analyze traffic, and stream live activity. It works the same way for you and for an AI coding agent that runs shell commands, such as Claude Code or Codex, and in CI.
The CLI and the MCP server both connect to the Arcjet API, but they don’t cover exactly the same commands. For example, only the CLI manages projects and streams live activity, and only the MCP server has the Guard policy tools. To compare them with Arcjet skills and the Arcjet plugin, see Tools for AI coding agents.
Install
Section titled “Install”You can run the CLI with npx, or install the arcjet binary.
Run with npx
Section titled “Run with npx”The npx path needs Node.js 18 or later. It works on macOS, Linux, and Windows with no install step:
npx -y @arcjet/cli@latest auth loginnpx -y @arcjet/cli@latest versionThe rest of this page uses arcjet in examples. If you haven’t installed the binary, replace arcjet with npx -y @arcjet/cli@latest.
Install the binary
Section titled “Install the binary”For frequent or interactive use, install the binary so that you can run arcjet directly. Homebrew, the install script, and the release binaries don’t need Node.js.
npm install -g @arcjet/cliRequires Node.js 18 or later.
brew install arcjet/tap/arcjetAvailable for macOS (Apple Silicon, Intel) and Linux (x86_64, arm64).
curl -sSfL https://arcjet.com/cli/install.sh | bashDownloads the release archive for your platform from
github.com/arcjet/cli/releases
and installs the arcjet binary onto your PATH. Available for macOS
(Apple Silicon, Intel) and Linux (x86_64, arm64).
Download the archive for your platform from
github.com/arcjet/cli/releases,
extract it, and place the arcjet binary somewhere on your PATH. Use
this for internal redistribution and air-gapped environments.
Available for macOS (Apple Silicon, Intel), Linux (x86_64, arm64), and Windows (x86_64, arm64).
To verify the install, print the version:
arcjet versionAuthentication
Section titled “Authentication”The CLI signs in with a browser-based device flow, like gh auth login or vercel login:
arcjet auth loginThe CLI prints a one-time code and opens a URL. Confirm the code in your browser, and the CLI stores the credentials in ~/.config/arcjet/credentials.json, readable only by your user. Later commands authenticate automatically and refresh the stored session when it expires.
Choose a team
Section titled “Choose a team”A session acts in one team. If you belong to more than one team, pass --team-id to choose it. Without it, the session acts in the team that the sign-in selects.
arcjet auth login --team-id team_01abc123To see which team the session acts in, check the teamId field of arcjet auth status. To switch teams, run arcjet auth login --team-id again.
Check status and sign out
Section titled “Check status and sign out”arcjet auth statusarcjet auth logoutNon-interactive authentication
Section titled “Non-interactive authentication”For CI, scripts, and other headless environments, set the ARCJET_TOKEN environment variable instead of running arcjet auth login. ARCJET_TOKEN holds an Arcjet access token, and it takes priority over stored credentials.
To get a token, sign in on a machine with a browser, then print the current token as a shell export:
eval "$(arcjet auth token)"arcjet auth token --shell fish | sourcearcjet auth token --shell powershell | Invoke-Expression--shell accepts posix (the default, also sh, bash, or zsh), fish, csh (or tcsh), and powershell (or pwsh). To get {"token": "..."} instead, pass --output json. You can’t combine --output json with --shell.
The CLI uses ARCJET_TOKEN as it is and never refreshes it. When the token expires, commands fail with exit code 2. Run arcjet auth token again to get a new one, and store it as a secret in your CI system.
Global flags
Section titled “Global flags”Every command accepts the following flags:
| Flag | Description |
|---|---|
--output, -o | Output format: text or json. The default is text when stdout is a terminal and json otherwise. |
--fields | Comma-separated list of top-level keys to include in JSON output, such as --fields traffic,quota. Keys inside lists aren’t filtered. |
--timeout | Maximum time the command can run, such as 30s or 5m. The default, 0, disables the timeout. |
--no-color | Disable ANSI color output. The CLI also honors the NO_COLOR environment variable. |
--help, -h | Show help for a command. |
arcjet --version (or -V) prints the version number only. arcjet version also prints the commit, build date, Go version, operating system, and architecture.
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 | Success. |
1 | General error, such as an unknown command, an API or network error, or a timeout. |
2 | Authentication error, such as not signed in, an expired token, or access denied. |
3 | Input validation error, such as an invalid ID format or a value out of range. |
4 | Confirmation required. A command that changes data ran without --confirm. |
With JSON output, errors go to stderr as an object with error, code, and, when there is one, remediation.
Confirm changes
Section titled “Confirm changes”Commands that create, change, or delete something require --confirm: projects create, sites create, and rules create, update, delete, and promote. Without --confirm, the command changes nothing. It prints a JSON preview on stdout and exits with code 4:
{ "status": "confirmation_required", "command": "rules delete", "changes": ["..."], "confirmCommand": "arcjet rules delete --site-id site_01abc123 --rule-id remote_rule_01abc123 --confirm"}Review the changes, then run the confirmCommand to apply them.
Command reference
Section titled “Command reference”Run arcjet --help to list the commands, or arcjet <command> --help for the flags and examples of one command. IDs use a prefix that shows what they identify: team_, prj_ (project), site_, req_ (request), gdec_ (guard decision), and remote_rule_.
Authentication commands
Section titled “Authentication commands”| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet auth login | – | --team-id | Sign in with the browser-based device flow. |
arcjet auth status | – | – | Show whether you’re signed in and the session’s team. |
arcjet auth token | – | --shell posix|fish|csh|powershell | Print the current token as a shell export of ARCJET_TOKEN. |
arcjet auth logout | – | – | Remove stored credentials. |
For examples, see Authentication.
| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet teams list | – | – | List the teams that this session can access. |
arcjet teams list --output jsonProjects
Section titled “Projects”A project groups related sites. Its project key starts with aj_prj_key_, and it’s the key that
coding agent hooks and OpenTelemetry export accept. The SDK needs a site key instead.
| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet projects list | --team-id | – | List the projects in a team. |
arcjet projects get-key | --project-id | – | Return a project’s key (aj_prj_key_). |
arcjet projects create | --team-id, --name | --confirm | Create a project in a team. Returns its ID and key. |
arcjet projects list --team-id team_01abc123arcjet projects get-key --project-id prj_01abc123arcjet projects create --team-id team_01abc123 --name "My Project" --confirmThe CLI and the API call an actor a site. A site’s key starts with ajkey_, and it’s the ARCJET_KEY that the SDK uses.
| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet sites list | --team-id | – | List the sites in a team. |
arcjet sites get-key | --site-id | – | Return the SDK key (ARCJET_KEY) for a site. |
arcjet sites create | --team-id, --name | --project-id, --confirm | Create a site, optionally in a project. |
arcjet sites list --team-id team_01abc123arcjet sites get-key --site-id site_01abc123arcjet sites create --team-id team_01abc123 --name "My API" --project-id prj_01abc123 --confirmRequests
Section titled “Requests”Requests are the decisions that protect() makes in the request SDKs.
| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet requests list | --site-id | --conclusion, --filter, --limit, --cursor | List recent requests. |
arcjet requests details | --site-id, --request-id | – | Show a request’s headers, rule results, and decision details. |
arcjet requests explain | --site-id, --request-id | – | Explain in plain English why a request was allowed or denied, with a per-rule breakdown and suggested next steps. |
requests list accepts the following filters:
--conclusion:ALLOW,DENY,CHALLENGE, orERROR.--filter: a search expression, such asHOST:example.comorPATH:/api. Combine terms withAND,OR, andNOT.--limit: the number of requests to return, from 1 to 100. The default is 25.--cursor: the cursor from a previous response, to fetch the next page. In text output, the CLI prints the next page’s--cursorvalue after the list.
The list covers your plan’s log retention period. When older requests fall outside it, the output says so.
arcjet requests list --site-id site_01abc123 --conclusion DENY --filter "PATH:/api" --limit 10arcjet requests details --site-id site_01abc123 --request-id req_01abc123arcjet requests explain --site-id site_01abc123 --request-id req_01abc123Guard decisions
Section titled “Guard decisions”Guard decisions are the decisions that guard() makes in the Guard SDKs, including coding agent hooks.
| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet guards list | --site-id | --conclusion, --limit, --cursor | List recent guard decisions. |
arcjet guards details | --site-id, --decision-id | – | Show a guard decision with the result of each rule. |
arcjet guards watch | --site-id | --conclusion, --interval | Stream new guard decisions as they arrive. Press Control+C to stop. |
For guard decisions, --conclusion accepts ALLOW or DENY. --limit (1 to 100, default 25) and --cursor work as they do for requests list. --interval sets how often guards watch checks for new decisions, from 1 to 60 seconds. The default is 5.
arcjet guards list --site-id site_01abc123 --conclusion DENY --limit 10arcjet guards details --site-id site_01abc123 --decision-id gdec_01abc123arcjet guards watch --site-id site_01abc123 --conclusion DENYRemote rules
Section titled “Remote rules”Remote rules apply to every request for a site without a code change. They support the rate_limit, bot, shield, and filter types. Rules that need the parsed request body (email, sensitive_info, prompt_injection) need the SDK.
| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet rules list | --site-id | – | List the remote rules for a site. |
arcjet rules create | --site-id, --type | --max, --window, --algorithm, --match, --allow, --deny, --confirm | Create a rule. New rules always start in DRY_RUN mode. |
arcjet rules update | --site-id, --rule-id | --mode, --max, --window, --algorithm, --match, --allow, --deny, --confirm | Replace a rule’s configuration. Provide every field the rule needs. |
arcjet rules delete | --site-id, --rule-id | --confirm | Delete a rule immediately. |
arcjet rules promote | --site-id, --rule-id | --confirm | Switch a rule from DRY_RUN to LIVE. |
The rule flags are as follows:
--type:rate_limit,bot,shield, orfilter.--maxand--window: forrate_limit, the maximum number of requests in a window of the given number of seconds. Both are required for a rate limit.--algorithm: forrate_limit,FIXED_WINDOW(the default) orSLIDING_WINDOW.--match: forrate_limit, a glob pattern for the paths the limit applies to.--allowand--deny: forbotandfilter, the bots or expressions to allow or deny. Repeat the flag, or separate values with commas.--mode: forrules update,MODE_LIVEorMODE_DRY_RUN. Without it, the rule keeps its current mode.
arcjet rules list --site-id site_01abc123arcjet rules create --site-id site_01abc123 --type rate_limit --max 100 --window 60 --confirmarcjet rules update --site-id site_01abc123 --rule-id remote_rule_01abc123 --max 200 --window 60 --confirmarcjet rules delete --site-id site_01abc123 --rule-id remote_rule_01abc123 --confirmarcjet rules promote --site-id site_01abc123 --rule-id remote_rule_01abc123 --confirmAnalysis
Section titled “Analysis”| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet analyze traffic | --site-id | --days | Total requests, denials, denial rate, top paths, top IPs, denial reasons, and the trend compared with the previous period. |
arcjet analyze anomalies | --site-id | --days | Unusual patterns compared with the previous period of the same length, such as traffic spikes, geographic shifts, and suspicious IPs. |
arcjet analyze dry-run-impact | --site-id | --days | How many allowed requests each DRY_RUN rule type would block if promoted, the affected IPs, and a false-positive estimate. |
arcjet analyze ip | --site-id, --ip | --days | Threat intelligence, location, and request activity for one IP address on a site. |
arcjet briefing | --site-id | --days | A security briefing: traffic, denial breakdown, quota status, and active rules. |
--days sets the period to analyze. The default is 7. It accepts 1 to 30, except for analyze anomalies, which accepts 1 to 15.
arcjet analyze traffic --site-id site_01abc123 --days 14arcjet analyze anomalies --site-id site_01abc123arcjet analyze dry-run-impact --site-id site_01abc123arcjet analyze ip --site-id site_01abc123 --ip 203.0.113.10arcjet briefing --site-id site_01abc123Live requests
Section titled “Live requests”| Command | Required flags | Optional flags | Description |
|---|---|---|---|
arcjet watch | --site-id | --conclusion, --filter, --interval | Stream new requests as they arrive. Press Control+C to stop. |
--conclusion and --filter work as they do for requests list. --interval sets how often to check for new requests, from 1 to 60 seconds. The default is 5. Timestamps are in UTC.
arcjet watch --site-id site_01abc123 --conclusion DENY --interval 3Utilities
Section titled “Utilities”| Command | Description |
|---|---|
arcjet skills | Print the install command for Arcjet skills, npx skills add arcjet/skills. |
arcjet completion <shell> | Generate shell completions for bash, zsh, or fish. |
arcjet version | Print version information. |
arcjet skillssource <(arcjet completion zsh)arcjet version --output jsonCommon workflows
Section titled “Common workflows”The following sections show common sequences of commands.
Set up a new application
Section titled “Set up a new application”- Sign in with
arcjet auth login. - Find your team with
arcjet teams list. - Find a site with
arcjet sites list --team-id <id>, or create one witharcjet sites create. - Get the key with
arcjet sites get-key --site-id <id>, and save it asARCJET_KEYin the application’s.envfile.
Investigate a request
Section titled “Investigate a request”- Find the request with
arcjet requests list --site-id <id> --conclusion DENY. - See its headers and rule results with
arcjet requests details --site-id <id> --request-id <request-id>. - Get a plain-English summary with
arcjet requests explain --site-id <id> --request-id <request-id>.
Review traffic
Section titled “Review traffic”Start with arcjet briefing --site-id <id> or arcjet analyze traffic --site-id <id> for an overview. Use arcjet analyze anomalies --site-id <id> to find unusual patterns, and arcjet analyze ip --site-id <id> --ip <ip> to look into a suspicious IP address.
Roll out a remote rule
Section titled “Roll out a remote rule”- Create the rule with
arcjet rules create. It starts inDRY_RUNmode. - After traffic has flowed through it, check the effect with
arcjet analyze dry-run-impact --site-id <id>. - Switch it to
LIVEwitharcjet rules promote --site-id <id> --rule-id <rule-id> --confirm.
Guidance for AI agents
Section titled “Guidance for AI agents”If you’re an AI coding agent running the CLI, follow these practices:
- Use JSON and limit fields. JSON is the default when stdout isn’t a terminal. Add
--fieldsto return only the top-level keys you need, for examplearcjet briefing --site-id site_01abc123 --fields traffic,rules. - Branch on exit codes. Read the exit code and, with JSON output, the error object on stderr. Exit code
2means the user needs to sign in again. - Confirm with the user before any change. Run a mutating command without
--confirmfirst, show the user thechangesfrom the preview, and run theconfirmCommandonly after they agree. - Don’t ask the user for a token. If
arcjet auth statusreports that the user isn’t signed in, runarcjet auth loginand wait for them to confirm in the browser. UseARCJET_TOKENonly in headless environments. - Install skills if they’re missing.
arcjet skillsprints the command that installs Arcjet skills. - Rely on the command contract. Commands and flags change only by addition, so existing invocations keep working.
See also
Section titled “See also”- Tools for AI coding agents compares the CLI with Arcjet skills, the MCP server, and the Arcjet plugin.
- Agent get started is the full setup guide for AI coding agents.
- MCP server connects AI clients without shell access to the Arcjet API.
- arcjet/cli on GitHub has release archives and the changelog.
Get help
Section titled “Get help”Need help with anything? Email us or join our Discord to get support from our engineering team.
