Skip to main content
Glama
JohnGilligan2

notify-mcp

notify-mcp

E-Mail- und SMS-Zustellung an sich selbst für Example Corp-Mitarbeiter als Entra-authentifizierter Remote-MCP-Server. Dies ist der Sendepfad für die Chief-of-Staff-Einführung von claude.ai: Agenten können dem angemeldeten Benutzer ihre eigenen Inhalte per E-Mail oder SMS senden, und strukturell nichts anderes.

Die Invariante (warum dieser Server existiert)

Agenten, die unvertrauenswürdige Inhalte lesen (eingehende E-Mails, Tickets, Chats), dürfen niemals eine uneingeschränkte Sendefähigkeit besitzen – eine Prompt-Injection könnte sie in einen Exfiltrationskanal verwandeln. Dieser Server löst das konstruktionsbedingt:

  • Empfänger sind keine Tool-Parameter. E-Mails gehen an die UPN des Aufrufers, die aus dem validierten Entra-Token stammt. SMS gehen an das hinterlegte Mobiltelefon des Aufrufers. Ein vollständig kompromittiertes Modell kann ändern, was gesendet wird, niemals wohin.

  • FROM ist gesperrt auf <agent>approver@example.com – der Server kann nicht als Mensch senden, also kann er niemanden impersonieren.

  • Die Resend- und Inteliquent-Schlüssel liegen nur in diesem Container. Benutzer sehen nie einen Schlüssel; sie authentifizieren sich mit ihrem eigenen M365-Login.

  • Stündliche Budgets pro Benutzer + eine Audit-Log-Zeile pro Sendung.

Related MCP server: graphdo-ts

Tools

Tool

Was es tut

whoami

Gibt die E-Mail-Adresse und die maskierte Mobilnummer zurück, an die Sendungen zugestellt werden. Testen Sie die Verbindung zuerst damit.

send_email_to_me(subject, body_markdown, agent_name?)

Sendet eine E-Mail an den Aufrufer. agent_name markiert den Absender (alertsapprover@example.com).

send_sms_to_me(message)

Sendet eine SMS an das Mobiltelefon des Aufrufers von der Firmen-DID 13105550100. ≤640 Zeichen.

register_my_mobile(mobile_number)

Startet die SMS-Einrichtung: sendet einen 6-stelligen Code an die Nummer.

confirm_my_mobile(code)

Schließt die Einrichtung ab: verifiziert den Code, speichert die Nummer und sendet dem Benutzer eine Änderungsmitteilung per E-Mail.

Wie der Server weiß, wer Sie sind

Claude → Entra-Anmeldung (das eigene Login des Benutzers) → jeder Tool-Aufruf trägt ein Bearer-JWT → AzureJWTVerifier validiert Signatur/Aussteller/Zielgruppe → preferred_username-Anspruch = der Empfänger. Keine Umgebungsvariablen pro Benutzer, keine Konfiguration; die Identität ist kryptografisch.

Mobilnummern sind nicht im Token enthalten, daher verwendet SMS verifizierte Selbstregistrierung (entwickelt für Mandanten, die kein Entra-mobilePhone befüllen – unserer tut das nicht):

  1. Benutzer (typischerweise während des CoS-Einrichtungsinterviews): „register my mobile 310-555-1212" → der Server sendet einen 6-stelligen Code an diese Nummer.

  2. Benutzer gibt den Code ein → confirm_my_mobile → Nummer wird in /data/sms_directory.json gespeichert, verknüpft mit ihrer UPN + Bestätigungs-E-Mail wird gesendet.

  3. Änderungen sind dann gesperrt (NOTIFY_ALLOW_MOBILE_CHANGE=false): Eine bestätigte Nummer kann nur vom Administrator durch Bearbeiten des Registers geändert werden. Die Code-Verifizierung beweist den Besitz; die Änderungssperre + E-Mail-Benachrichtigung verhindern den Injection-Rebind-Angriff (feindlicher Inhalt, der SMS anderswohin umleitet).

Auflösungsreihenfolge: Registry-Datei (manuelle Einträge sind einfache Zeichenfolgen, selbstregistrierte Einträge sind Objekte) → optionales Entra-mobilePhone über Graph (NOTIFY_GRAPH_LOOKUP_ENABLED=true + -GrantGraphUserRead; unnötig, wenn Selbstregistrierung verwendet wird).

Langlebigkeit der Connector-Sitzung (die Lösung für Trennungen)

