Skip to main content
Glama
katekruger

campaign-preflight-mcp

by katekruger

Kampagnen-Preflight

Campaign Preflight ist ein schreibgeschützter Linter für ausgehende Kampagnen. Er erkennt Konfigurations-, Kontaktdaten-, Personalisierungs-, Unterdrückungs-, Zeitplan- und Absenderprobleme vor dem Start.

CI Security Python 3.9+ Dependencies: none License: MIT


Was er tut

Jedes Outbound-Team hat schon eine Kampagne mit einem Fehler verschickt. Jemand, der sich abgemeldet hat, wurde trotzdem angemailt. Eine Sequenz hat weiter nachgefasst, nachdem der Interessent geantwortet hat. Ein Merge-Feld wurde nie zusammengeführt und zweihundert Leute bekamen „Hi {{first_name}}."

Man erfährt es erst, nachdem es raus ist.

Campaign Preflight führt 76 deterministische Prüfungen über die Konfiguration, Leads, Texte, Zeitplan, Absender und Unterdrückungs-Exposition einer Kampagne durch und liefert eine Bereitschaftsentscheidung mit Belegen für jeden Befund. Er schreibt nie in deinen Anbieter und kann nichts aktivieren.

Was er nicht tut, gleich vorweg statt versteckt:

  • Er garantiert keine Zustellbarkeit. Er prüft Konfiguration und Daten, nicht die Inbox-Platzierung, und erfindet nie einen Zustellbarkeits-Score.

  • Er gibt keine Rechtsberatung. Regions-, Domain- und Opt-out-Prüfungen vergleichen eine Kampagne mit deiner eigenen konfigurierten Richtlinie – nicht mit GDPR, CAN-SPAM oder CASL.

  • Er verifiziert keine Postfächer. Adressprüfungen sind reine Syntaxprüfungen. Kein DNS, kein SMTP.

  • Er ersetzt nicht die Schutzmechanismen deines Anbieters. Lass die eingeschaltet.

  • Ergebnisse sind eine Momentaufnahme. Eine Kampagne, die um 09:00 bestanden hat, kann um 09:05 bearbeitet werden.

Weitere Details in docs/limitations.md.


Related MCP server: Newsletter Tools

„Wir haben geprüft und es ist in Ordnung" ≠ „wir konnten nicht prüfen"

Ein Prüfer, der diese beiden nicht unterscheiden kann, ist schlimmer als gar kein Prüfer, weil er einen Berechtigungsfehler in ein grünes Licht verwandelt.

Campaign Preflight macht diese Unterscheidung strukturell. Jeder Anbieter-Read liefert Daten plus den Grund, warum sie existieren oder nicht, und jede Regel deklariert die Daten, die sie benötigt. Wenn diese Daten nicht verfügbar sind, unterbricht die Engine die Regel zu UNKNOWN, bevor sie laufen kann. Regeln können sich nicht abmelden.

Situation

Ergebnis

Unterdrückungsliste gelesen, niemand übereinstimmend

PASS

Keine Unterdrückungsliste angegeben

UNKNOWN → Lauf ist INCOMPLETE

Unterdrückungs-Endpoint gab 403 zurück

UNKNOWN → Lauf ist INCOMPLETE

Null Leads in der Kampagne

FAIL

Lead-Endpoint nicht erreichbar

UNKNOWN

Es gibt vier Urteile, nicht zwei: READY, READY_WITH_WARNINGS, NOT_READY und INCOMPLETE.


Anforderungen

Python 3.9 oder neuer. Das ist die ganze Liste.

Das Paket hat keine Laufzeitabhängigkeiten – es importiert nichts außerhalb der Standardbibliothek. httpx ist ein optionales Extra, das nur für den Live-Instantly-Anbieter benötigt wird, hinter einem Lazy Import.

Die 3.9-Untergrenze ist bewusst gewählt und bewusst niedriger, als man erwarten könnte. Es ist der älteste Interpreter, den das Plugin auf dem Rechner eines Benutzers antreffen kann, und da es keine Abhängigkeiten gibt, zwingt nichts zu einer höheren Version. CI läuft mit 3.9 bis 3.13 plus einem Bare-Interpreter-Job, der gar nichts installiert, auf Linux, macOS und Windows.

Diese Kombination ermöglicht es dem Plugin, ohne Installationsschritt zu laufen: Es verwendet das bereits vorhandene python3.


Installation

Als Claude-Plugin (Marketplace)

/plugin marketplace add katekruger/campaignpreflightplugin
/plugin install campaign-preflight

Das Repository ist sein eigener Marketplace: .claude-plugin/marketplace.json liegt im Root neben dem Plugin-Manifest.

Als Claude-Plugin (lokaler Checkout)

git clone https://github.com/katekruger/campaignpreflightplugin
/plugin marketplace add ./campaignpreflightplugin
/plugin install campaign-preflight

