MCP Server
hdply ships a built-in MCP server. Any MCP client — Claude Code, Claude Desktop, or your own agent — can list your sites, create one, read the HTML that is live, publish a new version, and inspect the deploy history. Five tools, one API key, nothing to run locally.
Safe to hand to an agent
There is no delete tool. Removing a site is web-console only, by design. An agent with full deploy rights can publish a bad version, but it cannot destroy your work.
Every deploy — human or agent — is versioned. A wrong deploy is one click away from being restored in the console, and get_deploy_history shows exactly which deploys came through MCP ("source": "mcp"). That is the difference from a general-purpose deployment MCP: hdply is scoped to one HTML file per site, so the worst case is a page that looks wrong for a minute.
The main use case
Claude writes you a page — a proposal, a dashboard, a mockup — as an HTML artifact. Instead of saving the file and uploading it somewhere, you say "publish this" and the same conversation ends with a public URL you can send. Later, "change the heading and republish" is another single turn.
Connect
Claude Code, one command:
claude mcp add --transport http hdply https://api.app.hdply.com/mcp \ --header "Authorization: Bearer hdply_sk_…"
Claude Desktop, in claude_desktop_config.json (through mcp-remote, since Desktop only launches local commands):
{
"mcpServers": {
"hdply": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://api.app.hdply.com/mcp",
"--header", "Authorization: Bearer hdply_sk_…"]
}
}
}
Any other client: it is a stateless Streamable HTTP endpoint. Send JSON-RPC to the URL below with the same bearer header.
POST https://api.app.hdply.com/mcp
Authorization: Bearer hdply_sk_…
Content-Type: application/json
{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}
The key comes from the console dashboard ("API key" card). It is shown once, and it grants access to every site on the account — treat it like a password.
Tools
Each tool takes a JSON object and returns text content. Errors come back as text with isError: true, never as a transport failure, so an agent can read the reason and try again.
list_sites
Every site you can manage, personal and team, with its live URL and whether anything is deployed yet. No arguments.
Example call
{ "name": "list_sites", "arguments": {} }
Result
[
{
"id": 42,
"name": "Q3 proposal",
"subroute": "k3v9x2m7q1",
"url": "https://k3v9x2m7q1.hdply.com",
"live": true
},
{
"id": 43,
"name": "Launch page",
"subroute": "launch",
"url": "https://launch.hdply.com",
"live": false,
"team_id": 7,
"team_name": "Design"
}
]
create_site
Create a site. With html it is live the moment the call returns, at a random subdomain the server assigns; without it, the site exists empty until deploy_site.
Input
{
"html": string // optional — full HTML document, max 1 MB; live immediately when given
"name": string // optional — falls back to the HTML <title>
"team_id": number // optional — create inside a team (0 = personal)
}
Example call
{
"name": "create_site",
"arguments": {
"html": "<!doctype html><html><head><title>Q3 proposal</title></head><body><h1>Q3 proposal</h1></body></html>"
}
}
Result
Site "Q3 proposal" live at https://k3v9x2m7q1.hdply.com (id 42, subroute k3v9x2m7q1)
get_site_html
The HTML that visitors currently get. Use it before an edit so the agent changes what is actually live, not what it remembers.
Input
{
"site": string // required — numeric project id ("42") or subdomain ("k3v9x2m7q1")
}
Example call
{ "name": "get_site_html", "arguments": { "site": "k3v9x2m7q1" } }
Result
<!doctype html><html><head><title>Q3 proposal</title>…
deploy_site
Publish new HTML to an existing site. Live when the call returns, versioned like every other deploy, tagged mcp in the history.
Input
{
"site": string // required — numeric project id or subdomain
"html": string // required — full HTML document, max 1 MB
}
Example call
{
"name": "deploy_site",
"arguments": {
"site": "k3v9x2m7q1",
"html": "<!doctype html>…"
}
}
Result
Deployed. Live at https://k3v9x2m7q1.hdply.com
get_deploy_history
The deploy history: who, when, how big, and through which path (web, api, mcp, restore). Newest first.
Input
{
"site": string // required — numeric project id ("42") or subdomain ("k3v9x2m7q1")
}
Example call
{ "name": "get_deploy_history", "arguments": { "site": "k3v9x2m7q1" } }
Result
[
{
"id": 918,
"size": 4812,
"hash": "3f9c1a7b2d4e6f80",
"source": "mcp",
"actor_email": "you@example.com",
"created_at": "2026-09-08T09:41:12Z"
},
{
"id": 902,
"size": 4790,
"hash": "b81e0c5d9a2f4711",
"source": "web",
"actor_email": "you@example.com",
"created_at": "2026-09-07T18:02:55Z"
}
]
Errors
Tool errors are ordinary results with isError: true. The text starts with a stable code where one exists: file_too_large (over 1 MB), project_limit (plan allowance reached), site not found. Authentication failures are the only HTTP-level errors (401).
{ "content": [{ "type": "text", "text": "file_too_large: html exceeds the 1MB size limit" }], "isError": true }
Limits
- One HTML file per site, 1 MB maximum. Inline your CSS and JavaScript; images can be external URLs or data URIs.
- Free accounts hold 6 sites; Light raises it to 25 and Pro is unlimited.
create_sitefails withproject_limitbeyond that. - New sites are served with
X-Robots-Tag: noindexuntil the owner turns indexing on in the console (or via the RESTPATCH /v1/projects/{id}/settings). An agent cannot make a page searchable by itself.
Discovery
The server describes itself at two unauthenticated URLs: a server card with the live tool list and schemas, and the manifest used for MCP directory listings.
https://api.app.hdply.com/.well-known/mcp/server-card.json # tools + schemas, live https://api.app.hdply.com/.well-known/mcp/server.json # registry manifest (com.hdply/hdply)
Prefer plain HTTP? The same operations exist as a REST API, and hdply.com/llms.txt summarizes both for agents.