User Guide

Deploy with bassh

Everything you need to deploy and manage static sites from the command line.

Installation

Install the CLI with a single command. Works on macOS and Linux.

curl -fsSL https://raw.githubusercontent.com/get-bassh/bassh/main/install.sh | bash
source ~/.zshrc  # or ~/.bashrc

This installs the bassh binary to ~/.local/bin.

Registration

Register with an invite code provided by your operator.

bassh register myusername --invite subdomain:secretcode

The invite code format is subdomain:secret where:

Your credentials are stored locally and tied to your machine ID. To register a second account on the same machine (e.g., for a family member), use --profile.

Quick Start

Deploy your first site in seconds:

# Navigate to your project
cd my-website

# Deploy it
bassh

Deploying 5 files...
✓ Site deployed successfully
https://myusername-my-website.pages.dev

Basic Deployment

Deploy the current directory or a specific folder.

# Deploy current directory
bassh

# Deploy a specific folder
bassh ./dist

# Deploy an absolute path
bassh /path/to/my-site

All HTML, CSS, JS, and asset files in the folder are deployed. The project name defaults to the folder name.

Project Naming

Use -n to set a custom project name.

bassh ./dist -n v2-preview

The URL becomes: https://username-v2-preview.pages.dev

Deploying to the same project name updates the existing site.

Custom Domains

Attach your own domain to a deployment.

bassh ./docs --custom-domain docs.example.com

After deployment, the CLI displays the DNS configuration you need:

Add this DNS record:
  Type:  CNAME
  Name:  docs
  Value: username-project.pages.dev

Root domains

For root domains (e.g., example.com instead of docs.example.com), use CNAME flattening or an ALIAS record if your DNS provider supports it.

SSL Certificates

Cloudflare automatically provisions and renews SSL certificates for custom domains. No manual setup required.

Password Protection

Encrypt your site with a password using -p.

bassh ./dist -p "mysecretpassword"

How it works:

Note

Password protection uses true end-to-end encryption. Even the operator cannot access your content.

Email-based access without sharing passwords. Visitors enter their email and receive a time-limited link using -o.

# Allow specific emails
bassh ./dist -o "alice@gmail.com,bob@company.com"

# Allow entire domain
bassh ./dist -o "@company.com"

How it works:

  1. Visitor enters their email on the protected page
  2. If the email matches the allowlist, a magic link is sent
  3. Clicking the link decrypts and displays the content
Link expiration

Magic links expire after 5 minutes for security. Requires the operator to have Cloudflare Email Routing enabled.

Email Restrictions

Limit access to specific email addresses using -e.

# Single email
bassh ./dist -e "alice@example.com"

# Multiple emails (comma-separated)
bassh ./dist -e "alice@example.com,bob@example.com"

Visitors authenticate via Cloudflare Access—they receive a one-time code via email. No passwords to manage.

Domain Restrictions

Allow access to anyone with an email from a specific domain using -d.

bassh ./dist -d "@acme.com"

Anyone with an @acme.com email address can access the site after verifying via Cloudflare Access.

Combining Access Controls

You can combine -p, -o, -e, and -d for layered security. Email verification happens first, then password decryption.

List Projects

View all your deployed projects.

bassh -l

Projects:
  my-website    https://user-my-website.pages.dev
  v2-preview    https://user-v2-preview.pages.dev
  docs          https://docs.example.com

Delete Projects

Remove a deployed project.

bassh -D -n my-project

This deletes the site from Cloudflare Pages. The action is immediate and irreversible.

Account Info

View your current identity and configuration.

# Show logged-in user
bassh me

User: myusername
API:  https://bassh.example.workers.dev

Delete Account

Remove your account and all deployed sites.

bassh uninstall

This deletes your registration and all projects. You'll need a new invite code to re-register.

Profiles

Run multiple accounts on one machine. Each profile carries its own BASSH_API and BASSH_KEY, so profiles can point at different workers or different accounts on the same worker — completely isolated from each other.