Als CLI

pipx install campaign-preflight

Oder direkt aus einem Checkout, ohne dass etwas installiert ist:

PYTHONPATH=src python3 -m campaign_preflight.cli demo

Als MCP-Server

claude mcp add campaign-preflight -- campaign-preflight-mcp

Sechs schreibgeschützte Tools. Nichts, das aktivieren, bearbeiten, importieren oder senden könnte. Einrichtung für Claude Code und Claude Desktop: docs/mcp.md.


Schnellstart

campaign-preflight demo

Kein API-Schlüssel. Kein Netzwerk. Keine Konfiguration.

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.

Beachte den letzten Befund. Ein Absender meldet kein Tageslimit, daher kann die Gesamtkapazität nicht summiert werden. Die meisten Tools würden die Absender, die eines melden, zusammenzählen und es eine Zahl nennen. Dieses sagt, dass es es nicht weiß – und senkt das Vertrauen von HIGH auf MEDIUM, genau deshalb.

Diese Unterscheidung ist die ganze Idee.

Eigene Kampagne prüfen

Sobald das Plugin installiert ist, beschreibe es in einfacher Sprache:

Prüfe diese Kampagne, bevor ich sie sende.

Hier ist meine Lead-Liste – ist etwas daran falsch? (einfügen oder hochladen)

Ich sende eine 3-E-Mail-Sequenz an 200 Personen, 80 pro Tag, werktags 9-17 Uhr Eastern. Ist das in Ordnung?

Es gibt drei Wege hinein, und keiner benötigt ein Konto:

Du hast

Was passiert

Eine Datei (hochgeladen oder auf der Festplatte)

Wird direkt geprüft.

Eine eingefügte Liste oder etwas Text

Wird in eine temporäre Datei geschrieben, geprüft und dann aufgeräumt.

Nur eine Beschreibung

Die Kampagnendatei wird aus dem erstellt, was du sagst, dir gezeigt und dann geprüft.

Alles, was du nicht weißt, bleibt leer, statt geraten zu werden – ein leeres Feld kommt als „konnte nicht geprüft werden" zurück, was die ehrliche Antwort ist.

Aus Dateien, auf der Kommandozeile

campaign-preflight check \
  --campaign examples/clean_campaign/campaign.yaml \
  --leads examples/clean_campaign/leads.csv \
  --suppressions examples/clean_campaign/suppressions.csv

Drei ausgearbeitete Beispiele sind im Repo enthalten, eines pro Urteil:

Beispiel

Urteil

Exit

examples/clean_campaign

READY, 100/100

0

examples/risky_campaign

NOT_READY, 13 Blocker

2

examples/incomplete_campaign

INCOMPLETE – nichts ist falsch, es kann nur nicht verifiziert werden

3

In CI

campaign-preflight check --campaign campaign.yaml --leads leads.csv --fail-on blocker

Exit-Codes tragen das Urteil, also passt das direkt in eine Pipeline. Siehe docs/ci.md.


Was drin ist

Das Repository-Root ist das Plugin. Es gibt keine zweite Kopie des Baums.

.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

Skills

Skill

Verwende es für

preflight-campaign

Prüfen einer echten Kampagne, die du lieferst – eine Datei, ein Einfügen oder eine Beschreibung.

preflight-demo

Den Prüfer gegen gebündelte Beispieldaten laufen sehen.

preflight-rules

Welche Regeln existieren, was jede testet und wie man sie neu einstellt oder deaktiviert.

Die Grenzen sind bewusst: Jede Beschreibung nennt ihre eigene Situation und verweist auf den Nachbarn, sodass ein Beinahe-Treffer an einem erholsamen Ort landet.


Was er prüft

76 Regeln in sieben Kategorien. Vollständiger Katalog: docs/rules.md.

Kategorie

Regeln

Beispiele

Kampagne

10

Stop-on-reply deaktiviert, Tagesvolumen über Schwelle, kein Sendezeitfenster, Daten, die keine Sendetage übrig lassen

Kontakte

15

Fehlerhafte Adressen, Duplikate (exakt und case-folded), Rollen-Postfächer, Platzhalterwerte, Steuer- und Bidi-Zeichen, Tabellenkalkulations-Formel-Injektion

Unterdrückung

8

Kontakte und Domains auf deiner Unterdrückungsliste, bestehende Kunden, interne Adressen, Wettbewerber, eingeschränkte Regionen – und ob die Unterdrückungsprüfung überhaupt laufen konnte

Personalisierung

13

Nicht gerenderte Merge-Tokens, eine Begrüßung an die falsche Person, ein Unternehmen, das nicht ihres ist, Behauptungen, die nicht durch ihre eigenen Beweise gestützt werden, veraltete Recherche, Prompt-Injection-Text, der von der Seite eines Ziels gescrapt wurde

