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:
- subdomain — The operator's worker subdomain
- secret — The registration secret
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.
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:
- Files are encrypted client-side with AES-256-GCM
- Key derived via PBKDF2 (100k iterations)
- Server never sees your password or unencrypted content
- Visitors enter the password in-browser to decrypt
Password protection uses true end-to-end encryption. Even the operator cannot access your content.
Magic Links
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:
- Visitor enters their email on the protected page
- If the email matches the allowlist, a magic link is sent
- Clicking the link decrypts and displays the content
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.
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.
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.
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:
.git,.svn,.hgnode_modules,__pycache__,.venv,venv.DS_Store,Thumbs.db.env,.env.*,*.log*.pem,*.key,id_rsa,id_ed25519
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:
- BASSH_API — Your operator's worker URL
- BASSH_KEY — Your API key
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.
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:
"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
- Sign up at connect.bassh.io and copy your API key.
- Open connect.bassh.io/connect and paste your API key to generate a
client_idandclient_secret. - In Cowork or Claude Desktop, add a Custom Connector with:
- MCP URL —
https://connect.bassh.io/mcp - Client ID — the
cowork_…value from/connect - Client secret — the
cs_…value from/connect
- MCP URL —
- 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. |
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 |