DEV Community

Cover image for Your AI agent deployed the app. Did it tell you the link expires?
dino
dino

Posted on

Your AI agent deployed the app. Did it tell you the link expires?

Note: I'm the maker of openpouch. This post is about an agent-UX lesson we learned from our first real user — honest limits included. Feedback very welcome.

Our first real user never opened our website. He talks to his coding agent; the agent deploys with openpouch; he gets a link. Exactly how it should work — the agent is the only UI.

Three days later his app was gone.

Nothing crashed. Anonymous previews expire after 72 hours — that's the free tier, and it's documented everywhere an agent looks: the CLI result, the JSON, the docs, llms.txt. The agent knew. It just never told him. When the deploy succeeded, the agent summarized the exciting part ("Your app is live! 🎉 Here's the link") and dropped the boring part (expiry date, how to keep it). The human learned about the 72-hour rule the hard way: by watching his app 404.

He told us (translated): "The AI has to actively spit that out at me — how long it's valid, and what my options are. Otherwise how would I ever know?"

He's right. And the fix turned out to be an interesting API-design lesson for anyone building tools that agents — not humans — consume.

The relay gap

When a human uses your CLI, your output IS the UI. When an agent uses your CLI, your output is raw material for a summary you don't control. Agents compress. They keep what looks like the point (the URL) and cut what looks like boilerplate (the caveats). We had tested this across several coding agents: the expiry info was reliably read — and unreliably relayed.

You can't fix that with more docs. The agent already read the docs. You have to design the response so that relaying is the path of least resistance.

The fix: a field whose name is the instruction

Since openpouch@0.3.3, a healthy deploy result carries a top-level field called tellYourUser:

{
  "ok": true,
  "url": "https://sunny-otter-x4kq.openpouch.sh",
  "healthStatus": "healthy",
  "deployment": { "expiresAt": "2026-07-19T09:12:44.000Z", "ownership": "anonymous" },
  "tellYourUser": "Your app is live at https://sunny-otter-x4kq.openpouch.sh. It's a free preview and expires on Sat, Jul 19, 2026 (UTC). To keep it: save it to a free account, redeploy any time, or upgrade for apps that stay up while they're used (paid plans from $15/month — openpouch.dev/pricing). Doing nothing is fine too — it just expires."
}
Enter fullscreen mode Exit fullscreen mode

Design decisions that matter more than they look:

  1. The field name is imperative. Not notice, not meta.expirytellYourUser. An agent deciding what to do with this field has the answer in the key itself. This is the whole trick: schema as instruction.
  2. It's pre-written, ready to relay. No assembly required. An agent can paste it verbatim into its summary — least-resistance path. Plain language, no jargon, exact date instead of "72 hours" (a human shouldn't have to do date math).
  3. It only appears on healthy deploys. A degraded app must not produce a cheerful hand-off block — absence is also a signal.
  4. It never contains the claim link. The claim URL is a capability token (whoever has it can take the preview). It stays in a private local file; the hand-off text describes the ways to keep the app, not the secret.
  5. All options, including "do nothing". Expiry pressure without an exit is a dark pattern. "Doing nothing is fine too" is in there on purpose — the user asked for the options "so I can think about it", not for a countdown.

Days after shipping it, the same user's agent told him the exact expiry date, unprompted, twice. His review: "the warning is still there … better."

The generalizable lesson

If agents consume your API, assume three things:

  • Your response is a hand-off, not a display. Somewhere behind the agent is a human who will get a summary of your output. Decide what must survive that summary, and package it.
  • Name fields like instructions when you need behavior. tellYourUser, nextCommands, suggestedCommand outperform metadata, info, details. Agents act on affordances.
  • Machine-truth next to human-truth. The same result carries deployment.expiresAt (ISO, for logic) and the friendly sentence (for relaying). Never make an agent choose between parsing and explaining.

None of this is openpouch-specific. If you're building a payments CLI, a migration tool, a cron service — anything an agent operates on a human's behalf — the relay gap applies to you.

Try it

The whole thing works without an account (that's the point):

npx openpouch deploy . --json
Enter fullscreen mode Exit fullscreen mode

Or as native MCP tools in Claude Code (every capability typed, deliberately no approve — production stays human-gated):

claude mcp add openpouch -- npx -y @openpouch/mcp
Enter fullscreen mode Exit fullscreen mode

The relay lesson kept paying off, by the way: the newest fields follow the same pattern. deploy --app <name> gives an app one stable URL across all future redeploys — and the result says urlStability: "stable" so the agent can tell its user "the link you shared keeps working" instead of guessing. data push/data pull move real files in and out of an app's persistent volume, which turns "migrate my app and keep the data" into something an agent can genuinely finish.

Honest limits, current as of July 2026: Node/static only (no Python runtime yet), no custom domains yet, anonymous previews expire after 72h (accounts keep apps alive while they're used; stable-URL apps and persistent volumes are account features). Everything is open source (Apache-2.0): https://github.com/openpouch/openpouch — and the agent-facing entry point is https://openpouch.dev/llms.txt.

What would you put in tellYourUser? And what's the field you wish agent-facing tools shipped?

Top comments (0)