Feedback

PerfDelta API: MCP und REST-API

Stand: 16. Oktober 2026.

PerfDelta bietet zwei Wege, Pagespeed-Messungen automatisiert zu starten, Ihre Projekte zu verwalten und die vollständigen Ergebnisse abzurufen: MCP für KI-Agenten wie Claude, ChatGPT oder Cursor und eine REST-API mit einfachem JSON für Zapier, Make oder eigene Dashboards. Beide nutzen denselben API-Schlüssel und dasselbe Budget wie die App. Wie jeder Wert gemessen wird, beschreibt die Methodik.

Zugang je Tarif

TarifMCPREST-APIPagespeed-Abfragen pro MonatPagespeed-Abfragen pro Tag für manuelle Messungen, MCP und REST
Freeneinneinkeineeine Messung mit bis zu drei Seiten in der App
Solojanein600120
Agencyjaja4.000800
Scalejaja12.0002.400

API-Schlüssel legen Sie auf der Seite API-Schlüssel in Ihrem Konto an. Team-Mitglieder nutzen Tarif, Projekte und Budget des Team-Inhabers.

Authentifizierung

Jede Anfrage trägt den API-Schlüssel als Bearer-Token:

Authorization: Bearer IHR_API_KEY

Für den Connector von Claude.ai, der keine Header senden kann, nimmt der MCP-Endpunkt den Schlüssel auch als URL-Parameter: https://perfdelta.com/api/mcp.php?key=IHR_API_KEY. Wer diese URL kennt, kann Ihren Schlüssel nutzen. Halten Sie sie deshalb geheim und widerrufen Sie den Schlüssel, falls sie bekannt wird. Die REST-API akzeptiert nur den Header.

REST: Ohne gültigen Schlüssel antwortet die API mit 401 unauthorized. Nach 20 Fehlversuchen innerhalb von 15 Minuten von derselben IP-Adresse antwortet sie mit 429 too_many_failed_attempts und Retry-After in Sekunden. Ein Tarif ohne Zugang bekommt 403 upgrade_required mit dem Tarif, der ihn enthält. MCP folgt denselben Regeln, antwortet aber mit JSON-RPC-Fehlern, siehe MCP-Fehler. Fehlversuche zählen für MCP und REST getrennt.

Budget und Kosten

Der Parameter devices legt fest, was gemessen wird: both (Standard), mobile oder desktop. Ein einzelnes Gerät halbiert die Kosten.

REST-API

Basis-URL: https://perfdelta.com/api/v1. Alle Antworten sind JSON. Zeiten stehen in deutscher Ortszeit (Europe/Berlin) im Format JJJJ-MM-TT HH:MM:SS.

Messung starten: POST /scans.php

Body als JSON oder formularkodiert: url (absolute, öffentlich erreichbare URL) oder url_id (eine URL aus Ihren Projekten, siehe /urls.php), dazu optional devices, project_id und scope. Kommen beide, gilt url. Mit project_id wird eine URL, die noch in keinem Ihrer Projekte steht, zuerst in dieses Projekt aufgenommen, wie mit „URL hinzufügen“ auf der Projektseite. Sie zählt dann auf Ihr URL-Limit, und die Messung erscheint in Dashboard und Projektverlauf. scope legt den Messumfang fest: url (Standard) misst nur diese URL. group misst alle URLs ihrer Projektgruppe auf derselben Domain wie der Scan-Knopf der Projektseite und kostet je URL und Gerät eine Abfrage. Teilt sich die URL ihre Gruppe mit weiteren URLs, erscheinen nur Gruppenmessungen in ihrem Projektverlauf. Eine Einzelmessung bleibt über scan_id und report_url abrufbar.

curl -X POST -H "Authorization: Bearer IHR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/", "devices": "both"}' \
  "https://perfdelta.com/api/v1/scans.php"

Antwort 202:

{
  "scan_id": "7c88c55c1d1bc8f6727d8d19ba9c9a00",
  "status": "running",
  "devices": "both",
  "scope": "url",
  "measured_urls": 1,
  "cost": 2,
  "report_url": "https://perfdelta.com/en/r/example.com/7c88c55c-1d1b-c8f6-727d-8d19ba9c9a00",
  "budget_remaining": 11936,
  "daily_remaining": 2398,
  "project_id": 3,
  "url_id": 41,
  "added_to_project": true
}

