MCP server to publish a website and get a public URL

https://chorus.host/mcp is a remote MCP server. Add it to Claude Code, Codex, Cursor or claude.ai and your agent can publish HTML, a file or a whole static site with one publish_site call. It gets back a live https://<name>.chorus.host link and a claim link. No account, no install, no API key.

Updated 1 October 2026 · For agents: /mcp.md

At a glance

Endpointhttps://chorus.host/mcp
TransportStreamable HTTP, stateless
AuthNone. Optional Authorization: Bearer chk_... publishes into your account
Toolspublish_site, get_site, get_docs
Per call4 MB of files without a key, 10 MB with one; up to 1,000 files
Sites without an accountLive for 24 hours; a claim link keeps them
Publishes per hour5 per IP address without a key, 60 per account with one
Official MCP Registry namehost.chorus/mcp
PriceFree

Add it to your client

Checked 1 October 2026. The Claude Code and Codex commands were run against this server that day; the Cursor and VS Code entries follow each client's documented config format and were not run by us.

Claude Code

claude mcp add --transport http chorus https://chorus.host/mcp

claude mcp list should show chorus: https://chorus.host/mcp (HTTP) - ✔ Connected.

Codex CLI

codex mcp add chorus --url https://chorus.host/mcp

This writes an [mcp_servers.chorus] entry with the URL to ~/.codex/config.toml. Codex's default workspace-write sandbox has no network, so approve the network request when Codex asks, or see the Codex section of the Claude Code and Codex guide.

opencode

In opencode.json:

{ "mcp": { "chorus": { "type": "remote", "url": "https://chorus.host/mcp" } } }

Cursor

In ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):

{ "mcpServers": { "chorus": { "url": "https://chorus.host/mcp" } } }

VS Code

In .vscode/mcp.json:

{ "servers": { "chorus": { "type": "http", "url": "https://chorus.host/mcp" } } }

claude.ai and Claude Desktop

Customize, then Connectors, then + and Add custom connector. Name it chorus.host and paste https://chorus.host/mcp as the URL. There's no OAuth step. The Free plan allows one custom connector.

ChatGPT

ChatGPT can only use MCP tools that write (publishing is a write) in Business and Enterprise or Edu workspaces, on the web, through developer mode (Settings, Apps, Advanced settings). On Pro, developer mode connectors can read and fetch but not write, according to OpenAI's help center on 1 October 2026. The article doesn't mention Plus, so expect the same there unless you test otherwise. On Pro or Plus, download the HTML ChatGPT made and drop it on chorus.host/html-to-url instead.

A note on shared addresses: claude.ai and ChatGPT call MCP servers from their own servers, so their requests share a small number of IP addresses. Publishing without a key is limited to 5 per hour per IP address, and that budget can run out on a shared address. If you see a rate-limit error there, add your API key as an Authorization: Bearer chk_... header (60 an hour per account).

What your agent gets

This reference is generated from the tool definitions the server registers, so it matches what tools/list returns.

publish_site: Publish website

Publish a website or any file (PDF, image, HTML, CSS/JS) to a live public HTTPS URL at <slug>.chorus.host in one call. Files keep their content type, so PDFs and images open in the browser.

ArgumentTypeRequiredWhat it is
claim_tokenstringnoThe claim_token (ctk_...) returned when the site was first published. Required to update an anonymous site.
expires_atstringnoOptional. When the site should be deleted: RFC 3339 (2026-10-08T00:00:00Z) or a duration from now (90m, 2h, 7d).
filesarray of objectyesEvery file of the site. Each call makes a new version with exactly these files; earlier versions are kept.
passwordobjectnoOptional. Put the site behind a browser login prompt (HTTP Basic Auth).
slugstringnoOptional. Subdomain to publish to (3-63 lowercase letters, digits and hyphens).
titlestringnoOptional human-readable title saved with the site.

Returns: anonymous, claim_token, claim_url, expires_at, file_count, file_url, next_steps, page_url, password_protected, slug, tell_the_user, total_bytes, updated, url, version_id, warnings.

Annotations: not destructive (earlier versions are kept).

get_site: Check site status

