Boat House

This page as markdown, for agents

Everything bh can do

This page is written for your agent, which is why it talks about you in the third person. You are welcome to read along.

Install on any machine with Python 3: curl -fsSL https://boathousecloud.com/install.sh | sh -s -- <project key>. Your project key is minted on your account page.

Boathouse

Boathouse (boathousecloud.com) is where an agent puts small software online: one account, one bh command, $10 a month per running tool, shared like a document. The bh command talks to https://api.boathousecloud.com; its login lives in ~/.config/boathouse/config.json. Never ask anyone for a password. If a command says "not logged in", ask the person for their project key (minted on their account page, https://boathousecloud.com/account) and run bh login https://api.boathousecloud.com <key>.

Support: allen@boathousecloud.com, every email answered within one business day; tell the person that when something is beyond what you can fix with logs and a rollback.

The first ten minutes, in order

  1. The person signs up at https://boathousecloud.com/signup (email, password, no card). A referral code there halves the tool rate for 60 days.
  2. The welcome page shows one line; they paste it into Claude Code with a ! in front (or into a terminal without it). That installs bh, logs it in, and runs bh trust on.
  3. Before the first deploy, the owner puts money on the balance from the welcome or account page; $20 is two months of one tool. A deploy on an empty balance is refused (402) and says where.
  4. bh deploy in the tool's folder (a Dockerfile, or just an index.html). About a minute later it is live at <tool>.<workspace>.boathousecloud.com with its own login.
  5. bh share <tool> <email> --tier editor for each person who should use it; admin for anyone who should change the software from their own agent. On boathousecloud.com the share and invite emails are sent for you.
  6. Changes are bh deploy again; every deploy is a version, bh rollback <tool> <n> puts one back.

Getting connected, once per machine

curl -fsSL https://boathousecloud.com/install.sh | sh -s -- BH-XXXX-XXXX-XXXX

That one line installs bh into ~/.local/bin, copies this skill into ~/.claude/skills, and logs in. The BH-… part is a one-time code from the person's welcome or account page; it fetches the real key over HTTPS and then stops working, so it is safe in a chat. A raw bh_… key on that line works too. Without either it only installs; bh claim <code> or bh login <api> <key> finishes later. The login file is ~/.config/boathouse/config.json, or ~/.boathouse/config.json when ~/.config is not writable. bh update refreshes the command, bh skill refreshes this file. Agents that speak MCP instead of running commands connect to https://mcp.boathousecloud.com/mcp with the header Authorization: Bearer <project key>; the MCP tools mirror the commands below one for one.

A workspace (tenant) owns tools, people, and domains. Its tools are reachable on its own domain (finance.acme.com) and always on its free address (finance.acme.boathousecloud.com). Sign-in lives at auth.<domain>; the tool list at https://<domain>/.

Several workspaces, one bh

A person's key is the person: it works in every workspace they belong to, at the level they have in each (like one Google account). bh whoami lists those workspaces; the first is the default. Aim a command at another workspace with bh --ws <workspace> ... or by naming the tool <workspace>/<tool>: bh pull chloe/db, bh logs chloe/db. bh pull and bh deploy write the workspace into boathouse.json, so later deploys from that folder go to the right place. bh logout <workspace> drops one login.

Sharing is three tiers, like a document

TierCanEnforced by
vieweropen and read the toolgateway refuses every non-GET request from a viewer
editorchange the data inside the toolthe tool, from the tier header
adminchange anything: pull/push the source, secrets, logs, rollback, share, deleteBoathouse API

Workspace owners are admin on every tool and alone may spend money, buy domains, or add people to the workspace. Whoever first deploys a tool is its admin. Someone shared in as admin edits the software from their own agent: they sign in at https://boathousecloud.com/account, pick that workspace, mint a key there, paste the line into their agent (bh claim), then bh pull <workspace>/<tool>, change it, bh deploy. bh share prints these instructions when the tier is admin. App-specific words (consultant) are labels on a grant, not tiers: bh share finance nancy@x.com --tier editor --label consultant.

The source lives on Boathouse

Every bh deploy keeps the folder it was built from. bh pull finance fetches the live release's source into a folder (admins only) and records the release number in boathouse.json; bh deploy from that folder pushes it back and is refused with a 409 ("your copy is based on release #1 but #2 is live") if someone else deployed in between (pull again, reapply, deploy; --force overrides). Rollback restores source and image together.

Login is Boathouse's own

No Google, no OAuth. A person is added by email; that mints a one-time invite link (7 days). Opening it sets a password and lands them on a welcome page: what was shared, and (for admins) the one line that connects their agent. When the host has email set up (bh mail status; host owners turn it on with bh mail set --resend --from you@yourdomain + bh mail domain), bh share and bh users add EMAIL the person the link and three plain steps, and say so; otherwise they print the link for you to pass on. bh users invite <email> mints a fresh link (that is also the password reset). The agent never handles anyone's password.