budget_remaining ist, was in diesem Monat nach dem Bedarf des Monitorings für manuelle Messungen, MCP und REST übrig bleibt; daily_remaining ist der Rest des heutigen Tagesdeckels. project_id und url_id nennen die Projekt-URL, zu der die Messung gehört (null bei einer URL außerhalb Ihrer Projekte); added_to_project ist true, wenn diese Anfrage die URL aufgenommen hat. scope wiederholt den Messumfang, measured_urls nennt die Zahl der URLs dieser Messung.

Messstand und Ergebnis: GET /scans.php?id={scan_id}

Liefert status (running, done oder error), started_at und report_url. Bei running kommen step, step_total, step_msg, updated_at und die bereits gemessenen pages (Format wie unten) hinzu, damit sich eine langsame von einer stehenden Messung unterscheiden lässt und fertige Seiten früh lesbar sind; bei error das Feld error. Bei done kommen mobile_score, desktop_score (durchschnittlicher Laborwert der gemessenen Seiten von 0 bis 100, null für ein nicht gemessenes Gerät), measured_at und pages hinzu: je gemessener Seite und Gerät ein Eintrag mit url, device, score, lab (lcp_ms, cls, fcp_ms, tbt_ms, ttfb_ms aus Lighthouse) und field (lcp_ms, inp_ms, cls, fcp_ms, ttfb_ms am 75. Perzentil echter Chrome-Nutzer, null ohne ausreichende Felddaten). Eine Messung dauert meist ein bis drei Minuten; fragen Sie alle 15 bis 30 Sekunden ab. Nur das Konto, das die Messung gestartet hat, kann sie abrufen, jeder andere Schlüssel bekommt 404. Die id darf auch mit Bindestrichen wie in report_url geschrieben sein; Groß- und Kleinschreibung spielt keine Rolle.

curl -H "Authorization: Bearer IHR_API_KEY" \
  "https://perfdelta.com/api/v1/scans.php?id=7c88c55c1d1bc8f6727d8d19ba9c9a00"

Budget: GET /usage.php

Felder: plan, unit (immer PageSpeed tests (one per URL and device)), daily_limit, daily_used, daily_remaining, monthly_budget, monthly_used, monitoring_projected (Bedarf des Monitorings pro Monat mit den aktuellen Einstellungen), monitoring_remaining_need (Bedarf bis Monatsende), available_for_manual_scans und upgrade_plan (nächster Tarif mit mehr Kapazität, null bei Scale). Alle Werte sind Pagespeed-Abfragen. Ohne Monatsbudget ist monthly_budget gleich null, und die vier Felder von monthly_used bis available_for_manual_scans entfallen.

Daten abrufen

