Documentation

What we support. How to ship it.

aft.page hosts small software at a durable *.aft.page URL. Detect the project, build if needed, upload ready files — then claim, share, and save environment secrets.

Agents: https://aft.page/docs.md · tool schemas at /mcp.md.

What we support

aft.page is a file host plus a permission layer. It does not run npm run build. You (or your agent) detect the project, build locally if needed, then upload ready files.

Kind What to ship Live
Plain HTML One file via Drop / MCP deploy hello.aft.page
Multi-file static HTML + CSS + JS share-checklist
Vite / React / Vue npm run builddist/ only vite-hello.aft.page
CRA / Rsbuild npm run buildbuild/ or dist/
Next.js static export output: 'export'out/
Next SSR / Worker OpenNext (or Worker) + upstream next-hello.aft.page

Look at package.json, vite.config.*, next.config.*, index.html. Plain HTML → upload those files. Bundler app → build, then upload the output folder only. Never upload src/, node_modules, or .next/.

Deploy

Four ways. Same result: https://{slug}.aft.page.

Drop (humans)

aft.page/drop — folder or zip. Include index.html.

README-only (no index.html): / is 404; the file is at /README.md. Same shape as a Vercel Drop of just a readme — readme-black-chi.vercel.app is that, not a web app.

Agent Plugin

npx plugins add vaibhavmule/aft.page — then ask Deploy this to aft.page. /plugins.

Agent MCP

Remote: https://mcp.aft.page/mcp

{
  "mcpServers": {
    "aft-page": { "url": "https://mcp.aft.page/mcp" }
  }
}

Ask: Deploy this to aft.page. Tool schemas: /mcp · /mcp.md. Cursor: /with/cursor/.

API

curl -X POST https://api.aft.page/v1/deploy \
  -H 'Content-Type: text/html' \
  -H 'X-Aft-Client: curl' \
  --data '<h1>Hello from aft.page</h1>'

Multi-file: JSON { "files": [{ "path", "content" }] } or multipart. Optional ?slug=vite-hello. Collision gets a suffix — never overwrites.

Logs

Owner and editors: project page → Logs, or GET /v1/sites/{slug}/logs. Document hits, errors, and failed deploys. No IP addresses. Kept 7 days.

Source

Owner, editors, and viewers: project page → Source, or GET /v1/sites/{slug}/files. File list for a deploy; click a text file to preview. Not a public URL — live *.aft.page/{path} is unchanged.

Secrets / environment

MCP does not set secrets. Claim the site first, then save env on the project page or API. Values are encrypted at rest; only names are listed.

  1. Open https://aft.page/claim?slug=…&token=… (deploy claimUrl) or Claim on the live URL.
  2. Sign in → the site appears under Projects.
  3. Secrets panel: name + value → Save. Or use the API:
# names only
curl https://api.aft.page/v1/sites/{slug}/secrets -H "Cookie: …"

curl -X PUT https://api.aft.page/v1/sites/{slug}/secrets/ANTHROPIC_API_KEY \
  -H "Content-Type: application/json" -H "Cookie: …" \
  -d '{"value":"sk-…"}'

Declare intended names in aft.json so approve-on-deploy can show them:

{
  "name": "my-app",
  "runtime": "next",
  "capabilities": {
    "secrets": ["ANTHROPIC_API_KEY"],
    "egress": ["api.anthropic.com"]
  }
}

Secrets are not baked into static HTML. A Vite SPA that needs a public API URL should bake it at build time; keep private keys in the vault for worker / next runtimes.

Custom domain

Invite-only during beta. Claim the site → project Domains → request access. Once approved, add app.example.com, then at your DNS host:

CNAME  app.example.com  →  cname.aft.page

HTTPS issues after DNS is live (progress on the same tab). Apex (example.com) needs ALIAS / ANAME / CNAME flattening to the same target. The *.aft.page URL stays. Private sign-in still uses that subdomain.

Claim, private, invite

Anonymous deploy is live immediately. Unclaimed sites stay live; they are permanently deleted after 30 days without a visit or update. Claim to keep the URL forever, make it private, invite by email, redeploy in place, roll back, or destroy. The URL stays the same.

Limits

Static worker / next
Files 200 200
Per file 10 MB 10 MB
Total 50 MB 50 MB

Always include index.html for static sites.

Examples

Source: examples/ in the aft.page repo.