From html-channel
Start a bidirectional HTML channel. Use when the user wants to create an interactive HTML tool (screener, planner, curator, editor, reviewer) that can send data back to Claude and receive live updates.
How this skill is triggered — by the user, by Claude, or both
Slash command
/html-channel:channel-startThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are setting up a **Claude HTML Channel** — a live, bidirectional link between
You are setting up a Claude HTML Channel — a live, bidirectional link between an interactive HTML page in the user's browser and this Claude session.
The html-channel MCP server provides these tools:
create_session — saves HTML and starts serving it, returns the URLsend_to_browser — pushes status/data/done messages to the browserreceive_from_browser — reads messages the browser sent (fallback if channels not enabled)update_page — replaces the HTML page contentRead the channel bridge JavaScript library from:
${CLAUDE_PLUGIN_ROOT}/lib/channel-bridge.js
You will embed this verbatim in a <script> tag in the HTML page.
Build a single self-contained HTML file for whatever the user asked for.
const DATA = { ... };render(data) function that builds/rebuilds the entire UI from a data objectrender(DATA) on page loadwindow.getChannelData = () => { ... } returning the current state (edits, selections, notes)Include the channel-bridge.js contents in a <script> tag, then:
<script>
ClaudeChannel.init(); // auto-detects port from window.location
ClaudeChannel.onData(payload => render(payload));
</script>
localStorage to persist the user's work across page refreshesgetChannelData() so it's sent along with the
structured data.Call the create_session tool with the HTML content. It returns the URL.
Open the URL in the browser (use xdg-open on Linux, open on macOS).
Start a polling loop to receive browser input:
/loop 30s receive and process browser input from the HTML channel
This checks receive_from_browser every 30 seconds. If channels are enabled,
data may also arrive directly as <channel source="html-channel"> messages.
When data arrives (either way):
send_to_browser with type: "status" to acknowledge receiptupdate_page to persist the changes, then send_to_browser with type: "refresh"send_to_browser with type: "done" to signal completionImportant: If multiple messages arrive, update the page after completing each task before continuing to the next. The user should see their changes applied incrementally, not all at once at the end.
There are two ways to send data back to the browser:
send_to_browser with type: "data" — real-time push via SSE
DATA constant (or localStorage), not from what you pushed.update_page — regenerate the HTML with new data baked in
DATA constant contains the updated valuesupdate_page, send type: "refresh" to auto-reload the browserDATA constant and any
necessary logic changes. Do NOT redesign the layout, colors, or UI on updates.
The user is familiar with the current design; preserve it.Rule of thumb: Use send_to_browser for progress updates and previews. Use
update_page when you're done processing and want the changes to stick.
npx claudepluginhub stbenjam/claude-html-channels --plugin html-channelGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.