EndpunktLiefert
GET /projects.phpprojects: id, name
GET /urls.php?project_id={id}urls: id, url, monitoring_enabled, last_monitored_at, within_plan_limit (false: jenseits Ihres URL-Limits, wird nicht gemessen)
GET /history.php?url_id={id}history, neueste zuerst: hash, created_at, mobile_score, desktop_score
GET /report.php?url={url}letztes fertiges Ergebnis jeder gemessenen Domain: status, mobile_score, desktop_score, measured_at, report_url, scan_id (für /details.php), mobile_measured_at und desktop_measured_at. Hat die jüngste Messung nur ein Gerät erfasst, stammt der andere Score aus der letzten früheren Messung mit diesem Gerät, mit deren Datum in mobile_measured_at bzw. desktop_measured_at (null, wenn das Gerät nie gemessen wurde). Läuft eine neuere Messung oder ist sie fehlgeschlagen, zusätzlich latest_status und latest_started_at. Ohne fertige Messung steht in status der Stand der jüngsten Messung, Scores und measured_at sind dann null. Unbekannte Domain: status: not_found. Es zählt nur der Host von url, ein Pfad wird ignoriert; den Parameter URL-kodiert übergeben.
GET /fixes.php?url={url}&lang=depriorisierte Maßnahmen aus der letzten fertigen Messung jeder gemessenen Domain, ohne Messung: status, measured_at, report_url, platform (erkanntes CMS oder Framework), field (source, p75, rating von LCP, INP und CLS bei echten Nutzern) und fixes, wichtigste zuerst. Je Maßnahme: id, type, title, problem, action (Text passend zur Plattform, lang en oder de), metrics (betroffene Core Web Vitals), fails_in_field (die betroffene Metrik, die bei echten Nutzern durchfällt, sonst null), impact (eines von estimated_savings_ms, estimated_savings_bytes, unused_bytes, main_thread_ms, transfer_bytes, total_blocking_time_ms, lcp_phase_ms, cls), devices, pages, files (url, wasted_bytes, wasted_ms, estimated), elements (HTML der verschobenen Elemente), benchmark (share der gemessenen Websites mit diesem Befund, median_ms typische Einsparung bzw. Hauptthread-Zeit dort, scope, platform, domain_count), observed_effect (metric, median_delta, n, scope: Median der Veränderung der Laborkennzahl, wo die Maßnahme zwischen zwei Messungen verschwand, ab zehn Beobachtungen) und guide_url.
GET /changes.php?url={url}&lang=dewas sich zwischen der letzten und der vorigen fertigen Messung geändert hat, ohne Messung: status (done, no_baseline ohne frühere Messung mit gespeicherten Seitendaten, not_found), measured_at, previous_measured_at, report_url, verglichene page und device, scores und previous_scores (mobile, desktop), changes (kind, direction worse, better oder neutral, summary, dazu je nach Art resource_type, name, phase, id, before, after, bytes) und implemented (Maßnahmen der vorigen Messung, die jetzt verschwunden sind: title, metric, before_value, after_value, delta).
curl -H "Authorization: Bearer IHR_API_KEY" \
  "https://perfdelta.com/api/v1/report.php?url=https%3A%2F%2Fexample.com%2F"

Vollständiger Report: GET /details.php?id={scan_id}

Dieselbe Antwort wie das MCP-Tool get_report_details, beschrieben weiter unten: alles, was die Report-Seite ihrem Eigentümer zeigt. id ist eine scan_id aus /scans.php oder /report.php oder ein hash aus /history.php; alternativ liefert url_id die neueste Messung einer Projekt-URL. Abrufbar sind selbst gestartete Messungen und jede Messung einer URL aus Ihren Projekten, auch Monitoring-Läufe. Jede andere Messung antwortet mit 404 not_found, eine Anfrage ohne id und url_id mit 422 missing_id. Kostenlos.

curl -H "Authorization: Bearer IHR_API_KEY" \
  "https://perfdelta.com/api/v1/details.php?id=7c88c55c1d1bc8f6727d8d19ba9c9a00"

Projekte, URLs, Wettbewerber und Notizen verwalten

Es gelten dieselben Regeln wie in der App: Tarife ohne mehrere Projekte haben ein Projekt, URLs zählen über alle Projekte gegen das URL-Limit Ihres Tarifs, angenommen werden nur öffentliche http(s)-URLs, und die Zahl der Wettbewerber je Projekt hängt vom Tarif ab. Bodys sind JSON; POST nimmt auch Formularfelder an.

EndpunktBody oder ParameterLiefert
POST /projects.phpname201 mit id, name
POST /urls.phpproject_id und url oder urls als Liste mit bis zu 100 Einträgenadded (id, url) und skipped (url, reason: invalid_url, duplicate oder url_limit_reached); 201, wenn mindestens eine URL aufgenommen wurde, sonst 200. URLs ohne Schema bekommen https://
PATCH /urls.phpurl_id, monitoring_enabled (true oder false)id, monitoring_enabled
DELETE /urls.php?url_id={id}keinedeleted mit der ID; fertige Reports bleiben erhalten
GET /competitors.php?project_id={id}keinecompetitors: id, domain
POST /competitors.phpproject_id, domain (Domain oder URL)201 mit id, domain; verglichen ab der nächsten Messung
DELETE /competitors.php?project_id={id}&id={competitor_id}keinedeleted mit der ID
GET /notes.php?id={scan_id}keinenotes: Ihre Notizen zu einer Messung mit id, note, created_at
POST /notes.phpscan_id, note (höchstens 280 Zeichen)201 mit id, scan_id, note, created_at; nur in Tarifen mit unbegrenzter Historie, die Notiz erscheint in der Report-Historie
PATCH /notes.phpnote_id, noteid, note; in jedem Tarif
DELETE /notes.php?note_id={id}keinedeleted mit der ID; in jedem Tarif
curl -X POST -H "Authorization: Bearer IHR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id": 6, "urls": ["https://example.com/", "https://example.com/preise/"]}' \
  "https://perfdelta.com/api/v1/urls.php"