Text

13

Leerer Betreff im ersten Schritt, kaputte Links, TODO-Marker, fehlende Opt-out-Sprache, ein Follow-up, das identisch mit der ersten E-Mail ist

Zeitplan

9

Ungültige Zeitzone, Senden am Wochenende, null aktive Tage, ein Fenster, das endet, bevor es beginnt, DST-Übergänge innerhalb der Kampagne

Absender

8

Postfächer unter deiner Gesundheits-Schwelle, Fehlerzustände, Volumen über Kapazität – und ehrliche UNKNOWNs, wenn der Anbieter es nicht sagt

Frage das Tool nach jedem davon:

campaign-preflight rules list --category suppression
campaign-preflight rules explain senders.aggregate_capacity

Was er bewusst nicht prüft

Es gibt keine Spam-Wort-Regel. „Kostenlos" und „Jetzt handeln" sind kein Beweis für irgendetwas, und diese Liste zu liefern würde dich trainieren, das Tool zu ignorieren. Regeln, die Ermessenssache sind – Textlänge, Linkanzahl, Generierungsartefakte – sind als heuristic markiert, in jedem Bericht als solche gekennzeichnet und standardmäßig nie Blocker.


Konfiguration

Campaign Preflight läuft mit sinnvollen Standardeinstellungen und ohne Konfigurationsdatei. Füge eine hinzu, wenn deine Schwellenwerte abweichen, oder um die Prüfungen zu aktivieren, die von deinen eigenen Domain- und Regionslisten abhängen.

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: false
campaign-preflight validate-config preflight.yaml
campaign-preflight check --campaign c.yaml --leads l.csv --config preflight.yaml

Die Validierung ist absichtlich streng: Eine unbekannte Regel-ID oder eine unbekannte Option ist ein harter Fehler, keine Warnung. Ein Tippfehler, der eine Sicherheitsprüfung stillschweigend deaktiviert, ist schlimmer als gar keine Konfiguration.

Vollständige Referenz: docs/configuration.md.


Warum Schreibschutz wichtig ist

Campaign Preflight hat keinen Codepfad, der schreibt. Nicht „wir haben uns dagegen entschieden" – es gibt nichts aufzurufen.

  • Der Instantly-Anbieter leitet jede Anfrage durch einen Transport, der (method, path) gegen eine explizite Allowlist prüft und bevor die Anfrage den Prozess verlässt, eine Ausnahme auslöst. Die Prüfung sitzt unterhalb des Clients und unterhalb des Anbieters, sodass eine zukünftige Codeänderung, die ein PATCH hinzufügt, laut scheitert, statt deine Kampagne still zu bearbeiten.

  • Zwei Wächter laufen beim Import: Die Allowlist darf kein PUT, PATCH, DELETE, HEAD oder OPTIONS enthalten, und POST ist nur für genau einen Pfad erlaubt (/leads/list, was Instantlys dokumentierte Form für einen gefilterten Read ist).

  • Der MCP-Server weigert sich zu starten, wenn ein registriertes Tool ein mutierendes Verb im Namen hat oder sich nicht als schreibgeschützt deklariert.

  • tests/contract/test_instantly_transport.py übt die vollständige Methoden × Pfad-Matrix plus jeden dokumentierten mutierenden Endpoint. Ein Fehler dort ist ein Sicherheitsvorfall, kein Testfehler.

Das macht es sicher, einem Agenten eine Live-Kampagne zu geben. Er bekommt die Analyse und keine der Befugnisse.

Was er niemals tun wird

  • Kampagne aktivieren, pausieren, fortsetzen oder planen

  • Lead erstellen, aktualisieren, verschieben, zusammenführen oder löschen

  • Zur Unterdrückungsliste hinzufügen oder daraus entfernen

  • E-Mail senden, beantworten oder weiterleiten

  • Etwas in Ihrer Versandplattform ändern

Es gibt keinen Codepfad zu einer dieser Funktionen, und zwei unabhängige Schutzmechanismen – die Transport-Allowlist und die MCP-Startup-Assertion – schließen im Fehlerfall, falls jemals eine hinzugefügt wird.


Exit-Codes

Code

Bedeutung

0

READY

1

READY_WITH_WARNINGS

2

NOT_READY

3

INCOMPLETE – eine kritische Prüfung konnte nicht ausgeführt werden

4

Konfigurations- oder Eingabefehler

5

Provider- oder Authentifizierungsfehler

6

Unerwarteter interner Fehler

--fail-on none|warning|high|blocker erhöht die Schwelle, ab der ein Urteil zu einem Exit-Code ungleich Null führt. Es ändert das Urteil selbst nie. INCOMPLETE wird durch eine Schweregrad-Schwelle nicht unterdrückt – eine Prüfung, die nicht ausgeführt werden konnte, ist ein anderes Problem als ein Befund mit geringem Schweregrad.