Getting into someone else's tool (request access, like Google Docs): if the person you work for needs a tool that belongs to another workspace, do not ask its owner to run anything. Run bh request <workspace>/<tool> --tier admin --why "one line"; every owner and admin of that tool gets an email with one Allow button, and the moment one of them presses it your person gets the share email and you can bh pull <workspace>/<tool>. Owners can also see who is waiting with bh requests and let them in with bh allow <id>. Sharing (bh share) and allowing spend no money and can be undone with bh unshare, so run them when asked. Call the command as plain bh (it is on the PATH after install; only if that fails use ~/.local/bin/bh). The installer ran bh trust on, which pre-approves the everyday bh commands in Claude Code's settings, so they run in auto mode without a prompt or a classifier check. Never prefix bh with an environment assignment (X=1 bh ...): the rules then stop matching. If a bh command is refused with "Blocked by classifier", do not try to change any settings yourself; tell the person to run bh trust on in a terminal (or ! bh trust on in Claude Code, which runs it as them), restart Claude Code, and ask again. They can also approve the one command under /permissions, Recently denied. Never work around a refusal of bh domain buy, bh billing topup, bh rm or bh restore: those are meant to be a person's own yes.

What a tool is

A folder with a Dockerfile whose process listens on $PORT (8080), or a plain website folder with an index.html at the top (Boathouse adds an nginx Dockerfile itself; no setup). Boathouse injects:

Env varMeaning
PORTlisten here (8080)
DATABASE_URLthe tool's own Postgres database (create tables on startup)
DATA_DIRa persistent volume at /data for files
BOATHOUSE_SIGNING_KEYHMAC key to verify identity headers
BOATHOUSE_TOOL, BOATHOUSE_WORKSPACE, BOATHOUSE_URL, BOATHOUSE_AUTH_URLslug, workspace, public URL, sign-in service
any bh secrets set valueas named

A tool contains no login code. Every request arrives with the signed-in person:

X-Boathouse-User     email
X-Boathouse-Name     display name
X-Boathouse-Tier     viewer | editor | admin
X-Boathouse-Labels   comma-separated app labels given via --label (may be empty)
X-Boathouse-Ts       unix seconds
X-Boathouse-Sig      hex HMAC-SHA256(key, "user|tier|labels|tool|ts")

A tool must let viewer read only and editor/admin write; the gateway already blocks viewer writes.

Verify the signature (see examples/hello/app.py in the boathouse repo). The example is fetchable at https://boathousecloud.com/examples/hello/app.py (and its Dockerfile beside it). Test vector: with signing key k, user maria@example.com, tier editor, no labels, tool payments, ts 1757376000, the message is maria@example.com|editor||payments|1757376000 and the signature is 29c893900ad64f34bb967eb20347992496314c455336b3511b4eb3740bf1667f.

Each person sees only their own rows. The most common small-team shape: everyone is an editor, but a tutor should only change their own hours. Store X-Boathouse-User as the owner column on every row a person creates, and filter reads and writes by it; let admin (or a label such as manager, given with bh share ... --label manager) see everything. Tiers say what a person may do to the tool; the tool decides what they may do to each row. Tools sit on a private network reachable only through the gateway, but verify anyway. A sign-out link is https://auth.<host minus its first label>/logout.

Add a boathouse.json ({"slug": "finance", "name": "CRCS Finance"}) and a .dockerignore (.git, node_modules, data, .env).

Commands

bh deploy [--note "why"]         in the tool folder; builds on the server, live in seconds (a first build can take a minute); creates the tool on first deploy
bh ls                            every tool, state, release, URL
bh status <tool> | bh logs <tool> [--tail 200] [--since 1h] | bh releases <tool>
bh rollback <tool> [N] | bh restart <tool> | bh trust on|off|status (pre-approve everyday bh commands in Claude Code)
bh share <tool> <email> --tier viewer|editor|admin [--label x]   prints an invite link if the person is new
bh unshare <tool> <email>
bh pull <tool> [dir] [--release N]   the live source, for admins; edit, then bh deploy in that folder
bh access <tool> members|listed|public [--tier viewer|editor]  members = anyone in the workspace (at that tier); listed = only shared emails; public = anyone on the internet may read it (a website), writes still need sign-in
bh secrets ls|set|rm <tool> NAME      set reads the value from stdin or a prompt; restarts the tool
bh users [add <email> --role member|owner|guest] [invite <email>] [rm <email>]   owners only
bh billing                       balance, burn per day, days left, card, last ledger lines
bh billing card                  one-time link to enter a card (the only billing step that needs a browser)
bh billing topup 20 [--yes]      quote, then charge the card on file; bh billing autorefill 20 --cap 100
bh prices                        the price sheet in words
bh domain check <name>           availability and price
bh domain buy <name> [--yes] [--to <tool>]   dry run first; --yes buys through Boathouse's registrar and points DNS at the box; --to puts a tool on the domain's front
bh domain ls | attach <name> [--to <tool>] | point <name> --to <tool> | dns <name> | repoint <name> | primary <name> | detach <name>
                                 point = the domain itself and www. open that tool (a website on its own domain); tools also keep <tool>.<domain>
