Run any pull request as a private copy of your app.

Stagely runs pull request previews in your own cloud account, each behind a private URL. Your coding agent tests the change first. Then your team reviews the same running copy.

Builds from the Docker Compose files you already have. Runs in your own DigitalOcean, AWS, Google Cloud, Azure, Hetzner Cloud or Vultr account. Your cloud credentials and secret values never leave it. Stagely deletes a stagelet when its pull request closes, or, by default, 3 days after its last deploy.

AgentMCP server: stagely
  1. List my Stagely projects. Deploy pull request 1 of acme/web. Wait until the stagelet is ready, then open it.

  2. stagelylist_projects

    "name": "acme/web"

  3. stagelydeploy_pull_request{"repository":"acme/web","pull_request":1}

    "state": "deploying"

    "ready": true

  4. The deploy started. ready is already true because the previous revision still serves. I will poll until the state is running.

  5. stagelyget_operation{"stagelet_id":"f543a41f9949"}

    "[start stderr] Container stagelet-web-1 Recreate"

  6. The build succeeded. The start step now recreates the web container.

  7. stagelyget_stagelet{"stagelet_id":"f543a41f9949"}

    "state": "running"

    "outcome": "applied"

  8. The stagelet is running, and the new revision is applied. I will open it now.

  9. stagelyopen_stagelet{"stagelet_id":"f543a41f9949"}

    "expires_in_seconds": 30

    "url": "https://f543a41f9949.stagelets.acme.dev/_stagely/handoff?token=‹redacted›"

  10. The link works only once and expires 30 seconds after I made it.

In your cloud

  1. Lease
  2. Secrets
  3. Build images
  4. Provision machine
  5. Start services
  6. Migrate
  7. Health check
  8. Route
The session shows the tool names, arguments and results that Stagely's MCP server uses. It leaves out repeated status checks. acme/web is a sample repository.

Your cloud runs it. Your keys stay there.

Stagely plans each deploy. The agent and the gateway in your cloud carry it out. Both open their connections to Stagely, so your cloud needs no inbound port from Stagely.

The agent and the gateway open both WebSockets from your cloud, so Stagely needs no inbound port into it. Reviewers and coding agents come in only through the gateway, with a pass from Stagely.
What lives where, and whether Stagely sees it
DataWhere it livesDoes Stagely see it?
Cloud provider credentialsThe agent host, and your computer while setup runsNo
Application secret valuesThe agent's encrypted store, or a file that your pipeline supplies. During a deploy, the agent also writes them to a file on the stagelet's VM that only root can read, and into the containers' environment.No. Stagely keeps only their names.
Built imagesYour registryNo
Stagelet trafficFrom the gateway to the stagelet's VMNo
Source codeBuild workers get the full source. Stagely reads .stagely.yml and the Compose files in memory while it plans a deploy.Partly: the plan inputs, while it plans. The bundle that Stagely keeps for resets holds the resolved Compose model and the contents of env_file files.
Plain config valuesStagely's config snapshots and compiled deploy bundlesYes

Compose rules

Stagely checks your Compose files when it plans a deploy. The agent checks the resolved project again, with every variable filled in, before it builds. It refuses:

  • privileged containers
  • host namespaces, such as network_mode and pid
  • added capabilities, other runtimes, and any security_opt except no-new-privileges
  • devices and GPUs
  • bind mounts and the Docker socket
  • build options that reach the build worker, such as network: host and ssh

Named volumes are fine. They survive deploys and resets of the same stagelet.

Passes and sessions

  • A pass into a stagelet works once, for 30 seconds. The gateway trades it for a session on that stagelet only.
  • A session belongs to the member who opened it, or to the agent's grant, and never outlives the grant.
  • Remove a member, revoke a grant or delete the stagelet, and access ends within about 50 seconds.
  • If the gateway loses its connection to Stagely, it refuses every session it can't confirm again within about 50 seconds, and closes open connections within about a minute.

Your coding agent checks its own work

An agent connects to Stagely over MCP. It deploys the pull request it just opened, reads why a deploy failed, and opens the running app to test its change. A person then reviews the same stagelet.

Connect Claude Code

Add the server, then sign in.

Terminal
claude mcp add --transport http \
  stagely https://app.stagely.dev/mcp
claude mcp login stagely

Your browser opens the consent page. Choose the account and click Allow. Other MCP clients connect the same way: Stagely's endpoint uses Streamable HTTP and OAuth with PKCE.

Sign-in and access

  • The agent signs in with OAuth and PKCE, through a consent page in the console.
  • Access tokens last 15 minutes. Stagely checks each one against a live grant.
  • An agent session lasts at most one hour.
  • Revoke the grant in the console, and the agent loses access within about 50 seconds. This includes the stagelets it opened.

