Skip to content

Turbo Server CLI (ts)

Use ts to administer a Turbo Server from a terminal or a script. It works the same against the server on the machine you are sitting at and a server across the network, and it covers the day-to-day administration you would otherwise do in the Administration site.

What You'll Learn

  • How to point ts at a server and sign in
  • Which commands cover which part of administration
  • How to get machine-readable output for scripts
  • What the exit codes mean

Installing

ts ships with Turbo Server. On a server it is installed to the Bin directory under the install root — ts.cmd on Windows, ts elsewhere. That directory keeps its name across upgrades, unlike the versioned directory holding the binary itself, so it is the path to put on your PATH or in a script. Adding it to PATH is a manual step; the installer does not modify PATH for you.

Name collision

On Linux, moreutils provides an unrelated ts (a timestamp filter). If you use both, alias one of them on your PATH.

Pointing at a Server

Set the server once and every later command uses it:

bash
ts config --server=https://turbo.example.net

Override it for a single command with the global --server flag, or for a whole script with the TSSERVER environment variable. Precedence is flag, then environment variable, then the stored default.

bash
ts --server=https://staging.example.net workspaces

Administering the Local Machine

On the server itself, --local administers the install over loopback with no sign-in at all:

bash
ts --local status

Authorization here is file permissions rather than an account: ts reads a service credential that only root or an Administrator can read, and exchanges it for a short-lived token. Run it elevated, or it will tell you it cannot read the credential.

This is the way to administer a server whose sign-in you have broken — a bad authentication setting, an identity provider that is down. It is also the only way to reach a few commands that require a service token rather than a user ticket; those pages say so.

Signing In

bash
# Interactive: prompts for the password, which is never echoed or logged
ts login alice

# Through your identity provider — opens a browser to approve a code
ts login --auth=sso

# On a machine with no browser
ts login --device-code

# Unattended, for scripts and CI
ts login --api-key=<key>

Tickets are stored per server, so several servers can stay signed in at once. ts logout discards the local ticket; ts logout --revoke additionally invalidates every ticket for that account on the server.

For unattended use, TSTICKET or TSAPIKEY supply a credential without a stored login.

Administration commands require an account in the Server Administrators group.

Output

Every command prints a readable table or summary by default, and structured JSON on request:

bash
ts workspaces                  # table
ts workspaces --csv            # tab-separated, nothing truncated
ts workspaces --no-trunc       # full-width columns
ts workspaces --format=json    # one JSON result envelope

The JSON envelope is stable and safe to parse:

json
[{
  "name": "workspaces",
  "arguments": ["workspaces", "--format", "json"],
  "result": { "exitCode": 0, "workspaces": [ { "id": "acme", "name": "Acme" } ] },
  "messages": ["..."]
}]

--format=json-stream emits one JSON event per line instead, for long-running commands.

Global Options

FlagDescriptionDefault/ValuesNotes
--serverTarget server for this invocation.URL, or the host of a stored loginOverrides the stored default and TSSERVER.
--localAdminister the install on this machine over loopback, with no sign-in.Requires an account that can read the service credential — root or an Administrator. Mutually exclusive with --server.
--formatOutput format.Default table; json, json-streamAnything else is an error.
--wait-after-exitWait for a key press before exiting.For double-click launches on Windows.
--wait-after-errorWait for a key press only on failure.

Commands

Run ts help for the list, or ts help <command> for one command's usage and options.

A page covering a plural list command and its singular counterpart is listed once, under the singular name.

Session

login · logout · config · status · version · help

Identity

user · group · api-key · api-keys · device-key · directory-service · auth-provider

Workspaces

workspace · app · channel · link · notification

Policy

policy — show, replace, or fetch the schema for the launch policy.

Infrastructure

server · site · proxy · routing-rule · fleet · session · runner

Storage and Sharing

storage-provider · storage-scope · share

Hub

repo — list, inspect, and remove repositories on this server's hub.

import — copy repositories from an upstream server and watch the runs.

AI

The AI commands sit under an ai namespace, because tool, endpoint, agent, and skill are generic nouns on their own — a bare ts ai lists what is there.

ai endpoint · ai tool · ai connector · ai agent · ai skill · ai transcript · ai usage

System

settings · audit · license · usage · report · signing-key

Command Shape

Commands follow the same two patterns throughout.

Plural lists, singular acts. ts workspaces lists them; ts workspace acme shows one. On a singular command the first word is an action when it names one, and the target otherwise, so ts workspace acme and ts workspace delete acme both read naturally. print is the default action.

Some resources are edited as JSON. Sites, proxies, routing rules, apps, channels, links, storage providers and scopes carry more configuration than a flag list can express, so they are read and written as documents:

bash
ts site 8f14e45f-ceea-467a-9a1f-6b3f0c1e77aa > site.json
# edit site.json
ts site set 8f14e45f-ceea-467a-9a1f-6b3f0c1e77aa --file=site.json

For a single field, reach for the accessor instead of a round trip through a file — every command supports it, whether or not it also has a document form:

bash
ts site 8f14e45f-ceea-467a-9a1f-6b3f0c1e77aa display-name    # read one field
ts site set 8f14e45f-ceea-467a-9a1f-6b3f0c1e77aa display-name "HQ"

Property names are kebab-case, and the value is typed from the field it replaces, so a number stays a number. A structured field — an object or an array — has no accessor form and is refused with a pointer at --file.

Do not add --format=json to the read half

--format=json wraps output in the result envelope, so the file you capture is an envelope rather than the document set expects. Redirect the default output, as above. The round trip also works only for set; creating a resource with new needs a document you write yourself, not one produced by print.

Destructive commands ask for confirmation. Pass --force (or -f) to skip the prompt; when there is no terminal, --force is required rather than assumed.

Exit Codes

CodeMeaning
0Success
-1The command failed
-2The arguments could not be parsed
-3The server could not be reached
-4Not signed in, or the ticket expired
-5Signed in, but not permitted
-6The named resource does not exist
9009No such command

Exit codes on Linux and macOS

The shell reports an exit code as an unsigned byte, so -4 appears as 252 in $?. Scripts that need the exact value should read result.exitCode from --format=json.