Push to deploy. No CI to write.

Connect a repository once and every push builds and ships. No workflow file, no runner, no deploy key, and no token pasted into anybody’s repository secrets.

You have written this pipeline before. Probably this month.

A new project starts the same way every time. Copy a workflow file from the last one. Mint a deploy key or a scoped token. Paste it into repository secrets. Fix the cache key, fix the Node version, fix the thing that only fails in CI. Then maintain all of it for as long as the project lives.

None of that is your product. It is the tax you pay for the gap between a commit and a running container, and you pay it again per repository, per environment, per person who joins.

Here the gap is closed from our side. You install a GitHub app on the repositories you choose, your agent links one to an app, and a push is a deploy. Your repository gains no file, holds no secret, and has nothing in it that has to be kept working.

Connected once, not per project

The GitHub app is installed once against your account or organization, scoped to the repositories you pick. Linking the next project is one tool call with no setup behind it.

Nothing lands in your tree

No workflow file, no action pinned to a version you will forget to bump, no bot commits. A repository you disconnect looks exactly like one that was never connected.

Revocable from GitHub, not from us

Access comes from the app you installed and is removed in your own GitHub settings. Nothing is stored on our side that still works after you revoke it.

What a push actually does.

The same build your agent would have got from a direct deploy, from source we read ourselves instead of source it typed.

Clone, build, ship

The connected branch is cloned, built and deployed. The app’s URL, its environment variables and its databases are untouched, so a deploy changes the code and nothing else.

It shows up on GitHub

The commit gets a deployment, so the commit page, the pull request that merged it and the repository’s Environments tab all show where it went and whether it came up.

Or turn the automatic part off

Set auto_deploy: false and nothing ships until somebody asks. The link stays, so you keep deploying from the repository on demand rather than on push.

Deploy a tag or a commit

deploy_from_repo takes a ref, so a release tag or a specific SHA ships without touching the branch the app is linked to. The whole flow →

Rollbacks that survive a force push.

The detail that decides whether a deploy target is real, and the one most push-to-deploy setups get wrong.

Most systems roll back by rebuilding a commit. That works right up until the branch was force pushed, the tag moved, or the branch is gone, which is exactly the situation you are in when you urgently need a rollback.

agenthost keeps its own copy of every tree it built. Deploys from a repository join the same history as every other deploy, so list_deploys and rollback_app work unchanged afterwards, and what you roll back to is what actually shipped rather than what the branch says today.

When the conventions don't fit your repo.

The defaults are shaped for source an agent just wrote. A repository that already exists usually wants something of its own, and it says so in its own tree rather than in a dashboard.

The conventions, if they fit

Static, Node, Python and PHP, each with one entrypoint and one dependency file. No port to expose, no proxy to configure, and your node_modules, vendor, .venv and .env are excluded from the build. What each one expects →

agenthost.yaml, when they don’t

runtime, install, build and start, committed at the root. Every value is a shell command, so ./scripts/build.sh is as valid as npm run build. Multi-line blocks run with set -e, and every key is optional. The reference →

All three apply to any source, not just a repository. Inline files, a streamed tarball and a cloned repo arrive at the build as the same tree, so a committed build file is honoured whichever way the code got there.

The rest of the surface.

What you get once something is deployed, and the parts you will want before you trust it with anything.

A database per app

Provisioned and attached, with its credentials injected at run time. Its own database rather than a schema in a shared one, destroyed with the app when you delete it.

Secrets never touch the agent

There is no tool that accepts a value, deliberately. You get a link, you type it in, the container restarts. Nothing lands in a transcript or a context window. Why it is built that way →

Tokens for anything unattended

CI, cron or a script that cannot run a browser sign-in mints a long-lived token and sends it as a bearer header. Listed and revocable by id. Token reference →

Logs your agent can read

Build and runtime logs come back through the same interface, so debugging a failed deploy is a question rather than a tab. Usually with the fix attached.

No token charges from us

Your agent runs on your own subscription, so the model bill stays where it already is. agenthost prices what exists, four euros an app, not how many times you asked.

EU, without a region setting

French servers, a French operator, and no dropdown to get wrong. A published DPA that is already in force. The whole chain →

The objections, in your own words.

I don't want an AI between me and my deploys.

Then do not have one. It is an MCP server with an ordinary tool surface and a documented API, so a token and a shell script drive it exactly as well as an agent does. The agent is the convenient path, not the required one.

Where do I configure the build?

In your repository, which is where it belongs. Nothing about the build lives in a dashboard here, so there is no state on our side to drift from your tree, and no setting somebody changed six months ago that nobody can find.

What if I outgrow it?

Take it with you. Your repository is the source of truth and gains nothing agenthost-shaped beyond an optional four-key yaml file, and your data exports through the service. There is no lock-in surface to speak of, which is deliberate.

Is this production-grade?

For side projects, internal tools, client work and small services, yes, and people run those here today. Be clear-eyed about the ceiling though: there is no SLA, and restores are best effort. The full list of what we do not claim →

The rest of it.

Do you need access to all my repositories?

No. You choose which repositories the GitHub app may read when you install it, and you can change the selection later. Pick one if you like. agenthost only ever sees what you selected, and the one sign-in afterwards exists so that your repositories become readable by your agenthost account and nobody else’s.

What runtimes are supported?

Static, Node, Python and PHP. The version goes in the runtime string, as node:22 or python:3.13, in the tool call or in agenthost.yaml, and install, build and start take it a long way past the defaults. A language outside those four is not supported today. The contract for each →

Can I run staging and production from one repository?

Yes, as two apps linked to the same repository on different branches, each with its own hostname, its own environment variables and its own database. Keep the staging one invite-only and it is not on the open web at all.

How do I ship a database migration?

Run it from your build or start command, which is what the build and start keys in agenthost.yaml are for. A multi-line block runs with set -e, so a failed migration fails the deploy rather than shipping over the top of it.

Can I deploy without GitHub?

Yes, and it is the default path. Your agent can hand files over inline, or stream a tarball with begin_upload for a real project on disk so the bytes never pass through your context. Sending a large project →

How do I know a deploy actually worked?

Builds are asynchronous, so a successful call means queued rather than live. Check the status and then fetch the URL, which is what your agent should be doing before it tells you it is done. Checking a deploy →

Link a repository and push.

Ten static sites free forever with no card. An app with its database, built from your repo on every push, is four euros a month.