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 needsadminfor 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
- 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-…__*. - Check who you areCall
heyo_whoami. Note yournamespace,admin_scopeandexpires_in_secs. - Check the platformCall
heyo_statusto see which services the server reaches and any current faults. - Ask for a planNot sure how to do something? Call
heyo_guidewith your goal in plain words, or with an error message, and it returns the tools to call and in what order.
Sandboxes
A sandbox is a VM for an agent to work in: install dependencies, run a build, execute tests, then pull the results out.
- Create it
sandbox_create {name?, image?, disk_size_gb?}boots a VM from a hub image (defaultheyo/debian:latest) with a/workspacedisk, and waits until it is ready. - 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. - Run commandsShort (under ~30s):
sandbox_exec. Longer:sandbox_exec_start, then pollsandbox_exec_status {id, operation, offset}. Several can run at once. - Get results out
sandbox_read_filefor small files, orsandbox_download {id, path}for a file or a whole directory as a tar.gz URL. - Pause or finish
sandbox_stopfrees the VM but keeps/workspace;sandbox_startbrings it back.sandbox_killdeletes 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"
}
- Only
/workspacesurvives a stop. The rest of the disk resets to the image on start. - Each
sandbox_execstarts in/with a fresh shell.cdin the same command and pass variables inenv. - A sandbox stops itself after
idle_secs(default 600) with nothing running. An operation started withsandbox_exec_startkeeps 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.
- Build locally if neededFrameworks produce a
dist/orbuild/folder. Plain HTML needs no build. - Create a repo
repo_create {name: "my-site"}creates a git repo in your namespace. It is idempotent: an existing repo is reused. - Commit the files
repo_write_files {repo, files: [{path, content}], message}. Useencoding: "base64"for images and other binaries. Up to 64 MiB per commit. - Deploy
repo_deploy {repo, kind: "site", context?: "dist", spa?: true, host?}. Withouthost, the site is served at<repo>.<region domain>; the result tells you which. - 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" }
spa: true so unknown paths serve index.html and client-side routing works.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.
- Write a DockerfileInstall the app (e.g. into
/app) plussocat. Heyo uses socat to stream the app's stdout/stderr out of the VM; without it, logs never appear. - Create the repo and commit
repo_create, thenrepo_write_fileswith your source and the Dockerfile. - Deploy
repo_deploy {repo, kind: "vm", port, start_command}. It waits for the image build. - Verify
applb_get_deployment {id}andapplb_metricsshow 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 &"
}
- 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>, not127.0.0.1, and on the same port you pass torepo_deploy. - Don't redirect output to a file. Heyo captures it, and that capture is what
deployment_logsanddiagnose_vm_bootread.
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.
- Publish
art_publish_files {tag: "<namespace>/<name>:<version>", files: [...]}with file contents inline (up to 64 MiB). Already have a tarball? Useart_publish {tag, content_base64}. - Deploy
applb_deploya site whoseartifactblock is just{ref: "<tag>"}. app-lb pulls it with its own credential, so the tag can stay private. - Manage versions
art_list_tags,art_get_tag,art_get_manifest,art_fetch,art_delete_tag, andart_set_publicto make a tag publicly fetchable.
store and auth out of the artifact block. A hand-written store URL gets a 401 on the pull.Redeploying
| Deployed from | To ship a change |
|---|---|
| A repo | repo_write_files (or git push), then repo_deploy again. Or applb_build {id} for a deployment that already has a build block. |
| An artifact | art_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
| Question | Tool |
|---|---|
| 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 once | diagnose_deployment {id}: record, recent jobs and logs |
| Requests, errors, latency, logs | namespace_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:
updateblock → build from a repo or pull an artifact instead.site.root→ leave it out.upstreamsat private/loopback addresses → run the app as avm.- 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
- Check
start_command: it must background the app and return. - Check the port: the app must listen on
0.0.0.0at the deployment'svm.port. - Run
diagnose_vm_boot {id}. It lints the spec, boots a VM, and inspects start_command output, listening sockets and the health path. Addforeground: trueto capture a crash. - Check
applb_deployment_jobs {id}: a failed build leaves the old image, or none. - 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
| Group | Tools |
|---|---|
| Start here | heyo_guide heyo_whoami heyo_status heyo_capacity |
| Sandboxes | sandbox_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 |
| Repos | repo_create repo_write_files repo_get repo_list repo_token repo_deploy |
| Artifacts | art_publish_files art_publish art_list_tags art_get_tag art_get_manifest art_fetch art_set_public art_delete_tag |
| Deployments | applb_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 |
| Diagnostics | diagnose_deployment diagnose_vm_boot diagnose_empty_pool applb_metrics deployment_logs namespace_telemetry |
For the full deployment spec, call applb_spec_schema.