# Hullwise API und MCP Hullwise prüft öffentliche Websites und vibe-gecodete Apps (Lovable, Bolt, Cursor, Claude Code, Codex, v0, Replit) von außen auf offen liegende Schlüssel, Datenlecks und Sicherheitslücken. Ein Check ruft die Seite einmal per GET ab und lädt die JavaScript-Dateien, die die Seite selbst einbindet. Dazu kommen ein TLS-Handschlag und SPF und DMARC aus dem öffentlichen DNS. REST-API unter https://hullwise.co/api/v1, MCP-Server unter https://hullwise.co/mcp. Beide prüfen gleich und nutzen dieselben Fehlercodes. Die REST-API braucht immer einen Schlüssel, der MCP-Server geht auch ohne. Jeder Befund hat eine feste ID. ## Authentifizierung - Die REST-API braucht einen Schlüssel im Header `Authorization: Bearer sc_live_…`. Echte Schlüssel: `sc_live_` plus 32 Zeichen. Gespeichert wird nur ein SHA-256-Hash. - Schlüssel anlegen und widerrufen im Konto unter https://hullwise.co/account/keys. - Test-Schlüssel `sc_test_demo`: ohne Konto, Limit des kostenlosen Zugangs, von allen geteilt. - Ohne Schlüssel gehen nur der MCP-Server und der Browser-Endpunkt GET /api/scan, je IP 20 Checks pro Stunde. Die REST-API antwortet ohne Schlüssel mit 401. - Limits pro Stunde: ohne Schlüssel 20, kostenlos 100, Business 2000. Fenster von einer Stunde ab der ersten Anfrage. Gezählt wird nicht auf die Anfrage genau, 429 immer abfangen. - Antwort-Header der REST-API: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (Unix-Zeit in Sekunden). - Ein ungültiger Schlüssel am MCP-Server ergibt HTTP 401, kein stiller Rückfall auf anonym. ## Gekürzte Berichte Ohne bezahlten Plan kürzt der Server den Bericht, bevor er ihn sendet: kostenloser Schlüssel, Test-Schlüssel `sc_test_demo`, MCP ohne Schlüssel und GET /api/scan ohne Konto mit Business. Mit einem Schlüssel aus einem Konto mit Business ist der Bericht vollständig und hat kein Feld `locked`. - Immer vollständig: url, scannedAt, https, score, grade, platforms, scripts, tls, email, disclaimer und die Zahl aller Befunde. - Vollständig sind die ersten 2 Befunde: offen liegende Schlüssel (critical: true) zuerst, dann Warnungen, dann Hinweise, zuletzt DNS-Hygiene (CAA, DNSSEC, security.txt, MTA-STS). Bei gleicher Stufe gilt die Reihenfolge exposure, versions, https, tls, headers, privacy, email, cookies, dns. - Alle übrigen Befunde: nur `sev`, `label` leer, `locked: true`. `id`, `why`, `refs` und `source` fehlen. Vor dem Verzweigen auf `id` immer `locked` prüfen. - `tech[].version` ist im gekürzten Bericht immer null. - `locked: { hidden, total }`: Zahl der gesperrten und aller Befunde. - MCP: Die Text-Antwort von scan_website endet mit `N more findings are only included with a Business plan: https://hullwise.co/pricing`. ```json { "data": { "findings": { "exposure": [{ "id": "code.secret.openai", "sev": "warn", "critical": true, "label": "OpenAI-API-Schlüssel …", "why": "…" }], "headers": [ { "id": "header.csp.missing", "sev": "warn", "label": "Kein Schutz gegen eingeschleuste Skripte (CSP)", "why": "…" }, { "sev": "info", "label": "", "locked": true }, { "sev": "info", "label": "", "locked": true } ], "email": [{ "sev": "warn", "label": "", "locked": true }] }, "locked": { "hidden": 3, "total": 5 } } } ``` ## Fehler Form: `{ "error": { "code": "…", "message": "…" } }`. Auf `code` verzweigen, `message` (Deutsch) Menschen zeigen. MCP liefert bei einem fehlgeschlagenen Check ein Tool-Ergebnis mit `isError: true` und dem Text `code: message`. Der Browser-Endpunkt GET /api/scan liefert `{ "error": "code", "message": "…" }`. - `no_url` (400): Bitte eine URL angeben. Neuer Versuch: hilft nicht. - `bad_url` (400): Das ist keine gültige Adresse. Neuer Versuch: hilft nicht. - `bad_scheme` (400): Nur http:// und https:// werden unterstützt. Neuer Versuch: hilft nicht. - `blocked_host` (400): Interne oder private Adressen werden nicht geprüft. Neuer Versuch: hilft nicht. - `dns_failed` (400): Die Adresse konnte nicht aufgelöst werden. Neuer Versuch: erst wenn der DNS-Eintrag steht. - `unauthorized` (401): API-Schlüssel fehlt oder ist ungültig. Neuer Versuch: hilft nicht. - `rate_limited` (429): Zu viele Anfragen. Bitte kurz warten. Neuer Versuch: ja, nach X-RateLimit-Reset. - `server_error` (500): Unerwarteter Fehler. Neuer Versuch: ja, einmal. - `fetch_failed` (502): Die Seite war nicht erreichbar. Neuer Versuch: ja, nach kurzer Pause. - `tls_invalid` (502): Das HTTPS-Zertifikat der Seite ist ungültig. Browser zeigen eine Warnung. Neuer Versuch: erst wenn das Zertifikat gültig ist. - `too_many_redirects` (502): Zu viele Weiterleitungen. Neuer Versuch: hilft nicht. - `not_configured` (503): Diese Funktion ist noch nicht eingerichtet. Neuer Versuch: hilft nicht. - `timeout` (504): Die Seite hat nicht rechtzeitig geantwortet. Neuer Versuch: ja, nach kurzer Pause. ## MCP Connector-URL: https://hullwise.co/mcp. Streamable HTTP über POST, zustandslos (kein Mcp-Session-Id), Antworten als JSON, kein OAuth, Schlüssel optional als Bearer-Header. Methoden: initialize, ping, tools/list, tools/call. Protokoll-Versionen: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05. ### Claude claude.ai > Einstellungen > Connectors > Eigenen Connector hinzufügen. Name Hullwise, URL https://hullwise.co/mcp. Keine Anmeldung nötig. ### ChatGPT Im Entwicklermodus (Einstellungen, Connectors) einen eigenen Connector mit der URL https://hullwise.co/mcp anlegen, Authentifizierung: keine. Menünamen können sich ändern. ### Claude Code ```bash claude mcp add --transport http hullwise https://hullwise.co/mcp # mit Schlüssel: claude mcp add --transport http --scope user hullwise https://hullwise.co/mcp --header "Authorization: Bearer $HULLWISE_API_KEY" ``` ### Codex ```toml # ~/.codex/config.toml [mcp_servers.hullwise] url = "https://hullwise.co/mcp" bearer_token_env_var = "HULLWISE_API_KEY" ``` ### Cursor ```json // ~/.cursor/mcp.json { "mcpServers": { "hullwise": { "url": "https://hullwise.co/mcp" } } } ``` Mit Schlüssel: `"headers": { "Authorization": "Bearer ${env:HULLWISE_API_KEY}" }` neben `url`. ### VS Code ```json // .vscode/mcp.json { "servers": { "hullwise": { "type": "http", "url": "https://hullwise.co/mcp" } } } ``` ### Tools - `scan_website` (Website prüfen; nur lesen, wiederholbar, greift nach außen): Prüft eine öffentliche Website oder App samt den JavaScript-Dateien, die sie selbst einbindet. Liefert Note, Punkte, erkannte Plattformen und Befunde als Text und als structuredContent (gleiche Form wie data der API). Nur Seiten prüfen, die der Person gehören oder die sie prüfen darf. - `list_checks` (Prüfpunkte anzeigen; nur lesen): Zeigt, was der Check prüft und was er bewusst nie tut. ## Endpunkte ### Scan #### Website prüfen `GET /api/v1/scan` und `POST /api/v1/scan` · MCP-Tool `scan_website` · Schlüssel nötig · nur lesen, wiederholbar, greift nach außen Ruft die Seite einmal per GET ab, folgt bis zu fünf Weiterleitungen (jede gegen interne Adressen geprüft), liest höchstens 800 KB HTML, Zeitlimit 8 Sekunden. Lädt danach die JavaScript-Dateien, die die Seite selbst über