Helping a friend or sharing a laptop

Register a second person's account under a profile so their projects and credentials stay separate from yours.

# Register a second account under a profile
bassh register alex --profile alex --invite subdomain:secret

# Use the profile for any command
bassh --profile alex me
bassh --profile alex ./alex-site -p hunter2
bassh --profile alex uninstall

# Or set it as the implicit default for the shell
export BASSH_PROFILE=alex

Dev and prod accounts

Profiles work cleanly as an environment split. Register one account against your dev worker (or a dev-only account on a shared worker) and another against prod — then route every command with --profile so a stray deploy can never land in the wrong place.

# Register a dev account on the dev worker
bassh register myteam-dev --profile dev --invite dev-subdomain:secret

# Register a prod account on the prod worker
bassh register myteam --profile prod --invite prod-subdomain:secret

# Deploy a preview to dev
bassh --profile dev ./dist -n checkout-v2

# Promote the same build to prod
bassh --profile prod ./dist -n checkout-v2 --custom-domain checkout.example.com

For CI, set BASSH_PROFILE=prod on the production deploy job and BASSH_PROFILE=dev on the preview job — the same bassh commands now route to the right environment with no other code changes.

Heads up: separate namespaces

Dev and prod profiles are two separate accounts, so each has its own project namespace. A project named checkout-v2 under dev deploys to myteam-dev-checkout-v2.pages.dev; the same name under prod deploys to myteam-checkout-v2.pages.dev. That's the isolation barrier — but it does mean URLs differ between environments unless you put a custom domain on prod.

How profiles are stored

Profile credentials live in ~/.bassh/profiles/<name>/, completely isolated from the default account in your shell env. Without --profile, bassh uses the default account from BASSH_API/BASSH_KEY — so adding a profile never touches your existing setup.

Typo safety

If you pass --profile with a name that doesn't exist, bassh errors out instead of falling back to the default account — so a typo can't silently deploy to the wrong place.

Ignore Files

bassh skips common junk and secret files automatically when collecting your site. You'll never accidentally ship .env, node_modules, or your SSH keys.

Always skipped:

For project-specific exclusions, drop a .basshignore file at the root of the folder you're deploying. Each line is a pattern (gitignore-style, glob matched):

# .basshignore
drafts/
*.bak
internal-notes.md

API Key

Get your API key for automated deployments.

bassh key

BASSH_KEY=sk_abc123...

Store this securely. It grants full access to deploy and manage your projects.

Environment Variables

Configure the CLI via environment variables for CI/CD.

