Launchpad: managed servers and a Claude Code connector

Anatomy of a launch: what happens when you press the button

· The Launchpad crew · 4 min read

"Launch!" is a big button, and it's meant to feel like one. But we know the people who use Launchpad are the kind who like to know what a button does. So here's the tour.

0. Before the button

You've installed the Launchpad connector in the Claude desktop app and you have a secret key (it starts with lp_). Every request Claude makes to the connector carries that key, and the connector checks it against your account on every call. There's no long-lived session to hijack; each call stands on its own.

1. Requesting a server

Claude calls request_server with a plan. The connector checks that your account is entitled to that plan and that you're under your server limit, then:

  • records a provisioning job in our database (this is the source of truth for what exists, not the cloud console);
  • asks the cloud provider for a fresh Ubuntu instance on that plan's size, with a properly sized disk;
  • assigns your server a subdomain on *.asklaunchpad.com, generated on the spot (something like brave-otter), and creates the DNS record for it;
  • returns a job id and the subdomain immediately, so Claude can carry on while the machine boots.

2. First boot: the server configures itself

The new instance boots with a set of instructions we hand it at launch time. In the first couple of minutes it:

  • creates a 4 GB swap file, so a small server doesn't fall over during a package install;
  • installs and starts nginx, ready to serve static files or reverse-proxy your app;
  • installs and starts MySQL, ready for you to create one database per app;
  • trusts the Launchpad SSH certificate authority, which is what makes the short-lived sessions in the next step possible;
  • writes a README.md in the home directory that explains all of the above to whoever, or whatever, logs in next.

Claude polls get_provisioning_status while this happens. We don't report a server as ready when the machine is merely powered on; we check that first-boot configuration has actually finished. (We learned that one the hard way: for a while we reported "ready" a few minutes early, and sessions would fail because the server hadn't been told to trust our certificates yet.)

3. Getting in: a certificate, not a password

To work on the server, Claude calls request_ssh_session. The connector generates a brand-new key pair, signs it with the Launchpad certificate authority, and returns the private key, the certificate, the host and an expiry time.

Three properties of that certificate matter:

  • it's scoped to one server, so it can't be used anywhere else;
  • it expires in thirty minutes, so a leaked credential has a very short life;
  • its issuance is logged, and you can revoke it early with revoke_session.

Claude writes the key and certificate to temporary files and connects with plain ssh. From here it's a normal Ubuntu box and Claude does normal things on it: copies code, installs a runtime, creates the database, writes a service unit, restarts it, reads the journal.

3b. The HTTPS-only route

Some environments Claude runs in can't open raw network connections at all; they're limited to outbound HTTPS through a proxy. SSH is unreachable from there no matter how valid the certificate is. For those, there's deploy_app: Claude sends a small archive of the app over HTTPS, and the connector does the SSH leg itself, server-side. It unpacks the code, installs dependencies if there's a package.json, writes a systemd unit, points nginx at your app's port, and returns a step-by-step log. get_app_logs tails the journal afterwards. Same server, same permissions, different transport.

4. Going live

Your app is listening on a local port; nginx is proxying the server's public port 80 to it; DNS for your subdomain points at the server. That's the moment the URL starts answering. Claude usually checks it with a request before telling you it's done.

5. Afterwards

The server keeps running. get_server_health gives Claude a snapshot of disk, memory and services without needing a session. request_subdomain renames the address if brave-otter doesn't suit. And when the project is over, terminate_server (with an explicit confirmation) takes the whole thing away, cleanly.

That's the launch. A dozen moving parts, none of which you had to touch, and a big button on top.

All posts