Paddenstoel

Technical guide for agents publishing static websites.

Read the same guide as Markdown.

Publish a website with Paddenstoel

Paddenstoel hosts small static websites in the EU. HTML version.

Install Mycelium: https://paddenstoel.app/install.sh. Select --zone paddenstoel.

Before publishing

Make sure the user has agreed to publish these files publicly. For an upload without a configured key, use their real email address; ask only if you do not have it. Never invent an address or use a placeholder or disposable inbox. The address is not shown on the website.

Build first. Upload only public output with a nonempty root index.html, plus its assets. Never upload secrets, .env, source projects, node_modules, or unpublished personal data. Limits: 25 MiB total, 10 MiB per file, 500 files, 240-byte relative paths. Static HTML, CSS, JavaScript, images, fonts and media work; server-side code does not. Forms and pop-ups are disabled.

Choose a route your tools support

  1. Shell with permitted network access: use tar and curl below. No CLI installation is required. With a configured or linked key, use the trusted route: no email question. Asked to link Paddenstoel or to work without email codes? Follow link a key. Never ask for a key in chat.
  2. No shell, but a tool can send HTTP POST: send JSON directly as below. A browsing/search tool that only reads pages cannot publish.
  3. No publishing tools or no network permission: say you cannot upload. If your tools can create attachments, provide the finished website as downloadable files (index.html for a single-page site). Otherwise provide the finished HTML as text: tell the user to paste it into a text editor and save as index.html, not index.html.txt. For assets, preserve filenames and folders. Send them to Zet je website online, where they choose “Zelf uploaden”, select the files and enter their email. Never put email in the URL or fabricate an attachment, upload or live website.

Check tool availability, especially on phones; never assume shell or POST access.

Confirmation email language

Match the language of the user's request or conversation, not this English guide. Use CLI --lang en/--lang nl or API lang=en/lang=nl with publish or update. Verified preferences win; anonymous hints never overwrite them. Default: Dutch.

Shell upload

Set EMAIL to the user's real address. Upload their existing finished output folder, shown here as dist. Replace dist with their actual output path. This command never creates or overwrites website files.

: "${EMAIL:?Set EMAIL to the real email address of the user}"
test -s dist/index.html || { printf '%s\n' 'Missing nonempty dist/index.html' >&2; exit 1; }
COPYFILE_DISABLE=1 tar -czf - -C dist . |
  curl -sS --fail-with-body --data-binary @- \
    -H "Paddenstoel-Email: $EMAIL" 'https://paddenstoel.app/api/v1/grow'

Direct HTTP upload

Replace REPLACE_WITH_USERS_REAL_EMAIL before sending. Use the user's finished HTML and asset contents, not this demonstration page. Keep a nonempty root index.html; JSON strings must be escaped correctly.

Send POST https://paddenstoel.app/api/v1/grow with Content-Type: application/json:

{"email":"REPLACE_WITH_USERS_REAL_EMAIL","files":[{"path":"index.html","content":"<!doctype html><html lang=\"nl\"><meta charset=\"utf-8\"><title>Mijn website</title><h1>Hallo!</h1></html>"}]}

Use the platform origin, not a tenant hostname. Optional naming: if the user supplies words, append ?slug=chosen-words. Names allow up to 58 ASCII letters, digits and single hyphens between words. Omit it for automatic naming; never require another question or guess the URL.

Read the result

Ordinary new uploads return HTTP 202 with status: "pending_confirmation", url, statusUrl and expiresAt. This is not live: uploaded files are not served yet. Tell the human to open Paddenstoel's email, follow its link, and deliberately confirm publication on that page within 12 hours. Check spam if needed. Unconfirmed sites and files are deleted after 12 hours. Never open their mailbox, confirm for them, or bypass confirmation.

Use only the returned url. Report live publication only for status: "live"; a configured key can publish immediately. Errors include a code and hint; honor Retry-After, fix the cause, and do not retry blindly.

Update a live site

Update the existing live site at the same URL, rather than grow a new site. Use its full slug from the existing URL. Prefer a configured or linked personal publishing key through the trusted route: no email or code question. If your shell keeps files between sessions, offer to link a key once; later updates need no codes. Never ask for a key in chat.

Without a key:

  1. Use the original exact email address the site was published with, not an alias or plus-tag variant. If the site or email is unknown, send the human to Mijn paddenstoelen: they log in with a 6-digit code from their mail and see their sites. Never ask for that code.
  2. Send POST https://paddenstoel.app/api/v1/sites/{slug}/update with the same grow body formats and email headers/fields shown above (tar with Paddenstoel-Email, or JSON with email and files). Upload only the finished public files.
  3. HTTP 202 with status: "update_requested" is not live. Keep your own returned requestId; ask the human for the six-digit code from Paddenstoel's email. It expires in one hour.
  4. Send POST https://paddenstoel.app/api/v1/updates/{requestId}/confirm with Content-Type: application/json and {"code":"REPLACE_WITH_USERS_CODE"}, replacing the placeholder with the human-provided code. Confirm only the requestId your own update call returned. HTTP 200 with status: "live" confirms publication; use the returned url.

Never access the mailbox yourself or guess a code. The previous version stays unchanged until confirmed.

No upload tools or network permission? Use the file/text handoff above and send the human to Mijn paddenstoelen. They log in with their own emailed login code, select the correct existing site and upload the finished files there themselves. Never ask for that login code.

Pilot

Tell the user to keep their own copy: this pilot may reset and every site may disappear, including live sites. Owners can download their files, take a site offline or remove it at Mijn paddenstoelen. By confirming the site, its owner accepts the Dutch terms. Live sites last six months and cannot be extended yet; the owner is emailed 14 days before the end.

See the full reference for same-URL updates, keys, retries, limits and errors. Never submit feedback on the user's behalf. Privacy; report abuse to abuse@paddenstoel.app.