Skip to main content
Glama
JohnGilligan2

notify-mcp

{"type": "text"}# notify-mcp

Correo electrónico y SMS de entrega a uno mismo para el personal de Example Corp, como servidor MCP remoto autenticado con Entra. Esta es la ruta de envío para el despliegue de jefe de personal de claude.ai: los agentes pueden enviar por correo o mensaje de texto el propio contenido del usuario autenticado, y estructuralmente nada más.

El invariante (por qué existe este servidor)

Los agentes que leen contenido no confiable (correo entrante, tickets, chats) nunca deben tener una capacidad de envío sin restricciones: una inyección de prompt podría convertirlo en un canal de exfiltración. Este servidor lo resuelve por construcción:

  • Los destinatarios no son parámetros de la herramienta. El correo se envía al UPN del llamante, tomado del token de Entra validado. El SMS se envía al móvil registrado del llamante. Un modelo completamente comprometido puede cambiar qué se envía, nunca dónde.

  • El remitente (FROM) está bloqueado a <agent>approver@example.com — el servidor no puede enviar como humano, por lo que no puede suplantar a nadie.

  • Las claves de Resend e Inteliquent viven solo en este contenedor. Los usuarios nunca ven una clave; se autentican con su propio inicio de sesión de M365.

  • Presupuestos por hora por usuario + una línea de registro de auditoría por envío.

Related MCP server: graphdo-ts

Herramientas

Tool

Qué hace

whoami

Devuelve el correo electrónico y el móvil enmascarado a los que se enviarán los envíos. Prueba la conexión con esto primero.

send_email_to_me(subject, body_markdown, agent_name?)

Envía un correo al llamante. agent_name personaliza el remitente (alertsapprover@example.com).

send_sms_to_me(message)

Envía un mensaje de texto al móvil del llamante desde el DID de la empresa 13105550100. ≤640 caracteres.

register_my_mobile(mobile_number)

Inicia la configuración de SMS: envía un código de 6 dígitos al número.

confirm_my_mobile(code)

Completa la configuración: verifica el código, guarda el número y envía un aviso de cambio por correo al usuario.

Cómo sabe el servidor quién eres

Claude → inicio de sesión de Entra (el propio inicio de sesión del usuario) → cada llamada de herramienta lleva un JWT de portador → AzureJWTVerifier valida firma/emisor/audiencia → la reclamación preferred_username = el destinatario. Sin variables de entorno por usuario, sin configuración; la identidad es criptográfica.

Los números de móvil no están en el token, por lo que el SMS utiliza auto-registro verificado (diseñado para inquilinos que no completan el campo mobilePhone de Entra — el nuestro no lo hace):

  1. El usuario (normalmente durante la entrevista de configuración del CoS): "registra mi móvil 310-555-1212" → el servidor envía un código de 6 dígitos a ese número.

  2. El usuario escribe el código → confirm_my_mobile → el número se guarda en /data/sms_directory.json vinculado a su UPN + se envía un correo de confirmación.

  3. Los cambios quedan entonces bloqueados (NOTIFY_ALLOW_MOBILE_CHANGE=false): un número confirmado solo puede ser cambiado por el administrador editando el registro. La verificación del código demuestra la posesión; el bloqueo de cambios + el aviso por correo eliminan el ataque de re-vinculación por inyección (contenido hostil que redirige los mensajes a otro lugar).

Orden de resolución: archivo de registro (las entradas manuales son cadenas simples, las entradas auto-registradas son objetos) → mobilePhone opcional de Entra a través de Graph (NOTIFY_GRAPH_LOOKUP_ENABLED=true + -GrantGraphUserRead; innecesario si se usa el auto-registro).

Duración de la sesión del conector (la solución a la desconexión)

Tres cosas evitan que el conector muestre "desconectado":

  1. offline_access se anuncia en los metadatos del recurso protegido (NOTIFY_ADVERTISE_OFFLINE_ACCESS=true), por lo que el inicio de sesión de Claude obtiene un token de actualización y renueva silenciosamente los tokens de acceso de ~60–90 min.

  2. stateless_http=True — las sesiones sobreviven a los redespliegues del contenedor.

  3. El host proxy NPM debe tener las anulaciones de tiempo de espera del playbook (ver PORTAINER_DEPLOY.md) para que las transmisiones inactivas no se corten a los 60 s.

También verifica que ninguna política de acceso condicional de frecuencia de inicio de sesión cubra esta aplicación. Prueba de aceptación: conéctate, espera 2+ horas inactivo, redespliega el contenedor y luego llama a whoami — no debería aparecer ninguna solicitud de re-autenticación.

Configuración (orden del playbook)

  1. scripts/setup_entra_app.ps1 -TenantId <tenant> (opcionalmente -GrantGraphUserRead) — imprime los valores de entorno del servidor + el secreto del conector (va en la configuración avanzada del conector de Claude, nunca en el servidor).

  2. Despliega mediante la pila Git de Portainer — PORTAINER_DEPLOY.md. Puerto de host sugerido 8093 (prueba primero; registrado en el registro del playbook).

  3. Host proxy NPM notify-mcp.example.com → el contenedor; tiempos de espera del playbook + lista de permitidos de IP de Anthropic; certificado LE antes de habilitar la lista de permitidos.

  4. Añádelo como conector personalizado de la organización en claude.ai; los usuarios se conectan una vez con su propio inicio de sesión de M365.

Pruebas de aceptación

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

Luego, en Claude, como miembro del grupo:

  1. whoami → tu propio correo electrónico, móvil "en registro (…1234)" o un fallo claro.

  2. send_email_to_me → llega a TU bandeja de entrada desde notify_ai@.

  3. Pide al modelo que "envíe esto a <alguien más>" → debe negarse / no tener forma de cumplirlo. Si esto falla es un P1 — no desplegar.

  4. register_my_mobile con tu número → llega el código → confirm_my_mobile → llega el correo de confirmación → send_sms_to_me funciona. Luego intenta registrar un número DIFERENTE → debe ser rechazado (bloqueo de cambios).

  5. La prueba de 2 horas inactivo + redespliegue anterior.

  6. Un no miembro se conecta → rechazado en el inicio de sesión (AADSTS50105).

Desarrollo local

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