Skip to content

CLI commands

Every skyportalai subcommand runs once and exits, so you can use them in scripts and CI/CD. Run skyportalai with no subcommand to open the interactive terminal instead.

Syntax

skyportalai [--json] [--base-url URL] [--version] COMMAND [ARGS]...
Option Behavior
--json Print a stable JSON envelope instead of human-readable output
--base-url URL Use this API target for this run. Also read from SKYPORTALAI_BASE_URL
--version Print the installed version and exit
--install-completion Install shell completion
--help Show help for any command

Tip

Global options go before the subcommand. skyportalai --json config show works; skyportalai config show --json fails with "No such option".

Command What it does
login, logout Sign in through the browser or with a pasted key, or delete the saved credential
config show, config set Show or save connection settings
chat ... Create chats, follow them, approve or reject actions, cancel
kubernetes ... Connect, list and remove Kubernetes clusters
ansible ... Store Ansible playbooks and deploy them through SARA
github-token ... Manage the GitHub token SARA uses for git clone
ask Send one message and print the reply
servers List the servers in your account
start Open the interactive terminal (same as skyportalai alone)

Connection settings

Show the effective settings

skyportalai config show
skyportalai --json config show

Shows the API target, the timeout, whether you are authenticated, where the credential came from, the config file path and any credential conflict. It never prints the credential itself.

Save settings

skyportalai config set --base-url https://app.skyportal.ai
skyportalai config set --timeout 30
  • Give at least one option. With none, the command exits with code 2.
  • --timeout is in seconds and must be greater than zero. Use a whole number if you also use the interactive terminal.
  • The settings go to ~/.skyportalai/config.yaml. No credential is ever written there.

skyportalai configure --portal-url URL --request-timeout N saves the same two settings.

Chats

Start a chat

skyportalai chat send \
  "Report disk usage and identify the largest directory" \
  --server 42 \
  --wait
skyportalai chat send MESSAGE
  [--server ID]...              # repeat for several hosts
  [--active-server ID]          # default host for commands, defaults to the first --server
  [--active-host ID]            # host for the terminal and Jupyter, defaults to the active server
  [--namespace SERVER_ID=NAME]...   # Kubernetes namespace scope, or SERVER_ID=__all__
  [--chat-id ID]                # follow-up to an existing chat
  [--wait]
  [--timeout SECONDS]
  [--poll-interval SECONDS]     # default 1.0
  • --server, --active-server, --active-host and --namespace only apply when you create a chat. Combined with --chat-id, they exit with code 2. To change the scope of an existing chat, use chat select-servers.
  • For a Kubernetes cluster, pick the namespaces SARA may use with --namespace, for example --namespace 12=ml-serving, or --namespace 12=__all__ for the whole cluster.
  • --wait polls until the turn settles or an action needs approval.
  • --timeout is optional. Without it, --wait keeps waiting until the chat settles.

Continue a chat

skyportalai chat send \
  "Now inspect the previous job logs" \
  --chat-id 123 \
  --wait

Change which hosts a chat can use

skyportalai chat select-servers 123 --server 42 --server 43 --active-server 42
skyportalai chat select-servers 123 --clear-scope

select-servers replaces the whole scope. It also takes --active-host, --namespace SERVER_ID=NAME and --clear-namespaces. It refuses to run (exit code 2) while the chat is busy or waiting for an approval.

Status, messages and waiting

skyportalai chat status 123
skyportalai chat messages 123
skyportalai chat messages 123 --after-sequence 40 --limit 100
skyportalai chat wait 123 --timeout 300
  • messages --after-sequence returns only newer messages (default 0). --limit is 1 to 500 (default 100).
  • chat wait takes the same --timeout and --poll-interval options as chat send --wait.

Approve or reject an action

Check the status first, then approve the exact action you reviewed:

skyportalai --json chat status 123

skyportalai chat approve \
  123 APPROVAL_ID \
  --type bash_command \
  --command "EXACT REVIEWED COMMAND"
skyportalai chat reject \
  123 APPROVAL_ID \
  --type bash_command \
  --reason "Outside the approved scope"

--type defaults to bash_command. Use plan when the pending approval is a plan.

Auto-approve applies here too

If your account's approval mode is Auto-approve, chat send --wait and chat wait approve pending commands and plans for you instead of stopping. See Approvals and safety.

Cancel a running workflow

skyportalai chat cancel 123
skyportalai chat cancel 123 --reason "No longer required"

The server returns a conflict if the chat is already idle.

Kubernetes clusters

skyportalai kubernetes connect my-cluster --kubeconfig ~/.kube/config --environment Staging
skyportalai kubernetes list
skyportalai kubernetes disconnect 12
  • --kubeconfig defaults to ~/.kube/config. Pass - to read it from standard input. The file can be up to 1 MiB.
  • --environment sets the environment label (Production, Staging, Dev or Custom, the default). The label decides which commands SARA may run; see Approvals and policies.
  • SkyPortal validates and encrypts the kubeconfig. Some kubeconfigs are refused; see Kubernetes.
  • disconnect asks for confirmation. Pass --yes to skip it.

Ansible playbooks

skyportalai ansible create nightly-cleanup --file cleanup.yml --description "Remove old checkpoints"
skyportalai ansible list
skyportalai ansible show 7
skyportalai ansible update 7 --file cleanup.yml
skyportalai ansible deploy 7 --server 42
skyportalai ansible delete 7 --yes

Playbooks can be up to 256 KiB. --file - reads the YAML from standard input. deploy starts a deployment through SARA on one of your SSH hosts.

GitHub token

skyportalai github-token status
skyportalai github-token set --repo OWNER/NAME
skyportalai github-token remove

set asks for the token without echoing it. With --repo, it checks the token against that repository. status never shows the token.

One-off questions

skyportalai ask "List my hosts"
skyportalai ask --server 42 "Show disk usage"
skyportalai servers

ask sends one message and prints the reply. Without a message, it asks for one. If SARA stops to wait for an approval, ask prints the chat number and exits. Open the interactive terminal and use /resume to answer it.

JSON mode

Put --json before the subcommand:

skyportalai --json chat send \
  "Check API connectivity" \
  --server 42 \
  --wait

Success goes to standard output:

{
  "ok": true,
  "api_target": "https://app.skyportal.ai",
  "data": {}
}

Expected failures go to standard error:

{
  "ok": false,
  "api_target": "https://app.skyportal.ai",
  "error": "Error message"
}
  • --json applies to the config, chat, ansible and kubernetes commands. login, logout, ask, servers, start, configure and github-token always print text.
  • Usage errors, such as a missing argument, are printed as text.
  • If the configuration itself can't be resolved, api_target is "unresolved".
  • ansible delete and kubernetes disconnect need --yes in JSON mode, because there is no prompt.

Exit codes

Code Meaning
0 Success
1 Configuration, authentication, connection, API or workflow error, or a declined confirmation
2 Waiting for approval, or a usage error: missing or conflicting options, invalid values, an unreadable file

Info

Exit code 2 with "status": "awaiting_approval" is an expected stop for a human decision, not an API failure.

Good practice

  • Use placeholders in scripts and docs.
  • Prefer --json in automation, so parsing doesn't depend on human-readable output.
  • Review an action before you approve it, and don't approve destructive actions you haven't read.
  • Never log real credentials or private infrastructure identifiers.