artifact-inbox
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@artifact-inboxpush this week's research summary to my inbox as markdown"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
artifact-inbox
A self-hosted inbox for everything your AI agents produce. Agents push finished documents (PDF, markdown, HTML, text) over MCP or REST; you read, sort and mark them done in one clean web UI.

Why
I run several agents: a chat bot, a coding agent, a research agent, scheduled jobs. Each one produces real work (reports, comparisons, drafts, summaries), and each one leaves it somewhere different: a chat thread, a desktop app, a file on a server. A 10-page report scrolling past in a chat bubble doesn't get read. A week later nobody (me included) can find it.
What I wanted was a single place where every artifact from every agent lands, so there is one thing to check instead of five, and a proper reading interface instead of whatever each bot's UI happens to offer: a real PDF viewer, rendered markdown, categories, an unread/done state, and a layout that works on a phone. Agents write; I read when I have time; nothing is lost in scrollback.
So: one small container, one bearer token, and a skill that teaches any agent when to push something and when to just answer in chat.
Related MCP server: DraftRelay
Features
Agent-friendly: MCP (streamable HTTP) at
/mcp, REST at/api/push, and/install, a page an agent can follow to configure itself (plus a ready-made skill,/install/SKILL.md).Per-agent tokens with one-click setup: in the UI, Agents → Add agent gives you a single-use install link. Hand it to the agent ("install this: https://your-host/install?claim=..."); it swaps the link for its own token, and the inbox then labels everything it pushes with that name. Revoke one agent later without touching the others.
Reads well: PDFs in the browser's viewer, sanitised markdown, sandboxed interactive HTML (a pushed checklist keeps its ticks), plain text. Dark mode and phone layout.
Triage: unread/done, categories with counts, "mark all done" per category, source agent and summary on every item.
Small: Python, SQLite, one container, ~256 MB.
Markdown | Interactive HTML | Phone | Agents | |
|
|
|
|
Quick start
cp .env.example .env # set INBOX_API_TOKEN (openssl rand -hex 32), INBOX_BASE_URL, INBOX_UI_PASSWORD
mkdir -p data && sudo chown 1000:1000 data
docker compose up -d # pulls ghcr.io/mrlo/artifact-inbox (amd64/arm64); UI on http://127.0.0.1:8000To build from source instead: docker compose up -d --build. Pin a release with image: ghcr.io/mrlo/artifact-inbox:0.2.0.
Push something:
curl -sS -X POST http://127.0.0.1:8000/api/push \
-H "Authorization: Bearer $INBOX_API_TOKEN" \
-F file=@report.pdf -F title="Report title" -F category=research -F source_agent=me -F summary="One line."Connect an agent over MCP (Claude Code example):
claude mcp add --transport http artifact-inbox http://127.0.0.1:8000/mcp --header "Authorization: Bearer $INBOX_API_TOKEN"Security: read this before exposing it
Two layers, both optional to combine:
/mcpand/api/*always require a bearer token: either the admin token (INBOX_API_TOKEN) or a per-agent token.Per-agent tokens come from single-use claim links (
/install?claim=..., valid 60 minutes by default). Opening the link doesn't use it up (so chat link previews can't burn it); the agent redeems it once withPOST /api/claim. Only SHA-256 hashes of tokens and claims are stored, and the server stamps each item with the agent's registered name.The web UI is protected by built-in HTTP basic auth when
INBOX_UI_PASSWORDis set (userINBOX_UI_USER, defaultadmin). If you leave it empty, the UI is open and you must put it behind your own auth (SSO proxy, VPN/Tailscale). The default compose file binds to127.0.0.1for that reason.
Basic auth has no lockout or rate limiting, so use a long password and serve it over HTTPS (or keep it private). See docs/DEPLOYMENT.md for the model and a Traefik example (examples/compose.traefik.yml).
What the app does enforce:
Constant-time token compare; fails closed if
INBOX_API_TOKENis unset.PDFs recognised by
%PDF-magic bytes, not file names; binary non-PDF content rejected (415); 50 MB cap (413).Files stored under random ids; user-supplied names never touch the disk.
Markdown rendered with raw HTML disabled, then sanitised (nh3). HTML items run in
<iframe sandbox="allow-scripts">with a CSP that blocks network access;/raw/<id>sendsCSP: sandbox. All files carryX-Content-Type-Options: nosniff.push_artifact(url=...)fetches only public addresses (non-global IPs refused, redirects re-checked, size capped).UI POSTs reject cross-origin
Originheaders.
Known limitations: one human user (no multi-user, no per-agent permissions beyond on/off), DNS-rebinding race on URL fetch (resolve-then-connect), UI lists only the newest 500 items, no rate limiting on failed token or password attempts.
Configuration
Variable | Purpose |
| Bearer token for |
| Enables basic auth on the web UI (empty = no UI auth; rely on your proxy) |
| Basic-auth user (default |
| Minutes an install link stays valid (default 60) |
| Public URL, used in returned links and the |
| Data directory inside the container (default |
Data lives in ./data (inbox.db and files/). Back it up. Rotate the token: new value in .env,
docker compose up -d, update each agent.
Docs
docs/GUIDE.md: user guide (UI, interfaces, rules, troubleshooting)
docs/DEPLOYMENT.md: security model and reverse-proxy setups
docs/INSTALL.md: agent-facing setup page served at
/installskill/SKILL.md: agent skill (
artifact-inbox)
Try it with demo data
INBOX_API_TOKEN=... python3 scripts/seed_demo.py http://127.0.0.1:8000Adds seven fictional items (markdown, a PDF, an interactive HTML checklist, text). The screenshots above were taken this way.
Development
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt pytest && .venv/bin/python -m pytest -q testsLicense
This server cannot be deployed
Maintenance
Related MCP Connectors
Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.
Impri MCP server — human-in-the-loop approval inbox for AI agents
AI agent messaging with durable inboxes, contacts and tasks. Connect through MCP with OAuth.
1Inbox for AI agents: one address per agent to message, share files and pay other agents.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceOpen-source, self-hosted Inbox-as-a-Service API for AI agents. It enables agents to manage email inboxes, send/receive emails, search messages, and wait for replies via REST or MCP.30Apache 2.0
- AlicenseNot gradedqualityDmaintenanceA delivery outbox MCP server that enables AI agents to save polished artifacts like emails, summaries, or updates for human review and copying, supporting local and hosted modes.MIT
- AlicenseNot gradedqualityCmaintenanceA self-hosted push inbox for AI agents that enables agents to send updates and ask questions, waiting for user answers before continuing.1MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that lets AI agents manage an Agent Inbox queue via natural language. It supports listing pending items, adding new URLs with notes, and marking items as reviewed or deleted.18 npm4MIT



