aft.page

Deploy HTML or dist/ to a live HTTPS URL. No account. Drop, MCP, or CLI.

Should I use this

Quality & Safety

A
Description quality
88%
Schema completeness
83%
Naming quality
80%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Findings (2)

  • LOWTool 'aft_rollback' description lacks action verbin aft_rollback
  • LOWTool 'aft_health' description lacks action verbin aft_health

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~948Tokens (tool definitions)
~1.3 KBTypical response size
Moderate attention impact (0.74% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

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

Remote endpoints

https://mcp.aft.page/mcpstreamable-http

What it can do

Tool inventory

Tools (5)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟡deploy(html, files, preferred_slug, edit_token, expires)

Publish to a live URL. Pass html (one page) OR files (built site). Plain HTML → html. Vite/React → npm run build, then files from dist/. Next static export → files from out/. Always include index.html. Never upload src/, node_modules, or .next/. First hit: preferred_slug from aft.json (include aft.json in files). Later: same slug + edit_token from .aft/state.json. Limits: 500 files, 25MB each, 100MB total.

Input Schema

{
  "type": "object",
  "properties": {
    "html": {
      "description": "One HTML document. Ignored if files is set.",
      "type": "string",
      "minLength": 1
    },
    "files": {
      "minItems": 1,
      "maxItems": 500,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "minLength": 1,
            "description": "Relative path, e.g. index.html"
          },
          "content": {
            "type": "string",
            "description": "UTF-8 text (or base64 if encoding=base64)"
          },
          "encoding": {
            "type": "string",
            "enum": [
              "utf8",
              "base64"
            ]
          }
        },
        "required": [
          "path",
          "content"
        ]
      }
    },
    "preferred_slug": {
      "description": "aft.json slug. Required with edit_token.",
      "type": "string",
      "pattern": "^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$"
    },
    "edit_token": {
      "type": "string",
      "minLength": 1,
      "description": "From first deploy / .aft/state.json. Required to update or rollback the same URL."
    },
    "expires": {
      "type": "string",
      "pattern": "^\\d+(s|m|h|d)?$",
      "description": "Optional quick-view expiry, e.g. \"1h\", \"24h\", \"90s\", \"7d\". Anonymous (unclaimed) deploys only — the link 404s after this."
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟡deploy_repo(url)

Same engine as aft.page/run: public GitHub URL → detect → build → live URL. Static is instant; Vite and Next.js build in the background (polls until live or failed). Private repos are refused. For a local project dir, use hosted CLI aft deploy instead.

Input Schema

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "minLength": 3,
      "description": "GitHub URL or owner/repo, e.g. https://github.com/mdn/beginner-html-site"
    }
  },
  "required": [
    "url"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟡aft_deploys(slug, edit_token)

List rollback-able deploys for a slug. Needs edit_token from .aft/state.json (or the first deploy). Same history the project UI shows after claim.

Input Schema

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$",
      "description": "Site slug from aft.json or .aft/state.json"
    },
    "edit_token": {
      "type": "string",
      "minLength": 1,
      "description": "From first deploy / .aft/state.json. Required to update or rollback the same URL."
    }
  },
  "required": [
    "slug",
    "edit_token"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟡aft_rollback(slug, edit_token, deploy_id)

Point the live slug at a prior deployId from aft_deploys. Same URL. Needs edit_token from .aft/state.json. Claim not required.

Input Schema

{
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$",
      "description": "Site slug from aft.json or .aft/state.json"
    },
    "edit_token": {
      "type": "string",
      "minLength": 1,
      "description": "From first deploy / .aft/state.json. Required to update or rollback the same URL."
    },
    "deploy_id": {
      "type": "string",
      "minLength": 1,
      "description": "Prior deployId from aft_deploys"
    }
  },
  "required": [
    "slug",
    "edit_token",
    "deploy_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟡aft_health

Ping the aft.page deploy API.

Input Schema

{
  "type": "object",
  "properties": {},
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded5 tools
verifiedversion not recorded5 tools