Publish a webpage to a live URL, straight from your AI.

Yapp turns "build me a page and publish it" into a live URL.

Community: Submitted by a user or imported; check the owner before granting accessOnlineNo sign-inGlobalFreeCan modify data

What it can do

  • Publish Page: Publish an HTML web page to yapp.page and get a live shareable URL. (To host an existing PDF, image, or ZIP file AS-IS — like a manual upload — use `publish_file` instead; do NOT convert
  • Publish File: Publish a FILE as-is to yapp.page — a PDF, image, or ZIP — and get a live shareable URL. This hosts the REAL file exactly like uploading it in the browser: a PDF gets a clean PDF viewer
  • List My Pages: List all pages owned by the current authenticated user. Returns each page with id (slug), name, url, views, expiresAt, hasForm, submission count, and demo flag. Use this when the user a

What data it sees

Do you need an account

No: the server works without sign-in

Yapp turns "build me a page and publish it" into a live URL. Connect once (browser OAuth, or a token for terminal clients) and your AI can publish a webpage from HTML, or host a PDF, image, or ZIP exactly as-is to a public .yapp.page URL in seconds, then update, password-protect, set expiry, attach a custom domain, or read form submissions, all by asking. Free to start; no local install.

Tools (15): publish_page, publish_file, update_page, delete_page, get_page_stats, list_my_pages, rename_page, change_page_slug, set_page_expiry, set_page_password, list_submissions, add_custom_domain, list_custom_domains, check_custom_domain, remove_custom_domain.

How to connect

How to connect Publish a webpage to a live URL, straight from your AI. to Claude

The server address to paste into Claude settings:

https://page--yapp.run.tools

  1. Open Claude (claude.ai or the desktop app).
  2. Go to Settings → Connectors.
  3. Click Add custom connector.
  4. Paste the server address copied below into Remote MCP server URL and click Add.
  5. In a chat, click + → Connectors and switch the new connector on.

Custom connectors are available on Free, Pro, Max, Team and Enterprise plans (Free is limited to one). On Team and Enterprise an organization Owner adds the connector first under Organization settings → Connectors.

Authorization

After you click Add, a sign-in window for the service opens. Sign in with your own account and approve access. Claude never sees your password.

How to connect Publish a webpage to a live URL, straight from your AI. to ChatGPT

The server address to paste into ChatGPT settings:

https://page--yapp.run.tools

  1. Open ChatGPT in a browser (chatgpt.com). A Plus, Pro, Business, Enterprise or Edu plan is required.
  2. Turn on developer mode once: Settings → Apps → Advanced settings → Developer mode.
  3. Open Settings → Connectors and click Create.
  4. Fill in the form: Name (anything), Description (one line about what the service does), MCP server URL (copy it below).
  5. Under Authentication choose OAuth if the service requires sign-in, otherwise None. Click Create.
  6. In a new chat open + → Apps/Connectors and enable the connector.

OpenAI has renamed this section before (Connectors → Apps/Plugins). If the label differs, search settings for "developer mode". On Business/Enterprise workspaces an admin must allow custom connectors first.

Authorization

On first use ChatGPT opens the service's sign-in window. Sign in and approve access.

How to connect Publish a webpage to a live URL, straight from your AI. to Cursor

The server address to paste into Cursor settings:

https://page--yapp.run.tools

Fastest: click Open in Cursor below and confirm the prompt.

Manually:

  1. In Cursor open Settings → Cursor Settings → MCP and click Add new global MCP server.
  2. Paste the JSON copied below into ~/.cursor/mcp.json (per project: .cursor/mcp.json in the repo root).
  3. Save the file. The server appears in the MCP list; authorize it there if asked.

Authorization

If the service needs sign-in, an authorize button appears next to the server in the MCP list.

Server tool list (15)

Raw names from tools/list. Only developers need these.

publish_pagePublish an HTML web page to yapp.page and get a live shareable URL. (To host an existing PDF, image, or ZIP file AS-IS — like a manual upload — use `publish_file` instead; do NOT convert a PDF into HTML.) LARGE FILES: if the HTML document is big (roughly >100 KB, or it contains a long minified array/blob), DO NOT paste it inline as `html` — it will be truncated/corrupted because the content has to be reproduced as model output. Instead host the file at a public https URL and pass `htmlUrl` — yapp downloads the document itself, byte-for-byte. Use `html` only for small pages. ATTACHED / UN-EMBEDDABLE FILES: if the user attached a file (or it is too large to reproduce) and you do NOT have a public URL for it, call publish_page with NO `html` and NO `htmlUrl`. You get back an `uploadUrl` — share it with the user so they drop the file in their browser. This is the reliable path for any file you cannot pass inline. BUNDLING ASSETS (images, CSS, JS, fonts): pass `assets` — an array where each entry has a `name` (the relative filename inside the page) plus either `base64` (raw bytes of the file) OR `url` (yapp.page will fetch and bundle for you). Reference each asset from your HTML by its `name`. EXAMPLES # Single HTML page publish_page({ html: "<h1>Hello</h1>" }) # Page with one inline image (you have the bytes) publish_page({ html: '<h1>Hi</h1><img src="hero.jpg">', assets: [{ name: "hero.jpg", base64: "<base64 bytes of the JPG>" }] }) # Page with multiple images + a stylesheet (relative paths preserved) publish_page({ html: '<link rel="stylesheet" href="style.css"><img src="img/logo.png"><img src="img/hero.jpg">', assets: [ { name: "style.css", base64: "..." }, { name: "img/logo.png", base64: "..." }, { name: "img/hero.jpg", base64: "..." } ] }) # Page that uses an image already hosted somewhere — yapp will fetch it publish_page({ html: '<img src="hero.jpg" style="width:100%">', assets: [{ name: "hero.jpg", url: "https://picsum.photos/seed/y/1200/800" }] }) Each asset name must be a safe relative path (letters/digits/dot/dash/underscore/slash, no ".."). FORMS — IMPORTANT: yapp.page auto-captures any `<form>` in your HTML. You DO NOT need Formspree, Netlify Forms, or any external service. Just write a normal HTML form: <form> <input name="email" type="email" required> <textarea name="message"></textarea> <button>Send</button> </form> No `action` attribute needed. yapp.page intercepts the submission, stores it in the database, and the owner sees submissions at /messages/<page-id> in their dashboard. Field names you choose become JSON keys. Max 16 KB per submission. Use the `list_submissions` tool later to read entries. OWNERSHIP: Pages you publish via MCP are owned by your account — you can `update_page`, `delete_page`, and `list_submissions` for them without an editKey.
publish_filePublish a FILE as-is to yapp.page — a PDF, image, or ZIP — and get a live shareable URL. This hosts the REAL file exactly like uploading it in the browser: a PDF gets a clean PDF viewer (with a download button), an image gets an image viewer, and a ZIP becomes a hosted website (if it contains index.html) or a download page. Use this whenever the user gives you an EXISTING file to host — do NOT rebuild a PDF as HTML; publish the actual file. Provide the file ONE of two ways: • `fileUrl` — a public https URL to the file. yapp downloads it byte-for-byte (reliable for any size). • `fileBase64` + `filename` — the raw bytes base64-encoded, for small/medium files you already have. (Large files become unreliable as model output — prefer `fileUrl`.) If you have NEITHER (e.g. a large chat attachment with no URL), call publish_file with no `fileUrl`/`fileBase64` to get a one-time browser upload link to share with the user. Supported: .pdf, .zip, and images (.png .jpg .jpeg .gif .webp .avif). The filename extension decides how the file is hosted. To build a web PAGE from HTML you write, use `publish_page` instead. OWNERSHIP: files you publish are owned by your account — update/delete them like any page.
list_my_pagesList all pages owned by the current authenticated user. Returns each page with id (slug), name, url, views, expiresAt, hasForm, submission count, and demo flag. Use this when the user asks "what pages do I have", "show me my pages", or to find a page id when they refer to one by name.
update_pageReplace the entire HTML content of a published page, keeping the same URL. This overwrites the existing content (the previous version is not recoverable), so confirm with the user before overwriting. Only the page owner can call this without an editKey.
rename_pageChange the friendly display name of a page (what shows in dashboards). Does NOT change the URL — use `change_page_slug` for that. Safe and reversible (just call again to set a new name).
change_page_slugChange a page's URL slug. The page moves from <old-id>.<apex> to <new-slug>.<apex>, and the old URL stops working (anyone who has it gets a 404). Confirm with the user before changing it, and share the new URL afterward. To change only the display name without affecting the URL, use `rename_page` instead.
set_page_expiryChange when a page auto-deletes. Pass `days` (e.g. 7, 30, 90) for relative expiry, or `forever` to disable auto-delete entirely. If shortening the expiry significantly (e.g. from "forever" to "1 day"), confirm with the user first — the page will delete sooner than they may expect.
set_page_passwordAdd, change, or remove a view password on an existing page — at any time, not just at publish. Pass `password` to require visitors to enter it before they can view the page; pass `remove: true` to take the page public again. Changing the password immediately logs out anyone who unlocked it with the old one. Note: this is a single shared password (good for casual gating, staging previews, soft-launches), not per-visitor accounts. Password protection requires the Pro plan. Only the page owner can call this without an editKey.
delete_pagePermanently delete a published page. The URL stops working and any form submissions are removed; this cannot be undone, so always confirm with the user first. If they are unsure, suggest `set_page_expiry { days: 1 }` instead, which lets the page expire naturally.
get_page_statsGet views, daily traffic, referrers and expiry info for a published page.
list_submissionsRead form submissions captured from a published page. yapp.page auto-captures any `<form>` on a page (no action attribute needed) and stores submissions in the database, ordered newest first. Use this to retrieve email signups, contact form entries, RSVPs, etc. Only the page owner (you, when publishing via MCP) and admins can read submissions. Returns up to `limit` entries (default 50, max 200).
add_custom_domainAttach a custom domain (e.g. example.com) to a published page. Pro / Team plans only. Either the bare apex or the www form is accepted — we always store the www form, and the apex is handled implicitly by a redirector (visitors typing example.com get 301-redirected to https://www.example.com). Returns the two DNS records the user must add at their registrar (one CNAME for www, one A record for the apex). After they paste those records, call `check_custom_domain` to poll status until `ssl_status` becomes "active" (usually a few minutes).
list_custom_domainsList all custom domains attached to pages you own. Returns hostname, status, SSL status, the page id each domain points to, and the DNS records needed (still useful after the fact in case the user needs to migrate registrars).
check_custom_domainForce a fresh poll of a custom domain's status with Cloudflare. Use this after the user has added the DNS records to confirm propagation + cert issuance. Status progresses: pending → dns_verified → ssl_active. Returns updated status fields.
remove_custom_domainDetach a custom domain from its page. The www hostname stops serving the page and the apex redirect stops responding for it. The user's DNS records become harmless orphans they can leave or remove. Confirm with the user before detaching.