Artifacts MCP server
Commit Nov 13, 2026Allows AI clients to self-host and publish HTML, React components, Markdown, PDFs, and zipped static sites to unguessable URLs on a custom domain.
Also known as kuyazee/artifacts
- Stars
- 8
- Tools
- —
- Downloads, 30 days
- —
- Latest version
- 1.0.0
- Last commit
- Nov 13, 2026
- License
- MIT
What is Artifacts MCP?
Artifacts allows AI clients to self-host and publish HTML, React components, Markdown, PDFs, and zipped static sites to unguessable URLs on a custom domain.
Summary generated from the project's README
About Artifacts MCP server
Artifacts provides a self-hosted solution for AI clients to publish shareable content on a custom domain. It allows developers and AI agents to host various file types including HTML, React components, Markdown, PDFs, and zipped static sites. Instead of relying on third-party infrastructure, you host the service in a single container and receive unguessable URLs for every piece of content produced.
Users can interact with the server through a drag-and-drop web dashboard, a command-line interface, or a built-in MCP server. The MCP server enables tools like Claude Code or Codex to publish results with a single tool call using scoped API keys. For data persistence, the system defaults to local files but supports external storage backends like S3-compatible buckets, git remotes, or Postgres via the STORAGE_BACKEND setting.
Security is managed through two-tier authentication, separating admin dashboard access from scoped read or publish keys. Content visibility can be adjusted per artifact, ranging from private links to password-protected or public access. The system also includes specialized viewers for BPMN 2.0 process maps and Markdown, ensuring that rendered outputs look professional and remain easy to navigate.
What you can do with it
- 1Automated agent publishingAn AI agent can use the MCP server to instantly host a prototype it just created.
- 2Hosting interactive React componentsDevelopers can deploy single React components without needing a complex build pipeline.
- 3Sharing process diagramsYou can publish BPMN 2.0 files that include interactive pan and zoom capabilities.
- 4Deploying static websitesThe server can host entire static sites provided as compressed archives.
Written from the project's README. Every use case is checked against a quote from it.
How to install Artifacts MCP
Formats verified 10 Nov 2026Install Artifacts MCP in Claude Code
$ claude mcp add --env ARTIFACTS_API_KEY=<YOUR_ARTIFACTS_API_KEY> artifacts -- docker run -i --rm ghcr.io/kuyazee/artifacts:latestInstall Artifacts MCP in Cursor
~/.cursor/mcp.json
{
"mcpServers": {
"artifacts": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/kuyazee/artifacts:latest"
],
"env": {
"ARTIFACTS_API_KEY": "<YOUR_ARTIFACTS_API_KEY>"
}
}
}
}Install Artifacts MCP in VS Code
.vscode/mcp.json
{
"servers": {
"artifacts": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/kuyazee/artifacts:latest"
],
"env": {
"ARTIFACTS_API_KEY": "<YOUR_ARTIFACTS_API_KEY>"
}
}
}
}Install Artifacts MCP in Claude Desktop
claude_desktop_config.json
{
"mcpServers": {
"artifacts": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/kuyazee/artifacts:latest"
],
"env": {
"ARTIFACTS_API_KEY": "<YOUR_ARTIFACTS_API_KEY>"
}
}
}
}Install Artifacts MCP in Codex
~/.codex/config.toml
[mcp_servers.artifacts] command = "docker" args = ["run", "-i", "--rm", "ghcr.io/kuyazee/artifacts:latest"] [mcp_servers.artifacts.env] ARTIFACTS_API_KEY = "<YOUR_ARTIFACTS_API_KEY>"
Install Artifacts MCP in Gemini CLI
~/.gemini/settings.json
{
"mcpServers": {
"artifacts": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/kuyazee/artifacts:latest"
],
"env": {
"ARTIFACTS_API_KEY": "<YOUR_ARTIFACTS_API_KEY>"
}
}
}
}Configuration
ARTIFACTS_API_KEYRequiredSecretBearer token required for all writes and the MCP endpoint
BASE_URLPublic origin used in returned artifact URLs (e.g. https://artifacts.example.com)
| Name | Description | |
|---|---|---|
| ARTIFACTS_API_KEY | Bearer token required for all writes and the MCP endpoint | RequiredSecret |
| BASE_URL | Public origin used in returned artifact URLs (e.g. https://artifacts.example.com) |
Automated checks
Ran Nov 12, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work
- Source repository linked and reachablePass
- Open source license (OSI)Pass
- Commit or release in the last yearPass
- Package name not close to a popular packageNot checked
- Remote endpoint uses HTTPSNot checked
- Destructive tools are labelledNot checked
- No hidden instructions to the modelPass
- No critical advisory in the package or its dependenciesNot checked
README
View on GitHubAbout
AI assistants produce a lot of shareable output: dashboards, prototypes, reports, small apps. Claude's hosted artifacts work well, but the URLs live on someone else's infrastructure. This is the self-hosted version, about 1,100 lines. You POST content, it serves the rendered result at an unguessable URL on a domain you control.
It runs as one container with a single admin account and, by default, no database. Each artifact is a directory of plain files under /data, so backing up that directory backs up everything. On hosts that wipe local disk on restart, point it at durable external storage instead (an S3-compatible bucket, a git remote, or Postgres) by setting STORAGE_BACKEND. See deploying.
Features
- Content types. HTML, JSX/TSX (a single React component, no build step), Markdown, BPMN 2.0 process maps, PDF, and zipped static sites.
- Agent-native, human-friendly. A built-in MCP server lets Claude Code, Codex, or any MCP client publish with one tool call. Humans get a drag-and-drop web UI at
/(behind an admin login) and a CLI. - Two-tier auth. An admin logs into the dashboard with a password; CLI and MCP carry scoped, revocable API keys (
read/publish/full) with optional expiry, so you never share one master secret. - Private by default, with per-artifact visibility. A new artifact is
private, shared through a signed capability link (?k=…) you can rotate to revoke. Switch any artifact topublic(anyone with the bare link) or password-protected. Nothing is discoverable by default: unguessable slugs,noindexeverywhere. See visibility. - Optional viewer frame. A slim top toolbar (title, copy link, hide) like Claude, Gemini, and ChatGPT artifacts. Toggle it globally in Settings or per artifact;
?raw=1serves the bare content. Redirects are never framed. - Markdown render settings. Pick the reading font, content width, base font size, and starting theme for every Markdown artifact in Settings. Markdown renders from its source on each view, so a change shows on existing artifacts too. Framed Markdown gets a navbar button that cycles Auto, Light, and Dark for that reader. A fenced
mermaidcode block is drawn as a diagram that follows the theme. See docs/formats.md. - BPMN process maps. Publish a BPMN 2.0 file and it gets a diagram viewer with pan, zoom, and SVG or
.bpmndownload. The XML is checked on publish, and a file with no diagram layout gets one drawn for it, pools and lanes included, so an agent can write the process and leave the coordinates to the server. See docs/formats.md. - PDF hosting. Publish a PDF and it gets a viewer page plus a direct-download link. Three per-artifact viewer modes (standard, presentation, minimal) and a download toggle that removes the viewer's buttons. The toggle is a convenience, not protection: the file's URL still answers with the bytes. See docs/formats.md.
- Redirects.
type: "redirect"turns a slug into a short link that answers an HTTP 301 at the server, where other hosts fall back to a JavaScript bounce. The target must be an absolute http(s) URL and cannot carry credentials, and the response is uncacheable, so repointing the slug takes effect on the next visit. Repoint one from the row menu in the dashboard, or with aPUT. Read the cost of running an open redirector on your domain first: docs/formats.md. - Embeddable. A public artifact drops into any page as one
<iframe>. The row menu writes the tag for you, pointing at?raw=1so the frame holds the artifact and not a second toolbar. Private and password-protected artifacts stay unembeddable on purpose, and the unlock prompt refuses to be framed at all. See docs/embedding.md. - QR code per artifact. Every artifact has a QR of its permanent URL, from the row menu in the dashboard,
GET /api/artifacts/:slug/qr, orartifacts qr <slug>. SVG or PNG, generated in-process: no QR library, no third-party image service, nothing about your artifacts leaves the box. See the API reference. - Organize by project. Group artifacts built for the same project into collapsible sections, with a search box across project, title, slug, tags, and a redirect's target. Tags stay for cross-cutting labels.
- Lifecycle controls. Custom slugs, rename, tags, disable without deleting, auto-expire, delete.
- Abuse-resistant. Login and unlock endpoints are rate-limited per client IP (failures only), and password hashing runs off the event loop, so a burst of guesses slows those two routes instead of stalling the server. Set
TRUST_PROXYfor the real client IP behind Cloudflare or a reverse proxy. See deploying.
Quick start
Clone, configure, start:
git clone https://github.com/anvilnine/artifacts && cd artifacts
cp .env.example .env # set ARTIFACTS_API_KEY (openssl rand -hex 32) and BASE_URL
docker compose up -d
Or skip the clone and run the image directly:
docker run -d -p 3000:3000 -v artifacts-data:/data \
-e ARTIFACTS_API_KEY=$(openssl rand -hex 32) \
-e BASE_URL=https://artifacts.example.com \
ghcr.io/anvilnine/artifacts:latest
Publish something:
curl -s -X POST https://artifacts.example.com/api/artifacts \
-H "Authorization: Bearer $ARTIFACTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "<h1>hello</h1>", "type": "html", "slug": "hello", "tags": ["demo"]}'
# {"slug":"hello","url":"https://artifacts.example.com/a/hello"}
Let Claude Code publish for you:
claude mcp add --transport http artifacts https://artifacts.example.com/mcp \
--header "Authorization: Bearer ${ARTIFACTS_API_KEY}" --scope user
Documentation
| I want to… | Read |
|---|---|
| Deploy it (Docker, compose, Coolify, bare node, env vars) | docs/deploy.md |
| Use the REST API (incl. zip sites and tags) | docs/api.md |
| Publish from the terminal | docs/cli.md |
| Hook up Claude Code / Codex / any agent | docs/mcp.md |
| Set up login + scoped API keys | docs/auth.md |
| Understand JSX/TSX rendering + zip validation | docs/formats.md |
| Put an artifact inside another page | docs/embedding.md |
Development
No build step. Node ≥ 22.
npm install
cp .env.example .env # any ARTIFACTS_API_KEY works locally, e.g. "test"
npm run dev
# UI at http://localhost:3000
The end-to-end suite is one shell script:
bash .github/workflows/smoke.sh http://localhost:3000 <your-key>
A few cases cannot be reached over HTTP, such as a hand-edited auth.json. Those run as unit
tests on node's built-in runner, no server needed:
npm test
That covers the dashboard too. dashboard-check.mjs fetches /, parses the inline script in
public/index.html, and checks that every element the script grabs by id is still in the markup.
It runs no browser, so it catches a syntax error or a deleted element but not a runtime error.
PRs welcome. See CONTRIBUTING.md.
Hosted version
Self-hosting is the product, and the open source version stays complete. If you would rather not run a server, Anvil Nine is building a managed version: same publishing flow, custom domains, backups handled for you. A waitlist page opens with the first cloud announcement; watch this repo's releases until then.
Security
Uploaded HTML runs in the browser. That is the whole point, so the model is built to contain it:
- Serve artifacts from their own origin. Point artifact URLs at a domain that hosts nothing else, so a published page can never touch the dashboard's session cookie.
- Writes need a scoped API key. Publishing carries a bearer key; the admin dashboard uses a separate HttpOnly, SameSite=Strict session cookie.
- Reads rely on unguessable slugs. Public artifacts are reachable by anyone with the link and carry
noindex, but there is no listing to browse. Don't publish secrets. - Credential routes are throttled. Login and unlock rate-limit per client IP and hash passwords off the event loop. A caller below
publishscope gets a 256 kB body parser instead of the 10 MB one, and a cap of 20 large bodies a minute per client IP, both checked before the body is parsed. Put a CDN or edge limiter in front for volumetric attacks.
Full threat model in SECURITY.md.
Acknowledgements
This project stands on other people's open source. All of the following are MIT licensed.
Runtime
- express for the HTTP server
- marked for Markdown rendering
- nanoid for unguessable slug generation
- adm-zip for zip site extraction
- zod for request validation
- @modelcontextprotocol/sdk for the built-in MCP server
Optional storage backends (loaded only when selected)
- aws4fetch for S3-compatible signing
- isomorphic-git for the git backend
- pg for the Postgres backend
The SQLite backend uses Node's built-in node:sqlite (no dependency).
Web UI
- Tabler Icons for the app-bar icons (search, new, settings, lock), inlined as SVG
License
MIT © 2026 Zonily Jame
Artifacts MCP questions
How do I add Artifacts MCP to Claude Code?
Run claude mcp add --env ARTIFACTS_API_KEY=<YOUR_ARTIFACTS_API_KEY> artifacts -- docker run -i --rm ghcr.io/kuyazee/artifacts:latest in your terminal. Add --scope user to make it available in every project.
How do I add Artifacts MCP to Cursor?
Open ~/.cursor/mcp.json and add the server under mcpServers, using the Cursor config shown in the install section above.
What content types can I publish?
You can publish HTML, JSX/TSX (single React components), Markdown, BPMN 2.0 process maps, PDF, and zipped static sites.
How do I back up my artifacts?
By default, each artifact is a directory of plain files under /data, so backing up that directory backs up everything.
Can I use my own domain?
Yes, the service allows you to get an unguessable URL on a domain you control.
Is there an MCP server included?
Yes, a built-in MCP server allows Claude Code, Codex, or any MCP client to publish artifacts with a single tool call.