Was macht host0?
host0 hostet, was Ihr Agent erstellt hat – HTML, Websites, Apps mit einer gemeinsamen Datenbank, Markdown, PDFs – unter einem Link, den Sie teilen können, so einfach wie das Teilen eines Google-Dokuments. Funktioniert mit jedem Agenten.
Das grundlegende Element ist eine App: Veröffentlichen Sie jede Datei oder jeden Ordner – ein Verzeichnis mit statischen Dateien oder eine einzelne Datei, die sich in einem Browser öffnet (PDF, Bild, einzelne HTML-Seite, Video, Audio, Markdown, CSV, Text; ein Archiv oder ein anderer Nur-Download-Typ wird abgelehnt – extrahieren Sie ein ZIP und veröffentlichen Sie den Ordner) – und erhalten Sie eine Live-URL unter https://{slug}.host0.app/ (lokale Entwicklung: http://{slug}.localhost:3000/). Jede App ist standardmäßig privat – nur der Besitzer (bei host0 angemeldet) und per E-Mail eingeladene Personen können sie öffnen. Die Freigabe für jeden mit der URL (ohne Anmeldung; ungelistet und nie indexiert) ist optional: --visibility link. --visibility public geht noch weiter – öffentlich im Web, Suchmaschinen können sie indexieren – und ist nur für Dinge gedacht, die der Benutzer in der Suche finden möchte. Die URL einer neuen App ist zufällig (k3x9q2m7ta.host0.app); benennen Sie sie in etwas Lesbares um (team-todo.host0.app), wenn der Benutzer einen schöneren Link wünscht – siehe „URL umbenennen“ unten.
Eine App kann auch gemeinsame Daten enthalten: Deklarieren Sie Datensammlungen in einer h0.json-Datei, und das Frontend erhält eine Datenbank auf seiner eigenen Herkunft, ohne Servercode. Siehe „Gemeinsame Daten“ unten – das macht aus einer Seite ein Tool, das ein Team gemeinsam nutzt.
Aktuelle Dokumentation
Die vollständige Dokumentation finden Sie unter https://host0.ai/docs – lesen Sie sie, wenn der Benutzer fragt, wie etwas funktioniert, was möglich ist, oder bevor Sie ihm sagen, dass eine Funktion nicht unterstützt wird.
Die API beschreibt sich auch selbst. Der maschinenlesbare Index:
curl -sS {base}/api/v1
Er gibt die aktuelle Endpunktliste, Dateibeschränkungen und den Plattformvertrag zurück (was host0 heute bietet). Senden Sie den API-Schlüssel (-H "authorization: bearer $HOST0_API_KEY"), und limits und plan sind die des Benutzers – die Beschränkungen hängen vom Konto-Plan ab; ohne Schlüssel erhalten Sie die Standardwerte für ein neues Konto. GET {base}/api/v1/account fügt hinzu, was das Konto in diesem Monat verbraucht hat. Wenn dieser Skill-Text und das Live-API-Verhalten voneinander abweichen, vertrauen Sie der Live-API.
So installieren oder aktualisieren Sie diesen Skill: npx skills add host0-ai/skills (jeder Agent, den die Skills CLI unterstützt; Quelle: https://github.com/host0-ai/skills), oder holen Sie zwei Dateien: https://host0.ai/skill.md → speichern als SKILL.md, und https://host0.ai/publish.sh → speichern als scripts/publish.sh daneben, dann chmod +x scripts/publish.sh. Die URL des Skripts ist /publish.sh – es gibt kein /scripts/ darin.
Voraussetzungen
- Erforderliche Binärdateien:
curl,jq(Das Skript stirbt mit einer klaren Meldung, wenn eine fehlt) - Ein API-Schlüssel, von
$HOST0_API_KEYoder~/.host0/credentials. Ohne einen startetpublish.sheine Geräteanmeldung für Sie – der Benutzer genehmigt einen Link + Code in seinem eigenen Browser (siehe „API-Schlüssel erhalten“) - Gebündelter Helfer:
./scripts/publish.sh - Netzwerk: ausgehendes HTTPS zu
host0.ai(der API) undhost0.app(Uploads und die Live-Apps). In einer Sandbox mit einer Egress-Whitelist, wenn eine Anfrage mitSSL_ERROR_SYSCALL, einem Proxy-Fehler oder einer Verbindungsverweigerung/-zurücksetzung jedes Mal fehlschlägt, sagen Sie dem Benutzer, welche Domain er zulassen soll – wiederholen Sie die Schleife nicht. - Vorübergehende Fehler treten auf: Einige Cloud-Sandboxes sehen gelegentlich Verbindungsabbrüche /
SSL_ERROR_SYSCALL/ Verbindungszeitüberschreitungen beim Erreichen vonhost0.ai.publish.shwiederholt diese selbst (Sie sehenhost0: network hiccup … retrying 2/4auf stderr) – lassen Sie es einfach laufen. Wenn Sie die API mit rohem curl aufrufen, wiederholen Sie die Anfrage selbst; für GETs und die Geräteanmeldung können Sie--retry 3 --retry-all-errorshinzufügen, niemals für POSTs, die etwas erstellen.
Eine App veröffentlichen
./scripts/publish.sh {verzeichnis} [--name "meine App"]
./scripts/publish.sh {datei} [--name "meine App"] # eine Datei: ein PDF, ein Bild, eine Seite
Gibt die Live-URL auf stdout aus (z. B. https://k3x9q2m7ta.host0.app/ – neue Apps erhalten einen zufälligen Slug; --name ist nur der Anzeigename).
Fügen Sie --client {ihr-agent} hinzu (z. B. --client claude-ai), wenn Sie nicht Claude Code, Codex, Cursor oder Gemini CLI sind – das Skript erkennt diese selbst. Es beschriftet nur die Bereitstellungsstatistiken.
Unter der Haube ist dies ein dreistufiger Ablauf: Manifest → Dateien hochladen → abschließen. Die App ist erst live, wenn der Abschluss erfolgreich ist.
Dateistruktur: index.html muss im Stammverzeichnis des von Ihnen veröffentlichten Ordners liegen – der Inhalt des Ordners wird zum Site-Stamm. Veröffentlichen Sie my-site/, wo my-site/index.html existiert, nicht einen übergeordneten Ordner, der my-site/ enthält.
Eine einzelne Datei: übergeben Sie die Datei selbst (./scripts/publish.sh report.pdf) – keine index.html erforderlich. Die Stamm-URL der App dient dieser Datei (in einem Browser-Tab öffnet sie sich im host0-Dateibetrachter – siehe Hinweis zum Badge unten; ?download ruft das Original ab, und PDFs behalten die Bereichsunterstützung für große Dateien), und sie ist auch unter /{filename} erreichbar. Verwenden Sie dies immer dann, wenn der Benutzer nur ein einzelnes Dokument oder Bild teilen möchte.
Erstellte Ausgabe bereitstellen, nicht Quelle: Wenn das Projekt einen Build-Schritt verwendet (React/Vite/Next export, .ts/.tsx/.vue/.svelte), bauen Sie zuerst und veröffentlichen Sie das Ausgabeverzeichnis (dist/, build/, out/). Veröffentlichen Sie niemals node_modules/, package.json oder Geheimnisse (.env, Schlüsseldateien) – die API lehnt Servercode und Geheimnisse mit einer umsetzbaren Meldung ab.
Kostenlos während der Beta, mit einem Badge: host0 ist während der Beta kostenlos, und jede App befindet sich im kostenlosen Plan, der ein kleines „Hosted on host0"-Badge hinzufügt, das in der unteren rechten Ecke jeder HTML-Seite fixiert ist (ca. 28px hoch, 12px von den Rändern entfernt). Lassen Sie daher dort etwas Platz (kein fixierter Button oder Chat-Bläschen bündig in dieser Ecke) und versuchen Sie nicht, es zu verstecken. Eine PDF-, Bild-, Video-, Audio- oder Textdatei (.txt, .csv, .md, .json), die direkt in einem Browser-Tab geöffnet wird, öffnet sich in einem host0-Dateibetrachter: Die Datei füllt das Fenster, mit einer schmalen Leiste darunter (Dateiname, Download, „Hosted on host0"), die sie nie verdeckt. Die Rohdatei wird weiterhin für <img>/<video>-Tags, Einbettungen, fetch(), curl, Link-Vorschauen und Suchmaschinen ausgeliefert; ?download auf jeder Datei-URL lädt das Original herunter. Andere Dateien (ZIP, Schriftarten, JS, CSS) werden so ausgeliefert, wie sie sind. Ob der Plan des Benutzers das Badge anzeigt, ist plan.badge in GET {base}/api/v1 (mit seinem Schlüssel). Wenn der Benutzer nach Preisen oder dem Entfernen des Badges fragt: Wenn dieser Index eine plans-Liste hat, benennt sie jeden Plan, seinen Preis und was er ändert (ein Plan mit badge: false entfernt es) – verweisen Sie ihn auf {base}/pricing; wenn es keine plans-Liste gibt, ist host0 während der Beta kostenlos, und kostenpflichtige Pläne können später kommen und ihm möglicherweise erlauben, es zu entfernen.
Analysen, integriert: host0 zählt Besuche jeder App ohne Cookies – ein winziges Same-Origin-Skript (/.h0/a.js) wird jeder HTML-Seite hinzugefügt, und geöffnete PDFs werden serverseitig gezählt. Der Besitzer sieht Besucher, Seiten, Referrer, Länder und Geräte im Dashboard-Reiter Analysen, mit GET {base}/api/v1/apps/{app_id_or_slug}/analytics?period=7d (Zeitraum: 24h, 7d, 30d, 90d, 365d; 400 invalid_period sonst; optionale Filter page=/path, referrer=host oder (direct), country=DE oder (unknown), device, browser grenzen jede Zahl ein – 400 invalid_filter bei fehlerhafter Eingabe), oder das MCP-Tool get_analytics. Entfernen Sie das Skript nicht. Wenn die App eine Content-Security-Policy setzt, erlauben Sie 'self' in script-src und connect-src. Wenn der Benutzer fragt: „Wie viele Leute haben es geöffnet?", antworten Sie von diesem Endpunkt.
Eine App aktualisieren
./scripts/publish.sh {verzeichnis} --slug {slug} # oder --app-id {uuid}
Ohne Flag löst das Skript die App aus .host0/state.json im veröffentlichten Verzeichnis auf (für eine einzelne Datei: .host0/state.json neben der Datei, mit dem Dateinamen als Schlüssel, sodass zwei Dateien in einem Ordner zwei Apps bleiben), und erstellt eine neue App nur, wenn nichts übereinstimmt. Unveränderte Dateien werden serverseitig per Hash übersprungen – die erneute Veröffentlichung einer großen Site mit einer bearbeiteten Datei lädt eine Datei hoch.
Fügen Sie --message "was geändert wurde" (maximal 200 Zeichen) hinzu, um der neuen Version einen Hinweis zu geben – z. B. --message "Fälligkeitsdatumsspalte hinzugefügt". Tun Sie dies immer, wenn Sie eine Änderung veröffentlichen, die der Benutzer angefordert hat; es ist das, was er in der Versionsliste sehen wird.
Versionen und Rollback
Jede Veröffentlichung, die live geht, ist eine nummerierte Version der App (v1, v2, …) – publish_result.version ist diese, publish_result.previous_version die, die sie ersetzt hat. Frühere Versionen werden für eine Anzahl von Tagen aufbewahrt, die vom Plan abhängt – GET {base}/api/v1 (mit dem Schlüssel) → limits.account.version_retention_days (0 = nur die Live-Version); ältere werden automatisch gelöscht.
Wenn der Benutzer eine Änderung rückgängig machen möchte („Rollback", „die alte wiederherstellen", „das hat es kaputt gemacht"), stellen Sie eine frühere Version wieder her – sie wird innerhalb einer Minute als neue Version für alle live, ohne erneutes Hochladen:
# Liste anzeigen, neueste zuerst (Version, live, Nachricht, Client, wiederhergestellte_Version, erstellt_am)
curl -sS {base}/api/v1/apps/{app_id_or_slug}/versions \
-H "authorization: bearer $HOST0_API_KEY"
# Version 3 wiederherstellen (akzeptiert auch v3); der Body ist optional
curl -sS -X POST {base}/api/v1/apps/{app_id_or_slug}/versions/3/restore \
-H "authorization: bearer $HOST0_API_KEY" \
-H "content-type: application/json" \
-d '{"message": "Zurück vor das Redesign"}'
- Die Antwort enthält
version(die neue),restored_from_versionundprevious_version– sagen Sie dem Benutzer: „Version 3 ist wieder live als Version 9", und dass die Wiederherstellung von Version 8 dies rückgängig macht. - Bestätigen Sie mit dem Benutzer vor dem Wiederherstellen: Es ändert, was jeder sieht, der die App öffnet.
- Gemeinsame Daten werden durch eine Wiederherstellung nie geändert. Die
h0.jsonder wiederhergestellten Version bestimmt, welche Sammlungen bereitgestellt werden – eine, die sie nicht deklariert, ist versteckt (noch im Export) und kommt zurück, wenn eine neuere Version wiederhergestellt wird. - Die Wiederherstellung dessen, was bereits live ist, gibt
already_live: truezurück und fügt keine Version hinzu – wiederholen Sie es nicht in einer Schleife. - 404
version_not_found: Diese Version wird nicht mehr aufbewahrt – listen Sie die Versionen auf und bieten Sie eine an, die es ist; präsentieren Sie niemals eine ältere, gelöschte Version als wiederherstellbar. 409version_not_restorable: Ihre Dateien sind weg – veröffentlichen Sie sie erneut aus den Dateien des Benutzers. 403versions_not_in_plan: Der Plan des Benutzers behält nur die Live-Version – veröffentlichen Sie die Dateien erneut, die er live haben möchte, und siehe „Wenn ein Fehlerupgrade_urlhat". - Setzen oder löschen Sie später einen Hinweis mit
PATCH {base}/api/v1/apps/{app_id_or_slug}/versions/{n}und{"message": "…"}(odernull). Der MCP-Server des Toolslist_versionsundrestore_versiontun dasselbe wie die obigen Aufrufe, und der Reiter Versionen der App im Dashboard hat einen Wiederherstellen-Button.
Zugriffskontrolle
Eine host0-App verwendet jeweils eine Sichtbarkeit:
private(Standard): nur der Besitzer und eingeladene E-Mails; Besucher melden sich an, um zu sehen. Jede neue App beginnt hier.link– „Jeder mit dem Link": Jeder mit der URL kann sehen, ohne Anmeldung. Die App ist ungelistet und wird nie indexiert (jede Antwort trägtX-Robots-Tag: noindex), und ihre URL ist zunächst zufällig – aber ein Link verbreitet sich, und eine umbenannte, lesbare URL kann erraten werden – halten Sie alles Vertrauliche privat.public– „Öffentlich im Web": Jeder kann sehen und Suchmaschinen können sie indexieren (die eigenen Seiten der App werden mitX-Robots-Tag: allausgeliefert). Opt-in und pro Konto gedeckelt (403public_app_limit_reached, mitmax_public_appsim Body). Verwenden Sie es nur, wenn der Benutzer möchte, dass die App in der Suche gefunden wird – ein Portfolio, eine Landingpage, Dokumentation, ein öffentliches Tool. Niemals für etwas Vertrauliches.
Wenn der Benutzer einen Link möchte, den jeder öffnen kann (eine Seite zum Herumschicken, eine Demo, ein gemeinsam genutztes PDF), veröffentlichen Sie mit --visibility link – das ist es, was „öffentlich machen" oder „Link teilen" fast immer bedeutet. Wählen Sie public nur, wenn er sagt, dass er es auf Google / in Suchergebnissen haben möchte; wenn es unklar ist, fragen Sie nach. Gemeinsame Daten funktionieren bei link und public gleich. Legen Sie die Sichtbarkeit beim Veröffentlichen mit --visibility private|link|public fest, oder jederzeit über die API:
curl -sS {base}/api/v1/apps/{app_id_or_slug} -X PATCH \
-H "authorization: bearer $HOST0_API_KEY" \
-H "content-type: application/json" \
-d '{"visibility": "link"}'
Wenn der Wechsel zu public public_app_limit_reached zurückgibt, teilen Sie dem Benutzer mit, dass das Konto sein Limit an Apps öffentlich im Web erreicht hat, und bieten Sie stattdessen link an (jeder mit der URL, nicht indexiert) oder verschieben Sie eine andere öffentliche App zurück zu link.
URL umbenennen
Die URL einer neuen App ist ein zufälliger Slug wie k3x9q2m7ta.host0.app. Um ihr einen lesbaren zu geben, überprüfen Sie den Namen, dann benennen Sie um:
curl -sS {base}/api/v1/slugs/team-todo -H "authorization: bearer $HOST0_API_KEY"
# → {"slug":"team-todo","available":true} (oder available:false + ein Grund)
curl -sS {base}/api/v1/apps/{app_id} -X PATCH \
-H "authorization: bearer $HOST0_API_KEY" \
-H "content-type: application/json" \
-d '{"slug": "team-todo"}'
# → {"app_id":"…","slug":"team-todo","url":"https://team-todo.host0.app/","old_slug":"k3x9q2m7ta",…}
Slugs bestehen aus 1–63 Kleinbuchstaben, Ziffern oder Bindestrichen, ohne Bindestrich am Anfang oder Ende. Ein belegter Slug gibt 409 slug_taken zurück; ein fehlerhafter oder reservierter 422 invalid_slug. Die Live-Bereitstellung, Datensätze und Freigaben werden mit der App verschoben, und publish.sh aktualisiert sie weiterhin (es verfolgt die App-ID). Für 30 Tage leitet die alte URL (301) auf die neue um und bleibt für den Benutzer reserviert, dann wird sie freigegeben – sagen Sie dies, bevor Sie einen Link umbenennen, den Leute bereits haben. Die URL einer gelöschten App ist ebenfalls für 30 Tage reserviert (sie gibt 404 zurück). Ein Slug, der in den letzten 30 Tagen von einem anderen Konto verwendet wurde, gibt 409 slug_taken zurück („wurde kürzlich von einer anderen App verwendet"). Der Benutzer kann ihn auch auf dem Reiter Einstellungen der Dashboard-Seite der App umbenennen.
Der Anzeigename der App (angezeigt im Dashboard und GET /api/v1/apps) ist getrennt von ihrer URL – ändern Sie ihn mit PATCH {base}/api/v1/apps/{app_id} {"name": "Team-Todo"} (1–100 Zeichen); die URL ändert sich nicht.
Teilen
Laden Sie Personen per E-Mail ein mit POST /api/v1/apps/{app_id_or_slug}/shares (Body {"emails": ["[email protected]"]}); entfernen Sie einen mit DELETE /api/v1/apps/{app_id_or_slug}/shares/{email}.
Neue Freigaben erhalten individuelle Einladungs-E-Mails mit Anmelde- und Registrierungslinks. Überprüfen Sie invite_delivery in der Antwort: accepted bedeutet, dass der E-Mail-Server die Zustellung akzeptiert hat.
…
[gekürzt zur Übersetzung]