Getting started
Install one package and construct a zero-argument client. Configure a URL and token only when selecting an explicit remote relay.
Install
pip install cmdop # or: uv add cmdopnpm install @cmdop/sdk # or: pnpm add @cmdop/sdkPython requires 3.10 or later. Node requires version 18 or later.
First local call
from cmdop import Client
async with Client() as client:
bootstrap = await client.system.bootstrap()
print(bootstrap.version, bootstrap.capabilities)
snapshot = await client.machines.list()
for machine in snapshot.machines:
print(machine.machine_id, machine.display_name, machine.presence)import { Client } from "@cmdop/sdk";
const client = new Client();
try {
const bootstrap = await client.system.bootstrap();
const snapshot = await client.machines.list();
for (const machine of snapshot.machines) {
console.log(machine.machineId, machine.displayName, machine.connected);
}
} finally {
await client.close();
}bootstrap() needs no credentials — it is the one call you can make before a
token is configured, which makes it the right reachability check. It returns the
relay version, its bundle id, the web contract range, the list of
capabilities the relay supports, and update state when one is in progress.
Explicit remote relay
Set both variables for a remote relay:
export CMDOP_BASE_URL="https://relay.example.com"
export CMDOP_TOKEN="<relay-token>"Then use the same zero-argument client. Constructor values are also available when configuration must remain inside the application:
async with Client(base_url="https://relay.example.com", token="...") as client:
snapshot = await client.machines.list()An explicit remote URL without a bearer token fails closed.
Lifecycle
Python clients are async context managers. If you do not use async with, call
await client.aclose(). In Node, call await client.close(); runtimes with
explicit resource management can also use await using.