MCP-Server
Nutze die kostenlosen Uptimeify-Checks aus jedem KI-Agenten über das Model Context Protocol (MCP).
Uptimeify stellt einen zustandslosen Model-Context-Protocol-Server bereit, damit KI-Agenten unsere kostenlosen Checks direkt ausführen können.
Einen Überblick darüber, was der Server kann und mit welchen Clients er funktioniert, findest du auf der MCP-Server-Seite auf uptimeify.io. Diese Seite hier ist die technische Referenz.
Endpunkt
POST https://uptimeify.io/mcp: Streamable-HTTP-Transport, zustandslos. Die anonymen Check-Tools brauchen keine Authentifizierung; die authentifizierten Tools benötigen einen Bearer-API-Token (siehe unten).
Den Server programmatisch über die MCP Server Card entdecken:
GET https://uptimeify.io/.well-known/mcp/server-card.json
MCP-Client verbinden
Richte einen beliebigen MCP-Client mit Streamable-HTTP-Transport auf den Endpunkt oben aus.
- Anonyme Tools funktionieren allein mit der URL: kein Token nötig.
- Authentifizierte Tools benötigen deinen Uptimeify-API-Token als
Authorization: Bearer <token>-Header. Erstelle einen unter Einstellungen → API-Tokens: lass das Kunden-Feld leer für einen organisationsweiten Token (sieht alle deine Monitore) oder wähle einen Kunden, um den Token auf diesen Kunden zu beschränken. Der Token wird nur einmal bei der Erstellung angezeigt: kopiere ihn sofort.
Clients, die HTTP-MCP-Server mit eigenen Headern unterstützen, zeigen direkt auf die URL:
{
"mcpServers": {
"uptimeify": {
"url": "https://uptimeify.io/mcp",
"headers": { "Authorization": "Bearer wsm_dein_token_hier" }
}
}
}Für Clients, die nur stdio sprechen, überbrückst du zum HTTP-Endpunkt mit mcp-remote:
{
"mcpServers": {
"uptimeify": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://uptimeify.io/mcp", "--header", "Authorization: Bearer wsm_dein_token_hier"]
}
}
}Lass den Authorization-Header weg, wenn du nur die anonymen Check-Tools brauchst.
Rate-Limits
Die anonymen Tools führen echte Netzwerk-Checks in deinem Auftrag aus und sind deshalb pro Client-IP gedeckelt. Für diese Limits brauchst du keinen Account, und um darunter zu bleiben ebenfalls nicht:
| Bereich | Limit |
|---|---|
POST /mcp insgesamt | 120 Anfragen pro Minute und IP |
| Jedes anonyme Check-Tool | 15-30 Aufrufe pro Minute und IP, je nach Aufwand des Checks (whois und domain_expiry sind mit 15 am strengsten) |
| Jedes authentifizierte Lese-Tool | 60 Aufrufe pro Minute und IP |
| Jedes authentifizierte Schreib-Tool | 10 Aufrufe pro Minute je Organisation, nicht je IP -- Schreiben ist seltener und teurer als Lesen, ein Modell, das einen Schreibaufruf in einer Schleife wiederholt, soll das absichtlich schnell zu spüren bekommen |
Beide Ebenen gelten gleichzeitig: 120 Aufrufe pro Minute verteilt über verschiedene Tools sind in Ordnung, 120 Aufrufe whois pro Minute nicht. Wird ein Limit überschritten, antwortet der Server mit HTTP 429 und einem retryAfter-Wert in Sekunden, der angibt, wann das aktuelle Fenster endet. Die Fenster sind fest, nicht gleitend, wer retryAfter abwartet, bekommt sofort das volle Kontingent.
Gezählt wird pro IP, nicht pro Token: Ein API-Token hebt die Grenze nicht an, und mehrere Agenten hinter derselben NAT-Adresse teilen sie sich. Wenn du einen Anwendungsfall hast, der wirklich mehr braucht, melde dich, statt es zu umgehen.
Verfügbare Tools
Alle Tools sind anonym und nur lesend. Sie entsprechen unseren öffentlichen Web-Tools:
- check_ssl: TLS/SSL-Zertifikatsprüfung (
host, optionalport) - check_dns, dns_propagation, mx_lookup: DNS-Auflösung und -Propagation (
domain) - spf_check, dkim_check (
domain,selector), dmarc_check: E-Mail-Authentifizierung (domain) - dnsbl_check (
ip), whois (domain), domain_expiry (domain) - http_headers (
url), hsts_check (domain), redirect_check (url) - port_check (
host,port), ping_test (host, optionalport) - website_status (
url), response_time (url) - ip_geolocation (
query), asn_lookup (query), reverse_dns (ip)
Authentifizierte Tools (lesend)
Diese Tools lesen deine eigenen Monitoring- und Kontodaten. Sende deinen Uptimeify-API-Token als Authorization: Bearer <token>-Header mit der MCP-Anfrage. Ein kundengebundener Token sieht nur die Monitore seines Kunden; ein Organisations-Token sieht alle Kunden der Organisation. Alle sind nur lesend.
- list_monitors (optional
kind): deine Monitore über alle acht Familien auflisten (website,dns,icmp,tcp,ftp,smtp,ssh,imap_pop). Ohnekindliefert es alle; jedes Element trägt sein eigeneskind. Jedes Element ist auf eine feste Feldliste begrenzt: Identität und Ziel (id,publicId,name,urlbeziehungsweisehostnameundport,monitoringType,status,managementType), die Prüfkonfiguration ohne jede Zugangsinformation (Intervall, Timeout, HTTP-Methode, erwartete Statuscodes, welche Prüfungen aktiv sind, Hinweis- und Fehlerschwellen), Zustand (isActive,isDown,isRecovering,hasCritical,hasWarning,inMaintenance,upSinceAt,lastCheckedAt), Uptime- und Antwortzeit-Kennzahlen, Name und öffentliche Kennung des Kunden,tags(id, öffentliche Kennung, Name, Farbe) und Zeitstempel. Nie enthalten: das Heartbeat-Token, gespeicherte Zugangsdaten oder verschlüsselte Einstellungen (Authorization-Header, Basic-Auth-Nutzer und -Passwort, eigene Header, Request-Body, mTLS-Zertifikat und -Schlüssel, Playwright-Umgebung), das Playwright-Skript, Alarm-Telefonnummer und -Mailadresse des Monitors, eigene Felder, die rohe Protokollkonfiguration der Nicht-HTTP-Familien und der eingebettete Kundendatensatz. - monitor_status (
monitor_id, optionalkind): ein einzelner Monitor mit aktuellem Up/Down-Status.kindist standardmäßigwebsite(rückwärtskompatibel). Dieselbe Feldliste wielist_monitors; die zusätzlichen Geheimnisse des Detail-Endpunkts (Heartbeat-Token, Playwright-Skript und -Umgebung, Präsenzflaggen für Zugangsdaten) werden auf dieselbe Weise zurückgehalten. - list_incidents (optional
limit): aktuelle Incidents über deine Monitore. Der eingebettetecustomerträgt Kennung, öffentliche Kennung und Firmennamen; die Kontakt-Mailadresse des Kunden wird entfernt. - check_history (
monitor_id, optionalkind,from,to): jüngste Checks, optional in einem ISO-Datumsbereich.kindist standardmäßigwebsite. - uptime_summary (
monitor_id): Verfügbarkeit und mittlere Antwortzeit für Tag / Monat / Jahr. Nur für Website-Monitore -- die übrigen sieben Familien haben diesen Endpunkt nicht. - list_alert_channels (optional
website_id): die Benachrichtigungskanäle, über die du überhaupt alarmiert werden kannst -- Name, Typ (E-Mail, SMS, Webhook oder eine der Chat- und Bereitschafts-Integrationen), ob der Kanal aktiv ist, dazu Eskalationspriorität und Verzögerung. Ohnewebsite_idbekommst du die Kanäle der Organisation; mit einer Website-Kennung auslist_monitorszusätzlich die Kanäle, die für genau diesen Monitor gelten, samt seiner Übersteuerungen. Die Konfiguration eines Kanals kommt nie mit: keine Empfängeradressen, Telefonnummern, Webhook-Ziele, keine Zugangsdaten. - alert_history (
monitor_id, optionalkind,from,to,status,page,limit): welche Alarme für einen Monitor rausgingen, wann, über welchen Kanal (Name und Typ) und ob die Zustellung geklappt hat oder mit welchem Fehler sie scheiterte. Zusammen mitlist_alert_channelsbeantwortet das die Frage „warum hat mich niemand angerufen".kindist standardmäßigwebsite,statusistsentoderfailed, und das Ergebnis ist geblättert: 25 Einträge je Seite, höchstens 100. Die gespeicherte Konfiguration des Kanals kommt auch hier nicht mit. MiterrorMessageverhält es sich anders: Es ist Freitext aus dem Zustellversuch selbst und kann zitieren, was die Gegenstelle gesagt hat. Eine gescheiterte Zustellung nennt darin also womöglich SMTP-Host und Port, eine vom Mailserver abgewiesene Empfängeradresse oder den Hostnamen eines Webhook-Ziels. - list_status_pages: deine Statusseiten -- Name, Slug, Beschreibung, der Kunde, zu dem sie gehören, ob sie veröffentlicht sind, ihre Sichtbarkeit (
public,customer_members_onlyoderpassword_protected) und ob ein gemeinsames Seitenpasswort gesetzt ist, die Monitore, die die Seite bewusst ausblendet, und die eigene Domain, unter der sie ausgeliefert wird. Nimmt keine Argumente; die Liste ergibt sich aus dem Token. Abonnentenlisten kommen nie zurück, ebenso wenig die Gestaltung der Seite oder der DNS-Nachweis-Token einer eigenen Domain. - list_maintenance_windows (optional
active_only): deine geplanten Wartungsfenster -- Name, Beginn und Ende, die IANA-Zeitzone, in der die Wiederholung gelesen wird, ob und wie es sich wiederholt, ob es aktiv ist, und welche Monitore es abdeckt. Ein Monitor in einem laufenden Fenster alarmiert nicht, und das ist die übliche Antwort auf „warum gab es keinen Vorfall". Dieser Endpunkt hat keinen Datumsfilter: Die Antwort umfasst immer jedes Fenster, das du sehen darfst, vergangene wie künftige. Grenze also selbst zeitlich ein, statt eine gefilterte Liste anzunehmen. - get_organization: deine eigene Organisation -- numerische Kennung, öffentliche Kennung, Name, Kontozustand (
activeodersuspended) und, wenn ein deaktiviertes Konto zur Löschung ansteht, das Datum dafür. Nimmt keine Argumente: Die Organisation ergibt sich aus dem Token. Diese fünf Felder sind die ganze Antwort. Rechnungsadresse und Abrechnungszyklus, Zahlungsmittel, Rabattcodes, Kontingent- und Preisgrenzen, die MFA-Richtlinie und die Standard-Benachrichtigungseinstellungen der Organisation kommen nicht mit, und die SMTP-, Audit-Log- und Datenexport-Endpunkte unter/api/organization/erreicht das Werkzeug gar nicht erst. - list_users: die Mitglieder deiner Organisation -- Name, Rolle (
admin,editoroderreadonly), ob das Mitglied noch aktiv ist und seit wann es dabei ist, dazulimits.currentSeats, die Zahl der Mitglieder in genau dieser Antwort. Nimmt keine Argumente. Die Antwort trägt überhaupt keine Mitgliedskennung, und das ist Absicht: Ein Mitglied lässt sich benennen, aber nicht referenzieren. Jede Rückfrage, die auf eine Person zeigt, läuft also über den Namen -- und zwei Mitglieder mit demselben Namen sind nicht auseinanderzuhalten. E-Mail-Adressen, Avatare und Kundenzuordnungen kommen ebenfalls nicht mit. Und beachte den Umfang der Liste: Sie ist auf den Kundenbereich des Aufrufers eingegrenzt, genau wieGET /api/users. Ein kundengebundener Token sieht nur die Mitglieder seines eigenen Kunden, dazu sich selbst -- undlimits.currentSeatszählt genau diese, ist also nicht die Kopfzahl der Organisation. - list_customers: die Kunden deiner Organisation -- numerische Kennung, öffentliche Kennung, Name, Kontozustand und Anlagedatum, dazu die Zahl der Monitore je Kunde (gesamt, verwaltet, selbstverwaltet und DNSBL-Einträge). Nimmt keine Argumente, und ein kundengebundener Token sieht nur seinen eigenen Kunden. Nicht enthalten: Kontakt- und Benachrichtigungs-E-Mail, Postanschrift, Umsatzsteuer-Identifikationsnummer, Telefonnummer, Kündigungsdaten, freie Zusatzfelder und der Tarifname -- der Tarif ist überhaupt kein Teil dieser Antwort.
- billing_summary: der SMS-Verbrauch des laufenden Monats -- die Summe
totalüber die Organisation und die Aufschlüsselung je Kunde. Nimmt keine Argumente, und der SMS-Verbrauch ist die einzige Abrechnungsgröße, die dabei herauskommt: nie ein Tarif, nie ein Betrag, keine Währung, kein Rechnungs- oder Abrechnungsdatum, keine Rechnungsadresse, keine Rechnungs-E-Mail, kein Zahlungsmittel. Die Antwort hängt an einem zweiten Bereich: Mitmcp:billing:readallein besteht jeder Kunde in der Aufschlüsselung aus seiner öffentlichen Kennung und seinem Verbrauchswert, sonst nichts; Name und Zustand des Kunden erscheinen nur, wenn zusätzlichmcp:organization:readfreigegeben wurde. Klarnamen gehören zum Organisationsbereich, wer ihn abwählt, bekommt die Kundenliste also nicht über den Verbrauch zurück. Ein kundengebundener Token sieht nur seinen eigenen Kunden.
Sechs Werkzeuge führen eine Positivliste und geben genau die oben genannten Felder aus und nichts sonst: die vier Konto-Werkzeuge sowie list_monitors und monitor_status -- eine Spalte, die am Endpunkt später dazukommt, wandert damit nicht von selbst mit hinaus. Fünf nehmen eine Handvoll benannter Felder aus der Endpunktantwort heraus -- list_alert_channels, alert_history, list_status_pages, list_maintenance_windows und list_incidents --, und zwei, check_history und uptime_summary, reichen die Antwort unverändert weiter, weil sie nichts als Prüfergebnisse enthält. Was dort fehlt, fehlt absichtlich und nicht aus Versehen.
Geblättert wird je Tool verschieden, und nur bei alert_history kannst du eine weitere Seite anfordern. list_monitors liefert je Monitor-Familie höchstens eine Seite (50 Einträge) pro Aufruf; total ist die echte Gesamtzahl über die abgefragten Familien, nicht die Zahl der gelieferten Elemente, weichen beide voneinander ab, ist die Liste also abgeschnitten. check_history liefert die erste Seite des Endpunkts, 10 Prüfungen aus dessen 30-Tage-Standardfenster, und nennt total, page und pageCount daneben. alert_history blättert über eigene Argumente: standardmäßig 25 Einträge je Seite, höchstens 100, gesteuert mit page und limit. list_alert_channels, list_status_pages, list_maintenance_windows, list_users, list_customers und billing_summary blättern gar nicht -- sie liefern jeweils alles, was der Token sehen darf. Eine kurze Liste ist dort eine kurze Liste, keine abgeschnittene. get_organization antwortet mit einem einzelnen Datensatz und hat nichts zu blättern.
Läuft list_monitors ohne kind, fragt es alle acht Familien parallel ab. Antwortet eine davon nicht, kommt trotzdem ein Ergebnis zurück, und sowohl der Textblock als auch structuredContent.partialFailures nennen die fehlenden Quellen. Eine solche Liste ist unvollständig zu lesen, nicht als "du hast keine davon".
Über OAuth sind diese Tools bereichsweise freigeschaltet: Die beiden Alarm-Tools brauchen mcp:alerts:read, die beiden Statusseiten-Tools mcp:statuspages:read, beide in der Gruppe Überwachung und Betrieb der Zustimmungsseite; get_organization, list_users und list_customers brauchen mcp:organization:read, billing_summary braucht mcp:billing:read, beide in der Gruppe Konto und Abrechnung (siehe unten). Ein Werkzeug, dessen Bereich nicht freigegeben ist, taucht in tools/list gar nicht erst auf -- ein Client soll nicht lernen, gegen eine Wand zu laufen. Ein wsm_-API-Token kennt diese Aufteilung nicht und erreicht alle 13.
Rufst du eines dieser Tools ohne Token auf, gibt es einen Fehler zurück und bittet um den Authorization: Bearer-Header. Einen Token erstellst du unter Einstellungen → API-Tokens. Eine Anfrage ganz ohne Authorization-Header sieht sie erst gar nicht: tools/list liefert dann nur die 20 anonymen Tools. Das ist dieselbe Regel wie oben, angewandt auf den Aufrufer, der nichts freigegeben hat -- angeboten wird nie, was ohnehin nicht aufrufbar ist.
Authentifizierte Tools (schreibend)
43 Tools ändern deine Monitoring-Daten, statt sie nur zu lesen. Sie rufen dieselben /api-Endpunkte auf, die auch die REST-API und das Dashboard benutzen -- es gibt keine eigene Schreib-API, und für sie ist kein neuer Endpunkt entstanden. Zwei Dinge unterscheiden sie von jedem Lese-Tool oben, und beide sind dauerhaft, keine Launch-Einschränkung:
- Nur über OAuth. Ein
wsm_-API-Token sieht nie ein Schreib-Tool, egal wie es berechtigt ist -- die Begründung ist eine Eigentümerentscheidung, siehe Verbundene Apps. Nur eine OAuth-Verbindung mit dem passenden Schreib-Scope kann eines aufrufen. - An die Bereitstellung gebunden. Schreib-Tools stehen im Werkzeugkatalog, aber eine Bereitstellung registriert sie nur, wenn sie ausdrücklich eingeschaltet wurden. Ist das nicht der Fall, taucht keines der 43 in
tools/listauf, und ein Aufruf beim Namen scheitert, als gäbe es das Tool nicht -- egal, welche Scopes deine Verbindung trägt. Frag bei der Person nach, die deine Uptimeify-Instanz betreibt, bevor du davon ausgehst, dass sie live sind.
Eine Verbindung braucht den passenden Schreib-Scope, um ein Tool überhaupt zu sehen: mcp:monitors:write schaltet die ersten sechs unten frei, mcp:incidents:write die nächsten vier, mcp:maintenance:write die nächsten drei, mcp:statuspages:write die nächsten acht, mcp:alerts:write die nächsten drei, mcp:organization:write die letzten neunzehn. Hakst du auf der Zustimmungsseite einen Schreib-Scope an, hakt das automatisch seinen gleichnamigen Lese-Zwilling mit an (zum Beispiel hakt mcp:monitors:write auch mcp:monitors:read an) -- die meisten dieser Tools vergleichen den aktuellen Zustand des Datensatzes, bevor sie schreiben, damit ein wiederholter Aufruf nicht doppelt schreibt, und dieser Vergleich braucht Lesezugriff auf dieselben Daten. mcp:maintenance:write ist die eine Ausnahme: Es hat keinen eigenen Lese-Zwilling, weil list_maintenance_windows schon unter mcp:statuspages:read liest und ein zweiter Scope für dieselben Daten nur ein Häkchen wäre, das nichts entscheidet. Es anzuhaken gibt deshalb mcp:statuspages:read nicht automatisch mit -- diesen Scope braucht eine Verbindung zusätzlich, bevor der Zustandsvergleich von update_maintenance_window (siehe unten) laufen kann. Auch keines der drei Alarmkanal-Tools vergleicht einen Zustand -- es gibt kein GET für einen einzelnen Kanal über diese Verbindung, ein wiederholter Aufruf schreibt also immer erneut. Unter mcp:organization:write vergleichen genau zwei der neunzehn einen Zustand, update_user und update_customer, und beide nur, wenn die Verbindung auch mcp:organization:read hält. Mit diesem Bereich trägt jeder der sechs Schreib-Scopes mindestens ein Tool; keiner steht mehr leer.
Monitor-Tools (mcp:monitors:write), alle über die acht Monitor-Familien hinweg (website, dns, icmp, tcp, ftp, smtp, ssh, imap_pop), sofern nicht anders angegeben:
- pause_monitor (
kind,monitor_id): einen Monitor anhalten. Während der Pause alarmiert er nicht, und die Pause erscheint in der Uptime-Kennzahl als Lücke, nicht als Ausfallzeit. Ein Aufruf auf einen bereits pausierten Monitor ändert nichts und sagt das, statt erneut zu schreiben. - resume_monitor (
kind,monitor_id): einen pausierten Monitor wieder prüfen lassen. Bleibt unangetastet, wenn der Monitor gerade in Wartung ist, nicht pausiert -- ein Wartungsfenster zu beenden ist eine eigene, bewusste Aktion, die dieses Tool nie ausführt. Unterliegt derselben Monitor-Kontingentprüfung wie das Anlegen eines Monitors und kann deshalb scheitern, wenn das Kontingent ausgeschöpft ist. - rename_monitor (
kind,monitor_id,name, 1-255 Zeichen): den Anzeigenamen ändern. Rein kosmetisch -- was geprüft wird, wie oft und die Alarmierung bleiben unverändert. - set_check_interval (
kind,monitor_id,check_interval_minutes, 1-60): wie oft ein Monitor geprüft wird. Das Paket der Organisation setzt ein Mindestintervall je Monitor; ein Wert darunter lässt den Aufruf scheitern, statt aufgerundet zu werden -- ein niedrigeres Intervall ist also nicht immer verfügbar. - create_website_monitor (
customer_id,name,url, optionalcheck_interval_minutes, optionalmonitoring_type): einen Website-Monitor für einen bestimmten Kunden anlegen.customer_idist Pflicht und sollte nie geraten werden -- ist der Kunde nicht bekannt, danach fragen. Unterliegt dem Monitor-Kontingent des Kontos und scheitert deshalb ganz, statt sich einzureihen, wenn das Kontingent ausgeschöpft ist. Führt keine Zugangsdaten oder Skripte: kein Basic-Auth-Passwort, kein mTLS-Schlüssel, kein eigener Authorization-Header, kein Playwright-Skript oder -Umgebung, undmonitoring_typeschließtplaywrightaus demselben Grund aus -- das richtest du im Dashboard ein. - delete_monitor (
kind,monitor_id,confirm: true): einen Monitor endgültig löschen, mitsamt Prüfhistorie, Incidents, Alarmkanälen, Tags und Wartungsfenstern. Das lässt sich nicht rückgängig machen. Wird für eine RollereadonlymitreadonlyMayNotDeleteabgewiesen, unabhängig davon, wem der Monitor gehört.confirmmusstruesein und sollte erst gesetzt werden, nachdem ein Mensch genau diese Löschung verlangt hat -- kein Kästchen, das ein Modell reflexhaft anhakt.
Incident-Tools (mcp:incidents:write), sowohl für manuelle (Statusseiten-)Incidents als auch für automatische (vom Monitoring ausgelöste), sofern nicht anders angegeben, und alle vier verlangen die Rolle admin oder editor -- ein Aufrufer mit readonly oder supporter wird bei jedem der vier generisch abgewiesen:
- acknowledge_incident (
incident_id): einen Incident als in Bearbeitung markieren. No-op, wenn er bereits bestätigt ist. Einen resolved Incident zu bestätigen ist ein echtes Wiedereröffnen -- Uptimeify behandelt sowohlopenals auchacknowledgedals "noch aktiv" -- deshalb plant es ein "reopened"-Ereignis auf der Statusseite und benachrichtigt Abonnenten erneut, denen gesagt wurde, es sei behoben. Nutze das auf einem bereits gelösten Incident nur, wenn er wirklich wieder aufgetreten ist. - resolve_incident (
incident_id): einen Incident lösen. Bei einem echten Übergang von open/acknowledged zu resolved plant das ein "resolved"-Ereignis auf der Statusseite und mailt Abonnenten, die vom Ausfall wussten. Ein erneuter Aufruf auf einem bereits gelösten Incident ist ein No-op und verschickt nie ein zweites Entwarnungs-Mail. - post_incident_update (
incident_id,status:investigating,identified,monitoringoderresolved,body, bis zu 5000 Zeichen): ein neues öffentliches Update an die Zeitleiste eines Incidents anhängen; es erscheint sofort auf der Statusseite. Nicht idempotent -- jeder Aufruf veröffentlicht ein eigenes, neues Update, ein Aufruf, dessen Antwort nie ankam, sollte deshalb nicht wiederholt werden, das würde dieselbe Neuigkeit ein zweites Mal verbreiten.status: 'resolved'löst dabei auch den übergeordneten Incident (wieresolve_incident) und verschickt die Entwarnung; jeder andere Status auf einem gerade gelösten Incident eröffnet ihn wieder (wie das Wiedereröffnen vonacknowledge_incident) und benachrichtigt Abonnenten erneut. - delete_incident (
incident_id,confirm: true): einen manuellen Incident (eine Statusseiten-Ankündigung) endgültig löschen, mitsamt jedem dazu erfassten Statusseiten-Ereignis. Das lässt sich nicht rückgängig machen. Wird für einen automatischen, vom Monitoring ausgelösten Incident mitnotManualIncidentabgewiesen -- die gehören den Workern und lassen sich über dieses Tool nie löschen.confirmmusstruesein, gesetzt erst, nachdem ein Mensch genau diese Löschung verlangt hat.
Wartungsfenster-Tools (mcp:maintenance:write):
- create_maintenance_window (
name,start_time,end_time, entwedercustomer_idodertag_ids, optionaldescription, optionaltimezone): ein Wartungsfenster anlegen -- während es läuft, alarmieren die Monitore, die es abdeckt, nicht, und der Zeitraum erscheint als geplante Wartung statt als Ausfallzeit. Verlangt entwedercustomer_id(jeder Monitor dieses Kunden) odertag_ids(jeder Monitor mit diesen Tags); ein Aufruf mit keinem von beiden scheitert ganz. Nicht idempotent -- ein zweiter identischer Aufruf legt ein zweites Fenster an und veröffentlicht eine zweite Statusseiten-Ankündigung an Abonnenten. Ein organisationsweites Fenster (tag_idsohnecustomer_id) verlangt einen uneingeschränkten Scope und die Rolle admin oder editor; alle anderen bekommen ein auf ihren eigenen Kunden begrenztes Fenster. - update_maintenance_window (
maintenance_window_id, optionalname,description,start_time,end_time,is_active): Name, Beschreibung, Zeitraum oder Aktivstatus eines geplanten Fensters ändern. Ein Fenster zu deaktivieren (is_active: false) stoppt die Alarmunterdrückung, ohne es zu löschen. Kann die Verbindung auch Wartungsfenster lesen (hältmcp:statuspages:read), vergleicht das Tool erst mit dem aktuellen Fenster und meldet keine Änderung, statt zu schreiben, wenn schon jedes Feld den gewünschten Wert trägt; ohne diesen Lese-Scope entfällt der Vergleich und der Aufruf schreibt in jedem Fall. - delete_maintenance_window (
maintenance_window_id,confirm: true): ein Wartungsfenster endgültig löschen. Läuft es gerade, endet die Alarmunterdrückung seiner Monitore sofort, und ein laufender Ausfall wird zu einem echten Alarm.confirmmusstruesein, gesetzt erst, nachdem ein Mensch genau diese Löschung verlangt hat.
Statusseiten-Tools (mcp:statuspages:write):
- create_status_page (
customer_id,name, optionalslug,description,visibility,is_published,subscriptions_enabled,subscription_delay_minutes): eine neue Statusseite für einen bestimmten Kunden anlegen.customer_idist Pflicht und sollte nie geraten werden -- ist der Kunde nicht bekannt, danach fragen. Nicht idempotent -- ein zweiter Aufruf, auch mit demselben Namen, legt eine ZWEITE Seite an: Der Handler hängt-2(dann-3und so weiter) an den Slug an, statt die bestehende Seite wiederzuverwenden, ein Aufruf, dessen Antwort nie ankam, sollte deshalb nicht wiederholt werden. Führt kein Passwort-Argument: Eine passwortgeschützte Seite braucht ein Passwort, das dieses Tool ohne Angabe ablehnen würde -- das richtest du im Dashboard ein. Die Gestaltung (Layout, Farben, welche Abschnitte erscheinen) lässt sich hier nicht setzen -- ruf danachupdate_status_page_designauf. - update_status_page (
status_page_id, optionalcustomer_id,name,slug,description,visibility,is_published,subscriptions_enabled,subscription_delay_minutes): Name, Slug, Beschreibung, Sichtbarkeit, Veröffentlichungsstatus, Kunde oder Abonnenten-Einstellungen einer Statusseite ändern. Für eine einzelne Statusseite gibt es über diese Verbindung keinen Lese-Endpunkt, dieses Tool kann also nicht vorher vergleichen: Jeder Aufruf schreibt, auch einer, der dieselben Werte erneut setzen würde. Führt kein Passwort-Argument, aus demselben Grund wiecreate_status_page, und keinshow_recent_incidents/show_recent_maintenance-- der Handler spiegelt beides als Nebeneffekt in die Gestaltungskonfiguration der Seite, was mitupdate_status_page_designstill kollidieren würde, diese Gestaltung gehört deshalb dem Design-Tool. - update_status_page_design (
status_page_id, optional Layout, Farbschema, Akzentfarbe, Kopfzeilen-Stil, Schriftart, Kartenrundung, Seitenbreite, eigener Titel/Untertitel, und welche Abschnitte erscheinen, jeweils mit eigenen Grenzen und Rückblickfenstern für Vorfälle und Wartung): die visuelle Gestaltung einer Statusseite ändern. Für einen Aufrufer mit der Rolle readonly erreichbar, anders als die übrigen drei Statusseiten-Tools, die admin oder editor verlangen. Kann die Verbindung auch Statusseiten lesen (hältmcp:statuspages:read), vergleicht das Tool erst mit der aktuellen Gestaltung und meldet "keine Änderung", statt zu schreiben, wenn jedes Feld, das dieser Vergleich sehen kann, schon den gewünschten Wert trägt; ohne diesen Lese-Scope, oder wenn die Anfrage ein Feld setzt, das der Vergleich nicht sehen kann (die Anzeige-Einstellungen für Historie, Vorfälle und Wartung), entfällt der Vergleich und der Aufruf schreibt in jedem Fall. - delete_status_page (
status_page_id,confirm: true): eine Statusseite endgültig löschen, mitsamt ihrer Abonnentenliste -- jede Abonnenten-Zeile fällt beim Löschen mit weg. Das lässt sich nicht rückgängig machen.confirmmusstruesein, gesetzt erst, nachdem ein Mensch genau diese Löschung verlangt hat. - add_status_page_domain (
status_page_id,hostname): eine eigene Domain an eine Statusseite binden. Legt die Zeile als ausstehend an und liefert Name und Wert des TXT-Eintrags, den der Mensch im DNS veröffentlichen muss. Mit der Veröffentlichung ist die Aufgabe nicht erledigt: Ruf danachverify_status_page_domainauf, um die Kontrolle über die Zone nachzuweisen, dannactivate_status_page_domain, um den Hostnamen live zu schalten. Nicht idempotent -- eine Statusseite kann nur eine Domain tragen, ein zweiter Aufruf für eine Seite, die schon eine hat, scheitert, statt sie zu ersetzen. - verify_status_page_domain (
domain_id): den DNS-TXT-Eintrag einer ausstehenden Statusseiten-Domain nachschlagen und sie bei Erfolg von ausstehend auf verifiziert heben. Scheitert, solange der Eintrag im DNS noch nicht sichtbar ist -- das ist der normale Zustand direkt nachadd_status_page_domain, oft so lange, wie die DNS-Verbreitung dauert, deshalb nicht in einer engen Schleife wiederholen. Nimmtdomain_idals reine Zahl, anders als die id-oder-öffentliche-Kennung-Form der Monitor- und Statusseiten-Tools. Verlangt die Rolle admin -- ein editor wird hier abgewiesen, obwohl editor die beiden anderen Domain-Tools aufrufen darf. - activate_status_page_domain (
domain_id): eine verifizierte Statusseiten-Domain auf aktiv setzen, der Moment, in dem der Hostname die Statusseite tatsächlich ausliefert. Führt keinen eigenen DNS-Abgleich aus -- das ist die Aufgabe vonverify_status_page_domain--, prüft aber erneut, ob diese Zeile den Anspruch auf den Hostnamen noch hält. Verlangt die Rolle admin, dieselbe Einschränkung wieverify_status_page_domain. - delete_status_page_domain (
status_page_id,domain_id,confirm: true): die eigene Domain einer Statusseite endgültig löschen. Die Statusseite selbst wird nicht gelöscht -- sie ist danach nur noch unter ihrer Standard-URL erreichbar.confirmmusstruesein, gesetzt erst, nachdem ein Mensch genau diese Löschung verlangt hat.
Alarmkanal-Tools (mcp:alerts:write):
- create_notification_channel (
channel_type:emailodersms,name,email_addressoderphone_number, optionalcustomer_id,priority,delay_seconds,is_active): einen Benachrichtigungskanal anlegen. Nuremailundsmsstehen hier zur Wahl -- jeder andere Kanaltyp (Slack, Telegram, ein generisches Webhook und 27 weitere) trägt Zugangsdaten in seiner Konfiguration und wird stattdessen im Dashboard eingerichtet. Nicht idempotent -- ein zweiter, identischer Aufruf legt einen ZWEITEN Kanal an; es gibt keine Eindeutigkeit über den Namen und keinen Zustandsvergleich, ein Aufruf ohne Antwort darf also nicht wiederholt werden. Ohnecustomer_identsteht ein organisationsweiter Kanal, der die Admin-Rolle braucht; mitcustomer_idein kundengebundener Kanal, den auch ein readonly-Aufrufer für den eigenen Kunden anlegen darf. - update_notification_channel (
channel_id, optionalname,priority,delay_seconds,is_active): Anzeigename, Eskalationspriorität, Verzögerung oder Aktivstatus eines Kanals ändern. Rührt die Konfiguration des Kanals nicht an -- weder Ziel noch Typ, keine Zugangsdaten; das Ziel wird im Dashboard geändert. Es gibt keinGETfür einen einzelnen Kanal über diese Verbindung, dieses Tool kann also nicht vorher vergleichen: jeder Aufruf schreibt, auch einer, der dieselben Werte erneut setzen würde. - delete_notification_channel (
channel_id,confirm: true): einen Benachrichtigungskanal endgültig löschen -- das lässt sich nicht rückgängig machen. Um einen Kanal zu pausieren, ohne ihn zu verlieren,update_notification_channelmitis_active: falseaufrufen.confirmmusstruesein, gesetzt erst, nachdem ein Mensch genau diese Löschung verlangt hat.
Organisations-Tools (mcp:organization:write), neunzehn Stück, der einzige Bereich, dessen Tools die Monitoring-Daten verlassen und das Konto selbst anfassen. Sieben davon sind zerstörend. Zwei, update_user und update_customer, vergleichen vor dem Schreiben den Zustand, wenn die Verbindung auch mcp:organization:read hält; jedes andere Tool dieses Bereichs schreibt bei jedem Aufruf. Zuerst die Etiketten:
- create_tag (
namebis 24 Zeichen,coloraus einer Palette von zehn Schlüsseln, optionalcustomer_id): ein Etikett zum Gruppieren von Monitoren anlegen. Nicht idempotent -- Etikettennamen sind nicht eindeutig, und es gibt hier keinGETfür ein einzelnes Etikett, ein zweiter gleicher Aufruf legt also ein ZWEITES an. Ohnecustomer_idgilt das Etikett organisationsweit; ein auf mehrere Kunden beschränkter Aufrufer, der keinen davon nennt, scheitert antagCustomerRequired. Eine Rollenhürde jenseits von globalsupporter gibt es hier nicht: auch eine readonly-Rolle darf ein Etikett anlegen, das Gegenteil voncreate_custom_fieldunter genau demselben Scope. - update_tag (
tag_id, optionalname,color): ein Etikett umbenennen oder seine Farbe ändern. Verschiebt es nie zu einem anderen Kunden. Ein Zustandsvergleich ist nicht möglich, jeder Aufruf schreibt. Wer ein Etikett ändern darf, entscheidet das Etikett, nicht die Rolle des Aufrufers: ein globaler Admin, sein Urheber, ein unbeschränkter Aufrufer oder einer, dessen Scope den Kunden des Etiketts enthält. - delete_tag (
tag_id,confirm: true): ein Etikett überall und endgültig löschen. Es fällt von jedem Monitor ab und wird aus jedem Wartungsfenster gestrichen, das es benutzt hat -- ein Fenster, dessen Umfang nur dieses Etikett war, steht danach ganz ohne Umfang da und unterdrückt womöglich nichts mehr. Die Antwort nennt inaffectedWindows, wie viele Fenster betroffen waren, vor dem Löschen gezählt; sieh diese Fenster danach durch.confirmmusstruesein, gesetzt erst, nachdem ein Mensch genau diese Löschung verlangt hat. - add_monitor_tag (
kind,monitor_id,tag_id): ein bestehendes Etikett an einen Monitor hängen. Der Endpunkt ist selbst idempotent, dieses Tool meldet aber in beiden Fällenchanged: true-- lies die Antwort als „das Etikett ist jetzt an diesem Monitor“, nicht als „es wurde etwas geschrieben“. Höchstens FÜNF Etiketten je Monitor; das sechste wird mittagLimitReached(422, mitmax) abgewiesen, dem einzigen 422 dieses Katalogs. Beide Ids sind numerisch. - remove_monitor_tag (
kind,monitor_id,tag_id,confirm: true): ein Etikett von GENAU EINEM Monitor nehmen. Das Etikett selbst bleibt und behält jeden anderen Monitor -- es überall zu löschen istdelete_tag, eine weit größere Handlung. Eine Zuordnung, die es nie gab, wird ebenfalls mit Erfolg beantwortet.confirmist nötig, weil jedes Löschen hier es verlangt, nicht weil die Folge schwer wiegt: ein einzigesadd_monitor_tagmacht es rückgängig.
Eigene Felder, drei Tools, alle drei mit der Rolle admin -- strenger als create_tag unter demselben Scope, dort erlaubt zu sein sagt hier also nichts:
- create_custom_field (
name,field_type, optionalfield_key,options,placeholder,help_text,is_required,show_in_table,sort_order): ein Feld auf einmal an JEDEM Kundendatensatz dieser Organisation definieren. Das ist eine Schemaänderung, keine Angabe an einem Kunden, und mitis_requiredändert es, was andere Menschen ausfüllen müssen. Nicht idempotent:field_keywird ausnameabgeleitet, wenn du keinen übergibst, ein wiederholter Name kollidiert also mitcustomFieldAlreadyExists(409), nicht mit einem 400. Kein Tool listet hier eigene Felder, halte die Id aus der Antwort also fest. - update_custom_field (
custom_field_id, optionalname,field_type,options,placeholder,help_text,is_required,show_in_table,sort_order,is_active): eine Felddefinition ändern. Nie ihrenfield_key, über den jeder bereits erfasste Wert adressiert wird. Ein Vergleich ist nicht möglich, jeder Aufruf schreibt.is_active: falsewirkt genau wiedelete_custom_fieldund verdient dieselbe menschliche Bestätigung, obwohl dieses Tool keine verlangt. Ein geänderterfield_typekonvertiert bereits gespeicherte Werte nicht. - delete_custom_field (
custom_field_id,confirm: true): trotz des Namens löscht das nichts. Der Endpunkt setzt die Definition auf inaktiv; die Definition und jeder bereits an jedem Kunden erfasste Wert bleiben unberührt in der Datenbank. Was sich ändert, ist die Sichtbarkeit: das Feld verlässt die Kundenformulare, die Kundentabelle und die eine Liste, über die seine Id noch lesbar wäre. Halte die Id vorher fest, dennupdate_custom_fieldmitis_active: trueist der Weg zurück. Ein stillgelegtes Feld hält seinenfield_keyweiter belegt,create_custom_fieldmit demselben Namen scheitert also weiterhin ancustomFieldAlreadyExists(409). Behandle es trotzdem als zerstörend: für die Menschen im Dashboard sind das Feld und seine Daten weg.
Geplante Berichte, drei Tools, alle drei mit der Rolle admin. Kein Tool liest hier einen Bericht zurück, also kann nichts mit dem Bestand abgleichen:
- create_report (
name,recipient_user_ids, optionalfrequency,weekday,day_of_month,scope_mode,scope_customer_ids,scope_tag_ids,monitor_types,format,enabled): einen geplanten Bericht anlegen, der benannten Mitgliedern der Organisation wiederkehrend eine Zusammenfassung mailt, ab dem nächsten Fälligkeitstermin und ohne weiteres Zutun. Nicht idempotent -- Berichtsnamen sind nicht eindeutig, ein zweiter Aufruf legt einen ZWEITEN Bericht an, der denselben Menschen nach demselben Plan schreibt und den nur ein Mensch wiederfindet. Der Plan ist standardmäßig monatlich,day_of_month(1 bis 28) ist also Pflicht, außer beifrequencydaily; wöchentlich verlangtweekday. Empfänger müssen Mitglieder dieser Organisation sein, freie Adressen sind hier bewusst nicht vorgesehen. Halte die Id aus der Antwort fest. - update_report (
report_id, dazu beliebige Felder aus dem Anlegen): Name, Zeitplan, Umfang, Monitorfamilien, Format, Empfänger oder das Senden selbst ändern.report_idist die öffentliche Id des Berichts, eine UUID. Jeder Aufruf schreibt, es gibt nichts zum Vergleichen.recipient_user_idsERSETZT die Empfängerliste, statt sie zu ergänzen. Die feldübergreifenden Prüfungen laufen gegen den ZUSAMMENGEFÜHRTEN Bericht, nicht gegen das Gesendete.enabled: falsestoppt das Senden, ohne den Bericht zu verlieren, und ist die umkehrbare Alternative zum Löschen. - delete_report (
report_id,confirm: true): einen geplanten Bericht endgültig löschen. Seine Laufhistorie geht mit, dazu der gespeicherte Pfad des PDF jedes Laufs; die PDF-Datei selbst wird nicht aus dem Objektspeicher entfernt und bleibt im Bucket liegen, ohne dass noch etwas auf sie zeigt. Bereits zugestellte Mails und die davon getrennten Kundenreports bleiben unberührt. Soll nur das Senden aufhören, nimmupdate_reportmitenabled: false.confirmmusstruesein, gesetzt erst, nachdem ein Mensch genau diese Löschung verlangt hat.
Ein Tool ändert ein Mitglied. Ein create_user und ein delete_user gibt es in dieser Verbindung bewusst nicht -- jemanden einladen und jemanden entfernen geschieht im Dashboard, versuche also keinen der beiden Namen:
- update_user (
user_id, optionalfirst_name,last_name,is_active): das Profil genau eines Mitglieds ändern. Es ändert keine Rolle und keine Kundenzuordnung, ein Aufruf hier kann also weder eine Berechtigung erteilen noch eine nehmen. Vergleicht vor dem Schreiben, wenn die Verbindung auchmcp:organization:readhält. Übergibfirst_nameundlast_nameimmer ZUSAMMEN, sobald du eines davon änderst: der Endpunkt baut den angezeigten vollen Namen aus genau den zwei Werten der Anfrage neu.is_active: falsesperrt das Mitglied binnen Sekunden aus, löscht aber nichts, undis_active: truemacht es rückgängig. Verlangt die Rolle admin und ein unbeschränktes Token; ein kundengebundenes Token wird mitcustomerScopedTokenForbidden(403) abgewiesen.list_usersgibt bewusst keine Mitglieder-Ids heraus,user_idmuss also von einem Menschen oder aus dem Dashboard kommen.
Kundschaften und die zwei abrechenbaren Einträge, die daran hängen, sieben Tools:
- create_customer (
name, eines vonpackage_idoderpackage_type, optional Kontaktfelder): eine neue Kundschaft unter dieser Organisation anlegen. Sie legt KEINEN Monitor an -- die Kundschaft startet leer. Zwei organisationsweite Voraussetzungen werden vorher geprüft:quotaRequired(403), wenn die Organisation noch kein Monitor-Kontingent gewählt hat, undbillingSetupRequired(403), wenn sie kein gültiges Lastschriftmandat hat. Ein Paket wählt Kontingent und Funktionsmerkmale und trägt keinen Preis. Nicht idempotent -- Kundennamen sind nicht eindeutig. Verlangt admin oder editor und ein unbeschränktes Token. Halte diepublicIdaus der Antwort fest: die anderen sechs sprechen die Kundschaft nur darüber an. - update_customer (
customer_id, optionalname, Kontaktfelder,status,package_id, Alarm-Umleitungen, Kennzeichen für den Monatsbericht): eine bestehende Kundschaft ändern. Vergleicht vor dem Schreiben, wenn die Verbindung auchmcp:organization:readhält, was hier zählt, weil der Endpunkt je geändertem Feld einen Prüfeintrag schreibt.status: inactiveist das Schwerste, das dieses Tool tut: jeder Monitor aller acht Familien, jede überwachte Domain und jede beobachtete IP wird abgeschaltet, laufende Wartungsfenster stoppen, und veröffentlichte Statusseiten verlassen das Netz. Das Zurücksetzen auf aktiv holt Monitore, Domains und IPs zurück, nicht aber die Statusseiten und die Fenster. - delete_customer (
customer_id,confirm: true): eine Kundschaft samt der weitesten Kaskade dieses Katalogs löschen -- 21 Tabellen verlieren ihre Zeilen mit, darunter ihre Monitore, Domains, IPs, Vorfälle, Statusseiten, Wartungsfenster, API-Token, Benachrichtigungskanäle und die gespeicherten PDFs bereits erzeugter Berichte. Soll nur die Überwachung aufhören, nimmupdate_customermitstatus: inactive. Verlangt die Rolle admin, also strikt mehr alsupdate_customer. Die Bericht-PDFs werden VOR der Zeile aus dem Objektspeicher entfernt, und scheitert das, scheitert der ganze Aufruf, statt persönliche PDFs zurückzulassen, auf die nichts mehr zeigt. - add_customer_domain (
customer_id,domain_name, optionalstatus,notes): das Ablaufdatum einer Domain-Registrierung überwachen. Das legt einen abrechenbaren Monitor an und verbraucht Organisations- wie Paketkontingent. Eine Organisation am Limit scheitert anmonitorQuotaReached(403), außer die automatische Erhöhung ist eingeschaltet -- dann hebt genau dieser Aufruf sie in eine höhere und teurere Stufe; eine schon auf der obersten Stufe scheitert stattdessen anmonitorQuotaNoHigherTier. Unterstützt sind nur Registries, die RDAP beantworten. Nicht idempotent, und es gibt nirgends eine Eindeutigkeitsprüfung: eine Wiederholung legt einen zweiten abrechenbaren Monitor an. Kein Tool listet diese Einträge, halte also Id undpublicIdfest. - delete_customer_domain (
customer_domain_id,confirm: true): eine überwachte Domain endgültig löschen. Ihre Ablauf-Statuszeile und ihre Etikett-Zuordnungen gehen mit; die Etiketten selbst bleiben. Der einzige Weg zurück istadd_customer_domainmit demselben Namen, was einen NEUEN Eintrag mit neuer Id erzeugt. Eine readonly-Rolle wird mitreadonlyMayNotDelete(403) abgewiesen, was immer sie sonst ändern darf.confirmmusstruesein, gesetzt erst, nachdem ein Mensch genau diese Entfernung verlangt hat. - add_customer_ip (
customer_id,ip_address, optionalstatus,notes): eine IP-Adresse auf den DNSBL-Blocklisten überwachen. Das legt einen abrechenbaren Monitor gegen das Limit aktiver IPs der Organisation an, und dieses Limit antwortet mit einem blanken 403 ganz ohnedata.code-- die Meldung muss also gelesen werden, ein Code lässt sich nicht abgleichen. Die Adresse allein entscheidet über IPv4 oder IPv6, ein Argument dafür gibt es bewusst nicht. Nicht idempotent, und es gibt nirgends eine Eindeutigkeitsprüfung. Halte Id undpublicIdaus der Antwort fest. - delete_customer_ip (
customer_ip_id,confirm: true): eine überwachte Adresse endgültig löschen. Ihre DNSBL-Statuszeile, ihre gesamte Listungshistorie und ein daran gebundenes Wartungsfenster gehen mit, und ihre Etikett-Zuordnungen werden entfernt, während die Etiketten bleiben. Der einzige Weg zurück istadd_customer_ipmit derselben Adresse, was einen NEUEN Eintrag mit leerer Historie erzeugt. Eine readonly-Rolle wird mitreadonlyMayNotDelete(403) abgewiesen.confirmmusstruesein.
Was dieser Bereich bewusst nicht erreicht: ein Mitglied anlegen oder entfernen, Sammel-Kundenpflege, einen Bericht von Hand versenden, die Stammdaten der Organisation, die SMTP-Einstellungen und die API-Token. All das bleibt im Dashboard.
Ein Schreib-Tool liefert { changed: true, result } bei einem echten Schreibvorgang oder { changed: false, reason }, wenn ein Zustandsvergleich nichts zu tun fand. pause_monitor, resume_monitor, rename_monitor, set_check_interval, acknowledge_incident, resolve_incident, update_maintenance_window, update_status_page_design, update_user und update_customer machen diesen Vergleich (update_maintenance_window nur, wenn die Verbindung auch mcp:statuspages:read hält; update_status_page_design nur, wenn sie mcp:statuspages:read hält und die Anfrage kein Feld setzt, das der Vergleich nicht sehen kann; update_user und update_customer nur, wenn sie mcp:organization:read hält); create_website_monitor, delete_monitor, post_incident_update, delete_incident, create_maintenance_window, delete_maintenance_window, create_status_page, update_status_page, delete_status_page, add_status_page_domain, verify_status_page_domain, activate_status_page_domain, delete_status_page_domain, create_notification_channel, update_notification_channel, delete_notification_channel, create_tag, update_tag, delete_tag, add_monitor_tag, remove_monitor_tag, create_custom_field, update_custom_field, delete_custom_field, create_report, update_report, delete_report, create_customer, delete_customer, add_customer_domain, delete_customer_domain, add_customer_ip und delete_customer_ip nicht -- ein Löschvorgang antwortet schon am Endpunkt selbst idempotent, die Kanal-, Etiketten-, Feld- und Bericht-Tools haben keinen Lese-Endpunkt zum Vergleichen, und die übrigen sind bewusst nie ein No-op. Fehler kommen wie bei den Lese-Tools oben zurück: isError: true mit einer schlichten Meldung, ohne structuredContent.
Strukturierte Ausgabe
Jedes Tool deklariert ein outputSchema, und jeder erfolgreiche Aufruf liefert neben dem Textblock ein structuredContent. Damit kannst du eine Antwort gegen das veröffentlichte Schema typprüfen, statt unser JSON von Hand zu parsen. Der Textblock bleibt unverändert und trägt weiterhin die vollständige Antwort, ein Client, der strukturierte Ausgabe ignoriert, sieht genau das, was er vorher gesehen hat.
Zwei Eigenschaften dieser Schemas sind bewusst so gewählt:
- Kein Feld ist Pflicht. Das Schema typisiert die Felder, die es kennt; es behauptet nie, dass eines vorhanden ist. Ein Endpunkt, der einen Wert weglässt oder auf
nullsetzt, macht aus einem Check keinen fehlgeschlagenen Tool-Aufruf. - Zusätzliche Felder sind erlaubt. Die Schemas sind offen: Ein später ergänztes Feld reist in
structuredContenteinfach mit, statt in einem strikten Client an der Validierung zu scheitern.
structuredContent muss ein JSON-Objekt sein, und vier dieser Tools antworten mit einem nackten Array: Bei list_incidents steckt es in der strukturierten Form unter dem Schlüssel incidents, bei list_alert_channels unter channels, bei list_maintenance_windows unter maintenanceWindows, bei list_customers unter customers. Der Textblock behält das Array in allen vier Fällen unverändert.
Fehler tragen kein structuredContent. Sie kommen wie bisher als isError: true mit einer schlichten Meldung zurück.
Tool-Namen bestehen nur aus Buchstaben, Ziffern und Unterstrichen. Das ist keine Kosmetik: Die großen Function-Calling-APIs prüfen Tool-Namen gegen ^[a-zA-Z0-9_-]{1,64}$ (OpenAI) beziehungsweise ^[a-zA-Z0-9_-]{1,128}$ (Anthropic), ein Name mit Punkten würde von jedem Client abgelehnt, der unsere Tools an ein Modell durchreicht.
Verbindung per OAuth (Claude Desktop / Claude.ai)
Der /mcp-Endpunkt von Uptimeify unterstützt außerdem Standard-MCP-OAuth (OAuth 2.1 + PKCE + Dynamic Client Registration): so authentifiziert sich der Remote-MCP-Connector von Claude, ohne dass du manuell ein API-Token anlegen musst.
- Füge in Claude
https://uptimeify.io/mcpals Remote-MCP-Server hinzu und wähle Verbinden. - Claude registriert sich automatisch (Dynamic Client Registration) und öffnet ein Browserfenster, in dem du dich bei Uptimeify anmeldest und den Zugriff bestätigst.
- Die Zustimmungsseite nennt die anfragende Anwendung und das Konto, mit dem sie verknüpft wird, und bietet jeden von der Anwendung angefragten Bereich als getrenntes Häkchen an, gebündelt in bis zu drei Gruppen: Überwachung und Betrieb (Monitore, Vorfälle, Prüfhistorie, Alarme, Statusseiten -- lesend), Konto und Abrechnung (Organisation, Abrechnung -- lesend) und Schreibzugriff (Monitore, Vorfälle, Wartungsfenster, Statusseiten, Alarmkanäle, Organisation -- siehe Authentifizierte Tools (schreibend) oben; Prüfhistorie und Abrechnung sind die zwei Lesebereiche ohne Schreib-Gegenstück). Claudes Remote-MCP-Connector fragt die sieben Lesebereiche an, du siehst hier also die breiteste Ausprägung der Lese-Hälfte der Seite; eine Anwendung, die Lesezugriff verlangt, ohne einen Bereich zu benennen, bekommt nur die drei Betriebsbereiche, die es vor dieser Erweiterung gab -- Monitore, Vorfälle, Prüfhistorie --, und nur diese drei erscheinen, vorangehakt. Welche Bereiche auch angeboten werden: Die Lesebereiche starten vorangehakt (Kontobereiche abgehakt, weil dort personenbezogene und Abrechnungsdaten liegen), und jeder Schreibbereich startet abgehakt -- hier ist von Anfang an nichts freigegeben. Hakst du einen Schreibbereich an, hakt das automatisch seinen gleichnamigen Lese-Zwilling mit an, weil die Tools einen Datensatz erst lesen müssen, bevor sie entscheiden, ob ein Schreibvorgang überhaupt etwas ändern würde -- hakst du den Schreibbereich danach wieder ab, bleibt die Lesefreigabe bestehen. Wartungsfenster sind der eine Schreibbereich ohne eigenen Lese-Zwilling zum Anhaken:
list_maintenance_windowsliegt stattdessen im Statusseiten-Lesebereich, den du separat anhaken musst, damitupdate_maintenance_windowvor dem Schreiben den Zustand vergleicht. Was du abwählst, bleibt aus der Verbindung heraus. Ausserhalb eines angehakten Schreibbereichs bleibt die Verbindung genauso lesend wie zuvor: Sie erhält genau die Sichtbarkeit deines eigenen Kontos, ein kundenbeschränkter Nutzer sieht in Claude nur diesen Kunden, ein Organisations-Administrator sieht die gesamte Organisation -- und selbst innerhalb eines angehakten Schreibbereichs hängt es davon ab, ob diese Bereitstellung Schreib-Tools überhaupt eingeschaltet hat (siehe oben), ob ein Tool tatsächlich etwas bewirkt. - Nach der Bestätigung sieht Claude nur die Werkzeuge der Bereiche, die du freigegeben hast, und keines der übrigen. Alle sieben Lesebereiche bringen Werkzeuge mit, dieselben 13 Lese-Tools wie bei
wsm_-API-Token:list_monitorsundmonitor_status(Monitore),list_incidents(Vorfälle),check_historyunduptime_summary(Prüfhistorie),list_alert_channelsundalert_history(Alarme),list_status_pagesundlist_maintenance_windows(Statusseiten),get_organization,list_usersundlist_customers(Organisation),billing_summary(Abrechnung). Die Abrechnung ist der eine Bereich, der sich mit einem zweiten anders liest: Gibst du die Organisation dazu frei, trägt die Verbrauchsaufschlüsselung Kundennamen, lässt du sie weg, bleibt es bei den öffentlichen Kennungen. Hakst du die sechs Schreibbereiche an, kommen dort, wo die Bereitstellung sie eingeschaltet hat, die 43 oben genannten Tools dazu --wsm_-API-Token bekommen diese nie, egal wie sie berechtigt sind. Die anonymen Prüfwerkzeuge bleiben von alldem unberührt.
An der Seite führt kein Weg vorbei. Eine Autorisierungsanfrage ohne prompt oder mit einem beliebigen anderen Wert bekommt die Zustimmungsseite trotzdem. Die einzige Anfrage, die wir nicht umschreiben, ist prompt=none: sie verlangt ausdrücklich keine Oberfläche und bekommt deshalb den Fehler-Redirect aus OpenID Connect, ohne Sitzung mit login_required, mit Sitzung mit consent_required. Die Scope-Namen selbst stehen unter Verbundene Apps.
OAuth-Access-Token sind kurzlebig (1 Stunde) und erneuern sich automatisch im Hintergrund, solange Claude die Verbindung nutzt; die zugrundeliegende Berechtigung läuft nach 7 Tagen Inaktivität automatisch ab. Verbundene Apps kannst du jederzeit unter Einstellungen → Verbundene Apps einsehen und widerrufen (siehe Verbundene Apps): der Widerruf wirkt sofort, für eine erneute Verbindung ist wieder eine OAuth-Zustimmung nötig.
OAuth und statische wsm_-API-Token funktionieren gleichzeitig auf /mcp: eine OAuth-Verbindung erfordert nicht, eine bestehende API-Token-Integration zu entfernen.
Beispiel (tools/list)
curl -X POST https://uptimeify.io/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Ohne Authorization-Header stehen hier die 20 anonymen Tools. Mit API-Token oder OAuth-Verbindung kommen die kontogebundenen dazu, die deine Freigabe abdeckt.
Beispiel (authentifizierter Tool-Aufruf)
Eigene Monitore auflisten: mit Authorization-Header:
curl -X POST https://uptimeify.io/mcp \
-H 'Authorization: Bearer wsm_dein_token_hier' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_monitors","arguments":{}}}'