Check a chorus.host site: whether it is live, its URL, whether it has a password, and when it expires. With the site's claim_token (or an API key that owns the site) it also returns the file list, total size, live version and claim link.

ArgumentTypeRequiredWhat it is
claim_tokenstringnoOptional claim_token (ctk_...) of the site. Unlocks the file list and other details.
slugstringyesThe site's slug, i.e. the subdomain in <slug>.chorus.host.

Returns: can_manage, claim_url, claimed, created_at, current_version_id, expires_at, file_count, files, files_truncated, password_protected, slug, status, summary, title, total_bytes, updated_at, url.

Annotations: read-only.

get_docs: Read chorus.host docs

Return the full chorus.host documentation as Markdown (the same text as https://chorus.host/skill.md): the REST API, the beacon CLI, accounts and API keys, claiming sites, password protection, and Workers, which run server-side JavaScript at <slug>.worker.chorus.host for APIs and webhook receivers (GitHub, Stripe), including Hono apps, with no Cloudflare account needed. Read it before building a backend, when the user asks about accounts or limits, or when a task needs something publish_site can't do.

Annotations: read-only.

Try it without a client

MCP is JSON over HTTP, so curl works. This publishes one page and prints the live URL:

jq -n --rawfile html index.html \
  '{jsonrpc:"2.0",id:1,method:"tools/call",params:{name:"publish_site",arguments:{files:[{path:"index.html",content:$html}]}}}' \
  | curl -sS https://chorus.host/mcp -H 'Content-Type: application/json' \
      -H 'Accept: application/json, text/event-stream' -d @- \
  | jq -r .result.structuredContent.url

The full result has url, page_url, file_url, claim_url, claim_token, expires_at and a tell_the_user message. If you only want curl, the plain HTTP endpoint is shorter: curl -sS https://chorus.host/v1/publish -F file=@index.html.

Keep it, update it, lock it

Which MCP server should you use?

Checked 1 October 2026 from each server's tools/list and public docs. Blank cells mean we couldn't confirm the answer, not that the feature is missing.

chorus.hostShipStaticJust Publish
Publish with only the URL configuredYesYesThe deploy tool asks for an email address
Lifetime without an account24 hours3 days
Password from the toolYesYes
Sign in from cloud clientsAPI key headerOAuth
Custom domainsNoYes
Change one file without resending the siteNo, full replaceYes (update_site_file)
Pick the subdomainYes
Server-side codeWorkers, over REST or CLI

Where they're better: ShipStatic keeps anonymous sites for 3 days instead of 24 hours, signs in over OAuth and supports custom domains. Just Publish can edit one file of a live site without sending the rest. here.now has no public MCP server; its agent card says MCP isn't supported.

Want to host your own MCP server?

This page is about an MCP server that publishes websites. If you want to run your own MCP server on the web, Cloudflare's guide to remote MCP servers on Workers is the place to start.

Questions

Is there an MCP server that publishes a website and returns a public URL?

Yes. Add https://chorus.host/mcp to your MCP client. Its publish_site tool takes the files and returns a live https://<name>.chorus.host URL, plus a claim link so a person can keep the site.

Do I need an account or an API key?

No. Without one, sites stay up for 24 hours and come with a claim link. With an API key in the Authorization header, sites go into your account and don't expire.

Does it work in ChatGPT?

Publishing needs a ChatGPT Business, Enterprise or Edu workspace with developer mode, on the web. On Pro, developer mode connectors are read and fetch only (OpenAI's help center doesn't cover Plus), so on Pro or Plus drag the HTML file onto chorus.host/html-to-url instead.

How long do sites stay up?

24 hours without an account, unless someone opens the claim link and signs in. Sites in an account stay up until you delete them, or until an expires_at you set.

How big can the site be?

4 MB of files per call without a key and 10 MB with one, up to 1,000 files. Bigger sites go through publish.py, the beacon CLI or the REST API: 250 MB per file without an account, 5 GB with one.

Can the agent update the same URL later?

Yes. Call publish_site again with the same slug and the claim_token it got the first time (or with your API key for sites in your account). The URL stays the same and the old version is kept.