Docs CLI

Providers, Accounts and the Server

Connecting the CLI to a CaptainCore Manager site, managing hosting providers and accounts, reading configuration, and running the HTTP server the Manager dispatches through.

The CLI keeps its own copy of the fleet in a local SQLite database and its own credentials in config.json. This page covers the commands that populate and read those, plus the HTTP server that lets the CaptainCore Manager plugin drive the CLI remotely.

connect

captaincore connect [--url=] [--username=] [--password=] [--skip-ssl] [--sync]
Flag Description
--url string WordPress site URL
--username string WordPress username
--password string WordPress application password
--skip-ssl Skip SSL certificate verification
--sync Re-sync data using saved credentials, no prompts

Authenticates against a CaptainCore Manager site using an application password over Basic Auth, then fetches the full data set in one response: sites, environments, accounts, providers, domains, the account/site, account/domain and account/user relationships, plus configurations and defaults. All of it is written to the local database, and the returned token, API URL and GUI URL are saved into config.json.

Missing values are prompted for interactively. --sync reuses the saved token and API URL, which is what you want from cron.

captaincore connect --url=https://anchor.host --username=austin
captaincore connect --sync

provider

captaincore provider <subcommand>
Subcommand Usage
list provider list
add provider add <name> <slug> [--credentials=]
update provider update <provider-id> [--credentials=] [--status=]
delete provider delete <provider-id>
sync provider sync [--debug]
remote-sites provider remote-sites <provider-id>
import provider import <provider-id> [--site-ids=] [--account-id=] [--update-extras]

--credentials takes a JSON array, for example [{"name":"api_key","value":"xxx"}]. provider sync pulls provider records down from the CaptainCore Manager. remote-sites queries the provider’s own API and lists what it holds, and import bulk-creates CaptainCore sites from a comma-separated list of remote site IDs. --update-extras runs the post-import batch sync.

Provider API integrations are implemented in the providers/ package, which currently ships Kinsta and GridPane clients.

captaincore provider remote-sites 3

account

captaincore account sync <account> [--debug]
captaincore account delete <account>

Both take an account ID. sync fetches the account from the Manager API and updates the local record.

captaincore account sync 412

account-portal

captaincore account-portal sync <account-portal-id>
captaincore account-portal delete <account-portal-id>

Account portals are the white-label customer portals a reseller runs on their own domain.

captaincore account-portal sync 7

connection

captaincore connection list
captaincore connection add <domain> <domain-token> <captaincore-token>

connection list prints the stored connections as JSON with created_at, domain and token.

captaincore connection list

config

config reads config.json directly. It is what the bash layer uses to load settings, via captaincore config fetch --captain-id=$captain_id.

captaincore config fetch [<section>] [<key>]
captaincore config fetch-captain-ids
captaincore config from-api [--field=<field>]

With no arguments, config fetch prints every setting for the current captain as KEY=VALUE lines. With one argument it prints that whole section as JSON. With two it prints a single value. fetch-captain-ids prints the captain IDs space separated, which is how fleet mode enumerates tenants.

captaincore config fetch
captaincore config fetch remotes rclone_backup
captaincore config fetch-captain-ids

What lives in config.json

config.json is an array. The first entry holds a system block shared by all tenants; each following entry is a tenant keyed by captain_id.

System key Purpose
captaincore_fleet Enables fleet mode path and remote suffixing
captaincore_dev When set and not false, SSL verification is skipped for API calls
captaincore_master, captaincore_master_port Master server SSH connection
path, path_tmp, path_scripts, path_keys, path_recipes, logs Local filesystem paths
rclone_backup, rclone_cli_backup, rclone_snapshot, rclone_upload, rclone_upload_uri Storage remotes
fathom_api_key Fathom Analytics lookups for captaincore stats
local_wp_db_pw Local MariaDB root password
captaincore_standby Standby mode, suppresses API writes from usage-update

Each tenant block carries keys (API access key, token, auth, B2 account and bucket credentials), remotes (rclone_archive, rclone_backup, rclone_logs, rclone_snapshot, b2_snapshots) and vars (branding, captaincore_server, captaincore_tracker, captaincore_gui, captaincore_api, captaincore_admin_email, captaincore_admin_user, websites).

Start from config-sample.json.

configuration

Where config reads the local file, configuration reads the global configuration synced down from the Manager and stored in the database.

captaincore configuration get [--field=<field>] [--bash]
captaincore configuration sync

get prints the whole configuration as JSON, or a single field with --field. sync calls configuration-get on the Manager API and stores the result.

captaincore configuration get --field=default_key

cron

captaincore cron

Reads the stored global configuration and pretty-prints its scheduled_tasks array as JSON. It prints nothing if there is no configuration or no scheduled_tasks key. In the current source it does not execute those tasks. See cron and scheduling.

captaincore cron

task

captaincore task list [--limit=<n>]
captaincore task get <id>

Read-only access to the server’s task table in ~/.captaincore/data/sql.db. list defaults to the ten most recent tasks and prints ID, status, command, created and updated columns. Results are scoped to the current captain ID unless --fleet is passed. get shows the full record including the stored response.

captaincore task list --limit=25

server

captaincore server [--debug]

Starts the HTTP service the CaptainCore Manager plugin dispatches through. It binds :8000 by default; set CAPTAINCORE_SERVER_BIND=127.0.0.1:8000 to pin it to loopback behind a TLS-terminating reverse proxy.

Endpoints

Method Path Purpose
POST /run Execute a command synchronously and return the output
POST /run/stream Execute with a streaming response, used for binary downloads
POST /run/background Execute in the background, non-blocking
POST /tasks Queue a task, returns a tracking token
GET /tasks, /tasks/{page} List tasks
GET /task/{id} Task status and response
GET /task/{id}/stream Stream a running task’s output
PUT /task/{id} Mark a task completed
DELETE /task/{id} Delete a task
GET /progress Progress of running bulk operations
GET /progress/{pid} Detail for one bulk run
DELETE /progress/{pid} Kill a running bulk operation
WS /ws WebSocket for real-time task output
GET / Version page

Authentication

Every endpoint except the index, the logo assets and the WebSocket upgrade goes through a token check. The client sends a token header, which is compared in constant time against the tokens in ~/.captaincore/data/config.json. A mismatch returns 401 - Unauthorized. Each token is tied to a captain ID.

How the Manager calls it

The Manager’s CaptainCore\Run class posts to the configured CLI address with the CLI token:

Run::CLI( "backup generate mysite-production" );          // synchronous
Run::CLI( "site sync mysite", $background = true );        // background
Run::CLI_Stream( "backup download mysite-production" );    // streaming binary
Run::task( "update @all" );                                // queued, returns a token

The server parses the incoming command, writes any large payload blob to ~/.captaincore/data/payload/<token>.txt and replaces it on the command line with --payload=<token>, then executes captaincore <command> as a subprocess. Output is captured, streamed over the WebSocket to any connected client, stored in SQLite, and returned. The payload file is deleted once consumed so secrets do not linger on disk. A task can carry an origin callback, which is invoked best-effort when the task finishes.

Read and write timeouts are deliberately unset on the HTTP server, because they would also apply to hijacked WebSocket connections and the long-lived streaming endpoints. ReadHeaderTimeout and IdleTimeout are set instead.

captaincore server --debug

version and completion

captaincore version
captaincore completion bash|zsh|fish|powershell [--no-descriptions]

version prints the CLI version, the Go version it was built with, and the platform.

source <(captaincore completion zsh)