Immutable parchment for what your AI builds.
A tiny self-hostable service — or a hosted endpoint — that turns every HTML report, dashboard, or design doc your AI generates into a permanent, versioned URL your team can actually open.
Try it live → · Docs · Claude Code skill · API health
Your AI generates beautiful HTML — reports, dashboards, design docs, plans. Then those artifacts vanish into chat scrollback. You lose the URL, you lose the version, you lose the trail.
pergam fixes that. One prompt → one shareable, permanent URL. Versioned. Immutable. No accounts, no telemetry, no SaaS lock-in. Self-host it in a docker compose up, or use the hosted service for quick public links.
- 📦 Publish HTML via one
POST, get a stable URL back. - 🕰️ Versioned — every logical
idkeeps full history.v1,v2, … all reachable forever. - 🔒 Immutable — pergams can't be edited or deleted, only superseded with a new version.
- 🤖 AI-native — ships with a Claude Code skill so your agent can press "ship" and hand back a link without you babysitting
curl. - 🪞 Built-in viewer — sandboxed iframe with strict CSP. Mermaid + jsDelivr allowed; everything else blocked.
- 🏷️ Typed taxonomy —
plan,investigacion,informe,reporte,otro. Filter the index by type, author, or substring. - 🐳 Self-hostable — one Python file (~500 LOC), one Postgres table, one
docker compose up. - ☁️ Also hosted — pergam.dev for ephemeral 30-day shares. Zero setup, drag-and-drop.
- 🪶 Tiny stack — Python stdlib +
psycopgfor the server. Cloudflare Worker + KV for the hosted side. No framework, no build step.
Two paths, depending on whether you want full history or just a quick public link.
git clone https://github.com/diesilveira/pergam
cd pergam
docker compose up -d --build
curl http://localhost:1111/healthz # → {"ok":true}Publish your first pergam:
curl -sS -X POST http://localhost:1111/pergam \
-H 'Content-Type: application/json' \
-d '{"title":"Hello","html":"<h1>hi</h1>","type":"otro","author":"you@example.com"}'You'll get a view_url back — open it in a browser. That's the whole loop. ✨
Drag any .html onto pergam.dev and you get a public link. No account, no key. Same thing via the API:
curl -sS -X POST https://api.pergam.dev/share \
-H 'Content-Type: application/json' \
-d '{"title":"Hello","html":"<h1>hi</h1>"}'Response: {"token": "…", "view_url": "https://pergam.dev/s/…", "expires_at": "…"}.
Install the post-pergam skill once and any project gets a "publish this as a pergam" verb:
git clone https://github.com/diesilveira/pergam
cp -r pergam/skills/post-pergam ~/.claude/skills/Inside any project, ask Claude:
"armá un pergam de X y publicalo"
The skill auto-picks the backend based on $PERGAM_URL:
- Unset /
https://api.pergam.dev→ hosted (Flow A, ephemeral) - Local URL like
http://localhost:1111→ self-hosted (Flow B, versioned)
See skills/post-pergam/SKILL.md for the full contract — when to bump a version, the type taxonomy, and the HTML guidelines for what the AI should produce.
┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ Client │ ───→ │ pergam │ ───→ │ Postgres │
│ (AI / curl) │ │ (Python · 500 LOC)│ │ (1 table) │
└─────────────┘ └──────────────────┘ └──────────────┘
- One Python process, no framework — just
http.server+psycopg. - One Postgres table:
pergams (id, version, …)with a composite key. Latest version peridresolved via a window function on read. - Strict CSP per response: sandboxed iframe,
frame-ancestorsallowlist, no inline scripts on the viewer chrome. - Hosted side (Cloudflare Worker + KV) is a separate ~200 LOC subset: token-based, TTL-bound, no versioning. See
web/worker/.
Full schema, request flow, and config knobs → DOCS.md.
| Topic | Where |
|---|---|
| 🔌 Full API reference | DOCS.md § API |
| 🕰️ Versioning model | DOCS.md § Versioning |
| ⚙️ Configuration | DOCS.md § Configuration |
| 🚢 Deployment guide | DOCS.md § Deployment |
| 🤖 Claude Code skill | skills/post-pergam/SKILL.md |
| ☁️ Hosted Worker | web/worker/ |
| 🌐 Landing source | web/public/ |
Issues and PRs welcome. Open an issue first for non-trivial changes — happy to chat about it before you put time in.
If pergam is the shape of what you wanted, starring the repo is the highest-signal way to tell me. ⭐
MIT — do whatever, no warranty.
Built by diesilveira.dev · Live at pergam.dev · v1.0.0