ANVILNINE

DROPKILN / SELF-HOSTED / MIT

Claude-style artifacts, on your domain.

POST HTML, React, Markdown, or a zipped site and get an unguessable URL on your domain. One container, MIT.

Free and MIT to self-host, forever. Pricing covers the tiers, and managed hosting is on the way.

artifacts.example.com
The Dropkiln web UI: a drop-to-publish zone above a searchable list of published artifacts grouped by project

Every row is a live page: copy the link, flip visibility, tag it, group it into a project, or disable it. A hosted demo is coming; until then the screenshot is the real UI.

Your agent publishes it.

The built-in MCP server gives Claude Code, Codex, or any MCP client a publish_artifact tool. The agent publishes the page it just wrote and replies with one link, instead of pasting hundreds of lines back into the chat.

Keys are scoped and revocable, so the one you hand an agent can publish without being able to delete.

How the MCP server works ↗

agent session artifacts · MCP
You

Publish the churn report I just built to Dropkiln, and keep it private.

Claude
Claude

Publishing it now, private visibility.

Tool call
publish_artifact published
{ type: "html", slug: "churn-jul", visibility: "private" }
→ https://artifacts.example.com/a/churn-jul-a4f9c2
Claude

Done. It's live, private so only key holders can open it.

artifacts.example.com/a/churn-jul-a4f9c2

One tool call. No shell glue, no pasted markup.

Running in 60 seconds

  1. 01 Clone, set ARTIFACTS_API_KEY and BASE_URL in .env, and docker compose up.
  2. 02 POST an .html, JSX/TSX, Markdown, or zipped site, using curl, the CLI, or the web UI.
  3. 03 Get back an unguessable URL under /a/. Public by default, private or password if you want.
artifacts zsh

$ git clone https://github.com/anvilnine/artifacts && cd artifacts

$ cp .env.example .env # set key + BASE_URL

$ docker compose up -d

$ npx github:anvilnine/artifacts publish page.html --slug hello

https://artifacts.example.com/a/hello

What you get

Four content types

POST an HTML page, a single JSX/TSX React component (no build step), Markdown, or a zipped static site. Each renders at its own URL.

.html .jsx / .tsx .md .zip

One container, plain files

By default each artifact is a directory of plain files under /data, so backing up that directory backs up everything. Point storage at S3, git, Postgres, or SQLite instead if your host wipes local disk on restart.

$ docker compose up -d

Private by default

Unguessable slugs, noindex everywhere, optional expiry. Each artifact can be public, private, or password-protected. An admin logs in with a password; the CLI and MCP carry scoped keys instead, so there is no shared master secret.

Small enough to read

About 1,100 lines, no build step, boring dependencies. An afternoon gets you the full picture of what runs on your own hardware.

Everything the API does, from your terminal.

One file, no dependencies. Run it with npx, or clone and node cli.js. Type is inferred from the file extension, and every command is a plain HTTP call you can make with curl instead.

artifacts zsh

$ artifacts publish report.html --slug churn-jul --visibility private

https://artifacts.example.com/a/churn-jul

$ artifacts deploy ./launch-site --slug launch

https://artifacts.example.com/a/launch/ (12 files)

CLI and API reference ↗

Two environment variables and a container.

The deploy guide walks the whole thing, from clone to first published URL. The source is about 1,100 lines if you would rather read it first.