Just Publish
Publish the website you built with AI to a live public URL, straight from chat, with no setup.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"just-publish": {
"url": "https://mcp.justpublish.ai/"
}
}
}Remote endpoints
https://mcp.justpublish.ai/streamable-httpWhat it can do
Tool inventory
Tools (3)
🟡deploy(files, email, site_id, edit_token)
Put a website live at a public URL. Use this when the user wants to publish, launch, or get a page online - e.g. 'I need a website', 'put up a page for my business', 'make this live'. Takes static files (HTML, CSS, JS, images) and returns a working URL anyone can open. No build step, no config. First call: omit site_id and edit_token - you get back a url, a site_id, and an edit_token. Keep the edit_token; it's the only way to change this site later. Later calls: pass site_id + edit_token to publish over the same site. deploy REPLACES the whole site - any file you leave out is DELETED. To change just one or a few files, use update_site_file instead. To see what's currently live before editing, use get_site_files first.
Input Schema
{
"type": "object",
"properties": {
"files": {
"type": "array",
"description": "Files to publish. Must include an index.html at the root.",
"items": {
"type": "object",
"required": [
"path",
"content"
],
"properties": {
"path": {
"type": "string",
"description": "Path under the site root, e.g. 'index.html', 'assets/logo.png'."
},
"content": {
"type": "string",
"description": "File body. Text by default; binary must be base64."
},
"encoding": {
"type": "string",
"enum": [
"base64",
"utf-8"
],
"description": "Defaults to utf-8 for text extensions, base64 otherwise."
}
}
},
"minItems": 1
},
"email": {
"type": "string",
"description": "Email address for the site. A link is sent to it to confirm the address; it is also used for recovery and service messages."
},
"site_id": {
"type": "string",
"description": "Existing site id to update. Omit to create a new site."
},
"edit_token": {
"type": "string",
"description": "Edit token returned at create time. Required to update."
}
},
"required": [
"files",
"email"
]
}Output Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The live URL of the published site."
},
"site_id": {
"type": "string",
"description": "The site's slug / id - pass back to update it later."
},
"edit_token": {
"type": "string",
"description": "Returned ONLY on first create. Save it - it's the only way to update this site."
},
"created": {
"type": "boolean",
"description": "true if this call created a new site; false if it updated an existing one."
},
"email_verified": {
"type": "boolean",
"description": "Whether the site's owner email is verified right now. False on a new site unless this address has been verified before."
},
"files_uploaded": {
"type": "integer",
"description": "Number of files written in this deploy."
},
"total_bytes": {
"type": "integer",
"description": "Total size of the site in bytes after this deploy."
},
"email_masked": {
"type": "string",
"description": "The owner email, masked for display (e.g. 'a***@example.com')."
},
"verify_required": {
"type": "boolean",
"description": "true when the owner still needs to verify their email (keys on !email_verified)."
},
"dashboard_url": {
"type": "string",
"description": "Deep link to this site in the owner's dashboard."
}
},
"required": [
"url",
"site_id",
"created",
"email_verified",
"files_uploaded",
"total_bytes",
"email_masked",
"verify_required",
"dashboard_url"
]
}🟢get_site_files(site_id, edit_token, paths)
Read the files of a site you already published, so you can make a targeted edit instead of rebuilding the whole site from memory. Returns a complete manifest (every file's path, size, content-type, sha256) plus the contents of the text files (HTML/CSS/JS/etc). Also returns the site's current `version` - pass it back to update_site_file so you don't overwrite a newer change. Pass `paths` to fetch only specific files; omit it to get all text files. Requires site_id + edit_token.
Input Schema
{
"type": "object",
"properties": {
"site_id": {
"type": "string",
"description": "The site id returned at publish time."
},
"edit_token": {
"type": "string",
"description": "The edit token returned at publish time."
},
"paths": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional. Specific file paths to return contents for (e.g. ['index.html','style.css']). Omit to get all text files. The manifest always lists every file regardless."
}
},
"required": [
"site_id",
"edit_token"
]
}Output Schema
{
"type": "object",
"properties": {
"site_id": {
"type": "string",
"description": "The site's slug / id."
},
"version": {
"type": "integer",
"description": "The site's current version - pass as expected_version to update_site_file to avoid clobbering."
},
"url": {
"type": "string",
"description": "The live URL of the site."
},
"manifest": {
"type": "array",
"description": "Every file on the site (always complete, regardless of which contents were inlined).",
"items": {
"type": "object",
"required": [
"path",
"size_bytes",
"content_type",
"sha256",
"is_text"
],
"properties": {
"path": {
"type": "string",
"description": "Path under the site root, e.g. 'index.html'."
},
"size_bytes": {
"type": "integer",
"description": "File size in bytes."
},
"content_type": {
"type": "string",
"description": "Stored content-type, e.g. 'text/html'."
},
"sha256": {
"type": [
"string",
"null"
],
"description": "Hex sha256 of the file bytes; null if not recorded for this file."
},
"is_text": {
"type": "boolean",
"description": "Whether the file is a text type eligible to have its content inlined."
}
}
}
},
"files": {
"type": "array",
"description": "Inlined contents of the requested text files (default: all text files, capped for size).",
"items": {
"type": "object",
"required": [
"path",
"content",
"encoding"
],
"properties": {
"path": {
"type": "string",
"description": "Path of this file under the site root."
},
"content": {
"type": "string",
"description": "Full text content of the file."
},
"encoding": {
"type": "string",
"enum": [
"utf-8"
],
"description": "Always 'utf-8' - only text files are inlined."
}
}
}
},
"truncated": {
"type": "boolean",
"description": "true if some requested file contents were omitted for size - request specific paths to read them."
}
},
"required": [
"site_id",
"version",
"url",
"manifest",
"files",
"truncated"
]
}🔴update_site_file(site_id, edit_token, files, expected_version)
Change one or a few files of an already-published site, leaving every other file untouched (a merge - unlike deploy, which replaces the whole site). Ideal for small edits: fix a typo in index.html, swap a stylesheet, add one page. Best practice: call get_site_files first, edit the returned content, then call this with the files you changed and the `expected_version` from that read - if the site changed in the meantime you get a clear conflict telling you to re-read. Requires site_id + edit_token. Cannot delete files (use deploy to drop a file) and cannot remove index.html.
Input Schema
{
"type": "object",
"properties": {
"site_id": {
"type": "string",
"description": "The site id returned at publish time."
},
"edit_token": {
"type": "string",
"description": "The edit token returned at publish time."
},
"files": {
"type": "array",
"minItems": 1,
"description": "The files to change. Only these are written; all other files on the site survive.",
"items": {
"type": "object",
"required": [
"path",
"content"
],
"properties": {
"path": {
"type": "string",
"description": "Path under the site root, e.g. 'index.html'."
},
"content": {
"type": "string",
"description": "Full new file body. Text by default; binary must be base64."
},
"encoding": {
"type": "string",
"enum": [
"base64",
"utf-8"
],
"description": "Defaults to utf-8 for text, base64 otherwise."
}
}
}
},
"expected_version": {
"type": "integer",
"description": "Optional but recommended. The `version` you got from get_site_files. If the site has changed since, the update is rejected with a conflict so you can re-read and re-apply. Omit to force last-writer-wins."
}
},
"required": [
"site_id",
"edit_token",
"files"
]
}Output Schema
{
"type": "object",
"properties": {
"site_id": {
"type": "string",
"description": "The site's slug / id."
},
"url": {
"type": "string",
"description": "The live URL of the site."
},
"version": {
"type": "integer",
"description": "The site's new version after the merge."
},
"files_written": {
"type": "array",
"items": {
"type": "string"
},
"description": "Paths of the files written in this update. All other files were left untouched."
},
"files_total": {
"type": "integer",
"description": "Total number of files on the site after the merge."
}
},
"required": [
"site_id",
"url",
"version",
"files_written",
"files_total"
]
}Recommended Prompts
get_site_filesget_site_filesCommunity
Evidence