Skip to main content

Agent integration

Give your coding agent its own window onto AppHaven. With the apphaven CLI and the AppHaven skill installed, an agent working in your repository can answer for itself: is the app deployed, on what URL, did the build succeed, why did it crash, what is it logging right now. It can also check apphaven.yaml against the platform's validation before anything is pushed.

The CLI inspects your app and submits configuration proposals for human review. It cannot approve or apply settings, deploy, restart, or read secret values. It can withdraw its user's own CLI submissions. Deploys keep following your configured Git push policy.

The fast path: install the plugin (step 1) and ask your agent to "set up AppHaven access". The skill walks it through installing the CLI and starting the login; your only step is approving the request in your browser. Steps 2 and 3 are the manual equivalent.

1. Teach your agent​

Claude Code: install the AppHaven plugin from the marketplace.

/plugin marketplace add apphaven-eu/claude-plugins
/plugin install apphaven

The plugin ships the skill: what the CLI can do, how to read build and runtime logs, how to author apphaven.yaml, and where these docs live. Updates arrive through the marketplace.

Codex and other agents: paste this block into the instructions file your agent reads (AGENTS.md or equivalent). Keep the markers so you can replace the block when it changes.

<!-- apphaven:begin -->
## AppHaven (this app's hosting platform)
- This repo deploys on AppHaven. Pushing the production branch deploys production. Pushing a
branch that matches the app's preview pattern (default `preview/*`) deploys it as a preview
on its own URL — the branch name is the deploy trigger. `apphaven app <name>` shows the
app's actual `Auto-deploy:` setting; check it before assuming.
- Preview loop: push a matching branch, `apphaven status <app> --wait`, hand the human the
preview URL (they sign in; you cannot fetch the protected page yourself). If no deployment
appears, `apphaven events <app>` says why: "Preview limit reached" means the human must
delete an old preview in the console first (nothing is evicted automatically), then push
again. Previews are not backed up; deleting the branch deletes the preview and its data;
30 days idle stops a preview (data kept, next push resumes it).
- The `apphaven` CLI inspects apps and submits changes for human review. Useful commands
(all support --json; `apphaven <cmd> --help` is authoritative):
- `apphaven status <app>`: deployment phase, branch, URL
- `apphaven build-log <app>`: latest build log (failures are at the tail)
- `apphaven crash-log <app>`: what to read when a deployment is Failed
- `apphaven logs <app> --service <svc>`: container output
- `apphaven variables <app>`: config names (secret values are never shown)
- `apphaven vulns <app>`: security scan findings — package, installed version,
and "update to <version>" when a fix is released; bump the dependency (or the
Dockerfile base image) and push, the next build is re-scanned automatically
- `apphaven validate`: validate apphaven.yaml before pushing
- Debugging order: status, then build-log (build failed), then crash-log
(deploy failed), then logs (running but misbehaving), then variables
(missing config).
- Submit configuration proposals with `apphaven proposals create <app> --file changes.json --open`.
Each item needs a stable id, type, value and reason. Read current settings and pending proposals
first. The CLI generates a request ID; retain it and reuse `--request-id <printed-request-id>`
after a timeout or uncertain result. Never invent random IDs or create duplicate retry batches.
- Give the human the review URL. Only humans approve in the console, with the same permissions
as manual edits: developers can approve deployment policy; administrators can also approve
access mode and public paths. Never approve via browser automation or direct console requests.
- Read outcomes using `apphaven proposals show <app> <proposal-id> --json`. Unselected items stay
pending. Respect declines; do not repeat a declined request under a different ID.
- Repository recommendations use `proposals` in apphaven.yaml with id/type/value/reason. Preserve
IDs when editing. Only the configured production branch (usually main) is imported. Reasons
and formatting do not reset decisions; changed operation/value creates a new version. Removing
an item does not undo accepted settings. Do not duplicate recommendations via CLI and manifest.
- `apphaven proposals withdraw <app> <proposal-id>` cancels pending items only in CLI batches
submitted by the same subject. Use repeated `--item <id>` (the item id from the batch file) for a subset. Other users' batches
and manifest recommendations require an authorized human in the console, even for admin tokens.
- Public-path and access-mode approval saves settings; each branch must deploy before they take
effect. A login redirect before that is expected. Explain how public endpoints authenticate callers.
- The CLI cannot apply settings, deploy, restart, or reveal secrets. Deploys follow Git push policy
or human console action. If login is required, run `apphaven login` and leave browser consent to
the human. Never echo credentials. Proposal guide: https://docs.apphaven.eu/proposals.
- apphaven.yaml is strictly validated; unknown fields are errors. Reference:
https://docs.apphaven.eu/reference/manifest (full docs index for agents:
https://docs.apphaven.eu/llms.txt)
<!-- apphaven:end -->

