Claude Code Artifacts: Publish a Page From a Session

An artifact is an interactive web page published from your Claude Code session to a private URL on claude.ai. Claude writes an HTML or Markdown file in your project, publishes it, and can update it in place as the session continues. It is meant as a capture of work you can send someone, not as a hosted application.
Yes, through MCP connectors, which the page can call each time someone views it. The unusual part is that each viewer's own connectors make the calls, so two people can see different data and the page never sees anyone's credentials. Viewers approve access before the first call, and a connector-backed artifact cannot be shared publicly on any plan.
Artifacts run under a strict content security policy that blocks requests to other hosts, with Google Fonts and connector data as the only exceptions. Scripts, stylesheets, fonts, images, fetch, XHR and WebSockets are all blocked, so CSS and JavaScript are inlined and images are embedded as data URIs. The rendered page must also be 16 MiB or smaller.
Set disableArtifact to true in your settings file, set the CLAUDE_CODE_DISABLE_ARTIFACT environment variable to 1, or deny the Artifact tool in your permissions rules. Administrators on Team and Enterprise plans have separate organisation-level toggles for artifacts, for connector calls from artifacts, and for public sharing.
Artifacts require a session backed by a claude.ai account. They are unavailable with an API key, an LLM gateway token, or cloud provider credentials, on Bedrock, Google Cloud's Agent Platform and Microsoft Foundry, in organisations with CMEK, HIPAA or Zero Data Retention, in Agent SDK, GitHub Action and MCP server contexts, and when non-essential traffic is disabled.

