Using Heyo Computer

Heyo gives AI agents real computers: disposable sandbox VMs to run code in, and an app load balancer that deploys static sites and Dockerized apps straight from git repos or published artifacts.

Overview

You drive Heyo through its MCP server, usually from an agent such as Claude Code. Every action is a tool call: create a sandbox, run a command, commit files to a repo, deploy it. There is no separate dashboard to learn, and no git or Docker is needed on your side.

Sandboxes

Firecracker microVMs with a persistent /workspace disk, for running builds, tests and scripts.

Repos

Git repositories on the Heyo remote. Commit files directly with a tool call, or push with git.

Sites

Static HTML/JS/CSS served by app-lb from a repo or an artifact, on its own hostname.

VM apps

APIs, servers and workers built from a Dockerfile into a microVM image and load-balanced.

This guide was itself written and deployed with Heyo: the HTML lives in a Heyo repo and is served as a static site.

Core concepts

Namespace

Your token confines you to one namespace. The repo tools and applb_deploy use it automatically when you leave namespace out, and every artifact tag you publish must start with <namespace>/. Run heyo_whoami to see yours.

app-lb

The app load balancer. It holds deployments (sites or VM pools), builds them from a repo or pulls them from an artifact, assigns each a hostname, and routes traffic to healthy replicas.

Credential tiers

Two scopes matter, and they are checked in different places:

  • Admin tier (none / view / admin): what the admin API requires. Publishing artifacts needs admin for the whole namespace.
  • Deployment scope: which deployments a token may reach through their own gate.

A token can pass one check and fail the other, so on any 401 or 403 read both fields from heyo_whoami.

Getting started

  1. Connect the MCP serverAdd the Heyo MCP server to your agent with the token you were issued. In Claude Code the tools appear as mcp__heyo-…__*.
  2. Check who you areCall heyo_whoami. Note your namespace, admin_scope and expires_in_secs.
  3. Check the platformCall heyo_status to see which services the server reaches and any current faults.
  4. Ask for a planNot sure how to do something? Call heyo_guide with your goal in plain words, or with an error message, and it returns the tools to call and in what order.
Tip: With an agent, you rarely call these tools yourself. Say “deploy this folder as a public site on Heyo” and the agent follows the same steps.

Sandboxes

A sandbox is a VM for an agent to work in: install dependencies, run a build, execute tests, then pull the results out.

  1. Create itsandbox_create {name?, image?, disk_size_gb?} boots a VM from a hub image (default heyo/debian:latest) with a /workspace disk, and waits until it is ready.
  2. Get code inSmall files: sandbox_write_file (up to 1 MiB). Larger: sandbox_upload {id, path: "/workspace/app"} returns a one-time URL; curl -T repo.tar.gz '<url>' and it is unpacked there.
  3. Run commandsShort (under ~30s): sandbox_exec. Longer: sandbox_exec_start, then poll sandbox_exec_status {id, operation, offset}. Several can run at once.
  4. Get results outsandbox_read_file for small files, or sandbox_download {id, path} for a file or a whole directory as a tar.gz URL.
  5. Pause or finishsandbox_stop frees the VM but keeps /workspace; sandbox_start brings it back. sandbox_kill deletes it.
# one sandbox_exec call: cd and run in the same command
sandbox_exec {
  "id": "sbx-123",
  "command": "cd /workspace/app && npm ci && npm test"
}
Watch out:
  • Only /workspace survives a stop. The rest of the disk resets to the image on start.
  • Each sandbox_exec starts in / with a fresh shell. cd in the same command and pass variables in env.
  • A sandbox stops itself after idle_secs (default 600) with nothing running. An operation started with sandbox_exec_start keeps it up.

Deploy a static site

For HTML/JS/CSS that is already built. Nothing in the repo is executed on the server, so commit the built output.

  1. Build locally if neededFrameworks produce a dist/ or build/ folder. Plain HTML needs no build.
  2. Create a reporepo_create {name: "my-site"} creates a git repo in your namespace. It is idempotent: an existing repo is reused.
  3. Commit the filesrepo_write_files {repo, files: [{path, content}], message}. Use encoding: "base64" for images and other binaries. Up to 64 MiB per commit.
  4. Deployrepo_deploy {repo, kind: "site", context?: "dist", spa?: true, host?}. Without host, the site is served at <repo>.<region domain>; the result tells you which.
  5. Open itVisit https://<host>/. Sites are public by default.
repo_write_files {
  "repo": "my-site",
  "message": "Initial site",
  "files": [
    { "path": "index.html", "content": "<!doctype html><h1>Hello</h1>" },
    { "path": "logo.png", "content": "iVBORw0KGgo…", "encoding": "base64" }
  ]
}

repo_deploy { "repo": "my-site", "kind": "site" }
Single-page apps: pass spa: true so unknown paths serve index.html and client-side routing works.
Don't set site.root (app-lb assigns it) or add an update block (operator-only; a namespace credential is refused).

Deploy an app (VM)

For anything that runs a process: an API, a web server, a worker. Heyo builds your Dockerfile into a microVM image and runs it behind app-lb.

  1. Write a DockerfileInstall the app (e.g. into /app) plus socat. Heyo uses socat to stream the app's stdout/stderr out of the VM; without it, logs never appear.
  2. Create the repo and commitrepo_create, then repo_write_files with your source and the Dockerfile.
  3. Deployrepo_deploy {repo, kind: "vm", port, start_command}. It waits for the image build.
  4. Verifyapplb_get_deployment {id} and applb_metrics show whether replicas are healthy.
