Guide
Publish HTML over MCP
One self-contained HTML document in, one share link out, from any MCP client that can send a bearer key.
Updated
What this does
Artifact Publisher is an MCP server that publishes one self-contained HTML document and returns a stable link. By default the link is unlisted: anyone who has it can open the page in a browser, with no account. The endpoint is https://app.artifactpublisher.com/mcp over streamable HTTP (POST), and every tool call needs Authorization: Bearer <publisher key>.
Before you start
- An account. Sign in at your workspace, create the workspace and copy the publisher key. It is shown once, and only a hash is stored, so a lost key is replaced rather than recovered.
- An MCP client that can send a custom
Authorizationheader. - One HTML document of up to 10 MiB of UTF-8, with all CSS, scripts, images and data inline.
Connect your client
Use <your-key> as the placeholder below and keep the real key out of prompts, repositories and artifacts. The Cursor, Codex CLI and Windsurf snippets read the key from an environment variable:
export ARTIFACT_PUBLISHER_KEY=<your-key>Claude Code
claude mcp add --transport http artifact-publisher https://app.artifactpublisher.com/mcp \
--header 'Authorization: Bearer <your-key>'Cursor
In ~/.cursor/mcp.json, or .cursor/mcp.json in a project:
{ "mcpServers": { "artifact-publisher": {
"url": "https://app.artifactpublisher.com/mcp",
"headers": { "Authorization": "Bearer ${env:ARTIFACT_PUBLISHER_KEY}" } } } }Codex CLI
In ~/.codex/config.toml, which the Codex IDE extension and the ChatGPT desktop app share:
[mcp_servers.artifact-publisher]
url = "https://app.artifactpublisher.com/mcp"
bearer_token_env_var = "ARTIFACT_PUBLISHER_KEY"VS Code and Copilot
In .vscode/mcp.json. VS Code prompts for the key:
{ "inputs": [{ "type": "promptString", "id": "ap-key", "description": "Artifact Publisher key", "password": true }],
"servers": { "artifact-publisher": { "type": "http",
"url": "https://app.artifactpublisher.com/mcp",
"headers": { "Authorization": "Bearer ${input:ap-key}" } } } }Windsurf
In mcp_config.json, opened from the Cascade panel:
{ "mcpServers": { "artifact-publisher": {
"serverUrl": "https://app.artifactpublisher.com/mcp",
"headers": { "Authorization": "Bearer ${env:ARTIFACT_PUBLISHER_KEY}" } } } }Claude Desktop uses a custom connector with a request header; the quickstart has the steps and notes that request headers are in beta and not on every account. ChatGPT on the web does not work yet, because its custom MCP servers accept only OAuth or no authentication and this server needs a bearer key. The ChatGPT desktop app works through the Codex configuration above.
Publish your first page
Ask the agent to call publish_artifact with title and html. A minimal document:
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Status</title>
<style>body{font:16px system-ui;margin:2rem}</style></head>
<body><h1>Status</h1><p>Build passed.</p></body>
</html>The result includes the share link in url (https://app.artifactpublisher.com/artifact/<slug>), the version and the access policy. Optional arguments are summary,expires_at, comments_enabled, visibility and allowed_emails.
Update in place
update_artifact adds a new immutable version behind the same link. Pass expected_versionequal to the current version, so two writers cannot overwrite each other without noticing. Earlier versions stay readable at their pinned URLs.
Tools at a glance
| Tool | Scope | Does |
|---|---|---|
publish_artifact | artifacts:write | Publish HTML as version 1 and return the link |
update_artifact | artifacts:write | Add a version, or rename, behind the same link |
set_artifact_access | artifacts:write | Change access without a new version |
revoke_artifact | artifacts:write | Stop serving the artifact |
list_artifacts | artifacts:read | List workspace artifacts with unresolved comment counts |
get_feedback | feedback:read | Read comments, pinned to a version |
reply_to_feedback | feedback:write | Reply in a comment thread |
The MCP integration page is the reference and lists every tool, including the ones not shown here.
Control access and take a page down
set_artifact_access switches visibility between unlisted (default),public, private and allowlist. allowlist takes up to 50allowed_emails, and those recipients need an Artifact Publisher account. revoke_artifactstops serving the page. It cannot recall a copy someone already saved.
Comments and feedback
Comments are optional. Readers can comment on the whole page or on a selected quote. Your agent reads them withget_feedback and answers with reply_to_feedback. Feedback is pull-only: there are no webhooks.
Limits
- The page runs in a sandboxed iframe with no network access, so remote fonts, images and APIs do not load.
- Unlisted is not authenticated. Anyone with the link can open it.
- Without a key,
initialize,tools/listandpingwork, with a 16 KiB body limit and 60 calls per minute per client. Everytools/callneeds the key. - Team workspaces are built but not enabled yet.
- Data is stored in Cloudflare's EU jurisdiction, and requests can be processed outside the EU on the way. Sign-in uses Clerk, a US sub-processor.
- No compliance certification, audit or penetration test is claimed.