Skip to main content
AGO Apps hosts small apps for your workspace: an internal web page for your team, or an API that your agents call. You write them with Claude, Codex or any coding agent; AGO builds and deploys every change, signs your users in and authenticates every call. Your code never handles a password, a token or a secret.
AGO Apps is enabled per workspace. Contact AGO to turn it on. For now, only staff members of the workspace can open an app in their browser.
This page describes what actually happens to your code, so that you, and the coding agent you work with, know what works and what does not.

What you can build

  • An internal web page. It is served at https://<app>.<workspace>.agoapps.com. Only members of your workspace can open it, after signing in with their AGO account.
  • An API for your agents. An HTTP Request Tool or an API Data Source that calls the app is authenticated automatically, and the app knows which user the agent is acting for.
An app is a single Cloudflare Worker: one fetch function that receives a request and returns a response. It has no database and no secrets. Each request may use up to 30 seconds of CPU and call 1,000 other URLs. That covers calculators, formatters, lookups over external APIs, forms, dashboards that combine several APIs, document generation, and glue between your agents and the services they need.

Create an app

From Claude or any MCP client

  1. Connect your MCP client to AGO and grant the Apps Write scope.
  2. Ask, for example: “Create an AGO app called price-check that returns the price including VAT for an amount and a country.”
Claude uses these tools:

From Claude Code, Codex or git

Get the remote and a token with get_app_git_credentials, then work like with any repository:

What a new app contains

Keep AGENTS.md in the repository: it is what makes the coding agent write code that runs here.

What happens when you commit

Every commit on main goes through these steps, usually in under a minute:
  1. The commit is checked out in an isolated build container. It has no AGO or Cloudflare credentials.
  2. If package.json exists, the dependencies are installed, without running install scripts (postinstall and others). With a committed package-lock.json, the exact versions it lists are installed; without one, the newest versions that package.json allows.
  3. src/index.ts, or src/index.js, is bundled with esbuild into a single file, with every npm dependency included.
  4. If package.json has a test script, npm test runs.
  5. The bundle goes live, but only if its commit is still the latest one on main. It gets the next version number: 1, 2, 3…
If any step fails, nothing changes: the previous version keeps answering. If two commits are built at the same time and the older one finishes last, the older one is marked superseded and is not deployed. Commits only build from main; other branches are stored but not deployed.

Check which version is live

Every deployed app answers GET /_ago/version, before your own code runs:
get_app returns the same information as live, and Admin › Developer › Apps marks the deployment the app is serving. A change is live once the commit served equals the commit you made. Right after a deployment, some requests can still reach the previous version for a few seconds.

How a request reaches your app

Every request first goes through AGO’s gateway, which:
  1. Checks who is calling. A browser needs an AGO session for this app; an agent call needs a token signed by AGO for this app.
  2. Removes the Authorization header, AGO’s session cookie and any X-Ago-* header sent by the client.
  3. Adds the headers below, then passes the request to your code.
Because AGO already authenticated the request, your app must not ask for a password, check a token, or store credentials. Trust these headers: a client cannot forge them. The first time someone opens the app, the browser goes to your AGO workspace and comes back signed in, without a consent screen. The session lasts one hour. After that, opening a page signs the user in again, usually without them noticing, while a fetch from the page receives 401 with {"error": "login_required"}: reload the page when that happens.

Code reference

The contract

The default export must have a fetch method that returns a Response. Route on new URL(request.url).pathname and request.method.

What is available

  • Web-standard APIs: fetch, Request, Response, Headers, URL, URLSearchParams, crypto.subtle, crypto.randomUUID, TextEncoder, TextDecoder, atob, btoa.
  • npm packages that only use those APIs, for example zod or date-fns.

What is not available

  • Node.js built-ins: fs, path, Buffer, process, child_process, net. Packages that need them fail at build or at run time.
  • A filesystem, a database or any storage. Global variables may survive between requests but can be reset at any time: never use them to keep data.
  • Environment variables and secrets: there are none. An API key in the code would be readable by anyone who can read the repository; keep secrets in AGO instead and let your agent tool pass the data the app needs.

Limits

Browser rules

  • POST, PUT, DELETE and WebSocket requests must come from the app’s own pages. A request sent from another site, including another app, gets 403 with {"error": "cross_origin_request"}.
  • Cookies set by the app must be host-only. A Set-Cookie header with a Domain attribute is removed.

Examples

A JSON API with validation

GET /vat?amount=100&country=FR returns {"amount":100,"rate":0.2,"total":120}.

A page that posts to its own API

The fetch comes from the app’s own page, so the gateway accepts the POST. The app has no storage: to keep notes, send them to a service that stores them, as in the next example.

Calling an external API

Each fetch counts toward the 1,000 calls per request. Only call APIs that need no secret.

Using an npm package

List the package in package.json; the build installs it.
The build bundles zod into the app.
If you test the app on your computer, commit the package-lock.json that npm install creates: the build then installs exactly the versions you tested. Without it, a later build may pick up newer versions. Leave it out only if you edit the app without running npm, for example from Claude on the web.
To run tests at build time, add a test script and its dev dependencies to package.json.

Calling your app from an agent

  1. Open Admin › Developer › Apps and copy the app’s API endpoint, for example https://api.agoapps.com/acme/price-check.
  2. Create an HTTP Request Tool whose URL is that endpoint followed by a path, such as https://api.agoapps.com/acme/price-check/vat, or use it in an API Data Source.
  3. Leave the authentication empty. AGO signs each call with a token valid 60 seconds for this app only, and adds X-Ago-User-Email when the agent acts for a user.
Only apps of your own workspace are signed this way.

Monitor and troubleshoot

Admin › Developer › Apps lists every app with its web URL, its API endpoint and its last deployment. Open an app to see its deployment history, build errors and logs, and its source code. The same information is available to Claude through get_app.

Security model

  • Each app runs isolated from every other app, and the build container never holds credentials.
  • The workspace an app belongs to comes from AGO’s authentication, never from the request or the code.
  • Users sign in through AGO; agent calls carry a token signed by AGO and valid 60 seconds for a single app. The app’s code never sees either.
  • AGO can turn AGO Apps off for a workspace at any time; the apps then stop answering.