Drei Dinge verhindern, dass der Connector „getrennt" anzeigt:

  1. offline_access wird beworben in den Metadaten der geschützten Ressource (NOTIFY_ADVERTISE_OFFLINE_ACCESS=true), sodass die Anmeldung von Claude ein Aktualisierungstoken erhält und die ~60–90 Minuten gültigen Zugriffstokens stillschweigend erneuert.

  2. stateless_http=True – Sitzungen überleben Container-Neubereitstellungen.

  3. NPM-Proxy-Host muss die Timeout-Überschreibungen des Playbooks haben (siehe PORTAINER_DEPLOY.md), damit Leerlauf-Streams nicht nach 60 Sekunden abgeschnitten werden.

Überprüfen Sie außerdem, dass keine Conditional-Access-Richtlinie für Anmeldehäufigkeit diese App abdeckt. Abnahmetest: Verbinden, 2+ Stunden im Leerlauf warten, Container neu bereitstellen, dann whoami aufrufen – keine erneute Authentifizierungsaufforderung sollte erscheinen.

Einrichtung (Playbook-Reihenfolge)

  1. scripts/setup_entra_app.ps1 -TenantId <tenant> (optional -GrantGraphUserRead) – gibt die Server-Umgebungsvariablen und das Connector-Geheimnis aus (geht in die erweiterten Einstellungen des Claude-Connectors, niemals auf den Server).

  2. Bereitstellung über Portainer-Git-Stack – PORTAINER_DEPLOY.md. Empfohlener Host-Port 8093 (zuerst testen; im Playbook-Register dokumentiert).

  3. NPM-Proxy-Host notify-mcp.example.com → der Container; Playbook-Timeouts + Anthropic-IP-Whitelist; LE-Zertifikat vor Aktivierung der Whitelist.

  4. Als benutzerdefinierten Connector der Organisation in claude.ai hinzufügen; Benutzer verbinden sich einmal mit ihrem eigenen M365-Login.

Abnahmetests

curl http://<docker-host>:8093/healthz                       # {"status":"ok",...}
curl -s https://notify-mcp.example.com/.well-known/oauth-protected-resource/mcp | jq
#   scopes_supported MUST include the full https://.../mcp/access_as_user scope
#   AND "offline_access"
curl -i https://notify-mcp.example.com/mcp                  # 401 + WWW-Authenticate

Dann in Claude, als Gruppenmitglied:

  1. whoami → Ihre eigene E-Mail-Adresse, Mobilnummer „hinterlegt (…1234)" oder ein klarer Fehlschlag.

  2. send_email_to_me → kommt in IHREM Posteingang von notify_ai@ an.

  3. Bitten Sie das Modell, „dies an zu senden" → es muss ablehnen / keine Möglichkeit haben, dem nachzukommen. Wenn dies fehlschlägt, ist es ein P1 – nicht ausrollen.

  4. register_my_mobile mit Ihrer Nummer → Code kommt an → confirm_my_mobile → Bestätigungs-E-Mail kommt an → send_sms_to_me funktioniert. Dann versuchen Sie, eine ANDERE Nummer zu registrieren → muss abgelehnt werden (Änderungssperre).

  5. Der 2-Stunden-Leerlauf- und Neubereitstellungstest von oben.

  6. Ein Nicht-Mitglied verbindet sich → bei der Anmeldung abgelehnt (AADSTS50105).

Lokale Entwicklung

pip install -r requirements.txt
MCP_AUTH_ENABLED=false python -m notify_mcp   # Inspector only — tools will
                                              # refuse to send without a token
                                              # identity; NEVER expose auth-off
F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    C
    quality
    D
    maintenance
    Enables secure, zero-trust access to MCP tools through short-lived, signed capability leases that bind tool execution to specific sessions, intents, and constraints. Prevents prompt injection attacks and privilege escalation with dynamic risk scoring, policy enforcement, and tamper-evident audit logging.
    4
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables email agents to send emails with granular trust levels per contact, ensuring human approval for high-risk or unknown recipients while allowing automatic sending for trusted ones.
    MIT

View all related MCP servers

Related MCP Connectors

  • Phone, SMS & email for AI agents — one remote MCP endpoint, OAuth login, zero install.

  • Hosted email MCP for AI agents with inboxes, send/receive, memory, recovery, and credits.

  • Remote MCP for Copilot CLI switch gate MCP, structured receipts, audit logs, and reviewer-ready evid

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JohnGilligan2/mcp-notify'

If you have feedback or need assistance with the MCP directory API, please join our Discord server