pelican is a typed, agent-friendly command-line client for the Pelican Panel client and application APIs. It has explicit commands for the supported API baseline; it does not provide a generic HTTP request escape hatch.
The project uses the Rust toolchain selected by rust-toolchain.toml.
cargo install --path .For a local release build instead:
cargo build --release
./target/release/pelican versionRun pelican --help to discover domains and append --help at any level, such as pelican servers admin --help. Generate shell completions without a configured profile:
pelican completion bash > pelican.bash
pelican completion zsh > _pelican
pelican completion fish > pelican.fishpowershell and elvish are also supported completion targets.
Pelican's OAuth redirect and callback routes are web-social-login routes. They are not an OAuth authorization server and do not expose authorization-code or device-code credentials to CLI clients. This CLI therefore uses static Laravel Sanctum API keys:
pacc_...account tokens authenticate client API commands such asaccount,servers, andfiles.papp_...application tokens authenticate administrative commands such asusers,nodes,eggs, andservers admin.
The preferred setup reads the token from standard input so it does not enter shell history or a command-line process listing:
printf '%s\n' "$PELICAN_ACCOUNT_TOKEN" |
pelican --profile production auth set \
--url https://panel.example.com \
--type account \
--token-stdin
printf '%s\n' "$PELICAN_APPLICATION_TOKEN" |
pelican --profile production auth set \
--url https://panel.example.com \
--type application \
--token-stdinThe second command preserves the first token in the same profile. Inspect non-secret profile state with pelican --profile production auth status. HTTPS is required unless --allow-http is explicitly supplied; --insecure-tls explicitly disables certificate verification and should be reserved for controlled environments.
Profile selection is, from highest to lowest precedence:
--profile NAMEPELICAN_PROFILEdefault
Configuration uses the platform-native directory by default. Set PELICAN_CONFIG_DIR to an absolute path only when an isolated configuration directory is required, such as in CI; credential permission checks still apply there.
The complete pair PELICAN_URL plus PELICAN_TOKEN is a standalone ephemeral configuration. It bypasses profile selection and every stored profile field, uses the default 30-second timeout and secure TLS unless a CLI override is supplied, and does not persist either value. With only one environment value, a usable selected profile is still required; that value overlays the corresponding stored field while the other URL, credentials, timeout, and TLS settings remain profile-backed. Supplying only one value without a usable profile fails with exit code 3. The pacc_ or papp_ prefix determines the environment token's type; because one PELICAN_TOKEN represents one credential, commands requiring the other type also fail with exit code 3.
For ephemeral automation:
export PELICAN_URL=https://panel.example.com
export PELICAN_TOKEN="$TOKEN_FROM_SECRET_STORE"
pelican account getDo not log or print these environment values.
JSON is the default. A successful structured response is emitted to standard output as:
{"ok":true,"data":{},"meta":{}}Use the client API with a pacc_ token:
pelican --profile production servers list --per-page 25
pelican --profile production account getUse the application API with a papp_ token:
pelican --profile production users list --filter-email ops@example.com
pelican --profile production users get --user 42The accepted --output values are:
json: the stable success envelope; this is the default and the safest general automation format.jsonl: one unwrapped JSON resource per line for list operations that support it, includingfiles list. Password includes are intentionally excluded because JSONL has no sensitivity metadata.raw: raw bytes for streaming commands that support them, including file content and downloads. For file and backup downloads, raw always means standard output and cannot be combined with--destination.table: a human-readable table without the JSON success envelope. Arrays use stable columns and row order, objects use key/value rows, and nested values use compact JSON. Agents must not parse this presentation format.
Diagnostics and structured errors go to standard error. Keep standard output separate when parsing command results.
File and backup downloads have exactly two execution modes: pass --destination PATH for an atomic file commit, or pass --output raw with no destination to stream exact bytes to standard output. --output raw --destination PATH and a non-dry-run download with neither mode fail locally with exit code 2 before the Panel is contacted. A dry-run may omit both because it emits only the redacted Panel request plan.
Every command exposing --include-password requires --output json. Successful password-bearing responses retain the stable JSON envelope and set meta.sensitive=true; JSONL, table, and raw modes are rejected locally before transport so the sensitivity marker cannot be lost. Never write these responses to logs or standard error.
Read and validate a target immediately before changing it. Remote mutations accept --dry-run and emit a redacted request plan without sending a request. Destructive commands require --yes unless they are dry runs:
pelican users get --user 42
pelican users delete --user 42 --dry-run
pelican users delete --user 42 --yesOnly add --yes after confirming the identifier and relevant target fields. Use --from-json - when a typed command exposes it and a body is complex or sensitive; currently servers admin create and servers admin update-build support JSON from a file or standard input.
Read retries are opt-in with --retry-reads 0..5. The CLI retries only safe GET/HEAD requests, never mutations. Do not blindly replay a mutation after a network or timeout error because the panel may already have applied it.
Many resource list commands expose --page (default 1), --per-page (default 50), and --all; use only the flags shown by that command's --help. Some API collections are unpaginated and apply local paging where those flags are exposed. files list is an unpaginated directory listing with JSON or JSONL output and intentionally has no page flags. Use --all deliberately and prefer --output jsonl for large collections when supported.
See Agent usage for stable errors, exit codes, and copyable automation workflows.