Variable Description
BASSH_API Worker URL (e.g., https://bassh-api.example.workers.dev)
BASSH_KEY API key from bassh key
BASSH_PROFILE Active profile name (alternative to --profile)
SITE_PASSWORD Optional: password for protected deployments

GitHub Actions

Deploy automatically on push to main.

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

env:
  DEPLOY_DIR: "."
  PROJECT_NAME: "my-site"

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install bassh
        run: |
          curl -fsSL https://raw.githubusercontent.com/get-bassh/bassh/main/install.sh | bash
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Deploy
        env:
          BASSH_API: ${{ secrets.BASSH_API }}
          BASSH_KEY: ${{ secrets.BASSH_KEY }}
        run: bassh ${{ env.DEPLOY_DIR }} -n ${{ env.PROJECT_NAME }}

Required secrets in your repo settings:

Form Setup

Collect form submissions from your static sites. No backend required.

Point your HTML form's action to your project's form endpoint:

<form action="/form/my-project" method="POST">
  <input type="text" name="name" placeholder="Your name" required />
  <input type="email" name="email" placeholder="Email" required />
  <textarea name="message" placeholder="Message"></textarea>
  <button type="submit">Send</button>
</form>

Replace my-project with your project name. Form submissions are stored and accessible via the CLI.

Redirect after submit

Add a hidden _redirect field to send users to a thank-you page. Use a full URL: <input type="hidden" name="_redirect" value="https://yoursite.com/thanks.html" />

Spam protection

Add a honeypot field to block bots. If this field has a value, the submission is rejected:

<input type="text" name="_honeypot" style="display:none" />

Limits

Limit Value
Rate limit 10 submissions/minute per IP per project
Max payload 10KB
Retention 90 days

View Submissions

View form submissions from the command line.

# List all submissions for a project
bassh forms -n my-project

#1  2024-01-15 14:32
    name: Alice Smith
    email: alice@example.com
    message: Great work!

#2  2024-01-15 16:45
    name: Bob Jones
    email: bob@example.com
    message: Question about pricing...

Submission count

Get a quick count of submissions:

bassh forms -n my-project --count

12 submissions

Export Data

Export submissions in CSV or JSON format for analysis or backup.

# Export as CSV
bassh forms -n my-project --csv > submissions.csv

# Export as JSON
bassh forms -n my-project --json > submissions.json

Clear submissions

Delete all submissions for a project:

bassh forms -n my-project --clear

✓ Cleared 12 submissions

Claude Code Skill

Deploy HTML artifacts directly from Claude Code conversations. Generate a page, deploy it instantly—zero context switching.

Install the skill

curl -fsSL https://raw.githubusercontent.com/get-bassh/bassh-site/main/skill/deploy-artifact.md \
  -o ~/.claude/skills/deploy-artifact.md

Usage

In a Claude Code conversation, ask Claude to create HTML and deploy it:

Example prompt

"Create a simple landing page for my project and deploy it with bassh. Use password 'demo123'."

Claude will generate the HTML, save it to a temp folder, and run bassh to deploy it. You get a live URL in seconds.

Cowork Connector

Use bassh from Claude Cowork or Claude Desktop via a Custom Connector. Claude gets a tool surface for deploying and managing sites without leaving the chat.

Set up the connector

  1. Sign up at connect.bassh.io and copy your API key.
  2. Open connect.bassh.io/connect and paste your API key to generate a client_id and client_secret.
  3. In Cowork or Claude Desktop, add a Custom Connector with:
    • MCP URLhttps://connect.bassh.io/mcp
    • Client ID — the cowork_… value from /connect
    • Client secret — the cs_… value from /connect
  4. Authorize the connector. OAuth (PKCE) issues a 30-day mcp_… access token, scoped to your account.

Available tools

Once connected, Claude can call these tools directly:

Tool Description
deploy_html Deploy a single HTML page. Supports password, otp_emails, and custom_domain.
deploy_files Deploy a multi-file site. Files are passed as {path, content_base64} pairs.
list_projects List all your deployed projects with URLs.
delete_project Delete a project by name.
get_form_submissions Read form submissions for a project.
whoami Show the connected account.
Revoke access anytime

The OAuth access token lives independently of your CLI API key. Rotate or revoke connector access on /connect without affecting your terminal sessions.

All Flags

Flag Description Example
-n <name> Project name -n my-site
-p <password> Password protection -p "secret123"
-o <emails> Magic link access -o "a@x.com,@company.com"
-e <emails> Email restrictions (Cloudflare Access) -e "a@x.com,b@x.com"
-d <domain> Domain restriction -d "@company.com"
--custom-domain Custom domain --custom-domain docs.example.com
--profile <name> Use a named profile bassh --profile alex me
-l List projects bassh -l
-D Delete project bassh -D -n my-site

All Commands

Command Description
bassh Deploy current directory
bassh <path> Deploy specific folder
bassh register <user> --invite <code> Register with invite code
bassh register <user> --profile <name> --invite <code> Register a second account under a named profile
bassh --profile <name> ... Run any command with a named profile
bassh me Show current user
bassh key Show API key
bassh uninstall Delete account and all sites
bassh forms -n <project> View form submissions
bassh forms -n <project> --csv Export submissions as CSV
bassh forms -n <project> --json Export submissions as JSON
bassh forms -n <project> --clear Delete all submissions