hstd speaks MCP, the protocol Claude, Cursor and most AI tools use to reach outside services. Connect once and your assistant can create sites, edit them as drafts, show you a preview, and publish when you say so. This page explains every tool it gets, in plain words. It is written for people and for the assistants themselves.
Add this address as a custom connector or MCP server in your AI tool. The first time it connects you sign in with your hstd account and approve it. That is the whole setup: no keys to copy, nothing to install.
The assistant works inside your current team. Switch teams in hstd and it follows. What it may do follows your role: members can deploy, admins and owners can also create sites, and owners handle billing. A team can have more than one owner. This is separate from the hstd platform admin.
https://hstd.app/mcp
Every edit the assistant makes goes into a draft: a copy of the live version with the changes applied. The live site does not move.
Each version, drafts included, has its own address such as mysite--v14.hstd.app. The assistant shows it to you; look before anyone else does.
One call flips the live pointer to the draft. Roll back by publishing an older version. The assistant is told to do this only after you say yes.
Sites are named by their slug, the part before .hstd.app. Every tool that touches a site takes that slug.
| Tool | What it does | When to use it |
|---|---|---|
| list-sites | List your sites with their live version and draft (if any). | Start here. It tells you which sites exist, which version is live and whether a draft is waiting. |
| create-site | Create a new, empty site. Then add files with write-files and put it live with publish. | Only when the user wants a new site. Pick a slug they will recognise; it becomes the address. |
| list-files | List the files in a site. Defaults to the draft when there is one, otherwise the live version. | Before editing, to see what is there. You get the draft if one exists, so you always see your own changes. |
| read-file | Read one file from a site. Text comes back as-is, binaries as {"encoding": "base64", "content": ...}. Defaults to the draft when there is one, otherwise the live version. | To read one file before changing it. Binaries come back as base64. |
| write-files | Create or overwrite files in the site's draft. Text as-is, binaries (images, fonts) as base64 with encoding "base64". Nothing goes live: the reply has a preview URL to show the user. Call publish when they approve. | Small edits and new text files. Send whole files, not diffs. Use base64 for images and fonts. Pass fresh: true to start a site from scratch. |
| delete-files | Delete files or folders from the site's draft. The live version is untouched until publish. | Remove files or folders from the draft. Nothing changes on the live site until publish. |
| list-versions | List a site's versions, newest first, each with its status (live, draft, published) and preview URL. | To find a version to roll back to, or to show the user the history. |
| publish | Make a version live. Defaults to the draft; pass an older version number to roll back. Only call this after the user has approved. | Only after the user has seen the preview and said yes. Without a version it publishes the draft; with an older version number it rolls back. |
| discard-draft | Throw away the site's draft. The live version is untouched. | When the user wants to throw the current draft away and start again from the live version. |
| import-upload | Import a zip that was posted to POST /uploads (see https://hstd.app/docs) as the site's new draft. Use this for built bundles and anything too big to send through write-files. The reply has a preview URL; call publish when the user approves. | Built bundles and anything big or binary. Zip the folder, post it to /uploads first, then import the token. It replaces the draft. |
Tool calls carry text, so a 250 KB JavaScript bundle or a folder of images does not fit through write-files. Instead, zip the folder and post it to /uploads. No sign-in is needed for that step, and the reply is a token that works for one hour. Then call import-upload with the token: the zip becomes the site's draft, with a preview address, and publishing stays a separate step.
Zips need an index.html at the root, or inside a single top-level folder. Up to 250 MB and 10,000 files; your plan's own limits apply when the draft is created.
cd dist && zip -r ../site.zip . && cd .. curl -F [email protected] https://hstd.app/uploads {"upload":"upl_3f9…","size":412880,"expires_at":"…"} # then, over MCP import-upload {"site": "mysite", "upload": "upl_3f9…"} publish {"site": "mysite"}
Any form on a hosted site can post to /_hstd/form/<name> on its own address. hstd stores the fields, emails the team owner (with Reply-To set to the sender when there is an email field) and shows every message under the site's Forms tab.
<form action="/_hstd/form/contact" method="post"> <input name="name" placeholder="Your name"> <input name="email" type="email" placeholder="Your email"> <textarea name="message"></textarea> <input name="_gotcha" style="display:none" tabindex="-1" autocomplete="off"> <input name="_next" type="hidden" value="/thanks.html"> <button>Send</button> </form>
Put a _config.json at the root of the site and hstd reads it on every request. Four things it can do, all optional.
A broken file is refused when you upload or publish, with a message that says what to fix. The file itself is never served.
{
"spa": true,
"notFound": "/404.html",
"redirects": [
{ "from": "/old/*", "to": "/new/:splat", "status": 301 },
{ "from": "/docs", "to": "https://hstd.app/docs", "status": 302 }
],
"headers": [
{ "path": "/assets/*", "headers": { "Cache-Control": "public, max-age=31536000, immutable" } },
{ "path": "/*", "headers": { "X-Frame-Options": "DENY" } }
]
}
| Plan | Sites | People | Space | Per upload | Custom domains |
|---|---|---|---|---|---|
| Free | 3 | 2 | 50 MB | 25 MB | No |
| Pro | 25 | 5 | 5 GB | 100 MB | Yes |
| Studio | 100 | ∞ | 25 GB | 250 MB | Yes |