Key Takeaway
A Claude Code artifact is a live, interactive web page published from your session to a private URL on claude.ai, updating in place as the session continues. It is one self-contained page with no backend, served under a strict content security policy, and its only route to outside data at view time is calling MCP connectors.
I had spent twenty minutes describing four possible layouts for a settings panel in prose, and the person reading it still asked me to just show them. Of course they did. The next time I asked for the four layouts on one page with a one-line trade-off under each, sent the link, and got a decision back in ninety seconds.
That is the whole case for artifacts, and the interesting part is the constraints rather than the concept. This post covers what an artifact is deliberately not, publishing and updating including the mistake that creates a duplicate, the content security policy that shapes what the page can do, the connector model where each viewer's own account makes the calls, comments and Claude replying to them, and the conditions under which the feature quietly is not there.
Reach for an artifact when terminal text is the wrong medium: output easier to look at and interact with than to read line by line. Claude builds the page from anything the session can reach, including your codebase and data pulled through connected tools, so it can show things that would take paragraphs to describe.
It is not a place to deploy an internal tool. One self-contained page, no backend, so it cannot store form input or serve multiple routes. If what you are describing has a database behind it, you want your own infrastructure and this is the wrong thing to stretch. The line is clean and worth respecting rather than fighting.
Claude writes the page to an HTML or Markdown file in your project and publishes it, asking permission the first time. Republishing an artifact you have already approved does not prompt again, and each publish becomes a version you can choose between from the share control.
# Ask for one directly, or let Claude offer.
Make an artifact that walks through this PR with the diff
annotated inline and findings colour-coded by severity.
Build a dashboard artifact of last week's deploy failures by
service and keep it updated as you investigate.
# Finding and updating one later:
/artifacts # every artifact you own and every one shared
# o open in the browser
# c copy the link
# Enter attach it to THIS session
Ctrl+] # reopen the most recent artifact from this session
# Updating from a DIFFERENT session needs the URL or an attach.
# Without either, a new session creates a NEW artifact rather
# than updating the one you meant.
Update https://claude.ai/code/artifact/5fbea6f3-… with today's numbers.
CLAUDE_CODE_ARTIFACT_AUTO_OPEN=0 # stop the browser openingThe mistake that costs you is updating from a new session. Without the URL or an attach, a fresh session creates a new artifact rather than updating the one you meant — and now there are two, one of which nobody has the link to. Attaching from the artifacts list at the start of a session is one keystroke and prevents it entirely.
Understanding the content security policy explains almost everything about what artifacts look like. There is no CDN, no external script, no fetch to your API — so everything is inlined, and pages are built out of what HTML, CSS and inline JavaScript can express on their own.
# One self-contained page, served under a strict CSP.
External requests Nothing from outside except Google Fonts and
connector data. Scripts, stylesheets, fonts and
images from other hosts are blocked, along with
fetch, XHR and WebSockets. So CSS and JS are
inlined and images embedded as data URIs.
No backend Cannot store form input or authenticate viewers.
Its only route to outside data at view time is
calling MCP connectors.
Single page Relative links do not resolve — nothing is
deployed alongside it. Multi-section content
uses in-page anchors.
File types .html, .htm or .md. Markdown renders as styled HTML.
Rendered size 16 MiB or smaller. Large embedded images are
the usual cause of a size failure.
# Token cost is real: a styled page costs more output than the
# same content as terminal text. Prefer SVG or HTML and CSS over
# embedded raster images, drop interactivity you do not need, and
# have the page summarise large datasets rather than inline them.A page can call MCP connectors each time someone views it, so it shows current data rather than a snapshot from the session that built it. The model here is unusual and worth getting right, because it produces behaviour that surprises people the first time.
How a connector call actually resolves:
| Property | What it means |
|---|---|
| Each viewer uses their own connectors | Two people opening the same dashboard can see different data, depending on what their accounts can reach. The page never sees anyone's credentials |
| Viewers approve access first | claude.ai asks each viewer before the page's first connector call; declining lasts for that page load |
| Actions use the viewer's account too | A control that posts a message or updates an issue acts as whoever selected it |
Two consequences follow. A connector-backed artifact cannot be shared to a public link on any plan — on Pro and Max, where public is the only sharing option, that means it stays private to you. And a viewer without the connector sees an empty section rather than an error, so ask Claude to put a fallback in each live section naming the connector it needs.
Sharing within your organisation lets people comment on the page, and Claude can read and reply to those threads. Public artifacts take no comments at all — to make a commented artifact public you have to delete the threads first. After your session publishes an artifact it watches for comments while the session runs, and what happens when one arrives depends on your permission mode:
There are three ways to stop Claude replying on its own and they last different lengths of time, which is a genuinely well-judged design. A single interrupt stops it everywhere and it resumes on an artifact when you publish that artifact again. Stopping the task in the task list stops it for that artifact for the rest of the session, and republishing does not restart it. And the kill-all-background-agents chord stops it everywhere for the rest of the session. Pick the one that matches how permanently you mean it.
Artifacts need every condition met, and when one is not, Claude writes a local HTML file or says it cannot publish rather than explaining which requirement failed. The list is worth knowing because two of these are configurations people adopt for unrelated reasons.
# Turn artifacts off for your own sessions, three ways:
{ "disableArtifact": true } // settings file
CLAUDE_CODE_DISABLE_ARTIFACT=1 // environment
{ "permissions": { "deny": ["Artifact"] } } // permission rule
# Where they are silently unavailable, and Claude writes a local
# HTML file or says it cannot publish instead:
#
# an API key, gateway token or cloud-provider credential —
# the session must be backed by a claude.ai account
# Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry
# organisations with CMEK, HIPAA, or Zero Data Retention
# Agent SDK, GitHub Action and MCP-server contexts (off by default)
# CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is setOn Team and Enterprise plans the organisation-level controls are more granular than a single switch, and one of them defaults in the conservative direction:
The habit worth forming is asking for an artifact whenever you catch yourself describing something visual in prose — a comparison, a diff walkthrough, a board of options. The constraints keep it honest: one page, no backend, everything inlined, which stops it drifting into being a badly hosted application. And if you are going to share connector-backed pages, put the fallback text in from the start, because the failure mode is a section that looks broken rather than one that explains itself.
Sources & further reading