Performance-Budgets als CI-Gate: /budgets.php

Ein Performance-Budget ist eine Grenze, die eine Seite nicht überschreiten darf, etwa Seitengewicht höchstens 1,5 MB, JavaScript höchstens 400 KB, LCP im Labor höchstens 2,5 s oder ein Lab-Score von mindestens 80. Budgets gelten je Projekt (alle URLs) oder je Projekt-URL, die dann für diese URL das Projekt-Budget ersetzt. Jedes Budget kann ein Ziel tragen; Ziele stehen neben dem Ergebnis und lassen keine Prüfung scheitern. Bewertet werden Werte, die jede Messung ohnehin liefert, eine Prüfung kostet also nichts über die Messung hinaus. Enthalten in allen bezahlten Tarifen; für den REST-Endpunkt gelten die REST-Regeln oben.

EndpunktBody oder ParameterRückgabe
GET /budgets.php?scan_id={scan_id}optional url für eine einzelne Seite, optional fail_status=1status (done, running oder no_budgets), passed (true, false oder null, solange die Messung läuft oder kein Budget greift), summary (over, ok, no_data) und je Projekt-URL url_id, url, passed und budgets mit metric, device, unit, direction (at_most oder at_least), value, limit, goal, status (ok, over, no_data), goal_met, headroom und scope (project oder url). Mit fail_status=1 antwortet eine nicht bestandene Prüfung mit 409, sodass curl --fail den Build ohne jq abbricht
GET /budgets.php?url_id={id}keinedieselbe Prüfung für die jüngste fertige Messung dieser Projekt-URL
GET /budgets.php?project_id={id}keinebudgets: url_id (null beim Projekt-Budget), metric, device, unit, limit, goal, source, updated_at
POST /budgets.phpproject_id, metric, device (mobile oder desktop, Standard mobile), limit, optional goal und url_id; delete: true entfernt das Budgetdas gespeicherte Budget; 422 invalid_metric oder 422 invalid_value bei ungültiger Eingabe

Kennzahlen: total_kb, script_kb, image_kb, stylesheet_kb, font_kb, third_party_kb, third_party_count, request_count, perf_score (Mindestwert), lab_lcp_ms, tbt_ms, lab_cls, fcp_ms, ttfb_ms und aus Felddaten (CrUX p75, nur mobil) field_lcp_ms, field_inp_ms, field_cls. limit und goal sind Zahlen in der Einheit der Kennzahl (KB, ms, Punkte, Anzahl, CLS) oder Text mit Einheit wie "1.5 MB" oder "2.5 s". Nicht zu verwechseln mit dem monatlichen Budget an Pagespeed-Abfragen in /usage.php.

curl -X POST -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id": 6, "metric": "script_kb", "device": "mobile", "limit": "400 KB", "goal": 300}' \
  "https://perfdelta.com/api/v1/budgets.php"

Eine Prüfung in der Deployment-Pipeline, etwa als Schritt in GitHub Actions nach dem Deploy auf Staging: Messung der URL starten, warten, bis sie fertig ist, dann die Budgets prüfen.

SCAN=$(curl -s -X POST -H "Authorization: Bearer $PERFDELTA_API_KEY" \
  -H "Content-Type: application/json" -d '{"url": "https://staging.example.com/"}' \
  "https://perfdelta.com/api/v1/scans.php" | jq -r .scan_id)
