campaign-preflight-mcp
Предполётная проверка кампании
Campaign Preflight — это линтер только для чтения для исходящих кампаний. Он выявляет проблемы с конфигурацией, контактными данными, персонализацией, подавлением, расписанием и отправителями до запуска.
Что он делает
Каждая команда, занимающаяся исходящими рассылками, отправляла кампанию с ошибкой. Кто-то, кто отписался, всё равно получил письмо. Последовательность продолжала отправлять follow-up после того, как потенциальный клиент ответил. Merge-поле никогда не подставлялось, и двести человек получили «Привет {{first_name}}».
Вы узнаёте об этом после отправки.
Campaign Preflight выполняет 76 детерминированных проверок конфигурации кампании, лидов, текста, расписания, отправителей и подверженности подавлению, и возвращает решение о готовности с доказательствами для каждого вывода. Он никогда не записывает данные в ваш провайдер и не может ничего активировать.
Что он не делает, сразу, а не в конце:
Он не гарантирует доставляемость. Он проверяет конфигурацию и данные, а не попадание во входящие, и никогда не выдумывает оценку доставляемости.
Он не даёт юридических консультаций. Проверки региона, домена и отказа от подписки сравнивают кампанию с вашей собственной настроенной политикой — а не с GDPR, CAN-SPAM или CASL.
Он не проверяет почтовые ящики. Проверки адресов — только синтаксические. Никакого DNS, никакого SMTP.
Он не заменяет защитные механизмы вашего провайдера. Оставьте их включёнными.
Результаты — это снимок на конкретный момент времени. Кампания, прошедшая проверку в 09:00, может быть отредактирована в 09:05.
Более подробно в docs/limitations.md.
Related MCP server: Newsletter Tools
«Мы проверили, и всё в порядке» ≠ «мы не смогли проверить»
Проверяющий инструмент, который не может отличить эти случаи, хуже, чем отсутствие проверки, потому что он превращает ошибку прав доступа в зелёный свет.
Campaign Preflight делает это различие структурным. Каждое чтение от провайдера возвращает данные плюс причину, по которой они существуют или не существуют, и каждое правило объявляет, какие данные ему нужны. Если эти данные недоступны, движок переводит правило в состояние UNKNOWN до того, как оно сможет выполниться. Правила не могут отказаться от этого.
Ситуация | Результат |
Список подавления прочитан, никто не совпал |
|
Список подавления не предоставлен |
|
Конечная точка подавления вернула 403 |
|
Ноль лидов в кампании |
|
Конечная точка лидов недоступна |
|
Есть четыре вердикта, а не два: READY, READY_WITH_WARNINGS, NOT_READY и INCOMPLETE.
Требования
Python 3.9 или новее. Это весь список.
У пакета нет зависимостей времени выполнения — он не импортирует ничего за пределами стандартной библиотеки. httpx — это опциональное дополнение, необходимое только для живого провайдера Instantly, за ленивым импортом.
Минимальная версия 3.9 выбрана намеренно и намеренно ниже, чем можно было бы ожидать. Это самый старый интерпретатор, который плагин может встретить на машине пользователя, и поскольку зависимостей нет, ничто не заставляет его быть выше. CI запускает 3.9–3.13 плюс задание с «голым» интерпретатором, которое вообще ничего не устанавливает, на Linux, macOS и Windows.
Именно эта комбинация позволяет плагину работать без этапа установки: он использует тот python3, который уже есть.
Установка
Как плагин Claude (маркетплейс)
/plugin marketplace add katekruger/campaignpreflightplugin
/plugin install campaign-preflightРепозиторий сам по себе является маркетплейсом: .claude-plugin/marketplace.json находится в корне рядом с манифестом плагина.
Как плагин Claude (локальная копия)
git clone https://github.com/katekruger/campaignpreflightplugin/plugin marketplace add ./campaignpreflightplugin
/plugin install campaign-preflightКак CLI
pipx install campaign-preflightИли прямо из копии репозитория, вообще ничего не устанавливая:
PYTHONPATH=src python3 -m campaign_preflight.cli demoКак MCP-сервер
claude mcp add campaign-preflight -- campaign-preflight-mcpШесть инструментов только для чтения. Ничего, что могло бы активировать, редактировать, импортировать или отправлять. Настройка для Claude Code и Claude Desktop: docs/mcp.md.
Быстрый старт
campaign-preflight demoНикакого API-ключа. Никакой сети. Никакой конфигурации.
CAMPAIGN PREFLIGHT
Campaign: Enterprise Q3 Outbound
Provider: demo
Readiness: NOT READY
Score: 0/100
Confidence: MEDIUM
BLOCKERS
[campaign.stop_on_reply]
Stop-on-reply is disabled: repliers will keep receiving follow-ups.
Remediation: Enable stop-on-reply on the campaign.
[personalization.prompt_injection]
1 contact(s) have prompt-injection text in their personalization.
Affected: s***********a@caldera.example.com
Remediation: Remove the affected personalization and review the enrichment source it came from.
[suppression.contact_listed]
1 contact(s) appear on the active suppression list.
Affected: m**********s@stonebridge.example.com
Remediation: Remove these contacts from the campaign before activation.
WARNINGS
[contacts.missing_first_name]
2 of 20 contacts (10.0%) are missing a first name.
Affected: i**o@summitforge.example.com, r******s@clearwater.example.com
Remediation: Backfill the missing first names, or use a fallback in your copy.
UNKNOWN
[senders.aggregate_capacity]
Sender capacity is unavailable: 1 of 3 senders report no daily limit.
Affected: r***n@example.com
------------------------------------------------------------------------------
Summary:
8 blockers, 17 failures, 21 warnings, 1 unknown, 32 passed
20 leads and 3 sender(s) checked in 0.0s
Confidence is MEDIUM: 1 check(s) could not run.
Point-in-time snapshot. Campaign state may change after this check ran.Обратите внимание на последний вывод. Один отправитель не сообщает дневной лимит, поэтому общую ёмкость невозможно суммировать. Большинство инструментов сложили бы отправителей, у которых лимит есть, и назвали бы это числом. Этот говорит, что не знает — и из-за этого снижает уверенность с HIGH до MEDIUM.
Это различие и есть вся идея.
Проверка собственной кампании
После установки плагина опишите её простым языком:
Проверь эту кампанию перед отправкой.
Вот мой список лидов — что с ним не так? (вставьте или загрузите)
Я отправляю последовательность из 3 писем 200 людям, по 80 в день, в будни с 9 до 17 по восточному времени. Это нормально?
Есть три способа начать, и ни один не требует учётной записи:
У вас есть | Что происходит |
Файл (загруженный или на диске) | Проверяется напрямую. |
Вставленный список или текст | Записывается во временный файл, проверяется, затем удаляется. |
Только описание | Файл кампании создаётся из ваших слов, показывается вам, затем проверяется. |
Всё, что вы не знаете, остаётся пустым, а не угадывается — пустое поле возвращается как «не удалось проверить», что является честным ответом.
Из файлов, в командной строке
campaign-preflight check \
--campaign examples/clean_campaign/campaign.yaml \
--leads examples/clean_campaign/leads.csv \
--suppressions examples/clean_campaign/suppressions.csvВ репозитории есть три рабочих примера, по одному на каждый вердикт:
Пример | Вердикт | Код выхода |
|
| |
|
| |
|
|
В CI
campaign-preflight check --campaign campaign.yaml --leads leads.csv --fail-on blockerКоды выхода несут вердикт, так что это напрямую встраивается в конвейер. См. docs/ci.md.
Что внутри
Корень репозитория и есть плагин. Нет второй копии дерева.
.claude-plugin/ plugin manifest and marketplace manifest
skills/ the three skills, one directory each
bin/ launchers the MCP server and CLI run through
src/ the Python package: rules, engine, providers, reporters
tests/ unit, integration, contract
docs/ rules catalogue, configuration, MCP, CI, limitations, architecture
examples/ three worked campaigns, one per verdict
scripts/ generators and the plugin packagerНавыки
Навык | Для чего использовать |
| Проверка реальной кампании, которую вы предоставляете — файл, вставленный текст или описание. |
| Наблюдение за работой проверщика на встроенных примерах данных. |
| Какие правила существуют, что каждое проверяет и как их перенастроить или отключить. |
Границы намеренны: каждое описание называет свою собственную ситуацию и указывает на соседнее, так что почти-попадание попадает в восстанавливаемое место.
Что он проверяет
76 правил в семи категориях. Полный каталог: docs/rules.md.
Категория | Правил | Примеры |
Кампания | 10 | Отключён stop-on-reply, дневной объём выше порога, нет окна отправки, даты, не оставляющие дней для отправки |
Контакты | 15 | Некорректные адреса, дубликаты (точные и с учётом регистра), ролевые ящики, значения-заглушки, управляющие и двунаправленные символы, инъекция формул в электронные таблицы |
Подавление | 8 | Контакты и домены в вашем списке подавления, существующие клиенты, внутренние адреса, конкуренты, ограниченные регионы — и могла ли проверка подавления вообще выполниться |
Персонализация | 13 | Необработанные merge-токены, приветствие, адресованное не тому человеку, компания, которая не их, утверждения, не подтверждённые их собственными доказательствами, устаревшие исследования, текст с prompt-инъекцией, соскобленный со страницы цели |
Текст | 13 | Пустая тема на первом шаге, битые ссылки, маркеры |
Расписание | 9 | Неверный часовой пояс, отправка в выходные, ноль активных дней, окно, которое заканчивается раньше, чем начинается, переходы на летнее время внутри кампании |
Отправители | 8 | Почтовые ящики ниже вашего порога здоровья, состояния ошибок, объём, превышающий ёмкость — и честные |
Спросите инструмент о любом из них:
campaign-preflight rules list --category suppression
campaign-preflight rules explain senders.aggregate_capacityЧто он намеренно не проверяет
Нет правила о спам-словах. «Бесплатно» и «действуйте сейчас» не являются доказательством чего-либо, и наличие такого списка приучило бы вас игнорировать инструмент. Правила, которые являются оценочными суждениями — длина текста, количество ссылок, артефакты генерации — помечены как heuristic, обозначены таковыми в каждом отчёте и по умолчанию никогда не являются блокирующими.
Конфигурация
Campaign Preflight работает с разумными настройками по умолчанию и без файла конфигурации. Добавьте его, когда ваши пороги отличаются, или чтобы включить проверки, зависящие от ваших собственных списков доменов и регионов.
version: 1
settings:
target_timezone: America/New_York
required_variables: [first_name, company_name]
internal_domains: [ourcompany.example.com]
customer_domains: [bigcustomer.example.com]
allow_weekend_sending: false
rules:
campaign.daily_volume:
warning_above: 100
blocker_above: 250
senders.health_below_threshold:
minimum_score: 80
contacts.missing_job_title:
enabled: falsecampaign-preflight validate-config preflight.yaml
campaign-preflight check --campaign c.yaml --leads l.csv --config preflight.yamlПроверка намеренно строгая: неизвестный идентификатор правила или неизвестная опция — это жёсткая ошибка, а не предупреждение. Опечатка, которая молча отключает проверку безопасности, хуже, чем отсутствие конфигурации вообще.
Полный справочник: docs/configuration.md.
Почему режим только для чтения важен
В Campaign Preflight нет пути кода, который записывает. Не «мы решили не делать» — вызывать нечего.
Провайдер Instantly направляет каждый запрос через транспорт, который проверяет
(method, path)по явному списку разрешений и вызывает исключение до того, как запрос покинет процесс. Проверка находится ниже клиента и ниже провайдера, поэтому будущее изменение кода, добавляющееPATCH, завершится с ошибкой, а не молча отредактирует вашу кампанию.Две проверки выполняются при импорте: список разрешений не может содержать
PUT,PATCH,DELETE,HEADилиOPTIONS, аPOSTразрешён ровно для одного пути (/leads/list, что является документированной формой Instantly для фильтрованного чтения).MCP-сервер отказывается запускаться, если у любого зарегистрированного инструмента есть изменяющий глагол в имени или он не объявляет себя доступным только для чтения.
tests/contract/test_instantly_transport.pyпроверяет полную матрицу метод × путь плюс каждую документированную изменяющую конечную точку. Сбой там — это инцидент безопасности, а не сбой теста.
Именно поэтому безопасно передавать агенту живую кампанию. Он получает анализ и никаких полномочий.
Что он никогда не будет делать
Активировать, приостановить, возобновить или запланировать кампанию
Создать, обновить, переместить, объединить или удалить лид
Добавить в список подавления или удалить из него
Отправить, ответить или переслать письмо
Изменить что-либо в вашей платформе отправки
Не существует пути кода ни к одному из этих действий, и два независимых предохранителя — транспортный белый список и проверка запуска MCP — закрываются по умолчанию, если такое действие когда-либо будет добавлено.
Коды выхода
Code | Meaning |
|
|
|
|
|
|
|
|
| Ошибка конфигурации или входных данных |
| Ошибка провайдера или аутентификации |
| Непредвиденная внутренняя ошибка |
--fail-on none|warning|high|blocker повышает порог, при котором вердикт приводит к ненулевому коду выхода. Он никогда не меняет сам вердикт. INCOMPLETE не подавляется порогом серьёзности — проверка, которая не смогла выполниться, это иная проблема, чем находка низкой серьёзности.
Оценка публикуется, а не скрывается
score = 100 - sum(weight[status][severity] for every FAIL and WARN)
readiness:
NOT_READY any BLOCKER FAIL, or any HIGH FAIL
INCOMPLETE else if any critical rule is UNKNOWN
READY_WITH_WARNINGS else if any FAIL or WARN
READY otherwiseИз этого следует четыре вещи, и для каждой есть тест:
Блокирующая проблема всегда даёт
NOT_READY. Число не может переопределить это.UNKNOWNничего не вычитает. Сбой провайдера не должен выглядеть как плохая кампания — он снижает уверенность.NOT_APPLICABLEни на что не влияет.Каждое вычитание детализировано.
--verboseвыводит арифметику, чтобы вы могли проверить её вручную.
Веса и список критических правил настраиваются: docs/configuration.md.
Архитектура
flowchart LR
CLI[CLI] --> Engine
MCP[MCP server] --> Engine
Engine -->|gather| Provider{Provider}
Provider --> CSV[CSV / files]
Provider --> Instantly[Instantly v2]
Instantly --> Guard[ReadOnlyTransport]
Guard -->|allowlist| API[(Instantly API)]
Provider -->|data + why| Context[Frozen context]
Context --> Rules[76 rules]
Rules --> Score[Scoring]
Score --> Out[Terminal / JSON / Markdown]
style Guard fill:#4a1f1f,stroke:#c04040,color:#fffКонтекст — это замороженная модель Pydantic, поэтому «правило никогда не изменяет свои входные данные» обеспечивается системой типов, а не ревью. Поведение, специфичное для провайдера, полностью скрыто за интерфейсом провайдера.
Полный дизайн и модель угроз: docs/architecture.md.
Конфиденциальность
Редактируется по умолчанию. Локальные части почтовых ящиков маскируются (
m**********s@stonebridge.example.com); домены сохраняются, потому что домен — это то, что делает находку о подавлении применимой.Секреты безусловно вычищаются.
--no-redactотключает маскирование PII, но никогда не маскирование учётных данных. Провайдер, который возвращает ваш API-ключ в теле ошибки, не сможет протащить его в отчёт — для этого есть тест.По умолчанию ничего не покидает вашу машину. Опциональный оценщик утверждений LLM выключен, пока вы его не настроите, а
validate-configпредупреждает вас, когда конфигурация его включает.Файлы отчётов записываются с правами
0600, во временный файл, а затем переименовываются.Выборки ограничены. Кампания на 100 000 лидов не может выдать 100 000 строк.
Производительность
Нагрузка | Время |
Демо (20 лидов) | 0.02 s |
10 000 лидов | 0.28 s |
100 000 лидов | 3.0 s, пик ~300 МБ |
Строки передаются потоком, а не загружаются целиком. Пагинация, повторы, конкурентность отправителя и размер вывода ограничены.
Разработка
git clone https://github.com/katekruger/campaignpreflightplugin
cd campaignpreflightplugin
uv sync --all-extras
uv run pytestuv run ruff format . # format
uv run ruff check . # lint
uv run mypy # typecheck, strict
claude plugin validate . --strict # manifests
uv run python scripts/generate_rules_doc.py --check # docs/rules.md is current
./scripts/bump-version.sh --check # version fields agree
uv run python scripts/build_plugin.py # dist/campaign-preflight.pluginСам пакет не имеет зависимостей времени выполнения; группа dev существует для тестового набора, линтеров и двух библиотек, используемых только как тестовые оракулы — httpx для опционального провайдера Instantly и PyYAML для дифференциального тестирования встроенного YAML-парсера.
Соглашения, которые выглядят как ошибки, пока не узнаешь причину, описаны в CLAUDE.md.
Дорожная карта
Дополнительные провайдеры за тем же интерфейсом только для чтения (Smartlead, HubSpot Sequences, Apollo)
Проверки репутации домена и DNS-записей (SPF, DKIM, DMARC alignment)
GitHub Action, оборачивающий CLI с аннотациями в PR
Сравнение с базовым уровнем: сравнение двух отчётов и показ изменений с прошлого запуска
Пороги для каждого сегмента, чтобы один конфиг мог покрывать несколько сценариев
Участие
Правила небольшие, чистые и независимо тестируемые — новое правило обычно представляет собой класс, docstring и несколько тестов. См. CONTRIBUTING.md и CODE_OF_CONDUCT.md.
Безопасность
Сообщайте об уязвимостях конфиденциально: SECURITY.md. Правило, которое вернуло PASS при отсутствии данных, считается проблемой безопасности.
Лицензия
MIT. См. LICENSE.
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
- AlicenseBqualityFmaintenanceA Model Context Protocol server that provides read-only access to Mailchimp's Marketing API for comprehensive email marketing data retrieval.3822811MIT
- FlicenseNot gradedqualityDmaintenanceA utility MCP server providing 10 specialized tools for newsletter content preparation and optimization, including subject line generation, HTML-to-text extraction, read time estimation, and email validation. Enables newsletter operators, developers, and content teams to automate pre-send workflows and audit newsletter issues through natural language interactions.
- AlicenseBqualityAmaintenanceLocal-first production-readiness MCP server for AI-built apps. It runs read-only checks, produces an evidence-based readiness score, and guides fixes before launch.95Apache 2.0
- FlicenseNot gradedqualityAmaintenanceRead-only MCP server that performs deterministic local preflights of agent-payment boundary documents and x402 v2 PaymentRequired JSON, and prepares unsubmitted public quote-request drafts without network calls or fund movement.
Related MCP Connectors
Render markdown into email-safe HTML, lint drafts for deliverability problems, and preview emails.
Read-only MVR preflight for trust, permission, evidence gaps, and African market-entry readiness.
Send transactional email, run campaigns, manage contacts and automations, audit deliverability.
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/katekruger/campaignpreflightplugin'
If you have feedback or need assistance with the MCP directory API, please join our Discord server