Scoring ist veröffentlicht, nicht versteckt

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

Daraus ergeben sich vier Dinge, und jedes hat einen Test:

  1. Ein Blocker erzeugt immer NOT_READY. Die Zahl kann das nicht außer Kraft setzen.

  2. UNKNOWN zieht nichts ab. Ein Provider-Ausfall darf nicht wie eine schlechte Kampagne aussehen – er senkt stattdessen die Konfidenz.

  3. NOT_APPLICABLE hat keine Auswirkungen.

  4. Jeder Abzug wird einzeln aufgeführt. --verbose gibt die Rechnung aus, damit Sie sie von Hand überprüfen können.

Gewichte und die Liste der kritischen Regeln sind konfigurierbar: docs/configuration.md.


Architektur

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

Der Kontext ist ein eingefrorenes Pydantic-Modell, sodass „eine Regel mutiert ihre Eingabe nie“ durch das Typsystem erzwungen wird und nicht durch Review. Providerspezifisches Verhalten lebt vollständig hinter der Provider-Schnittstelle.

Vollständiges Design und Bedrohungsmodell: docs/architecture.md.


Datenschutz

  • Standardmäßig redigiert. Lokale Teile von Postfächern werden maskiert (m**********s@stonebridge.example.com); Domains bleiben erhalten, denn eine Domain ist es, die einen Unterdrückungsbefund umsetzbar macht.

  • Geheimnisse werden bedingungslos entfernt. --no-redact deaktiviert die Maskierung personenbezogener Daten, niemals die Maskierung von Anmeldedaten. Ein Provider, der Ihren API-Schlüssel in einem Fehlertext zurückspiegelt, kann ihn nicht in einen Bericht bringen – dafür gibt es genau einen Test.

  • Standardmäßig verlässt nichts Ihren Rechner. Der optionale LLM-Anspruchsbewerter ist aus, sofern Sie ihn nicht konfigurieren, und validate-config warnt Sie, wenn eine Konfiguration ihn aktiviert.

  • Berichtsdateien werden mit 0600 geschrieben, in eine temporäre Datei und dann umbenannt.

  • Stichproben sind begrenzt. Eine Kampagne mit 100.000 Leads kann keine 100.000 Zeilen ausgeben.


Leistung

Arbeitslast

Zeit

Demo (20 Leads)

0.02 s

10.000 Leads

0.28 s

100.000 Leads

3.0 s, ~300 MB Spitze

Zeilen werden gestreamt, nicht geschluckt. Paginierung, Wiederholungen, Sender-Parallelität und Ausgabegröße sind alle begrenzt.


Entwicklung

git clone https://github.com/katekruger/campaignpreflightplugin
cd campaignpreflightplugin
uv sync --all-extras
uv run pytest
uv 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

Das Paket selbst hat keine Laufzeitabhängigkeiten; die Dev-Gruppe existiert für die Testsuite, die Linter und zwei Bibliotheken, die nur als Test-Orakel verwendet werden – httpx für den optionalen Instantly-Provider und PyYAML, um den gebündelten YAML-Parser differentiell zu testen.

Konventionen, die wie Fehler aussehen, bis man den Grund kennt, sind in CLAUDE.md festgehalten.


Roadmap

  • Zusätzliche Provider hinter derselben Nur-Lese-Schnittstelle (Smartlead, HubSpot Sequences, Apollo)

  • Domain-Reputations- und DNS-Eintragsprüfungen (SPF, DKIM, DMARC-Ausrichtung)

  • Eine GitHub Action, die die CLI mit PR-Anmerkungen umschließt

  • Basislinienvergleich: Zwei Berichte diffen und zeigen, was sich seit dem letzten Lauf geändert hat

  • Schwellenwerte pro Segment, sodass eine Konfiguration mehrere Bewegungen abdecken kann


Mitwirken

Regeln sind klein, rein und unabhängig testbar – eine neue Regel ist normalerweise eine Klasse, ein Docstring und eine Handvoll Tests. Siehe CONTRIBUTING.md und CODE_OF_CONDUCT.md.

Sicherheit

Melden Sie Schwachstellen privat: SECURITY.md. Eine Regel, die PASS zurückgab, wenn die Daten fehlten, gilt als Sicherheitsproblem.

Lizenz

MIT. Siehe LICENSE.

Install Server
A
license - permissive license
A
quality
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
    B
    quality
    F
    maintenance
    A Model Context Protocol server that provides read-only access to Mailchimp's Marketing API for comprehensive email marketing data retrieval.
    38
    228
    11
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A 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.
  • F
    license
    Not graded
    quality
    A
    maintenance
    Read-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.

View all related MCP servers

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.

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/katekruger/campaignpreflightplugin'

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