# Artifacts

> Small self-contained pages — published from a file, versioned, shareable by link, and rendered on an origin of their own.

**URL:** https://inference.sh/docs/artifacts
**Last updated:** 2026-10-25

---

**Small self-contained pages — published from a file, versioned, shareable by link, and rendered on an origin of their own.**

An artifact is a single HTML or Markdown file that becomes a real page with a URL. You write the content; the platform wraps it in a document with the inference.sh design tokens, serves it under a strict Content-Security-Policy, and keeps every version you publish.

Agents publish them too. When terminal output is the wrong medium — a dashboard from data you just pulled, several options side by side, a checklist someone else has to act on — an artifact is the thing to hand over.

The same HTML page can also be an **app UI** (named on the app version as `metadata.ui.artifact`) or an **MCP Apps** resource (`ui://inference.sh/artifacts/...`) for clients connected to the [inference shell MCP server](/docs/connectors/mcp-server#mcp-apps-interactive-uis). In an MCP host the page is nested in an inference.sh viewer, which answers `window.inferencesh` for it through page-only MCP tools. The page itself only ever talks to whoever shows it, so it runs unchanged in the app, in chat, and in an MCP host.

---

## Publish one

```bash
belt artifact publish ./report.html --title "Q3 funnel" --favicon 📊
```

That prints a URL. The page is private until you share it.

Publishing the same name again creates a new version and updates the page in place for anyone who has it open. Identical content is skipped.

---

## What a page can do

By default a page is static. It can load and `fetch` its own files ([several pages](/docs/artifacts/publishing#several-pages)), and nothing else: `connect-src` is `'self'`, so it cannot call out even to us.

Every page loads `window.inferencesh`. Declare a capability and it unlocks part of it:

| capability | what it gives the page |
|---|---|
| `db` | its own small store — a poll, a checklist, a sign-up sheet |
| `user` | who is viewing: name, avatar, whether they can edit |
| `assets` | files stored beside it: images, video, fonts, PDFs |

```bash
belt artifact publish ./poll.html --capability db --capability user
```

A page gets only what its published version declared. See [capabilities](/docs/artifacts/capabilities).

---

## Where a page runs

Published pages are served from `inferenceusercontent.com`, never from the API domain, and every artifact gets its own hostname on it.

That matters for one reason: your session cookie is scoped to `inference.sh` and can never reach a page's origin. A page you were handed by a stranger runs in a different origin from the app, holds no credential of yours, and cannot reach the API as you.

Each page has two hostnames — one embedded in the viewer, one for opening it directly — so the two contexts share no storage and cannot script each other.

---

## Covers

The gallery card shows the page itself. When the platform's server covers are enabled, the API renders the top 16:9 of each newly published version, in the light and dark themes, and that becomes its cover. Rendering runs in the background, so a new version's cover can take a moment to appear.

A cover you set yourself with `images` (or `belt artifact publish --image`) is never replaced by a render. See [Covers](/docs/api/rest/artifacts#covers).

---

## Next

- [publishing](/docs/artifacts/publishing) — the file, the flags, versions, updating in place
- [capabilities](/docs/artifacts/capabilities) — the runtime, the store, limits
- [sharing](/docs/artifacts/sharing) — visibility, pinned versions, comments
