@topolo/cli
v0.1.30
Published
Command-line interface for Topolo developers, operators, and agents, with internal first-party scaffolding available under the topolo platform namespace.
Downloads
1,548
Readme
TopoloCli
Command-line interface for the Topolo platform. Designed for both humans and
third-party agents (Claude Code, Codex, Cursor, etc.) that prefer to interact
via stdin/stdout.
Current scope
- API-key authentication (long-lived, service-scoped).
- Access-token authentication via OAuth device flow when a CLI OAuth client id is configured.
- Stored access-token refresh when the config includes a refresh token and OAuth client id.
- First-class
productionandstagingCLI environments with separate stored credentials, OAuth client ids, and service URL overrides. - Commands:
auth login/logout/status,whoami,apps,apps scaffold,oauth clients,integrations prompt/check,services, credential-scopedactions, and genericapipassthrough for SDK-registered services.
Install
npm install -g @topolo/cli
# or run ad-hoc:
npx @topolo/cli whoamiConfigure
Credentials come from (in priority order):
- Environment-specific vars such as
TOPOLO_STAGING_API_KEYorTOPOLO_PRODUCTION_ACCESS_TOKEN - Global vars
TOPOLO_API_KEYorTOPOLO_ACCESS_TOKEN - The selected environment profile in the config file (
$XDG_CONFIG_HOME/topolo/config.json, mode0600)
Production is the default. Select staging with --env staging anywhere in the command, or set TOPOLO_ENV=staging:
topolo auth status --env staging --json
topolo auth login --env staging --client-id doac_...
topolo platform apps scaffold home --env staging --write --jsonThe staging profile uses auth.stg.topolo.us, developers.stg.topolo.us, and seed.stg.topolo.us by default. Other SDK service calls in staging must have an explicit staging URL override; the CLI refuses to call a production SDK URL while --env staging is selected.
For interactive use:
topolo auth login --client-id doac_... # device flow
topolo auth login --api-key topo_live_... # store API key directly
topolo auth status # shows which source is active
topolo auth logout # clears the stored credentialIf no client id is configured, topolo auth login falls back to an API-key
prompt in an interactive terminal. Non-interactive sessions should pass
--api-key or set TOPOLO_PRODUCTION_CLI_CLIENT_ID,
TOPOLO_STAGING_CLI_CLIENT_ID, or the shared TOPOLO_CLI_CLIENT_ID.
Cross-org isolation
The CLI never accepts an orgId argument. Every command is scoped to the
organization embedded in the credential. This is enforced in two places:
- The SDK does not expose any
orgIdparameter on any public method. - Each Topolo backend app re-derives
orgIdfrom the credential on every request and binds it to SQL query filters.
There is no code path in the CLI that could ever let you read or mutate another organization's data.
Audit headers
Every outbound request carries:
X-Topolo-Client: topolo-cli/<version>X-Topolo-Agent: <label>(ifTOPOLO_AGENT_NAMEis set)X-Topolo-Request-Id: <uuid>
The platform logs these for traceability.
Write-action gating
The SDK defaults to requiring an explicit --confirm flag on any mutating
request. Dynamic action calls and the generic topolo api passthrough enforce
this too:
topolo actions call topolo_mail_messages_send --data '{"mailboxId":"primary","subject":"Hello"}' --confirm
topolo api mail POST /api/mail/mailboxes/primary/messages --data '{"subject":"Hello"}' --confirmCommands
topolo whoami
Prints the user, organization, and granted scopes.
topolo whoami # pretty
topolo whoami --json # machine-readabletopolo services
Lists the services the current credential can use in its organization, with the
effective URL and granted permissions. This command requires a credential and
does not expose the global platform catalog. In staging, environmentSafe:
false means that service still resolves to a production URL and will be
refused by topolo api until a staging URL override is configured.
topolo services --json
topolo services --env staging --jsontopolo api accepts the IDs/slugs returned by this credential-scoped live
catalog. New services become usable without a CLI release once Auth grants the
organization and credential the relevant permissions.
topolo actions
Lists the callable actions available to the current credential. Applications publish actions through Topolo Developers, Auth filters them by the same service permissions already used by API keys, launchers, and backend services, and the CLI calls them through the shared SDK.
topolo actions --json
topolo actions --service mail --json
topolo actions get topolo_mail_messages_send --json
topolo actions call topolo_mail_messages_send \
--data '{"mailboxId":"primary","subject":"Hello","text":"..."}' \
--confirm --jsonUse topolo actions before topolo api when an app has published a machine
contract for the operation. topolo api remains the escape hatch for endpoints
that are not yet in the action catalog.
topolo apps
Lists launchable Topolo applications available to the current credential. This
uses the same live Auth catalog as topolo services; it is not the global
generated application list.
topolo apps --json
topolo apps get mail --json
topolo apps requirements mail --json
topolo apps audit mail --json
topolo apps audit mail --local --repo-root /Users/ashes/Projects/topolo --fail-on needs_review --json
topolo apps scaffold insights --json
topolo apps scaffold insights --write --repo-root /Users/ashes/Projects/topolo --json
topolo apps scaffold score --target developer --write --repo-root ./starters --json
topolo apps scaffold insights --workflow-only --no-jsonAgents should call topolo apps requirements <app> --json before creating or
expanding a Topolo app. The output is the versioned platform contract for app
metadata, canonical docs, shared auth, shared shell, service registration,
deployment metadata, agent surfaces, observability, and verification.
topolo apps audit --json turns the same contract into per-app scores and a
catalog-backed migration queue. Add --local --repo-root <topolo-checkout> to
include filesystem evidence from the app repo, CloudControl metadata, and
TopoloDocs. Add --fail-on needs_review for the default new-work gate, or
--fail-on partial for strict release readiness.
topolo apps scaffold <app> generates the required new-application scaffold,
including package/auth/shell/docs/CloudControl files, a deploy-ready
Wrangler Worker/static-assets baseline, an Auth service manifest, and a
topolo-conformance.yml GitHub Actions workflow for first-party platform
apps. Add --write --repo-root <topolo-checkout> to create the files on disk;
existing files are refused unless --force is passed. The generated workflow
checks out the app under PlatformApplications/<AppDir>, checks out
Topolo-io/TopoloDocs, Topolo-io/topolo-sdk, and Topolo-io/TopoloCli, builds the
current CLI from source, then runs the local conformance audit with
--fail-on needs_review.
For third-party developers, use --target developer or --developer. Developer
scaffolds are standalone starter projects with topolo.app.json, .env.example,
an @topolo/login authorization-code + PKCE browser starter, and no internal TopoloDocs,
CloudControl, or private first-party package dependencies. Developer scaffolds
are browser-only by default; add --with-api to include a protected Worker
baseline that validates bearer tokens through Topolo Auth over HTTP.
topolo oauth clients
Manage OAuth clients for Login with Topolo.
topolo oauth clients list --json
topolo oauth clients create \
--name "Acme App" \
--developer-id dev_... \
--redirect-uri https://acme.example.com/auth/topolo/callback \
--scope openid profile email organization:read entitlements:read \
--json
topolo oauth clients rotate-secret oac_... --json
topolo oauth clients revoke oac_... --jsonClient revoke disables the developer OAuth client for everyone. User disconnect
is separate and uses DELETE /api/developer-oauth/connected-apps/:clientId.
topolo integrations
Generate and validate agent handoffs for third-party integrations.
topolo integrations prompt login-with-topolo --framework auto
topolo integrations check login-with-topolo --repo-root . --jsonThe Login with Topolo check looks for @topolo/login, callback handling,
required env vars, account-linking fields, and refresh handling.
topolo api <service> <method> <path>
Escape hatch for endpoints without typed modules yet.
topolo api auth GET /api/me
topolo api mail POST /api/mail/mailboxes/primary/messages --data '{"subject":"Hello"}' --confirmUse topolo services --json to discover service ids permitted for the current
credential before calling a service that does not have a typed command yet.
Output modes
- Pretty when stdout is a TTY.
- JSON when piped or redirected.
- Force either with
--json/--no-json.
Exit codes
| Code | Meaning | | ---- | ----------------------- | | 0 | Success | | 1 | Generic error | | 2 | Auth error | | 3 | Permission denied |
Development
cd TopoloCli
npm install
npm run build
node dist/index.js whoamiAgent skills
Installable guides for agents that drive the CLI on behalf of a user.
- Claude Code — copy
skills/topolo/into~/.claude/skills/(per-user) or<your-project>/.claude/skills/(per-project). Claude picks it up automatically when the description matches the user's request. - Codex / Cursor / generic — drop
skills/codex/AGENTS.mdat the root of your repo (or alongside the code your agent works in). Codex readsAGENTS.mdfiles by convention.
Both docs cover the same CLI surface: credential handling, the JSON invocation
contract, the write-safety --confirm guardrail, and the cross-org isolation
rules. Keep them in sync when adding new commands.
For agents that support MCP, also register @topolo/mcp; the skill/AGENTS
guidance still matters because it tells the agent when to prefer MCP tools,
when to fall back to shell commands, and how to handle writes.
Debug output
Set TOPOLO_DEBUG=1 to trace every SDK request to stderr (stdout stays clean
so --json piping still works):
TOPOLO_DEBUG=1 topolo whoami
# [topolo] → GET auth /api/auth/me (req=8f3...)
# [topolo] ← 200 GET auth /api/auth/me (142ms, req=8f3...)Request IDs match the X-Topolo-Request-Id header, so you can correlate a
failing CLI call with the backend access log. Accepted truthy values:
anything except 0 or false.
Token auto-refresh
If the stored access token is within 60 s of expiry, the CLI transparently
exchanges the stored refresh token for a new pair before making the request
and rewrites the config — no user action required. The OAuth client_id used
at login is persisted alongside the credential so refresh can re-authenticate.
If refresh fails (network, rotated/revoked refresh token), the CLI proceeds
with the stale credential and the request returns auth_error — run
topolo auth login to re-authenticate. The stored config is not cleared on
transient refresh failures.
