Deploy from CI or an unattended agent
API tokens for clients that can't open a browser — CI, cron, a background agent. How to mint one, use it and revoke it.
The normal way in is OAuth: a person signs in through the browser and their MCP client holds the session. That doesn't work for something with nobody sitting in front of it — a GitHub Actions job, a cron task, a background agent on a server. Those use a long-lived API token instead.
This page is for technical readers. If you're deploying by asking your agent, you don't need it.
Mint a token
Ask an already-connected agent:
create an agenthost API token called "ci"
Shown once
The secret appears in that result and never again — listing tokens returns metadata only. Put it straight into your secret store. If you lose it, mint a new one and revoke the old.
Use it
Send it as a bearer header on requests to the MCP endpoint:
POST https://agenthost.eu/mcp
Authorization: Bearer <token>In an MCP client config, that's whatever your client calls a static header:
{
"mcpServers": {
"agenthost": {
"url": "https://agenthost.eu/mcp",
"headers": {
"Authorization": "Bearer ${AGENTHOST_TOKEN}"
}
}
}
}A token acts as the user who minted it, on the organization it was minted in, with that person's role. It never expires — revoking is the only way to retire one.
A CI deploy, end to end
Mint the token once, by hand
From your own connected agent. Store it as a secret in your CI provider (AGENTHOST_TOKEN).
Point an agent at agenthost in the job
Any MCP client works. Give it the token as the bearer header above.
Deploy the existing app
Your app already exists, so the call is deploy_app with the service id and your project files —
not create_app, which would make a second app on a different address. Keep the service id in your
repository or CI config.
Verify, and fail the job if it didn't come up
Poll get_app until the status settles, then make a real request to the app's URL and assert on the
response. A queued build that later crashes will otherwise pass silently.
Managing tokens
| What | Ask |
|---|---|
| See what exists | "list my agenthost tokens" — label, prefix, active or revoked, and id |
| Revoke one | "revoke the token called ci" |
Revoking is immediate and permanent. Rotate by minting the replacement, deploying it, then revoking the old one.
Keeping it tight
- One token per job, labelled after the job. A shared token can't be revoked without breaking everything.
- A token has the same power as the person who made it — including deleting apps and projects. There is no scoped or read-only token.
- Never put a token in a repository, and never paste one into a chat. Your agent doesn't need to see it; the client does.
Under the hood
Only a hash of each token is stored (SHA-256 with a server-side pepper), so nobody — including us — can read one back. The same is true of OAuth tokens and sign-in codes. Access tokens from the OAuth flow live an hour and refresh silently; refresh tokens rotate on every use, and revoking either half drops the whole grant.
Tools: create_token, list_tokens, revoke_token. Full auth model:
Signing in.
Take something down
Deleting an app or a project, what goes with it, and how to get your files out first.
How deploying works
The contract between your source and agenthost — how a deploy runs, how the runtime is chosen, the one entrypoint each runtime looks for, and how to confirm a deploy actually serves. Read this before your first deploy.