Tools the MCP server gives your agent

deploy_pull_request
Build and start the head commit of an open pull request as a stagelet.
get_stagelet
A stagelet's lifecycle state, machine and app health, reachability, and the revision that runs.
get_operation
A deploy or delete with its steps, its error and the last 200 log lines.
open_stagelet
A single-use URL into a ready stagelet. It expires after 30 seconds.
reset_stagelet
Restore the last successful deploy: the same images and config, on the same machine.
delete_stagelet
Revoke all access to a stagelet, then delete its VM.
list_projects
The account's projects. Each binds a GitHub repository to an environment.
list_stagelets
The account's stagelets that are not deleted.

How pull request previews work

When the project deploys on push, the default, a new pull request or a push to one starts a deploy. New commits on a pull request from a fork never deploy it. A comment on the pull request, a click in the console, an MCP call or a deploy label, if the project sets one, can also start a deploy.

Describe your app once

.stagely.yml names your Compose files, the service people open, its health check and an optional migration command.

For each deploy, Stagely reads this file and the Compose files at the pull request's head commit through the GitHub API. It does not clone your repository. Plain config values fill in variables such as GREETING. Secret values reach containers only as environment variables, straight from the agent.

.stagely.yml
version: 1
compose:
  - compose.yml
public:
  service: web
  port: 8080
health:
  path: /healthz
migration:
  command: /app/migrate
compose.yml
services:
  web:
    build: ./web
    environment:
      GREETING: ${GREETING:-hello}
      PROBE_URL: ${PROBE_URL:-}
    env_file:
      - web.env
    depends_on:
      - cache
  cache:
    image: redis:7-alpine

Watch every step

The agent in your cloud takes the job and fills in secret values from its own store. A build worker builds the images and pushes them to your registry. Meanwhile, the agent prepares the stagelet's own VM. Then it starts the services with each image pinned by digest, runs your migration and checks the health path. Last, the gateway routes the private URL.

The console and MCP show each step live, with its log. Each state has its own card: revision, app health, machine, gateway, reachability and expiry. So a failed deploy never hides a stagelet that still serves.

The Stagely console page for stagelet acme/web #1. It is Running. Six cards show the revision applied, the app healthy, the machine ready, the gateway serving it, the route reachable, and its expiry in 3 days. Below, a deploy that succeeded in 58 seconds lists its steps: Lease, Secrets, Build images, Provision machine, Start services, Migrate, Health check and Route.
The Stagely console page for stagelet acme/web #1 on a phone. It is Running, with Reset, Delete and Open buttons, and six stacked cards: revision applied, app healthy, machine ready, the gateway serves it, reachable, and deleted in 3 days unless deployed again.A deploy of the same stagelet that succeeded in 15 seconds, with its eight steps checked: Lease, Secrets, Build images, Provision machine, Start services, Migrate, Health check and Route.
The console page of a stagelet, from a local run on a Mac. Its first deploy created the VMs, so Build images and Provision machine took most of the 58 seconds.The same stagelet's console page on a phone, from a local run on a Mac, after a later deploy that took 15 seconds.

Open it, then let it go

A reviewer clicks Open on the stagelet in the console. The console gives them a pass into the private URL. The pass works once, for 30 seconds. The session it starts belongs to that reviewer. Without a pass, the gateway turns everyone away.

Terminal
$ curl -s -i https://f543a41f9949.stagelets.acme.dev/
HTTP/2 401 
content-type: text/plain; charset=utf-8
x-content-type-options: nosniff
content-length: 35
date: Sun, 11 Oct 2026 12:13:27 GMT

open this stagelet through Stagely
New commits
Redeploy the same stagelet, when the project deploys on push.
Reset
Restores the last good build: the same images and config, on the same VM.
Close the pull request
Stagely removes access first, then the agent deletes the VM.
TTL
Stagely deletes a stagelet when the project's TTL ends, unless someone deploys it again.

Set up once

Setup takes six steps: an account, the GitHub App, two commands, a DNS record, a file in your repository and your config. After that, each pull request needs nothing from you.

  1. Sign up and subscribe

    Sign up with GitHub, start a 14-day trial in Stripe Checkout and invite your team.

  2. Install the GitHub App

    Install the Stagely GitHub App where your repositories live, and link it to your Stagely account.

  3. Run stagely setup

    Sign in with stagely login, then run stagely setup <cloud>. Point -binaries at a directory with Linux builds of stagely-agent and stagely-gateway. Setup applies a Terraform module with OpenTofu or Terraform. It creates a network, the agent host, the gateway host and their firewall rules in your cloud account. On DigitalOcean, Google Cloud, Azure and Vultr, it also creates a container registry. AWS uses Amazon ECR in your account. On Hetzner Cloud, you bring your own registry. Then setup installs the agent and the gateway and enrolls them with Stagely. Run it again at any time to repair or upgrade.

  4. Point DNS at the gateway

    Setup prints the gateway's address. Point *.stagelets.example.com at it with an A record. On DigitalOcean, setup can add the record for you.

  5. Add .stagely.yml

    Commit it to the repository, then bind the repository to a project in the console.

  6. Add config

    Add plain values in Stagely. Store secret values on the agent. Stagely keeps only their names.

