Quickstart: MCP Server
Let any MCP-compatible agent (Claude Desktop, Claude Code, etc.) publish the sites it generates straight to live hosting, provision custom domains for them, and send transactional email — in under 5 minutes.
1. Get a Platform API Key
Sign up at thin.host, then open Email & API → Settings in your dashboard to create an API key (one per app or agent — each can be revoked on its own). For testing, you can use the free tier (3 domains, 100 API calls/day).
Sending email (the send_email tool) needs a separate, founder-approved access step beyond the API key. See Get access to email.
2. Connect an agent
Three ways in, all exposing the same tools. The hosted endpoint is the zero-install path and the one to start with.
A. Hosted endpoint (no install)
The MCP server runs at https://thin.host/mcp. Authenticate with your API key as a bearer token, or sign in through OAuth — clients that support it (claude.ai custom connectors, Claude Desktop connectors, Claude Code) discover the OAuth flow automatically and show a thin.host consent page.
# Claude Code, with an API key
claude mcp add --transport http thin-host https://thin.host/mcp \
--header "Authorization: Bearer th_live_your_key"
# Claude Code, with OAuth (a browser window asks you to allow the connection)
claude mcp add --transport http thin-host https://thin.host/mcp
claude.ai / Claude Desktop: Settings → Connectors → Add custom connector → URL https://thin.host/mcp. You'll be asked to sign in to thin.host and allow access.
The hosted server cannot read your disk, so it publishes from a URL (publish_website_from_url / update_website_from_url — a .zip of the site or a single HTML page). If you connected with an API key rather than OAuth, the agent can also upload a zip straight to the REST API with that key: curl -F file=@site.zip -F title="My Docs" https://thin.host/v1/websites/archive -H "Authorization: Bearer th_live_…".
B. Local server via uvx (reads your files)
Runs the same server on your machine so publish_website can read a local folder or build directory directly — no zipping. Needs uv.
claude mcp add thin-host \
-e THINHOST_API_URL=https://thin.host/v1 \
-e THIN_HOST_API_KEY=th_live_your_key \
-- uvx thinhost-mcp
The package is thinhost-mcp on PyPI; the same wheel is also served at https://thin.host/dl/thinhost-mcp/latest if you would rather pin to the URL.
C. Claude Desktop bundle (.mcpb)
Download a ready-to-install bundle from the dashboard (Email & API → MCP package) and open it in Claude Desktop, or add the server by hand to claude_desktop_config.json:
{
"mcpServers": {
"thin-host": {
"command": "uvx",
"args": ["thinhost-mcp"],
"env": {
"THINHOST_API_URL": "https://thin.host/v1",
"THIN_HOST_API_KEY": "th_live_your_key_here"
}
}
}
}
3. Use It
In a Claude conversation, ask Claude to build something and put it live:
"Build me a landing page for my bakery and publish it."
Claude writes the site, calls publish_website, and hands you a live URL like https://thin.host/s/sunrise-bakery/. Iterate in the same conversation — "make the header green" — and Claude pushes the change with update_website.
Custom domains work the same way:
"I just deployed my site to https://myapp.vercel.app. Can you set up myportfolio.com as a custom domain?"
Claude will call provision_domain, get back a claim URL, and share it with you. You visit the claim page, pay, configure DNS, and the domain goes live.
Available Tools
| Tool | Description |
|---|---|
publish_website | Publish a local HTML file, directory, or ZIP as a live hosted site |
update_website | Push updated pages/assets to an existing hosted site |
list_websites | List your hosted sites with their live URLs |
provision_domain | Create a new custom domain with payment/claim flow |
check_domain_status | Poll domain provisioning progress |
update_origin | Change the target URL for a domain |
release_domain | Tear down a provisioned domain |
list_domains | List all domains with optional filtering |
send_email | Send a transactional notification email (requires email access approval) |
Example Flow
# Agent provisions a domain
result = await mcp.call("provision_domain", {
"domain": "mysite.com",
"origin_url": "https://myapp.vercel.app",
"user_email": "user@example.com"
})
# → { provision_id, status: "pending_payment", claim_url, dns_instructions }
# Agent shares the claim_url with the user
# User pays and configures DNS
# Agent checks status
status = await mcp.call("check_domain_status", {
"provision_id": result["provision_id"]
})
# → { status: "active", ready: true }
See the MCP Tool Reference for full parameter and response documentation.