notify-mcp
notify-mcp
Доставка на себя по электронной почте и SMS для сотрудников Example Corp, как удалённый MCP-сервер с аутентификацией Entra. Это путь отправки для развертывания claude.ai для руководителя аппарата: агенты могут отправлять по электронной почте или SMS вошедшему в систему пользователю их собственный контент, и структурно ничего больше.
Инвариант (почему существует этот сервер)
Агенты, которые читают недоверенный контент (входящая почта, тикеты, чаты), никогда не должны обладать неограниченной возможностью отправки — инъекция подсказок может превратить её в канал эксфильтрации. Этот сервер решает эту проблему конструктивно:
Получатели не являются параметрами инструмента. Электронная почта отправляется на UPN вызывающего, взятый из проверенного токена Entra. SMS отправляется на мобильный номер вызывающего, указанный в записи. Полностью скомпрометированная модель может изменить что отправляется, но никогда куда.
FROM заблокирован на
<agent>approver@example.com— сервер не может отправлять от имени человека, поэтому не может выдавать себя за кого-либо.Ключи Resend + Inteliquent живут только в этом контейнере. Пользователи никогда не видят ключ; они аутентифицируются с помощью своего собственного входа M365.
Почасовые бюджеты на пользователя + строка журнала аудита для каждой отправки.
Related MCP server: graphdo-ts
Инструменты
Инструмент | Что делает |
| Возвращает адрес электронной почты и замаскированный мобильный номер, на которые будут доставляться отправления. Сначала проверьте подключение с помощью этого. |
| Отправляет электронное письмо вызывающему. |
| Отправляет SMS на мобильный номер вызывающего с корпоративного DID 13105550100. ≤640 символов. |
| Запускает настройку SMS: отправляет 6-значный код на номер. |
| Завершает настройку: проверяет код, сохраняет номер, отправляет пользователю уведомление об изменении. |
Как сервер узнаёт, кто вы
Claude → вход в Entra (собственный логин пользователя) → каждый вызов инструмента несёт bearer JWT → AzureJWTVerifier проверяет подпись/эмитента/аудиторию → утверждение preferred_username = получатель. Никаких переменных окружения на пользователя, никакой конфигурации; идентичность криптографическая.
Мобильные номера не в токене, поэтому SMS использует подтверждённую саморегистрацию (создано для тенантов, которые не заполняют mobilePhone в Entra — наш не заполняет):
Пользователь (обычно во время интервью по настройке CoS): «зарегистрируй мой мобильный 310-555-1212» → сервер отправляет 6-значный код на этот номер.
Пользователь вводит код →
confirm_my_mobile→ номер сохраняется в/data/sms_directory.jsonс привязкой к их UPN + отправляется подтверждающее письмо.Затем изменения блокируются (
NOTIFY_ALLOW_MOBILE_CHANGE=false): подтверждённый номер может быть изменён только администратором, редактирующим реестр. Проверка кода доказывает владение; блокировка изменений + уведомление по электронной почте устраняют атаку с переназначением через инъекцию (враждебный контент, перенаправляющий тексты в другое место).
Порядок разрешения: файл реестра (ручные записи — простые строки, саморегистрируемые записи — объекты) → необязательный mobilePhone в Entra через Graph (NOTIFY_GRAPH_LOOKUP_ENABLED=true + -GrantGraphUserRead; не требуется, если используется саморегистрация).
Долговечность сеанса коннектора (исправление отключения)
Три вещи не дают коннектору показывать «отключено»:
offline_accessрекламируется в метаданных защищённого ресурса (NOTIFY_ADVERTISE_OFFLINE_ACCESS=true), поэтому вход Claude получает токен обновления и незаметно продлевает токены доступа на ~60–90 минут.stateless_http=True— сеансы переживают повторное развёртывание контейнера.Прокси-хост NPM должен иметь переопределения тайм-аутов из плейбука (см. PORTAINER_DEPLOY.md), чтобы простаивающие потоки не обрывались на 60 секунд.
Также проверьте, что ни одна политика условного доступа с частотой входа не покрывает это приложение. Приёмочный тест: подключитесь, подождите 2+ часа простоя, переразверните контейнер, затем вызовите whoami — не должно появиться запроса на повторную аутентификацию.
Настройка (порядок плейбука)
scripts/setup_entra_app.ps1 -TenantId <tenant>(необязательно-GrantGraphUserRead) — выводит значения env для сервера + секрет коннектора (идёт в расширенные настройки коннектора Claude, никогда на сервер).Разверните через Git-стек Portainer — PORTAINER_DEPLOY.md. Рекомендуемый порт хоста 8093 (сначала проверьте; записано в реестре плейбука).
Прокси-хост NPM
notify-mcp.example.com→ контейнер; тайм-ауты плейбука + список разрешённых IP Anthropic; сертификат LE перед включением списка разрешённых.Добавьте как пользовательский коннектор организации в claude.ai; пользователи подключаются один раз со своим собственным входом M365.
Приёмочные тесты
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Затем в Claude, как участник группы:
whoami→ ваш собственный адрес электронной почты, мобильный «в записи (…1234)» или явный промах.send_email_to_me→ приходит в ВАШ ящик отnotify_ai@.Попросите модель «отправить это <кому-то другому>» → она должна отказаться / не иметь возможности выполнить. Если это не работает — это P1, не разворачивайте.
register_my_mobileс вашим номером → приходит код →confirm_my_mobile→ приходит подтверждающее письмо →send_sms_to_meработает. Затем попробуйте зарегистрировать ДРУГОЙ номер → должно быть отказано (блокировка изменений).Тест с 2-часовым простоем и переразвёртыванием выше.
Не участник подключается → отклонено при входе (AADSTS50105).
Локальная разработка
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-offThis server cannot be installed
Maintenance
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
- AlicenseCqualityDmaintenanceEnables 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.41MIT

graphdo-tsofficial
AlicenseAqualityCmaintenanceEnables AI agents to send emails and manage tasks in Microsoft To Do with scoped, low-risk access to Microsoft Graph.3511MIT- AlicenseNot gradedqualityCmaintenanceEnables 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
- AlicenseNot gradedqualityBmaintenanceAuthenticated email service MCP for AI agents.183Apache 2.0
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
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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