until [ "$(curl -s -H "Authorization: Bearer $PERFDELTA_API_KEY" \
  "https://perfdelta.com/api/v1/scans.php?id=$SCAN" | jq -r .status)" != "running" ]; do sleep 20; done
curl --fail -s -H "Authorization: Bearer $PERFDELTA_API_KEY" \
  "https://perfdelta.com/api/v1/budgets.php?scan_id=$SCAN&fail_status=1"

Fehlercodes

Fehler haben die Form {"error": "code"}. Fehler beim Start einer Messung, beim Anlegen oder Ändern von Projekten, URLs, Wettbewerbern und Notizen sowie upgrade_required bringen zusätzlich eine message mit, Messfehler je nach Fall weitere Angaben aus der Tabelle. Die Meldungen sind englisch.

HTTPerrorBedeutung
401unauthorizedSchlüssel fehlt, ist falsch oder widerrufen
402budget_exhausteddas Monatsbudget nach dem Bedarf des Monitorings reicht nicht für diese Messung; mit needed, remaining, limit, upgrade_plan
402daily_limitder heutige Tagesdeckel reicht nicht für diese Messung; gleiche Angaben, wieder voll um Mitternacht
403upgrade_requiredIhr Tarif enthält die REST-API nicht
403over_url_limit, url_limit_reached, demo_blockedURL jenseits des URL-Limits Ihres Tarifs, alle URLs des Tarifs belegt beim Aufnehmen per project_id (mit upgrade_plan) oder die feste Demo-Domain
403project_limit, competitor_limit, monitoring_unavailable, notes_unavailableIhr Tarif erlaubt kein weiteres Projekt, keinen weiteren Wettbewerber in diesem Projekt oder enthält kein Monitoring bzw. keine Notizen
404not_found, url_not_found, unknown_project_id, unknown_url_id, unknown_competitor_id, unknown_note_idunbekannt oder nicht Ihres
405method_not_allowedfalsche HTTP-Methode
409duplicateder Wettbewerber ist bereits im Projekt
422missing_url, invalid_url, invalid_devices, invalid_scope, missing_id, missing_name, too_many_urls, invalid_domain, invalid_monitoring_enabled, missing_note, note_too_longEingabe fehlt oder ist ungültig; gemessen und aufgenommen werden nur öffentliche http(s)-URLs
429throttled, rate_limited, too_many_failed_attemptsdieselbe URL wurde vor wenigen Minuten gemessen (mit retry_at), zu viele Anfragen, zu viele Fehlversuche
500scan_faileddie Messung ließ sich aus einem anderen Grund nicht starten; später erneut versuchen oder uns kontaktieren
503busy, capacity_exhausted, disabledalle Messplätze belegt (kurz danach erneut versuchen), Tageskapazität verbraucht, API abgeschaltet

MCP für KI-Agenten

Endpunkt: https://perfdelta.com/api/mcp.php. Der Transport ist Streamable HTTP mit JSON-RPC 2.0, zustandslos: Jede Anfrage ist ein einzelnes POST mit JSON-Body und bekommt eine JSON-Antwort. Es gibt keine Mcp-Session-Id und keinen SSE-Stream; GET antwortet mit 405. Unterstützte Protokollversionen: 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26 und 2024-11-05. Der Server beantwortet initialize mit der Version, die der Client verlangt, bei einer unbekannten mit 2026-07-28, und liefert instructions zu Kosten und Ablauf mit.

initialize, notifications/initialized, ping und tools/list funktionieren ohne Schlüssel, damit Clients und Verzeichnisse die Tool-Liste vor der Anmeldung lesen können. tools/call verlangt einen Schlüssel. Ein mitgeschickter, aber ungültiger Schlüssel wird bei jeder Methode abgewiesen. Sendet ein Client die optionalen Header Mcp-Method oder Mcp-Name, müssen sie zu Methode und Tool-Namen im Body passen.

Einrichtung

Claude Code:

claude mcp add --transport http perfdelta https://perfdelta.com/api/mcp.php \
  --header "Authorization: Bearer IHR_API_KEY"

Oder in der .mcp.json eines Projekts:

{
  "mcpServers": {
    "perfdelta": {
      "type": "http",
      "url": "https://perfdelta.com/api/mcp.php",
      "headers": { "Authorization": "Bearer IHR_API_KEY" }
    }
  }
}

Cursor: derselbe Block ohne "type" in .cursor/mcp.json. VS Code: in .vscode/mcp.json unter "servers" statt "mcpServers", mit "type": "http".

Claude.ai und Claude Desktop: Einstellungen, Connectors, eigenen Connector hinzufügen, mit der Connector-URL https://perfdelta.com/api/mcp.php?key=IHR_API_KEY. ChatGPT (Entwicklermodus): Einstellungen, Connectors, Erstellen, mit derselben URL samt ?key= und ohne Authentifizierung, weil der Dialog keine eigenen Header anbietet.

Tools

ToolParameterKostenFunktion
scan_urlurl (String, Pflicht), devices (optional), project_id (optional), scope (optional, url oder group)Pagespeed-Abfragenstartet eine Messung; liefert dieselben Felder wie POST /scans.php. Ein url_id gibt es hier nicht: Übergeben Sie die Projekt-URL selbst. Standardmäßig wird nur diese URL gemessen, scope=group misst ihre ganze Projektgruppe. Mit project_id wird eine neue URL zuerst in dieses Projekt aufgenommen, damit der Report im Dashboard erscheint
get_scanscan_id (String, Pflicht)kostenlosStand, Fortschritt, Scores und Core Web Vitals je Seite, dieselben Felder wie GET /scans.php
get_usagekeinekostenlosBudget und verbleibende Abfragen, dieselben Felder wie GET /usage.php
get_reporturl (String, Pflicht)kostenlosletztes Ergebnis jeder gemessenen Domain, dieselben Felder wie GET /report.php
get_report_detailsscan_id oder url_idkostenlosder vollständige Report einer Ihrer Messungen, siehe unten
list_projectskeinekostenlosIhre Projekte als Liste mit id, name, url_count
get_projectproject_id (Integer, Pflicht)kostenlosein Projekt mit settings (Monitoring-Takt und -Geräte, Alerts, Wochenreport, öffentliches Dashboard), competitors und urls, je mit tags, Monitoring-Stand, within_plan_limit und latest_scan (scan_id, status, Scores, measured_at, report_url)
get_fixesurl (String, Pflicht), lang (optional, en oder de)kostenlospriorisierte Maßnahmen mit betroffenen Dateien, Elementen, Vergleichswerten und beobachteter Wirkung, dieselben Felder wie GET /fixes.php. Die Dateien lassen sich direkt an einen Coding-Agenten übergeben
get_changesurl (String, Pflicht), lang (optional, en oder de)kostenlosVeränderungen seit der vorigen Messung und umgesetzte Maßnahmen, dieselben Felder wie GET /changes.php. Erklärt einen Score-Einbruch
list_urlsproject_id (Integer, Pflicht)kostenlosURLs eines Projekts als Liste mit den Feldern von GET /urls.php
get_historyurl_id (Integer, Pflicht)kostenlosScore-Verlauf einer Projekt-URL, {"history": [...]} wie bei GET /history.php; jeder hash ist eine scan_id für get_report_details
get_monitoring_eventsproject_id (Integer, Pflicht), limit (optional, Standard 50, höchstens 200)kostenlos{"events": [...]}, neueste zuerst: kind (regression, improvement oder budget_over und budget_ok, wenn ein Performance-Budget überschritten oder wieder eingehalten wird), url_id, url, scan_id, reasons (Score-Änderung oder Core Web Vitals durchgefallen/wieder bestanden), alert_sent, created_at; Aufbewahrung 90 Tage
get_budget_statusscan_id oder url_id, optional urlkostenlosdie Prüfung der Performance-Budgets, dieselben Felder wie GET /budgets.php: passed gesamt und je Projekt-URL; nach get_scan mit Status done aufrufen
set_budgetproject_id (Integer, Pflicht), metric, device, limit, optional goal, url_id, delete; list: true liefert alle Budgets des Projektskostenlosdas gespeicherte Budget, mit list dieselben Felder wie GET /budgets.php?project_id=
create_projectname (String, Pflicht)kostenloslegt ein Projekt an, liefert id, name
add_urlsproject_id (Integer, Pflicht), urls (Liste von Strings, Pflicht)kostenlosnimmt URLs in ein Projekt auf, added und skipped wie bei POST /urls.php
remove_urlurl_id (Integer, Pflicht)kostenlosentfernt eine URL aus ihrem Projekt
set_monitoringurl_id (Integer, Pflicht), enabled (Boolean, Pflicht)kostenlosschaltet das Monitoring einer Projekt-URL an oder aus
list_competitorsproject_id (Integer, Pflicht)kostenlosWettbewerber eines Projekts als Liste mit id, domain
add_competitorproject_id (Integer, Pflicht), domain (String, Pflicht)kostenlosfügt einen Wettbewerber hinzu, liefert id, domain
remove_competitorproject_id (Integer, Pflicht), competitor_id (Integer, Pflicht)kostenlosentfernt einen Wettbewerber aus einem Projekt
add_notescan_id (String, Pflicht), note (String, Pflicht)kostenloshängt eine Notiz an eine Messung, dieselben Felder wie POST /notes.php
update_notenote_id (Integer, Pflicht), note (String, Pflicht)kostenlosändert eine Ihrer Notizen
delete_notenote_id (Integer, Pflicht)kostenloslöscht eine Ihrer Notizen

Ergebnisse kommen als ein Textblock mit JSON. Anders als bei REST liefern list_projects, list_urls und list_competitors die Liste direkt, ohne umschließendes Objekt. Typischer Ablauf für einen Agenten: get_usage, dann scan_url, dann get_scan alle 15 bis 30 Sekunden bis done, danach get_report_details für den vollständigen Report. Für ein Monitoring: create_project, add_urls, bei Bedarf add_competitor.

Vollständiger Report: get_report_details

Liefert alles, was die Report-Seite dem Eigentümer zeigt, als JSON zur Auswertung durch eine KI: summary (Scores, vorherige Scores, Seiten mit bestandenen Core Web Vitals je Gerät, Schwellen, globale Bestehensquote, größter Engpass), origin_field_data und origin_field_history (CrUX für die ganze Domain), competitors, perfdelta_average, industry_benchmark (Tarife mit Branchenvergleich), pages, tech_stack, ai_recommendations, notes und history. Jeder Eintrag in pages steht für eine URL und ein Gerät: score, field und lab mit Bewertung je Messwert (good, ni, poor), field_distribution, cwv_pass, page_weight_bytes, resource_breakdown, third_parties, opportunities mit geschätzter Ersparnis und diagnostics (LCP-Element, Layout-Verschiebungen, Main-Thread-Arbeit, Skript-Bundles, größte Anfragen). screenshots und filmstrip (jeweils mobile und desktop) enthalten absolute Bild-URLs, Filmstreifen-Bilder mit url und timing_ms. notes listet Ihre eigenen Notizen mit id, note, created_at, passend zu update_note und delete_note. Funktioniert für Messungen in Ihren Projekten und für Messungen, die Ihr Konto gestartet hat; für andere Domains gibt es get_report. Die Felder im Einzelnen: Oben stehen complete (true, sobald die Messung done ist) und purged (true, wenn die Seitendaten einer alten Messung gelöscht sind). summary enthält mobile_score, desktop_score, previous_mobile_score, previous_desktop_score, cwv_pages_passing (je Gerät pass und total), cwv_thresholds, global_cwv_pass_rate (mit source) und biggest_bottleneck. Jede Seite hat field_is_origin_fallback (true: Werte der ganzen Domain, die Seite hatte keine eigenen Felddaten), field_distribution mit dist-Anteilen je Metrik, request_count und je Optimierung id, title, savings_ms und resources; der score der Seite ist der Lighthouse-performance_score. ai_recommendations_lang nennt die Sprache der Empfehlungen.

MCP-Fehler

Fehler innerhalb eines Tools kommen als normales Tool-Ergebnis mit isError: true und einem Meldungstext, ohne den REST-Fehlercode und dessen Zusatzangaben. Beispiele: unbekannte scan_id, project_id, url_id oder competitor_id, fehlende url, ein erreichtes Projekt-, URL- oder Wettbewerberlimit, erschöpftes Budget oder ein Tarif ohne MCP-Zugang (mit dem Tarif, der ihn enthält). Scheitert scan_url an Budget oder Tagesdeckel, endet der Text mit dem Link zur Preisseite. Protokollfehler nutzen JSON-RPC-Fehlercodes und tragen die id der Anfrage, sofern sie lesbar ist:

HTTPcodeBedeutung
200-32700Body ist kein gültiges JSON
200-32600keine JSON-RPC-2.0-Anfrage, oder der Header Mcp-Method/Mcp-Name passt nicht zum Body
200-32601unbekannte Methode
401-32001Schlüssel fehlt, ist falsch oder widerrufen
429-32002zu viele Fehlversuche von dieser IP-Adresse, Retry-After in Sekunden
429-32003mehr als 60 Anfragen pro Minute, Retry-After: 60
503keinerMCP abgeschaltet; einfacher Body {"error":"disabled"}

Fragen oder eine Antwort, die nicht zu dieser Seite passt: Kontaktformular.