Note: This package is a prototype written by Claude. Review the code before using it in production.
A command-line interface for SURF Research Cloud, built on the SURF Research Cloud API.
surf-cli is managed with uv.
uv tool install surf-cliOr install into a virtual environment for development:
git clone https://github.com/chrisflav-agents/surf-cli
cd surf-cli
uv sync --extra devsurf-cli looks for an API token in the following order:
- Environment variable –
SURF_API_TOKEN - Configuration file –
~/.config/surf-cli/config.toml
export SURF_API_TOKEN="<your-token>"Save the token once with the config set-token command:
surf config set-token "<your-token>"The token is written to ~/.config/surf-cli/config.toml with permissions 0600. Verify the current configuration with:
surf config showsurf [OPTIONS] COMMAND [ARGS]...
Run surf --help to see all available commands.
| Flag | Description |
|---|---|
-V, --version |
Print the version and exit. |
--install-completion |
Install shell completion for the current shell and exit. |
--show-completion |
Show the shell completion script for the current shell and exit. |
--help |
Show help and exit. |
surf-cli supports tab completion for bash, zsh, and fish. To install completion for your current shell:
surf --install-completionTo print the completion script without installing it (useful for custom setups):
surf --show-completionAfter installing, restart your shell or source the updated RC file to activate completions.
Most read commands (list, get, members) accept a -f / --format option that controls how results are printed:
| Value | Description |
|---|---|
json |
Pretty-printed JSON (default). |
table |
Formatted table rendered with Rich. |
# JSON output (default)
surf workspace list
# Table output
surf workspace list --format table
surf catalog list -f tableWrite commands (create, update, delete, action, etc.) always output JSON.
- workspace — manage workspaces
- catalog — browse the catalog
- storage — manage storage volumes
- co — manage collaborative organisations
- wallet — manage wallets
Manage SURF Research Cloud workspaces.
surf workspace [COMMAND]
List workspaces accessible to the authenticated user.
surf workspace list [OPTIONS]| Option | Description |
|---|---|
-t, --application-type TEXT |
Filter by type: Compute, Storage, IP, or Network. |
--by-owner TEXT |
Return only workspaces owned by the authenticated user (true/false). |
--co-id TEXT |
Filter by collaborative organisation ID. |
--deleted TEXT |
Include deleted workspaces (true/false). |
-l, --limit INTEGER |
Maximum number of results to return. |
-n, --name TEXT |
Search by workspace name. |
--offset INTEGER |
Pagination offset. |
-s, --status TEXT |
Filter by status (e.g. running, paused, failed). |
-w, --wallet-id TEXT |
Filter by wallet ID. |
-f, --format TEXT |
Output format: json (default) or table. |
Get details of a specific workspace.
surf workspace get WORKSPACE_ID [OPTIONS]| Option | Description |
|---|---|
-f, --format TEXT |
Output format: json (default) or table. |
Create a new workspace from a JSON payload.
surf workspace create PAYLOAD [OPTIONS]PAYLOAD must be a JSON string matching CreateComputeApplicationSchema (for Compute) or
CreateApplicationSchema (for other types).
| Option | Description |
|---|---|
-t, --application-type TEXT |
Workspace type: Compute (default), Storage, IP, or Network. |
Example:
surf workspace create '{"name": "my-workspace", "co_id": "co-1", "wallet_id": "wallet-1", "catalog_item": "item-1"}'Update a workspace's name or end time.
surf workspace update WORKSPACE_ID [OPTIONS]At least one option is required.
| Option | Description |
|---|---|
-n, --name TEXT |
New workspace name. |
--end-time TEXT |
New end time in ISO 8601 format (e.g. 2024-12-31T23:59:59Z). |
Delete a workspace.
surf workspace delete WORKSPACE_ID [--yes]| Option | Description |
|---|---|
-y, --yes |
Skip the confirmation prompt. |
Perform a single action on a workspace.
surf workspace action WORKSPACE_ID ACTION_TYPE [OPTIONS]Supported action types: pause, resume, reboot, update_nsgs, update_storages.
| Option | Description |
|---|---|
-p, --params TEXT |
JSON body for the action (required for update_nsgs and update_storages). |
Examples:
# Pause a workspace
surf workspace action ws-123 pause
# Attach a storage volume
surf workspace action ws-123 update_storages --params '{"storages": [{"id": "st-456"}]}'
# Update network security group rules
surf workspace action ws-123 update_nsgs --params '{"network_security_group_rules": ["in tcp 22 22 0.0.0.0/0"]}'Perform a sequence of actions on a workspace in one call.
surf workspace actions WORKSPACE_ID PAYLOADPAYLOAD is a JSON array of action objects, each with an action key and an optional parameters key.
Example:
surf workspace actions ws-123 '[{"action": "pause"}, {"action": "resume"}]'Move a workspace to a different wallet.
surf workspace change-wallet WORKSPACE_ID --wallet-id WALLET_ID [OPTIONS]| Option | Description |
|---|---|
-w, --wallet-id TEXT |
(Required) New wallet ID. |
--wallet-name TEXT |
New wallet name (optional). |
Claim ownership of a workspace (workspace admin only).
surf workspace claim-ownership WORKSPACE_IDRetrieve the logs for a workspace.
surf workspace logs WORKSPACE_IDBrowse the SURF Research Cloud catalog (read-only).
surf catalog [COMMAND]
List available catalog items.
surf catalog list [OPTIONS]| Option | Description |
|---|---|
--co-id TEXT |
Filter by collaborative organisation ID. |
-l, --limit INTEGER |
Maximum number of results to return. |
-n, --name TEXT |
Search by catalog item name. |
--offset INTEGER |
Pagination offset. |
-t, --type TEXT |
Filter by type: Compute, Storage, IP, or Network. |
-f, --format TEXT |
Output format: json (default) or table. |
Get details of a specific catalog item.
surf catalog get ITEM_ID [OPTIONS]| Option | Description |
|---|---|
-f, --format TEXT |
Output format: json (default) or table. |
Manage SURF Research Cloud storage volumes.
surf storage [COMMAND]
List storage volumes.
surf storage list [OPTIONS]| Option | Description |
|---|---|
--co-id TEXT |
Filter by collaborative organisation ID. |
-l, --limit INTEGER |
Maximum number of results to return. |
-n, --name TEXT |
Search by storage volume name. |
--offset INTEGER |
Pagination offset. |
-s, --status TEXT |
Filter by status: creating, available, in-use, full, updating, deleting, deleted, failed, or unknown. |
-w, --wallet-id TEXT |
Filter by wallet ID. |
-f, --format TEXT |
Output format: json (default) or table. |
Get details of a specific storage volume.
surf storage get STORAGE_ID [OPTIONS]| Option | Description |
|---|---|
-f, --format TEXT |
Output format: json (default) or table. |
Create a new storage volume from a JSON payload.
surf storage create PAYLOADExample:
surf storage create '{"name": "my-storage", "co_id": "co-1", "wallet_id": "wallet-1"}'Update a storage volume's name or end time.
surf storage update STORAGE_ID [OPTIONS]At least one option is required.
| Option | Description |
|---|---|
-n, --name TEXT |
New storage volume name. |
--end-time TEXT |
New end time in ISO 8601 format (e.g. 2024-12-31T23:59:59Z). |
Examples:
surf storage update st-456 --name "renamed-storage"
surf storage update st-456 --end-time "2025-12-31T23:59:59Z"Delete a storage volume.
surf storage delete STORAGE_ID [--yes]| Option | Description |
|---|---|
-y, --yes |
Skip the confirmation prompt. |
Example:
surf storage delete st-456 --yesManage SURF Research Cloud collaborative organisations (COs) and their members.
surf co [COMMAND]
List collaborative organisations.
surf co list [OPTIONS]| Option | Description |
|---|---|
-l, --limit INTEGER |
Maximum number of results to return. |
-n, --name TEXT |
Search by collaborative organisation name. |
--offset INTEGER |
Pagination offset. |
-f, --format TEXT |
Output format: json (default) or table. |
Get details of a specific collaborative organisation.
surf co get CO_ID [OPTIONS]| Option | Description |
|---|---|
-f, --format TEXT |
Output format: json (default) or table. |
Create a new collaborative organisation from a JSON payload.
surf co create PAYLOADExample:
surf co create '{"name": "my-co", "description": "My collaborative organisation"}'Update a collaborative organisation's name or description.
surf co update CO_ID [OPTIONS]At least one option is required.
| Option | Description |
|---|---|
-n, --name TEXT |
New name. |
-d, --description TEXT |
New description. |
Examples:
surf co update co-1 --name "Renamed CO"
surf co update co-1 --description "Updated description"Delete a collaborative organisation.
surf co delete CO_ID [--yes]| Option | Description |
|---|---|
-y, --yes |
Skip the confirmation prompt. |
Example:
surf co delete co-1 --yesList members of a collaborative organisation.
surf co members CO_ID [OPTIONS]| Option | Description |
|---|---|
-l, --limit INTEGER |
Maximum number of results to return. |
--offset INTEGER |
Pagination offset. |
-f, --format TEXT |
Output format: json (default) or table. |
Example:
surf co members co-1 --format tableAdd a user to a collaborative organisation.
surf co add-member CO_ID --user-id USER_ID [OPTIONS]| Option | Description |
|---|---|
-u, --user-id TEXT |
(Required) User ID to add. |
-r, --role TEXT |
Role to assign: member (default) or admin. |
Examples:
surf co add-member co-1 --user-id user-42
surf co add-member co-1 --user-id user-42 --role adminRemove a user from a collaborative organisation.
surf co remove-member CO_ID USER_ID [--yes]| Option | Description |
|---|---|
-y, --yes |
Skip the confirmation prompt. |
Example:
surf co remove-member co-1 user-42 --yesManage SURF Research Cloud wallets (budget allocations).
surf wallet [COMMAND]
List wallets.
surf wallet list [OPTIONS]| Option | Description |
|---|---|
--co-id TEXT |
Filter by collaborative organisation ID. |
-l, --limit INTEGER |
Maximum number of results to return. |
-n, --name TEXT |
Search by wallet name. |
--offset INTEGER |
Pagination offset. |
-f, --format TEXT |
Output format: json (default) or table. |
Get details of a specific wallet.
surf wallet get WALLET_ID [OPTIONS]| Option | Description |
|---|---|
-f, --format TEXT |
Output format: json (default) or table. |
Create a new wallet from a JSON payload.
surf wallet create PAYLOADExample:
surf wallet create '{"name": "my-wallet", "co_id": "co-1"}'Update a wallet's name or description.
surf wallet update WALLET_ID [OPTIONS]At least one option is required.
| Option | Description |
|---|---|
-n, --name TEXT |
New wallet name. |
-d, --description TEXT |
New wallet description. |
Delete a wallet.
surf wallet delete WALLET_ID [--yes]| Option | Description |
|---|---|
-y, --yes |
Skip the confirmation prompt. |
uv run pytestuv run ruff check src testssrc/surf_cli/
├── __init__.py # package metadata
├── client.py # HTTP client wrapping the SURF API
├── main.py # CLI entry point (typer app)
└── commands/ # one module per API resource group
├── __init__.py
├── workspaces.py # workspace commands
├── catalog.py # catalog commands
├── storage.py # storage commands
├── co.py # collaborative organisation commands
└── wallets.py # wallet commands
tests/
├── conftest.py
├── test_client.py
├── test_main.py
├── test_workspaces.py
├── test_catalog.py
├── test_storage.py
├── test_co.py
└── test_wallets.py
The CI workflow lives at .github/workflows/ci.yml. It runs lint (ruff) and tests
across Python 3.11, 3.12, and 3.13 on every push and pull request to main.
Apache 2.0 — see LICENSE.