CLI reference
Complete reference for the Arctic command-line interface
The Arctic CLI (arctic) manages Arctic agents and clusters. It follows the pattern arctic <command> [subcommand] [flags].
Most read commands map to a collection (list) or a single item (get). Output goes to stdout; progress messages, prompts, and errors go to stderr, so you can pipe machine-readable output cleanly.
bootstrap
Initialize an Arctic agent with a license file.
Synopsis
arctic bootstrap --url <agent-url> --license-file <path> [flags]Description
Bootstrap initializes an agent with a license. This:
- Uploads the license to the agent
- Generates a unique peer identity (Ed25519 key pair)
- Creates OAuth2 credentials for API access
- Saves the cluster to your CLI config file and sets it as current
Flags
| Flag | Description |
|---|---|
--url | Agent URL (e.g. http://192.168.1.10:8080). Provide via the global --url flag |
--license-file | Path to the license JSON file (required) |
--name | Human-readable name for this peer (optional) |
Output
Peer ID: peer_01HXYZ...
Cluster ID: clu_01HABC...
Client ID: cli_01HXYZ...
License ID: lic_abc123...
Expires: 2025-12-31 23:59:59 UTC
Max Nodes: 10
Max Services: 100
Configuration saved to ~/.config/arctic/config.yaml
Set as current cluster: clu_01HABC...Examples
# Basic bootstrap
arctic bootstrap \
--url http://192.168.1.10:8080 \
--license-file license.json
# With a peer name
arctic bootstrap \
--url http://192.168.1.10:8080 \
--license-file license.json \
--name prod-svr-1Notes
- An agent can only be bootstrapped once. To re-bootstrap, reset the agent's database.
- The license file is
license.json, provided by Tillered. - For multi-peer clusters, prefer
arctic compose applyover running bootstrap by hand.
cluster
Manage cluster operations.
Synopsis
arctic cluster <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
init | Initialize cluster for legacy upgraded agents |
identity | Show cluster identity of a peer |
sync | Trigger cluster synchronization |
status | Show gossip status for diagnostics |
cluster init
Initialize a cluster on a legacy agent that predates cluster IDs. Required scope: urn:tillered:arctic:admin.
arctic cluster init [--force]| Flag | Description |
|---|---|
--force | Force reinitialize even if a cluster already exists |
Cluster initialized
Cluster ID: clu_01HABC...
Created By: peer_01HXYZ...
Oldest Peer: peer_01HXYZ...
Was Created: trueNotes:
- New agents have a cluster initialized during bootstrap. This command exists for upgraded agents only.
--forceregenerates the cluster ID and destroys existing cluster state.
cluster identity
Show the cluster identity of a peer. This is a public endpoint and requires no authentication.
arctic cluster identityPeer ID: peer_01KBYMHC35F0N070F3XXMEZAZR
Public Key: qnGyPtol7lqzLYU3989eaC+K4xda0w9KXlcEOM9cSBQ=
License ID: lic_01KB45EYP1VJ1RZEGJDPKJQ9V4
Cluster ID: clu_01KBYMHMRJ92E090P50VRKG4ZC
Version: v1.4.0Use -j for JSON output:
{
"peer_id": "peer_01KBYMHC35F0N070F3XXMEZAZR",
"public_key": "qnGyPtol7lqzLYU3989eaC+K4xda0w9KXlcEOM9cSBQ=",
"license_id": "lic_01KB45EYP1VJ1RZEGJDPKJQ9V4",
"cluster_id": "clu_01KBYMHMRJ92E090P50VRKG4ZC",
"version": "v1.4.0"
}The version field reports the agent build that answered the request, so the exact value depends on the peer you query.
cluster sync
Trigger immediate cluster synchronization. Required scope: urn:tillered:arctic:admin.
arctic cluster syncThis forces a gossip round and reconciliation across the agent's reconcilers instead of waiting for the next periodic resync. Use it to speed up propagation after adding a peer or changing config.
cluster status
Show gossip status for diagnostics. Required scope: urn:tillered:arctic:admin.
arctic cluster statusGossip Status
-------------
Local Peer: peer_01KBYMHC35F0N070F3XXMEZAZR
Cluster ID: clu_01KBYMHMRJ92E090P50VRKG4ZC
Peer Status:
peer_01KBYMD32Z2RVDE3G5Y9M530QR:
Last Seen: 2025-12-09 10:15:30 UTC
Status: healthy
Registry Hash: a1b2c3d4...
Registry:
Services: 5
Routes: 12
Hash: e5f6g7h8...Use -j for JSON output. Useful for diagnosing synchronization issues and detecting registry drift between peers.
completion
Generate shell completion scripts for the Arctic CLI.
Synopsis
arctic completion <shell>| Argument | Description |
|---|---|
shell | Shell type: bash, zsh, or fish |
Installation
# Bash: add to ~/.bashrc
source <(arctic completion bash)
# Zsh: add to ~/.zshrc
source <(arctic completion zsh)
# Fish: save to the completions directory
arctic completion fish > ~/.config/fish/completions/arctic.fishFeatures
- Command completion:
arctic pe<TAB>completes topeers. - Subcommand completion:
arctic peers l<TAB>completes tolist. - Flag completion:
arctic peers list --<TAB>lists available flags. - Value completion: peer IDs and service IDs complete from the local cache (see
arctic cache).
Example session
$ arctic <TAB>
bootstrap cache cluster completion compose
config credentials health license mcp
peers routes services state
$ arctic peers <TAB>
add delete get list remove-self update
$ arctic peers list --<TAB>
--local --remote --client-id --client-secret
--config --context --debug --insecure
--json --no-headers --output --quiet
--timeout --token --url --yes
-c -j -o -q -ycompose
Manage Arctic clusters declaratively from a YAML configuration file. This is the recommended way to deploy and operate a cluster.
See the compose guide for a walkthrough and the configuration reference for the full schema.
Synopsis
arctic compose <subcommand> [config-file] [flags]Subcommands
| Subcommand | Description |
|---|---|
apply | Apply cluster configuration from YAML |
diff | Show differences between config and cluster state |
export | Export cluster configuration to YAML |
validate | Validate YAML syntax and schema |
init | Generate a starter configuration template |
fmt | Format a configuration file |
compose apply
Apply cluster configuration from a YAML file. Required scope: urn:tillered:arctic:admin.
arctic compose apply <config-file> [flags]| Flag | Default | Description |
|---|---|---|
--dry-run | false | Show changes without applying |
--prune | false | Delete resources not in config |
--ignore-unreachable | false | Skip unreachable peers |
--license-file | License file for bootstrap | |
--credentials-file | Write credentials to a JSON file on bootstrap | |
--env-file | Write credentials to a .env file on bootstrap | |
--save-config | true | Save cluster to CLI config and set as current (use --save-config=false to disable) |
--skip-validate | false | Skip pre-validation checks (not recommended) |
--skip-preflight | false | Skip pre-flight peer connectivity checks |
--skip-requires | false | Skip the requires block version checks |
--strict | false | Treat validation warnings as errors |
--backup-retention | 0 | Override preferences.backup_retention for this run (1-100; 0 uses the configured default) |
--state-dir | Override the .arctic/ state directory location | |
--no-lock | false | Skip cluster-wide lock acquisition (the local file lock still applies). Required when the server peer is unreachable or compose modifies server.peer |
# Validate and apply
arctic compose apply cluster.yaml
# Preview changes without applying
arctic compose apply cluster.yaml --dry-run
# Apply and prune resources not in config
arctic compose apply cluster.yaml --prune
# Bootstrap and save credentials in one step
arctic compose apply cluster.yaml \
--license-file license.json \
--credentials-file creds.json
# Apply without saving to CLI config
arctic compose apply cluster.yaml --save-config=falseExample output:
Validating cluster.yaml...
OK - Configuration valid
Checking cluster state...
peer-a: bootstrapped
peer-b: bootstrapped
Planning changes...
+ Create service: web-tunnel (peer-a -> peer-b)
+ Create route: 0.0.0.0/0 -> 10.0.0.0/8
Applying changes...
[OK] Created service web-tunnel
[OK] Created route 10.0.0.0/8
Apply complete: 1 service created, 1 route createdcompose diff
Show differences between the configuration file and current cluster state. Required scopes: urn:tillered:arctic:peers.read, urn:tillered:arctic:services.read.
arctic compose diff <config-file> [flags]| Flag | Description |
|---|---|
--skip-preflight | Skip pre-flight peer connectivity checks |
--skip-requires | Skip the requires block version checks |
--state-dir | Override the .arctic/ state directory location |
Comparing cluster.yaml with cluster state...
Services:
~ web-tunnel: bandwidth_limit_mbps changed (0 -> 100)
+ new-tunnel: will be created
- old-tunnel: will be deleted (with --prune)
Routes:
+ 10.0.0.0/8: will be added to web-tunnelcompose export
Export the current cluster configuration to YAML. Required scopes: urn:tillered:arctic:peers.read, urn:tillered:arctic:services.read.
arctic compose export [flags]| Flag | Description |
|---|---|
--file | Output file path (defaults to stdout) |
arctic compose export
arctic compose export --file cluster.yamlcompose validate
Validate configuration YAML syntax and schema. Runs locally; no agent connection or auth required.
arctic compose validate <config-file> [flags]| Flag | Default | Description |
|---|---|---|
--strict | false | Treat warnings as errors |
Use -j for JSON output and -q to suppress non-error output (both are global flags).
Validating cluster.yaml...
OK - Configuration valid
Schema version: v1
Peers: 2
Services: 1
Routes: 1compose init
Generate a starter configuration template.
arctic compose init [flags]| Flag | Default | Description |
|---|---|---|
--file | Output file path (defaults to stdout) | |
--minimal | false | Generate a minimal config without comments |
arctic compose init # full example to stdout
arctic compose init --file cluster.yaml # full example to a file
arctic compose init --minimal # minimal configcompose fmt
Format a configuration file to canonical form. Reorders keys to the canonical order, normalizes to 2-space indentation, and preserves comments.
arctic compose fmt <config-file> [flags]| Flag | Default | Description |
|---|---|---|
--write | false | Write formatted output back to the file |
--check | false | Check if the file is formatted (exit 1 if not) |
arctic compose fmt cluster.yaml # print formatted config
arctic compose fmt cluster.yaml --write # format in place
arctic compose fmt cluster.yaml --check # CI checkExit codes
| Code | Condition |
|---|---|
| 0 | Success |
| 2 | Usage or validation error |
| 3 | Configuration error |
| 4 | Connection error |
| 7 | Lock contention (another apply holds the lock) |
config
Manage the Arctic CLI's local configuration file.
Synopsis
arctic config <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List all clusters and peers |
view | View the full configuration |
current | Show the current cluster context |
use-cluster | Set the current cluster |
add-peer | Add a peer to a cluster |
delete-peer | Delete a peer from the cluster configuration |
config list
arctic config listID NAME URL LICENSE CURRENT
clu_01HXYZABC123... agent-a http://192.168.1.10:8080 lic_... *
clu_01HXYZDEF789... agent-b http://192.168.1.20:8080 lic_...config view
View the full configuration file.
arctic config viewconfig current
Show the current cluster context.
arctic config currentCluster ID: clu_01HABC...
Name: Production
Customer ID: cust_...
Peer Count: 3
Default Peer: peer_01HXYZ...
Default URL: http://192.168.1.10:8080
Format: clusterconfig use-cluster
Set the current cluster context by ID or name.
arctic config use-cluster <cluster-id-or-name>arctic config use-cluster Production
arctic config use-cluster clu_01HABCDEF...config add-peer
Add a peer entry to a cluster in your local config (does not contact the agent).
arctic config add-peer --peer-id <id> --peer-url <url> [flags]| Flag | Description |
|---|---|
--peer-id | Peer ID (required) |
--peer-url | Agent URL (required) |
--cluster | Cluster ID or name (defaults to current cluster) |
--name | Human-readable name for the peer |
arctic config add-peer \
--peer-id peer_01HXYZ... \
--peer-url http://192.168.1.30:8080 \
--name agent-c \
--cluster Productionconfig delete-peer
Remove a peer entry from a cluster in your local config.
arctic config delete-peer <peer-id-or-name> [flags]| Flag | Description |
|---|---|
--cluster | Cluster ID or name (defaults to current cluster) |
arctic config delete-peer agent-c
arctic config delete-peer agent-c --cluster ProductionRequires confirmation unless --yes is specified.
credentials
Manage OAuth2 API credentials. Alias: credential.
Synopsis
arctic credentials <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List all credentials |
create | Create a new credential |
revoke | Revoke a credential |
rotate | Rotate the shared cluster credential secret |
credentials list
List credentials for the current license. Required scope: urn:tillered:arctic:credentials.read.
arctic credentials listEach entry shows the client ID, scopes, license ID, creation time, and last-used time. The client secret is never returned by list. Use -j for JSON output.
credentials create
Create a new credential. Required scope: urn:tillered:arctic:credentials.write.
arctic credentials create [--scopes <list>]| Flag | Description |
|---|---|
--scopes | Comma-separated scopes (optional; omit for full access) |
The client secret is shown once, on stderr, and cannot be retrieved again:
arctic credentials create --scopes urn:tillered:arctic:peers.read,urn:tillered:arctic:services.readIMPORTANT: Save the client_secret below. It will NOT be shown again.
Credential created successfully:
Client ID: cli_01HXYZ...
Client Secret: sec_abc123...
Scopes: urn:tillered:arctic:peers.read, urn:tillered:arctic:services.readcredentials revoke
Revoke a credential by client ID. Required scope: urn:tillered:arctic:credentials.write.
arctic credentials revoke <client-id>arctic credentials revoke cli_01HXYZ...credentials rotate
Rotate the shared cluster credential secret. The old secret keeps working for 24 hours so peers can pick up the new one via gossip. Required scope: urn:tillered:arctic:credentials.write.
arctic credentials rotate [--update-config]| Flag | Description |
|---|---|
--update-config | Update the CLI config file with the rotated secret |
IMPORTANT: Save the new client_secret below. The old secret expires in 24 hours.
Cluster credential rotated successfully:
Client ID: cli_01HXYZ...
Client Secret: sec_def456...
Version: 2
Rotated By: peer_01HXYZ...
The new credential will be gossiped to all cluster peers.health
Check Arctic agent health. Requires no authentication.
Synopsis
arctic health [flags]Flags
| Flag | Description |
|---|---|
--readyz | Check readiness (/readyz) instead of liveness (/livez) |
arctic health # liveness, current context
arctic health --readyz # readiness
arctic health --url http://192.168.1.30:8080 # specific agent
arctic health -j # JSON outputDefault output:
Peer ID: peer_01KBYMHC35F0N070F3XXMEZAZR
Name: agent-1
URL: http://192.168.3.251:8080
Status: ok
Timestamp: 2025-12-09 04:43:41 UTCJSON output:
{
"peer_id": "peer_01KBYMHC35F0N070F3XXMEZAZR",
"name": "agent-1",
"url": "http://192.168.3.251:8080",
"status": "ok",
"timestamp": "2025-12-09 04:43:41 UTC"
}Liveness (/livez) indicates the process is running. Readiness (/readyz) indicates the agent is ready to serve requests, and may return not-ready during startup. Both are unauthenticated, which makes them suitable for load balancers and Kubernetes probes.
Scripting example
arctic health --url http://192.168.1.10:8080
case $? in
0) echo "Agent healthy" ;;
4) echo "Agent unreachable"; send_alert "Arctic agent down" ;;
*) echo "Unexpected error" ;;
esaclicense
Manage the agent license. The agent re-verifies the license on every startup.
Synopsis
arctic license <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
status | Show license usage status |
update | Update the license |
license status
Show license usage status. Required scope: urn:tillered:arctic:admin.
arctic license statusLicense Information
-------------------
License ID: lic_abc123...
Customer ID: cust_xyz789...
Customer Name: Acme Corp
Validity
--------
Issued: 2024-01-01 00:00:00 UTC
Expires: 2025-12-31 23:59:59 UTC
Status: Valid (350 days remaining)
Limits
------
Max Nodes: 10
Max Services: 100
Metadata
--------
Issuer: Tillered
Key ID: 2024Q4
Algorithm: Ed25519Use -o json for JSON output.
license update
Update the agent license with a new license file. Required scope: urn:tillered:arctic:admin.
arctic license update --license-file <path>| Flag | Description |
|---|---|
--license-file | Path to the new license file (required) |
arctic license update --license-file new-license.jsonLicense updated
Customer ID: cust_xyz789...
License ID: lic_def456...
Expires: 2026-12-31 23:59:59 UTC
Max Nodes: 20
Max Services: 200Notes:
- The new license must be for the same customer.
- Connected peers receive the updated license via gossip.
peers
Manage cluster peers. Alias: peer.
Synopsis
arctic peers <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List all peers |
get | Get details of a specific peer |
add | Add a remote peer |
update | Update peer metadata |
delete | Delete a peer |
remove-self | Remove the local peer from the cluster |
peers list
List peers in the cluster. Required scope: urn:tillered:arctic:peers.read.
arctic peers list [flags]| Flag | Description |
|---|---|
--local | Show only the local peer (mutually exclusive with --remote) |
--remote | Show only remote peers (mutually exclusive with --local) |
arctic peers list
arctic peers list --remote
arctic peers list -jID NAME ADDRESS
peer_01KBYMHC35F0N070F3XXMEZAZR agent-1 192.168.3.251:8080
peer_01KBYMD32Z2RVDE3G5Y9M530QR agent-2 10.10.40.95:8080peers get
Get a specific peer by ID. Required scope: urn:tillered:arctic:peers.read.
arctic peers get <peer-id>ID: peer_01KBYMHC35F0N070F3XXMEZAZR
Name: agent-1
Public Key: qnGyPtol7lqzLYU3989eaC+K4xda0w9KXlcEOM9cSBQ=
Is Local: Yes
Address: 192.168.3.251:8080
Created At: 2025-12-08 09:26:30 UTCpeers add
Add a remote peer to the cluster. Required scope: urn:tillered:arctic:peers.write.
arctic peers add <peer-address> [flags]| Flag | Description |
|---|---|
--name | Human-readable name for the peer |
arctic peers add 192.168.1.20:8080
arctic peers add 192.168.1.20:8080 --name prod-svrThis contacts the remote peer, performs a handshake (exchanging public keys), verifies both signatures against the license, then records the peer locally. The remote peer adds the local peer via gossip.
peers update
Update a peer's metadata. Required scope: urn:tillered:arctic:peers.write.
arctic peers update <peer-id> [flags]| Flag | Default | Description |
|---|---|---|
--name | Human-readable name for the peer | |
--qos | true | Enable QoS for this peer (use --qos=false to disable) |
arctic peers update peer_01HXYZ... --name prod-svr-2
arctic peers update peer_01HXYZ... --qos=falsepeers delete
Delete a remote peer. Required scope: urn:tillered:arctic:peers.write.
arctic peers delete <peer-id> [--yes]arctic peers delete peer_01HXYZ...
arctic peers delete peer_01HXYZ... --yesTo remove the local peer, use remove-self.
peers remove-self
Gracefully remove the local peer from the cluster. Required scope: urn:tillered:arctic:admin.
arctic peers remove-self [--yes]This deactivates the local peer and broadcasts the deactivation so other peers drop it from their databases. Services involving this peer become inactive.
routes
Manage CIDR-based routing rules for services. Alias: route.
Synopsis
arctic routes <subcommand> --service <service-id> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List routes for a service |
add | Add a route to a service |
update | Update a route |
delete | Delete a route |
routes list
List routes for a service. Required scope: urn:tillered:arctic:services.read.
arctic routes list --service <service-id>ID PRIORITY SOURCE CIDR DEST CIDR
6 100 10.0.0.0/8 192.168.100.0/24
7 200 10.1.0.0/16 192.168.200.0/24routes add
Add a route to a service. Required scope: urn:tillered:arctic:services.write.
arctic routes add --service <service-id> [flags]| Flag | Description |
|---|---|
--service | Service ID (required) |
--priority | Route priority (lower value = higher priority) |
--source-cidr | Source CIDR (e.g. 10.0.0.0/8) |
--dest-cidr | Destination CIDR (e.g. 192.168.100.0/24) |
At least one of --source-cidr or --dest-cidr is required.
# Source and destination CIDR
arctic routes add --service svc_01HSVCABC123... \
--priority 100 \
--source-cidr 10.0.0.0/8 \
--dest-cidr 192.168.100.0/24
# Destination only
arctic routes add --service svc_01HSVCABC123... \
--priority 100 \
--dest-cidr 192.168.100.0/24routes update
Update a route. Required scope: urn:tillered:arctic:services.write.
arctic routes update --service <service-id> --route <route-id> [flags]| Flag | Description |
|---|---|
--service | Service ID (required) |
--route | Route ID (required) |
--priority | New priority |
--source-cidr | New source CIDR |
--dest-cidr | New destination CIDR |
arctic routes update --service svc_01HSVCABC123... --route 6 --priority 200routes delete
Delete a route. Required scope: urn:tillered:arctic:services.write.
arctic routes delete --service <service-id> --route <route-id> [--yes]arctic routes delete --service svc_01HSVCABC123... --route 6 --yesRoute priority and specificity
Routes are matched by specificity first, then priority breaks ties. Specificity order, most specific first: MACVLAN interface match, source plus destination CIDR, source-only CIDR, destination-only CIDR. When two routes have equal specificity, the lower --priority value wins.
| Priority | Source CIDR | Dest CIDR | Order |
|---|---|---|---|
| 200 | 10.1.0.0/16 | 192.168.100.0/24 | 1st (source + dest) |
| 100 | 10.0.0.0/8 | (none) | 2nd (source only) |
| 100 | (none) | 192.168.0.0/16 | 3rd (dest only) |
services
Manage services for network routing. Alias: service.
Synopsis
arctic services <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List services |
get | Get details of a specific service |
create | Create a new service |
update | Update service settings |
delete | Delete a service |
services list
List services. Required scope: urn:tillered:arctic:services.read.
arctic services list [flags]| Flag | Description |
|---|---|
--source-peer | Filter by source peer ID |
--target-peer | Filter by target peer ID |
--requires-interface | Filter to services requiring a MACVLAN interface |
arctic services list
arctic services list --target-peer peer_01HXYZ...
arctic services list -jTable output is a compact view with a per-service flags column:
ID SOURCE TARGET TRANSPORT FLAGS
svc_01KBYMNEVYN9NC4M3RB3ZGN4RZ agent-1 agent-2 tcp I
svc_01KBYMP88A7MBM1KTXBYSFA7VK agent-2 agent-1 tcp IT
FLAGS: I=interface, T=transparent, Q=qos, -=noneUse -j or -o json for full detail with all fields.
services get
Get a specific service by ID. Required scope: urn:tillered:arctic:services.read.
arctic services get <service-id>ID: svc_01KBYMNEVYN9NC4M3RB3ZGN4RZ
Source Peer ID: peer_01KBYMHC35F0N070F3XXMEZAZR
Source Peer Name: agent-1
Target Peer ID: peer_01KBYMD32Z2RVDE3G5Y9M530QR
Target Peer Name: agent-2
Transport: tcp
Requires Interface: Yes
Interface MAC: 4a:cc:db:76:cf:59
Actual Interface IPv4: 192.168.3.219
Fully Transparent: No
Created At: 2025-12-08 09:28:44 UTC
Updated At: 2025-12-08 09:28:44 UTC
Data Source: sourceIf the source peer is unreachable, the CLI queries the target peer for service data. Interface details may then be incomplete and Data Source: local is shown.
services create
Create a new service. Required scope: urn:tillered:arctic:services.write.
arctic services create --target-peer <id> [flags]| Flag | Default | Description |
|---|---|---|
--target-peer | Target peer ID (required) | |
--source-peer | local peer | Source peer ID |
--transport | tcp | Transport type: tcp or kcp |
--requires-interface | false | Create a MACVLAN interface |
--desired-ipv4 | IPv4 CIDR for the interface | |
--fully-transparent | false | Enable fully transparent mode |
--bandwidth-limit | 0 | Bandwidth limit in Mbps (0 = unlimited) |
arctic services create --target-peer peer_01HXYZ...
arctic services create \
--target-peer peer_01HXYZ... \
--requires-interface \
--desired-ipv4 192.168.100.10/24
arctic services create \
--target-peer peer_01HXYZ... \
--transport kcp \
--bandwidth-limit 1000services update
Update a service's settings. Required scope: urn:tillered:arctic:services.write.
arctic services update <service-id> [flags]| Flag | Description |
|---|---|
--requires-interface[=BOOL] | Set the MACVLAN interface requirement |
--fully-transparent[=BOOL] | Set fully transparent mode |
--bandwidth-limit | Bandwidth limit in Mbps (0 = unlimited) |
--desired-ipv4 | IPv4 CIDR for the interface |
arctic services update svc_01HSVCABC123... --requires-interface
arctic services update svc_01HSVCABC123... --requires-interface=false
arctic services update svc_01HSVCABC123... --bandwidth-limit 500services delete
Delete a service. Required scope: urn:tillered:arctic:services.write.
arctic services delete <service-id> [--yes]Deleting a service removes its routes and MACVLAN interface (if any) and updates the firewall and data-plane state.
cache
Manage the local completion cache. Shell completion uses this cache to suggest peer and service IDs.
Synopsis
arctic cache <subcommand>Subcommands
| Subcommand | Description |
|---|---|
refresh | Fetch peers and services from the cluster and update the cache |
status | Show cache location, age, and contents |
delete | Delete the cache file |
cache refresh
arctic cache refreshCache updated: 2 success, 0 failed (84ms)cache status
arctic cache statusCache Location: ~/.config/arctic/cache.json
Last Updated: 2025-12-09 04:43:41 UTC (12m ago)
TTL: 1h
Cluster: clu_01HABC...
Peers: 3
Services: 5If the cache is older than its TTL, a hint to run arctic cache refresh is printed.
cache delete
arctic cache delete [--yes]Prompts for confirmation unless --yes is set.
state
Manage the local .arctic/ working-directory state used by compose apply.
Synopsis
arctic state <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
unlock | Release stale local and cluster locks |
state unlock
Release a stale lock left behind by an interrupted compose apply. The lock ID is the positional argument and comes from the contention error message.
arctic state unlock <lock-id> [flags]| Flag | Description |
|---|---|
--state-dir | Override the .arctic/ state directory location |
--force | Admin override on the cluster tier; bypasses the holder-id check when releasing the cluster lock |
--cluster-only | Skip the local file lock; only release the cluster lock |
--local-only | Skip the cluster lock; only release the local file lock |
arctic state unlock 01HXYZLOCK...Released local lock 01HXYZLOCK...If the lock ID does not match the recorded holder, the command reports a mismatch and exits with a usage error unless --force is supplied on the cluster tier.
mcp
Start a Model Context Protocol (MCP) stdio server so an LLM agent can drive cluster management. The server reads and writes MCP messages over stdio.
Synopsis
arctic mcp [flags]Flags
| Flag | Default | Description |
|---|---|---|
--allow-write | false | Enable write tools (e.g. compose apply). Omit to restrict to read-only tools |
By default only read-only tools are exposed. Pass --allow-write to permit mutating operations.
Global flags
These flags work with any command.
Context and connection
| Flag | Description |
|---|---|
--context, -c | Context to use (peer ID, peer name, cluster ID, or cluster name) |
--url | Override the agent URL for this command |
--token | Use a specific bearer token instead of configured credentials |
--client-id | Override the OAuth client ID (e.g. cli_01HXYZ...) |
--client-secret | Override the OAuth client secret (e.g. sec_...) |
--insecure | Skip TLS certificate validation (testing only) |
arctic peers list --context prod-cluster
arctic peers list --client-id cli_01HXYZ... --client-secret sec_abc123...Output control
| Flag | Description |
|---|---|
--output, -o | Output format: table, json, or yaml |
--json, -j | Shorthand for -o json |
--no-headers | Omit column headers in table output |
--quiet, -q | Suppress non-error output |
Table format is a compact view for list commands. Use -j or -o json for full detail. Errors always go to stderr regardless of output format.
Confirmation and debugging
| Flag | Description |
|---|---|
--yes, -y | Skip confirmation prompts for destructive operations |
--debug, --verbose, -v | Enable debug logging |
--trace | Show full HTTP request and response traces |
--timeout | Request timeout (e.g. 30s, 1m30s) |
--config | Path to the config file (default ~/.config/arctic/config.yaml) |
Environment variables
| Flag | Environment variable |
|---|---|
--config | ARCTIC_CONFIG |
--context | ARCTIC_CONTEXT |
--url | ARCTIC_URL |
--token | ARCTIC_TOKEN |
--client-id | ARCTIC_CLIENT_ID |
--client-secret | ARCTIC_CLIENT_SECRET |
Exit codes
| Code | Name | Description |
|---|---|---|
| 0 | Success | Command completed successfully |
| 1 | General error | Unspecified error |
| 2 | Usage error | Invalid arguments, unknown flags, or a missing required value |
| 3 | Config error | Missing or invalid configuration |
| 4 | Connection error | Agent could not be reached |
| 5 | Auth error | Invalid or expired credentials |
| 6 | Partial failure | Some operations succeeded, others failed |
| 7 | Lock contention | A compose apply lock is held by another process |
| 130 | Interrupted | The operation was cancelled (Ctrl+C) at a prompt |
Exit codes are independent of output format. Error messages are always written to stderr.
arctic health --url http://192.168.1.10:8080
case $? in
0) echo "healthy" ;;
4) echo "unreachable" ;;
5) echo "auth failed" ;;
*) echo "error" ;;
esac