Terminal
Applying the bootstrap module in ~/.stagely/local/setup/terraform
…
Plan: 4 to add, 0 to change, 0 to destroy.
…
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
…
Started dev.stagely.local.agent; its log is ~/.stagely/local/setup/agent.log
Creating Lima VM stagely-local-gateway for the gateway
Installing stagely-gateway in Lima VM stagely-local-gateway

Environment local (0d2b8bc75509d5a6) runs on this Mac. Stagelets open at https://<id>.stagelets.localhost:9444.

Output of stagely setup lima, shortened. This command sets up a local test environment on a Mac.

The setup command for each cloud

You need

  • Repositories on GitHub, and the right to install a GitHub App where they live.
  • Services that run with Docker Compose, within the supported Compose rules.
  • An account on one of the six clouds, and credentials for it: an API token (DigitalOcean, Hetzner Cloud, Vultr), an access key (AWS), a service account key (Google Cloud) or a service principal (Azure).
  • The address ranges of the people who run setup. Only they can reach the hosts over SSH.
  • OpenTofu or Terraform on the machine that runs setup.
  • A domain for stagelet addresses, such as stagelets.example.com.
  • On Hetzner Cloud, a container registry that you already run.

Pricing

One flat price for each plan, with unlimited members. Your own cloud bill covers what runs in your cloud. The first 14 days are free, and you need no card to start.

Starter

$199a month

Or $1,990 a year: 2 months free.

  • 10 concurrent stagelets
  • 1 environment
  • Unlimited members
  • No extra stagelets
Sign up

Team

$499a month

Or $4,990 a year: 2 months free.

  • 50 concurrent stagelets
  • 3 environments
  • Unlimited members
  • Add 10 stagelets for $149 a month
Sign up

Business

$1,499a month

Or $14,990 a year: 2 months free.

  • 200 concurrent stagelets
  • Unlimited environments
  • Unlimited members
  • Add 10 stagelets for $99 a month
Sign up

Every plan includes

  • The console, the API, MCP and the GitHub App
  • All six clouds and the setup CLI
  • Deploy on push, reset, TTL and private URLs
  • Billing through Stripe, with a change of plan at any time

A stagelet counts until Stagely deletes it, in any state. At the limit, Stagely refuses a deploy that needs a new stagelet and says why. Deploys of stagelets that exist always work.

Who pays for what

The Stagely plan
You pay Stagely.
VMs for the agent host, the gateway host, build workers and stagelets
Your own cloud bill.
Container registry, the gateway's static IP address and DNS
Your own cloud bill.

The agent host and the gateway host run all the time. Stagely deletes a stagelet when its pull request closes or its project's TTL ends, so its VM does not keep running.

Questions

Is a stagelet a preview environment?

Yes. Other tools call a running copy of one pull request a preview environment. A stagelet has its own VM and a private URL. In Stagely, an environment is something else: the part of your cloud account that stagely setup prepares, with one agent and one gateway. One environment runs many stagelets.

Does Stagely see my source code?

Partly. To plan each deploy, Stagely reads .stagely.yml, your Compose files and the files they reference through the GitHub API, in memory. It keeps a compiled bundle for resets. The bundle holds the resolved Compose model and the contents of env_file files. The full source goes only to the build workers in your cloud.

Which apps work with Stagely?

Apps that run with Docker Compose, within the Compose rules above. Stagely follows include, extends and env_file. It refuses settings that give a container access to its machine, such as privileged mode, host namespaces, bind mounts and the Docker socket.

Can pull requests from forks deploy?

Only on purpose. Someone with write access comments the deploy command, clicks Deploy in the console, or adds a deploy label, if the project sets one. New commits on a fork's pull request never deploy it on their own.

What happens when a deploy fails?

The stagelet shows the failed step, its error and its log, in the console and over MCP. Stagely tracks the revision, the machine and the app's health separately, so you can see whether the previous revision still serves. Reset restores the last good build.

What happens when Stagely can't be reached?

Your stagelets keep running in your cloud, but the gateway fails closed. It refuses every session it can't confirm again within about 50 seconds, and closes open connections within about a minute.

What does the first release not do?

It works only with GitHub. It does not run unrestricted or privileged Compose, and it does not deploy to Kubernetes. Stagely does not host your apps: stagelets always run in your cloud.

Review your next pull request as a running app.