# Deploy from the terminal (CLI)

If you build with a coding tool — Claude Code, Cursor, or a plain editor and
a bundler — the fastest way to ship the result is straight from the terminal.
The **Volly CLI** packs your files, creates the app if it doesn't exist yet,
and publishes it, all in one command:

```console
$ volly login                 # browser sign-in, one time
$ volly deploy ./dist
Deployed my-app → https://acme-my-app.volly.so
```

The CLI is open source ([github.com/volly-app/volly-cli](https://github.com/volly-app/volly-cli))
and ships on npm as [`@volly-app/cli`](https://www.npmjs.com/package/@volly-app/cli).

## Install

With Node.js 20 or newer:

```bash
npm install -g @volly-app/cli    # or: pnpm add -g @volly-app/cli
```

Or skip the install and run it directly:

```bash
npx @volly-app/cli deploy ./dist
```

## Sign in

```bash
volly login
```

This opens your browser to sign in to Volly and approve access — the same
flow as [connecting an AI agent](https://volly.so/docs/mcp), with no keys to paste. The CLI
acts as you afterwards: it can only see and change what your Volly account
can. On a remote machine without a browser, use `volly login --no-browser`
and open the printed URL from any device, or paste a token with
`volly login --with-token`.

## Deploy an app

Point `volly deploy` at a folder with an `index.html` at its root (it's
zipped automatically, skipping dotfiles and `node_modules`), or at a single
`.html`, `.zip`, `.jsx`, or `.tsx` file:

```bash
volly deploy ./dist --app my-app
```

If the app doesn't exist yet, the CLI offers to create it and drops a small
`volly.json` next to your files remembering the slug — after that, a bare
`volly deploy` from the same folder is enough.

Updates work the same way: each deploy fully replaces the live build at the
same address. To try a change privately first, stage it as a
[draft](https://volly.so/docs/drafts):

```bash
volly deploy ./dist --draft -m "new navigation"
volly draft publish        # ship it when it looks right
volly draft discard        # or throw it away
```

A few other everyday commands:

```bash
volly app list             # your workspace's apps
volly deployments list     # an app's deploy history
volly whoami               # who the CLI is signed in as
```

## Deploy from CI

CI can't open a browser, so it authenticates with a **personal access
token** instead. Mint one from your signed-in CLI and store it as a secret
in your CI system:

```console
$ volly token create --name github-actions
volly_pat_…
```

The token acts as your account, limited to the scopes you give it
(`apps:read`, `apps:write`). You can list and revoke tokens any time with
`volly token list` and `volly token revoke`, and a token can never create
more tokens.

With the secret set as the `VOLLY_TOKEN` environment variable, any CI system
that has Node.js can deploy:

```bash
npx @volly-app/cli deploy ./dist --yes
```

## GitHub Actions

On GitHub, skip the scripting — the CLI repo doubles as an action. Add your
token as a repository secret named `VOLLY_TOKEN`, then:

```yaml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      # …your build steps producing ./dist…
      - name: Deploy to Volly
        id: deploy
        uses: volly-app/volly-cli@v1
        with:
          token: ${{ secrets.VOLLY_TOKEN }}
          path: ./dist
          app: my-app
          message: ${{ github.event.head_commit.message }}
      - run: echo "Live at ${{ steps.deploy.outputs.url }}"
```

The action creates the app on first run, posts the deploy URL to the job
summary, and exposes `url`, `deployment-id`, and `draft` as outputs. Set
`draft: 'true'` to stage a preview instead of publishing — handy for pull
requests — and publish from your terminal with `volly draft publish` once
it's reviewed.

All inputs and outputs are documented in the
[repository README](https://github.com/volly-app/volly-cli#github-action).

## CLI or MCP?

Both surfaces do the same job with the same permissions — pick per workflow.
[MCP](https://volly.so/docs/mcp) lets an AI agent publish as part of a conversation; the CLI
is for when _you_ (or a CI pipeline) run the deploy.