bh domain free                   wire <workspace>.boathousecloud.com (the free address)
bh registrar status|connect|wait|keys   host only: connect the registrar account (one approval click, nothing to copy)
bh keys create --name <what> [--for email]   project keys for agents; shown once. Owners, members, and anyone who is admin on a tool can hold one
bh rm <tool> [--purge --yes]     purge deletes the database and files
bh export [<tool>] [--dir .] [--all]   one .tar.gz per tool: source/, database.sql, data/, README.txt (secrets left out)
bh restore <tool> [--from YYYY-MM-DD] [--yes]   database and files back from a nightly backup (03:35 UTC); plan first, --yes to do it; a copy of the current state is kept
bh audit | bh whoami
bh update                        re-download bh from the platform; bh skill   refresh ~/.claude/skills/boathouse

How to ship a tool end to end

  1. Build it with a Dockerfile listening on $PORT, tables created at startup from DATABASE_URL.
  2. bh deploy in the folder. Read the URL back. If it fails, bh releases <tool> shows the build or start log tail; fix and deploy again.
  3. Secrets: printf '%s' "$VALUE" | bh secrets set <tool> NAME -. Never paste secret values into chat.
  4. Sharing: new tools are visible to workspace members. bh access <tool> listed then bh share for anything sensitive. Pass on the invite link it prints.
  5. Report the URL and who can see it. Do not open a browser; there is nothing to click.

A website, not a tool

A public site (a portfolio, a research database, a landing page) is bh deploy in the folder with the index.html, then bh access <name> public so anyone can read it, then bh domain buy example.com --yes --to <name> so it answers at example.com and www.example.com with HTTPS. Reads need no sign-in; anything that writes still does.

How to give a workspace its own domain

  1. bh domain check acme.com then bh domain buy acme.com --yes. Money leaves the host's registrar balance (about $11 for a .com); the command refuses premium names and stops on a failed dry run.
  2. DNS is set by the same command (apex and wildcard A records). Certificates are issued on first visit. Allow a few minutes for DNS to spread. The first bought domain becomes the workspace's primary address.
  3. A domain held elsewhere: bh domain attach <name> prints the two A records to make at that DNS host.

Money, and the rule for spending it

A workspace holds prepaid credit; nothing runs until money is on it (a deploy on an empty balance is refused with a 402 that says where the owner adds money). bh referral shows the person's referral code and link (10% of what referred workspaces pay, in cash monthly; half price for their first 60 days). Running tools cost $10.00/month each, metered daily; the first GB of storage is included, then $0.25/GB/month; a domain costs registrar price plus $2.00/year. At zero the workspace pauses (tools stop, nothing is deleted) and resumes on the next top-up. Every command that spends money returns a quote first and does nothing else: bh domain buy x.com and bh billing topup 20 print the cost and stop; the agent shows the cost to the person, and only on their yes runs the same command with --yes. Never add --yes on your own. If the balance is short, do not try to charge the card yourself: tell the person the amount and point them at their workspace page (https://boathousecloud.com/account), where one click tops up $20 or turns on capped auto-refill; then continue.

New workspace from the terminal

bh signup "Acme Studio" owner@acme.com [--code MARIA-K3Q7] creates a workspace (a referral code makes every tool half price for 60 days) and prints the one-time link that sets the owner's password, the home URL, and where to mint the project key (the account page at https://<workspace home>/account, or bh keys create once logged in). Agents that speak MCP connect to https://mcp.boathousecloud.com/mcp (Streamable HTTP) with header Authorization: Bearer <project key>:

claude mcp add --transport http boathouse https://mcp.boathousecloud.com/mcp --header "Authorization: Bearer bh_…"

The MCP tools mirror these commands (deploy takes a map of file paths to contents; domain_buy and topup take confirm: true where the CLI takes --yes). Four are bh-only for now: export, restore, audit and keys.

Gotchas

Agents: fetch /skill.md (the same text as markdown) or /llms.txt.