2. Install the CLI​

One line, no dependencies: the CLI is a single static binary.

# Linux, macOS, and WSL
curl -fsSL https://raw.githubusercontent.com/apphaven-eu/cli/main/install.sh | sh
# Windows (PowerShell)
irm https://raw.githubusercontent.com/apphaven-eu/cli/main/install.ps1 | iex

Verify with apphaven version. Your agent can run the installer for you; its normal command-approval flow is your consent gate.

When a newer CLI is available, any command prints a one-line notice on stderr (at most once a day; command output on stdout is never touched, so --json pipelines are safe). Rerun the installer to update. Set APPHAVEN_NO_UPDATE_NOTIFY=1 to silence the notice, for example in CI.

3. Log in​

apphaven login

Your browser opens on auth.apphaven.eu and asks you to approve read access and proposal submission. The CLI can submit proposed settings and withdraw your own CLI requests; it cannot approve or apply settings. Existing read-only grants stay read-only until you log in again and approve the expanded access. Credentials stay in your user profile (~/.config/apphaven/, or %APPDATA%\apphaven on Windows) and refresh automatically.

It is safe to let an agent run apphaven login: the approval happens in your browser, and credentials never appear in the command's output, so there is nothing for the agent to see or echo.

You stay in control afterwards: the CLI access page in your account on auth.apphaven.eu lists every active CLI login with its last use, and one click revokes it. apphaven logout does the same from the terminal.

4. What the agent can (and cannot) do​

Can readCan never do
Projects and applications you are a member ofDeploy, stop, or restart anything
Deployment status, branches, and URLsCreate, change, or delete applications
Build logs, crash reports, container outputChange variables or any configuration
Variable names (secret values stay masked)Read secret values
The activity timelineAct on projects you are not a member of
Submit proposals and withdraw its own CLI requestsApprove or apply proposed settings
Vulnerability findings and the inventory behind themChange the access mode or public paths

apphaven vulns <app> is worth pointing an agent at deliberately: it prints the affected package, the version you run, and the version that fixes it, which is everything needed to raise a dependency and push. Building with AI agents covers that loop.

Reads follow your project membership. Revoking the grant (or losing membership) cuts the agent off at the next refresh.

5. Writing apphaven.yaml with an agent​

Two tools keep a generated manifest honest:

  • apphaven validate checks workload and proposal authoring rules. Invalid recommendations appear as validation/import errors but do not block an otherwise valid workload deployment.

  • The JSON Schema gives editors and agents inline checking as the file is written. Add one comment line at the top of apphaven.yaml:

    # yaml-language-server: $schema=https://docs.apphaven.eu/schemas/apphaven.schema.json

The schema checks structure; apphaven validate is the authority. It also catches what a schema cannot, like dependency cycles or a ${...} reference to a service that doesn't exist. The manifest reference documents every field.

For agents that read documentation directly: https://docs.apphaven.eu/llms.txt is an index of every page on this site, and llms-full.txt is the whole documentation in one file.

6. Suggesting a public path​

Use a public_path.add proposal, with an explanation of how the endpoint authenticates callers. The CLI submits a batch and opens its review URL; the administrator decides in the app's Proposals section. For repository-carried recommendations use the proposals manifest section, which is imported only from the production branch. auth.public_paths remains a compatibility input.

After approval, the exemption takes effect on each branch's next deployment. Until then, a login redirect is expected. Requests to an exempt path carry no AppHaven identity header; your app must validate signatures, API keys, or other credentials itself.

Troubleshooting​

  • Not logged in. Run "apphaven login". Exactly that; the grant may have been revoked or expired after long disuse.
  • The browser never reaches the terminal (firewall, SSH box, container): run apphaven login --manual, open the printed URL on any device, and paste the code the approval page shows you back into the terminal.
  • 403: you are not a member of that project, or the grant was revoked.
  • 429: the CLI is rate-limited per user; agents should respect the Retry-After header (apphaven status --wait and logs --follow do this automatically).
  • "ambiguous app name": two apps share a name across your projects; pass --project.