The FadeHost CLI

fadehost is the FadeHost command line. It lists, creates, deploys, restarts and tails the apps and bots on your account without opening the panel, and it can connect an AI assistant to the same account in one command.

It talks to the same API the panel does, with a token of your own, so it can do exactly what you can do in the panel and nothing more.

Install

Run it once, installing nothing:

npx fadehost apps list

Or keep it on your PATH:

npm install -g fadehost

Node 20 or newer. The package is fadehost on npm. The examples below write npx fadehost; drop the npx once it is installed globally.

Sign in

npx fadehost login

The command prints a short code and opens https://laplace.fadehost.com/cli/connect?code=... in your browser. Add --no-browser and it prints the link instead of opening it.

The page shows the code, the machine the code came from, the program that asked and its operating system, so you can check it is the terminal you just used. Under What it may do you pick the scope:

  • Read and manage does everything you can do yourself: deploy, start, stop, restart, variables, hostnames, creating and deleting apps.
  • Read only can list, read status, read logs and read variable names. It changes nothing.

Press Approve and the terminal has its token within a few seconds. Deny makes no token at all. A code is good for fifteen minutes, so run login again if one has been sitting there.

Where the token lives, and how to revoke it

The token is an AI access token, the same kind an assistant uses. On your machine it goes into ~/.config/fadehost/config.json, written so only your user can read it.

In the panel it is listed under Profile, AI access as CLI on <machine>, with its scope, when it was made and when it was last used. Revoke on that row signs that machine out at once. An account can hold ten of these tokens, assistants included.

If you already have a token, skip the code:

npx fadehost login --token YOUR_TOKEN

Who this machine is, and signing out

npx fadehost whoami
npx fadehost logout

whoami prints the account, the API it talks to, and the token’s scope when that is known. logout forgets the token on this machine; the token itself keeps working until you revoke it in the panel.

Your apps

An app is named by its bot_... id or by the name you gave it, so npx fadehost apps logs status-bot and npx fadehost apps logs bot_a1b2c3 mean the same app.

CommandWhat it does
fadehost apps listEvery app and bot on the account.
fadehost apps status status-botWhat one app is doing right now.
fadehost apps create --repo https://github.com/you/your-botDeploy a new app or bot from a Git repository.
fadehost apps deploy status-botPull the latest commit and start the app again.
fadehost apps start status-botStart the app.
fadehost apps stop status-botStop the app.
fadehost apps restart status-botRelaunch the build that is already on the node.
fadehost apps logs status-bot --tail 200The last lines of the app console.
fadehost apps logs status-bot --followKeep printing new lines until Ctrl-C.
fadehost apps env status-bot getThe variable names, values masked.
fadehost apps env status-bot set LOG_LEVEL=debugAdd or change variables.
fadehost apps env status-bot unset OLD_API_KEYRemove a variable.
fadehost apps domains dashboardThe custom hostnames on the app’s address.
fadehost apps open dashboardOpen the app’s address in the browser.
fadehost apps delete old-botDelete the app and its data, after a question.

Use deploy for new code. restart relaunches the build that is on the node already, so a push you have not deployed stays where it is.

Create an app

create takes the fields the panel’s create dialog takes:

npx fadehost apps create --repo https://github.com/you/your-bot --tier starter --region Europe
FlagWhat it sets
--repo <url>The repository, for example https://github.com/owner/repo.
--name <name>A name for the app. The repository name by default.
--branch <branch>The branch to deploy. The repository’s default branch by default.
--tier <tier>One of free, starter, standard, pro.
--region <id|name>Where it runs. Required for a paid app; a free app is placed for you. Part of the name is enough, as in Europe or Singapore.
--runtime <runtime>One of node, python, bun, deno, go, java, php, ruby, static. Detected from the repository by default.
--kind <kind>One of discord, telegram, whatsapp, web, static, worker, app. discord by default.
--env KEY=VALUEAn environment variable. Repeat the flag for more.
--start-command <command>Override the start command.
--build-command <command>A build step to run after the install.
--git-token <token>A token for a private repository.
--web-address <name>A public address, for example my-app for my-app.fadehost.app.
--port <port>The port the web address points at. 8080 by default.

A Discord bot needs its token, so pass it in:

npx fadehost apps create --repo https://github.com/you/your-bot --env DISCORD_TOKEN=...

A web app can take its address in the same command:

npx fadehost apps create --repo https://github.com/you/dashboard --kind web \
  --web-address my-dashboard --port 3000

That answers at https://my-dashboard.fadehost.app once the app listens on the PORT variable. If the name is taken the app is still created, and the CLI says only the address was refused.

Environment variables

npx fadehost apps env status-bot get
npx fadehost apps env status-bot get --show
npx fadehost apps env status-bot set LOG_LEVEL=debug TZ=Europe/Zurich
npx fadehost apps env status-bot unset OLD_API_KEY

get masks the values and --show prints them in full. Saving variables recreates the container, so the app restarts.

Custom hostnames

npx fadehost apps domains dashboard
npx fadehost apps domains dashboard add app.example.com
npx fadehost apps domains dashboard remove app.example.com

The address itself, and what a hostname needs in DNS, is under Web address.

Deleting an app

npx fadehost apps delete old-bot
npx fadehost apps delete old-bot --yes

delete asks before it does anything. --yes skips the question, for a script that has nobody to answer it.

Output for scripts

Every command takes --json and prints the API’s data unformatted, so jq can read it:

npx fadehost apps list --json | jq -r '.bots[].name'

Progress lines, such as the login code and the wait, go to standard error under --json, so standard output holds the data and nothing else.

--json on env get prints the values too, so keep it out of shared terminals and CI logs.

FADEHOST_TOKEN and FADEHOST_API

VariableWhat it does
FADEHOST_TOKENThe token to use. The CLI needs no config file when this is set.
FADEHOST_APIThe API host to talk to. https://api.fadehost.com by default.

Both override the saved config. --api <url> overrides them in turn.

In CI

Mint a token in the panel under Profile, AI access, put it in your CI secrets as FADEHOST_TOKEN, and the CLI needs no login step:

# GitHub Actions: deploy after the tests pass
- name: Deploy to FadeHost
  env:
    FADEHOST_TOKEN: ${{ secrets.FADEHOST_TOKEN }}
  run: npx fadehost apps deploy status-bot

Most apps need none of this: every push to the tracked branch deploys on its own. Reach for CI when you want the deploy to wait for your tests, or to go out in a particular order.

A read-only token is enough for a job that only reads, for example a status check that calls apps list --json. Give a deploy job a manage token, and revoke it in the panel when the project ends.

Connect an AI assistant

npx fadehost mcp install --client claude-code
npx fadehost mcp install --client cursor
npx fadehost mcp install --client claude-desktop

This prints a code, opens the same approval page, and waits while you approve it. You pick what the assistant may do there, read only or read and manage, exactly as for the CLI itself. The approved token is written into the client’s config, or printed for you to paste.

The assistant gets its own token, so this needs no fadehost login and does not touch the token the CLI uses. Without --client the command asks which one. What an assistant can then do, tool by tool, is on AI access.

Need help?

Join our Discord and a person will answer.

Something missing or wrong? Tell us or ask in Discord.