Agent Skill
A portable Agent Skill teaches MCP clients how to publish self-contained HTML to a stable share link, update the same link, pull optional page feedback, and style with built-in themes. It is markdown + judgement only — thin MCP wiring, no shell scripts, curl wrappers, or binary downloads.
MCP endpoint: https://app.artifactpublisher.com/mcp (streamable HTTP)
Full MCP reference: MCP integration
Install
Section titled “Install”Until an official registry publish is available, install by copying the
skill text from this page (or the in-repo tree skills/artifact-publisher/
if you already have a checkout).
Do not claim a public npx skills add install path until that publish is live.
Place a folder like this in your client’s skills directory:
artifact-publisher/ SKILL.md references/ publish-ops.md desk-admin.md failures.mdCopy the bodies below into those files. Then wire the hosted MCP once (see Connect).
Hard rules
Section titled “Hard rules”- After
publish_artifact/update_artifact, reportartifact.url(control-origin share/viewer) first. Useartifact.viewer_urlwhen a version pin helps. Never make the raw artifact-origin URL the primary share link. - Never print, paste, commit, or write into artifacts:
ar_pk_…,ar_oat_…,ar_ort_…,ar_oac_…, refresh tokens, cookies, orAuthorizationheaders. Prefer OAuth or envARTIFACT_PUBLISHER_KEY. - Do not invent HTML when a real file exists — read the file and pass its
contents to
publish_artifact/update_artifact. - Call
get_authoring_guidebefore large styling; prefer<meta name="ap-theme" content="firn">. - Feedback is optional/secondary.
get_feedbackis pull-only — do not frame the product as an approval loop. - Thin MCP wiring only — no shell scripts, no curl wrappers, no reckless
exec, no downloading or running arbitrary binaries.
Connect
Section titled “Connect”Credential
Section titled “Credential”- Open Your dashboard and mint a publisher key (shown once). Store it in the client secret store or env — never echo it in chat.
- OAuth (preferred when the client supports browser consent): production
has OAuth mode on. Register
https://app.artifactpublisher.com/mcp, complete consent in the browser; never ask the user to paste an access token into chat. - Key (practical for Hermes / OpenClaw headless / always-on): set
ARTIFACT_PUBLISHER_KEYand sendAuthorization: Bearer ${ARTIFACT_PUBLISHER_KEY}. - Keyless
initialize/tools/list/pingwork for discovery only.
Example client snippets
Section titled “Example client snippets”Claude Code (prefer env-backed header):
claude mcp add --transport http artifact-publisher https://app.artifactpublisher.com/mcp \ --header "Authorization: Bearer ${ARTIFACT_PUBLISHER_KEY}"Cursor / Codex / similar (mcpServers):
{ "mcpServers": { "artifact-publisher": { "url": "https://app.artifactpublisher.com/mcp", "headers": { "Authorization": "Bearer ${env:ARTIFACT_PUBLISHER_KEY}" } } }}(Some clients use ${ARTIFACT_PUBLISHER_KEY} without env: — match your client.)
More client tabs: Quickstart.
Live tools
Section titled “Live tools”Only these names exist on the live surface today (tools/list):
publish_artifact, update_artifact, set_artifact_access, get_feedback,
reply_to_feedback, list_artifacts, revoke_artifact, configure_workspace,
get_artifact_board, reset_artifact_board, get_artifact_state,
set_artifact_state, reset_artifact_state, get_authoring_guide.
(get_artifact_board / reset_artifact_board are deprecated aliases — prefer
the state tools.)
Details: MCP tools.
Quick loop
Section titled “Quick loop”- Read existing HTML if a file exists; else author self-contained HTML (inline assets; sandbox has no network).
- Optional:
get_authoring_guide+ap-themefirn before large CSS. publish_artifact→ reportartifact.urlfirst.- Later:
update_artifact(same link), optionalget_feedback/reply_to_feedback,set_artifact_access, orrevoke_artifact.
Skill body (copy)
Section titled “Skill body (copy)”The canonical private source is skills/artifact-publisher/ in the product
repo. The publishable files are reproduced here for install without a private
clone.
SKILL.md
Section titled “SKILL.md”---name: artifact-publisherdescription: Publish self-contained HTML to a stable share link and read page feedback via Artifact Publisher MCP. Use when the user wants a review/share URL for agent-made HTML, to update the same link, change access, pull comments, or style with built-in themes. Do not use for unrelated hosting, SPA/multi-file deploys, or package registries.version: 0.1.0author: Angle Labs GmbHlicense: MIT-0platforms: [macos, linux, windows]required_environment_variables: - name: ARTIFACT_PUBLISHER_KEY optional: true prompt: "Publisher key for headless/always-on agents (Hermes, OpenClaw operators). Mint once at https://artifactpublisher.com/account/ — shown once; never paste into chat. Prefer OAuth browser consent when the client supports it."metadata: tags: [html, publishing, sharing, share-link, mcp, feedback, review] hermes: tags: [html, publishing, sharing, mcp, feedback] homepage: https://artifactpublisher.com openclaw: emoji: 📎 homepage: https://artifactpublisher.com primaryEnv: ARTIFACT_PUBLISHER_KEY requires: env: - ARTIFACT_PUBLISHER_KEY envVars: - name: ARTIFACT_PUBLISHER_KEY required: true description: Scoped publisher key (Bearer). Prefer OAuth when the client supports browser consent; for headless/always-on agents this env var is the practical path. Mint at https://artifactpublisher.com/account/ — never commit or paste into chat.---
# Artifact Publisher
Hosted MCP server that turns one self-contained HTML document into a stable,unlisted share link. Reviewers open it without an AI-vendor account; optionalpage comments come back to the agent with `get_feedback`. MCP-first andprovider-agnostic. Free plan available.
**Server:** `artifact-publisher` · version `0.1.0`**Endpoint:** `https://app.artifactpublisher.com/mcp` (streamable HTTP)**Docs:** https://artifactpublisher.com/docs/mcp/
## Hard rules
1. After `publish_artifact` / `update_artifact`, report **`artifact.url`** (control-origin share/viewer) **first**. Use `artifact.viewer_url` when a version pin helps. **Never** make the raw artifact-origin URL the primary share link.2. **Never** print, paste, commit, or write into artifacts: `ar_pk_…`, `ar_oat_…`, `ar_ort_…`, `ar_oac_…`, refresh tokens, cookies, or `Authorization` headers. Prefer OAuth or env `ARTIFACT_PUBLISHER_KEY`.3. Do **not** invent HTML when a real file exists — read the file and pass its contents to `publish_artifact` / `update_artifact`.4. Call `get_authoring_guide` before large styling; prefer `<meta name="ap-theme" content="firn">`.5. Feedback is optional/secondary. `get_feedback` is **pull-only** — do not frame the product as an approval loop.6. **Thin MCP wiring only** — no shell scripts, no curl wrappers, no reckless `exec`, no downloading or running arbitrary binaries.
## Route the request
| Route | When | Load || --- | --- | --- || Publish / update / access / feedback / state / authoring | Publish HTML, refresh a link, read/reply to feedback, themes, shared state | [publish-ops](references/publish-ops.md) || Desk / keys / account links | User asks to sign in, mint/revoke keys, or connect MCP from the desk | [desk-admin](references/desk-admin.md) || Failures | Auth, size, quota, or consent problems | [failures](references/failures.md) only after a failure |
## Setup
Wire the hosted MCP once. This skill is markdown + judgement only; it does notship binaries.
### 1. Credential
1. Open https://artifactpublisher.com/account/ and mint a publisher key (shown once). Store it in the client secret store or env — **never echo it in chat**.2. **OAuth (preferred when the client supports browser consent):** register `https://app.artifactpublisher.com/mcp`, complete consent in the browser; never ask the user to paste an access token into chat.3. **Key (practical for Hermes / OpenClaw headless / always-on):** set `ARTIFACT_PUBLISHER_KEY` and send `Authorization: Bearer ${ARTIFACT_PUBLISHER_KEY}`.4. Keyless `initialize` / `tools/list` / `ping` work for discovery only.
### 2. Other MCP clients
See https://artifactpublisher.com/docs/ for Claude Code, Cursor, Codex, andother client snippets. Prefer env-backed headers; never paste keys into chat.
### 3. Desk
Mint and manage keys at https://artifactpublisher.com/account/. Keys are shownonce; only a hash is stored server-side.
## Live tools (honesty)
Only these names exist on the live surface today(`ARTIFACT_RELAY_TOOLS` / `tools/list`):
`publish_artifact`, `update_artifact`, `set_artifact_access`, `get_feedback`,`reply_to_feedback`, `list_artifacts`, `revoke_artifact`, `configure_workspace`,`get_artifact_board`, `reset_artifact_board`, `get_artifact_state`,`set_artifact_state`, `reset_artifact_state`, `get_authoring_guide`.
(`get_artifact_board` / `reset_artifact_board` are deprecated aliases — preferthe state tools.)
## Quick loop
1. Read existing HTML if a file exists; else author self-contained HTML (inline assets; sandbox has no network).2. Optional: `get_authoring_guide` + `ap-theme` firn before large CSS.3. `publish_artifact` → report **`artifact.url` first**.4. Later: `update_artifact` (same link), optional `get_feedback` / `reply_to_feedback`, `set_artifact_access`, or `revoke_artifact`.
Details: [publish-ops](references/publish-ops.md).references/publish-ops.md
Section titled “references/publish-ops.md”# Publish operations
Use the connected Artifact Publisher MCP. Do not shell out, curl the endpoint,or wrap tools in scripts.
## Publish
1. If a real HTML file exists on the machine, **read it** and pass the full string as `html`. Do not invent a stub or paraphrase.2. HTML must be self-contained: sandbox has **no network**, so inline CSS, scripts, fonts, and images (e.g. data URIs). Plain links still open in a new tab for the viewer.3. Optional before large styling: `get_authoring_guide`. Prefer `<meta name="ap-theme" content="firn">` in `<head>`.4. Call `publish_artifact` with `html` and optional `title`, `summary`, `expires_at`, `comments_enabled`, `visibility`, `allowed_emails`.5. On success, report **`artifact.url` first** (control-origin share/viewer). Add `artifact.viewer_url` when a version pin helps. Do **not** lead with the raw artifact-origin document URL (iframe-only).
Default visibility is `public` (unlisted by link; not indexed). For coworkerswithout accounts, use `public`, not `allowlist`.
Free plan (current product defaults): size ceiling on UTF-8 HTML (see toolerror / docs; typically 10 MiB), 5 active artifacts, 50 versions — treat livetool errors as authoritative.
## Update (same link)
1. Call `update_artifact` with `artifact_id` (id, slug, or viewer URL) and `expected_version` equal to the current version.2. Pass new `html` for a new immutable version; the share link moves to it. Earlier versions stay at pinned URLs.3. Optional `title` renames; title-only (no `html`) renames without a new body version (still counts toward some rate limits — see tool text).4. Again report **`artifact.url` first**.
## Access without a new version
`set_artifact_access` — change `visibility` / `allowed_emails` without bumpingthe HTML version.
| visibility | Who can open || --- | --- || `public` (default; `unlisted` alias) | Anyone with the link; no sign-in || `private` | Owner only (signed in) || `allowlist` | Signed-in users whose primary email is listed |
## Feedback (optional, secondary)
Not an approval workflow (share-first product).
- `get_feedback` — pull comments (oldest first). Filters: `unresolved_only`, `since`, `version` (default current for `anchor_status`), page with `limit` / `cursor`.- `reply_to_feedback` — one reply per comment; optional `resolve: true`. Second reply → conflict.
Selected-passage / quote-anchored comments may appear when the viewer supportsthem; do not claim long-press or chat-native annotation UX.
## List / revoke
- `list_artifacts` — workspace artifacts, newest first, unresolved counts.- `revoke_artifact` — stop serving (410); cannot undo. Confirm with the user.
## Shared state
Synced JSON key/value for page JS (`ArtifactRelayState`). Limits: 200 keys,16 KiB/value, 64 KiB total.
- `get_artifact_state` / `set_artifact_state` / `reset_artifact_state`- Deprecated: `get_artifact_board` / `reset_artifact_board` — prefer state tools
## Workspace defaults
`configure_workspace` — read/update allowed defaults (empty settings = read).Platform guardrails are refused. Not available in every workspace.
## Authoring
`get_authoring_guide` — themes, `ap-*` layout classes, example, snippet, sizeand sandbox rules. Optional `theme` (`firn`, `firn@1`) validated as selected.
## Non-goals
Multi-file / SPA hosting, DOM annotation bundles, local serverinstall/upgrade/backup, inventing HTML when a file exists.references/desk-admin.md
Section titled “references/desk-admin.md”# Desk / account / connect
Load only when the user explicitly asks to sign in, mint or revoke keys, managethe account, or connect MCP from the desk. Do **not** invent Stripe customerIDs, key plaintext, plan prices, or checkout steps.
## Desk URLs
| Need | Link || --- | --- || Account / mint publisher key | https://artifactpublisher.com/account/ || MCP docs | https://artifactpublisher.com/docs/mcp/ || Quickstart | https://artifactpublisher.com/docs/ || Agent Skill | https://artifactpublisher.com/docs/skill/ || Pricing (user opens themselves) | https://artifactpublisher.com/pricing/ || Privacy | https://artifactpublisher.com/privacy/ || Imprint / operator | https://artifactpublisher.com/imprint/ || Support | contact@artifactpublisher.com |
A desk `#mcp` deep-link may land later; until then, point people at **Account**plus MCP docs. Do not invent fragment URLs.
## Keys
1. User mints a scoped publisher key in the desk UI.2. Key is **shown once**; server stores only a hash.3. Agent / skill: put the value in env `ARTIFACT_PUBLISHER_KEY` or the client secret store. **Never** ask the user to paste the key (or any `ar_pk_…` / `ar_oat_…` / refresh token) into chat.4. If a key was exposed in chat, logs, or a repo: tell the user to revoke it in the desk and mint a new one — do not “fix” by echoing the old value.
## OAuth connect
When the MCP client supports browser consent:
1. Register resource `https://app.artifactpublisher.com/mcp`.2. User completes consent in the browser on the site origin.3. Tokens stay in the **client** secret store.4. Never ask the user to paste access tokens, refresh tokens, or auth codes into chat.
Headless / always-on agents (Hermes gateway, OpenClaw operators): publisher keyvia env remains the practical path.
## What this skill must not do
- Invent billing portal URLs, Stripe Dashboard links, or invoice amounts.- Print or store secrets in artifacts, commits, or skill files.- Claim a CLI name (`artifactpublisher` or otherwise) — none is reserved yet.- Claim a public `npx skills add` install path until an official registry publish is live.references/failures.md
Section titled “references/failures.md”# Failures
Load after an auth, size, quota, or consent failure. Do not invent success.
## Authentication
| Symptom | What to do || --- | --- || `401` / missing or bad Bearer | Confirm MCP config uses env `ARTIFACT_PUBLISHER_KEY` or OAuth client store. Point user to https://artifactpublisher.com/account/ to mint/rotate. Never ask them to paste the key or `ar_oat_…` into chat. || Keyless call to a write/read tool | Only `initialize`, `tools/list`, and `ping` are keyless. Publish and other tools need a credential. || OAuth consent abandoned / expired | Ask the user to complete browser consent again in their MCP client. Do not collect tokens in chat. || Wrong workspace / `not_found` on `artifact_id` | Id, slug, or viewer URL must belong to this key’s workspace. Re-check with `list_artifacts`. |
Never fall back to printing Authorization headers, cookies, or raw secrets “to debug.”
## Size and HTML validation
| Symptom | What to do || --- | --- || Size / UTF-8 limit error | Shrink HTML; inline only what is needed. Live error text is authoritative for the workspace ceiling. || `invalid_input` on theme / HTML | Fix per error message (e.g. `ap-theme` marker). Call `get_authoring_guide` rather than inventing CSS. || Sandbox “broken” assets | External fonts/images/APIs will not load — inline or drop them. |
## Quota
| Symptom | What to do || --- | --- || `quota_exceeded` on active artifacts | Revoke or let expire unused artifacts (`revoke_artifact`), or ask the user to manage plan at the desk/pricing page. Do not invent upgrade checkout flows. || `quota_exceeded` on versions | Prefer fewer updates; revoke old artifacts if appropriate. Free plan version caps apply — see error details. || Rate limit / `429` | Wait for `Retry-After` if present; retry once. Do not hammer the endpoint. |
## Update conflicts
| Symptom | What to do || --- | --- || `expected_version` mismatch | Another publish won the race. Re-read current version (`list_artifacts` / prior result), explain, and ask before retrying with the user’s HTML. |
## Maintenance / unavailable
If the server returns maintenance or read-only errors: report plainly; preferread tools (`get_authoring_guide`, `list_artifacts`, `get_feedback`) when thosestill work. Do not switch to a different product or invent a local host.
## Safety
Stop on uncertainty. Do not download or run binaries, curl wrappers, or“helper scripts” to work around MCP failures.