# Dockerfile
FROM node:20-slim
RUN apt-get update && apt-get install -y socat && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
RUN npm ci --omit=dev

# repo_deploy
{
  "repo": "my-api",
  "kind": "vm",
  "port": 8080,
  "start_command": "cd /app && setsid nohup node server.js </dev/null &"
}
The three rules of start_command:
  • It must return. Background the app with setsid nohup … &; a foreground command means the VM never finishes booting.
  • The app must listen on 0.0.0.0:<port>, not 127.0.0.1, and on the same port you pass to repo_deploy.
  • Don't redirect output to a file. Heyo captures it, and that capture is what deployment_logs and diagnose_vm_boot read.
A VM does not run the image's CMD/ENTRYPOINT; start_command is what starts your app (repo_deploy derives one from the Dockerfile if you give none).

Artifacts

An alternative to repos: publish a versioned bundle of files to your namespace's artifact store, then point a deployment at it.

  1. Publishart_publish_files {tag: "<namespace>/<name>:<version>", files: [...]} with file contents inline (up to 64 MiB). Already have a tarball? Use art_publish {tag, content_base64}.
  2. Deployapplb_deploy a site whose artifact block is just {ref: "<tag>"}. app-lb pulls it with its own credential, so the tag can stay private.
  3. Manage versionsart_list_tags, art_get_tag, art_get_manifest, art_fetch, art_delete_tag, and art_set_public to make a tag publicly fetchable.
Watch out: leave store and auth out of the artifact block. A hand-written store URL gets a 401 on the pull.

Redeploying

Deployed fromTo ship a change
A reporepo_write_files (or git push), then repo_deploy again. Or applb_build {id} for a deployment that already has a build block.
An artifactart_publish_files with a new version tag and deployment: <id>, or applb_pull {id}.

Then poll applb_job {job_id, deployment} until it finishes. Pass base (the branch's current commit from repo_get) to repo_write_files if you want the commit to fail rather than overwrite someone else's concurrent change.

Monitoring

QuestionTool
Is the platform healthy?heyo_status, heyo_capacity
What is deployed?applb_list_deployments, applb_get_deployment {id}
Did the build/pull succeed?applb_deployment_jobs {id}, applb_job
Are replicas healthy and taking traffic?applb_metrics
Everything at oncediagnose_deployment {id}: record, recent jobs and logs
Requests, errors, latency, logsnamespace_telemetry, then deployment_logs (needs the obs plugin in your namespace)

Troubleshooting

First move for any unfamiliar error: paste it into heyo_guide {goal: "<the error>"}.

401 / 403 / “namespace credential may not”

Run heyo_whoami and check namespace and tier. Everything you create must be in your namespace. Namespace credentials are refused for anything that acts on the app-lb host:

  • update block → build from a repo or pull an artifact instead.
  • site.root → leave it out.
  • upstreams at private/loopback addresses → run the app as a vm.
  • Non-https build.repo (paths, ssh, s3) → use the Heyo remote or an https URL.
  • vm.image_download_url, gateway, discovery → operator-only.

applb_job returning 403? Pass deployment too.

Site status is “empty” or “missing” (every request 404s)

“Missing” means the site root was never written; “empty” means it has no files. Registering a site doesn't fill it. Fix: repo_write_files then repo_deploy {repo, kind: "site", deployment: <id>}. If the site uses an artifact block, art_publish_files with deployment: <id>.

VM never becomes ready / pool stays empty
  1. Check start_command: it must background the app and return.
  2. Check the port: the app must listen on 0.0.0.0 at the deployment's vm.port.
  3. Run diagnose_vm_boot {id}. It lints the spec, boots a VM, and inspects start_command output, listening sockets and the health path. Add foreground: true to capture a crash.
  4. Check applb_deployment_jobs {id}: a failed build leaves the old image, or none.
  5. App crashing on start (missing dependency, wrong module type, unwritable path)? Fix the code and redeploy.
Build fails: “could not read Username” / authentication failed

The build cloned a private repo without a credential. Run repo_deploy again with deployment: <id>; it adds build.auth. applb_build alone fails the same way. For GitHub or another host, store a token with applb_request {method: "POST", path: "/secrets", …} and reference it in build.auth.

Logs are empty for a VM app

Install socat in the image, and don't redirect the app's stdout/stderr to a file in start_command.

Tool reference

GroupTools
Start hereheyo_guide heyo_whoami heyo_status heyo_capacity
Sandboxessandbox_create sandbox_exec sandbox_exec_start sandbox_exec_status sandbox_exec_cancel sandbox_read_file sandbox_write_file sandbox_upload sandbox_download sandbox_transfer_status sandbox_info sandbox_list sandbox_stop sandbox_start sandbox_restart sandbox_kill
Reposrepo_create repo_write_files repo_get repo_list repo_token repo_deploy
Artifactsart_publish_files art_publish art_list_tags art_get_tag art_get_manifest art_fetch art_set_public art_delete_tag
Deploymentsapplb_deploy applb_list_deployments applb_get_deployment applb_update_deployment applb_delete_deployment applb_build applb_pull applb_scale applb_spec_schema applb_deployment_jobs applb_job applb_certs
Diagnosticsdiagnose_deployment diagnose_vm_boot diagnose_empty_pool applb_metrics deployment_logs namespace_telemetry

For the full deployment spec, call applb_spec_schema.