Skip to main content
Glama
katekruger

campaign-preflight-mcp

by katekruger

キャンペーンプリフライト

Campaign Preflight は、アウトバウンドキャンペーン向けの読み取り専用リンターです。設定、連絡先データ、パーソナライゼーション、抑制、スケジュール、送信者に関する問題を、配信前に検出します。

CI Security Python 3.9+ Dependencies: none License: MIT


機能概要

どのアウトバウンドチームも、ミスを含んだキャンペーンを配信した経験があります。解約したはずの人にメールが届いた。見込み客が返信したのに、シーケンスがフォローアップを続けた。マージフィールドがマージされず、200人に「こんにちは {{first_name}}」と送られた。

それが送信後に判明するのです。

Campaign Preflight は、キャンペーンの設定、リード、コピー、スケジュール、送信者、抑制の露出に対して76の決定的チェックを実行し、各指摘に証拠を添えた準備完了判定を返します。プロバイダーへの書き込みは一切行わず、何かを有効化することもできません。

やらないことを、後回しにせず最初に明記します:

  • 配信到達性を保証しません。 設定とデータをチェックするのであって、受信トレイへの到達状況をチェックするのではありません。配信スコアをでっち上げることもありません。

  • 法的アドバイスを提供しません。 地域、ドメイン、オプトアウトのチェックは、キャンペーンをお客様自身が設定したポリシーと比較するものであり、GDPR、CAN-SPAM、CASL ではありません。

  • メールボックスを検証しません。 アドレスチェックは構文のみです。DNS も SMTP もありません。

  • プロバイダーの保護機能を置き換えません。 それらは有効にしておいてください。

  • 結果は特定時点のスナップショットです。 09:00 に合格したキャンペーンも、09:05 に編集されれば変わります。

詳細は docs/limitations.md にあります。


Related MCP server: Newsletter Tools

「チェック済みで問題なし」≠「チェックできなかった」

この2つを区別できないチェッカーは、チェッカーがないより悪いものです。権限エラーを緑信号に変えてしまうからです。

Campaign Preflight は、この区別を構造的に行います。すべてのプロバイダー読み取りは、データと、それが存在するかしないかの理由を返し、すべてのルールは必要なデータを宣言します。そのデータが利用できない場合、エンジンはルールを実行する前に UNKNOWN に短絡させます。ルールはこれを回避できません。

状況

結果

抑制リストを読み取り、一致なし

PASS

抑制リストが提供されていない

UNKNOWN → 実行は INCOMPLETE

抑制エンドポイントが 403 を返した

UNKNOWN → 実行は INCOMPLETE

キャンペーン内のリードがゼロ

FAIL

リードエンドポイントに到達できない

UNKNOWN

判定は2つではなく4つあります:READYREADY_WITH_WARNINGSNOT_READYINCOMPLETE


要件

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

読み取り専用ツールが6つ。アクティブ化、編集、インポート、送信ができるものはありません。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.

最後の指摘に注目してください。1つの送信者が1日の上限を報告していないため、合計容量を合計できません。ほとんどのツールは、報告している送信者を合計して数値と呼ぶでしょう。これは「不明」と述べ、そのために信頼度を HIGH から MEDIUM に下げます。

その区別が全体のアイデアです。

自分のキャンペーンをチェックする

プラグインがインストールされたら、平易な言葉で説明します:

送信する前にこのキャンペーンをチェックして。

これが私のリードリストです — 何か問題ありますか? (貼り付けまたはアップロード)

200人に3通のメールシーケンスを送ります。1日80通、平日の9時から17時(東部時間)です。大丈夫ですか?

3つの入力方法があり、どれもアカウントは不要です:

あなたが持っているもの

何が起こるか

ファイル(アップロード、またはディスク上)

直接チェックされます。

貼り付けたリストまたはコピー

スクラッチファイルに書き込まれ、チェックされ、その後クリーンアップされます。

説明のみ

キャンペーンファイルはあなたの言葉から構築され、表示され、その後チェックされます。

わからないことは空白のままにされ、推測されません — 空白のフィールドは「チェックできませんでした」として返され、それが正直な答えです。

ファイルから、コマンドラインで

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

3つの実例がリポジトリに同梱されており、各判定に1つずつあります:

判定

終了コード

examples/clean_campaign

READY、100/100

0

examples/risky_campaign

NOT_READY、13件のブロッカー

2

examples/incomplete_campaign

INCOMPLETE — 問題はないが、検証できないだけ

3

CI で

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

終了コードが判定を伝えるため、これはそのままパイプラインに組み込めます。docs/ci.md を参照してください。


内部構造

リポジトリのルートプラグインです。ツリーの2番目のコピーはありません。

.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

スキル

スキル

使用目的

preflight-campaign

提供された実際のキャンペーン(ファイル、貼り付け、説明)をチェックする。

preflight-demo

バンドルされたサンプルデータに対してチェッカーが実行されるのを見る。

preflight-rules

どのルールが存在するか、各ルールが何をテストするか、再調整または無効化する方法。

境界は意図的です:各説明は自身の状況を指定し、隣接するスキルを指すため、ニアミスは回復可能な場所に着地します。


チェック内容

7カテゴリにわたる76のルール。完全なカタログ:docs/rules.md

カテゴリ

ルール数

キャンペーン

10

返信で停止が無効、1日のボリュームがしきい値を超える、送信ウィンドウなし、送信日が残らない日付

連絡先

15

不正なアドレス、重複(完全一致と大文字小文字を無視)、ロール用インボックス、プレースホルダー値、制御文字と双方向文字、スプレッドシートの数式インジェクション

抑制

8

抑制リスト上の連絡先とドメイン、既存顧客、内部アドレス、競合他社、制限地域 — そして抑制チェックがそもそも実行できたかどうか

パーソナライゼーション

13

未レンダリングのマージトークン、間違った人宛ての挨拶、彼らの会社ではない会社、彼ら自身の証拠で裏付けられていない主張、古いリサーチ、ターゲットのページからスクレイピングされたプロンプトインジェクションのテキスト

コピー

13

最初のステップの件名が空、壊れたリンク、TODO マーカー、オプトアウト文言の欠落、最初のメールと同一のフォローアップ

スケジュール

9

無効なタイムゾーン、週末送信、アクティブ日数ゼロ、開始前に終了するウィンドウ、キャンペーン内の DST 移行

送信者

8

健全性しきい値を下回るメールボックス、エラー状態、容量を超えるボリューム — そしてプロバイダーが言わない場合の正直な UNKNOWN

これらのいずれかについてツールに尋ねてください:

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

検証は意図的に厳格です:未知のルール ID や未知のオプションは警告ではなくハードエラーです。安全チェックを静かに無効化するタイプミスは、設定がないことより悪いです。

完全なリファレンス:docs/configuration.md


読み取り専用が重要な理由

Campaign Preflight には、書き込むコードパスがありません。「選択しなかった」のではなく — 呼び出すものがないのです。

  • Instantly プロバイダーは、すべてのリクエストを明示的な許可リストに対して (method, path) をチェックするトランスポート経由でルーティングし、リクエストがプロセスを離れる前に例外を発生させます。チェックはクライアントとプロバイダーの下にあり、将来 PATCH を追加するコード変更は、キャンペーンを静かに編集する代わりに大きな音を立てて失敗します。

  • インポート時に2つのガードが実行されます:許可リストは PUTPATCHDELETEHEADOPTIONS を含むことができず、POST は正確に1つのパス(/leads/list、これは Instantly の文書化されたフィルタリング読み取りの形状)にのみ許可されます。

  • MCP サーバーは、登録されたツールに変更動詞が名前に含まれているか、読み取り専用を宣言していない場合、起動を拒否します

  • tests/contract/test_instantly_transport.py は、完全なメソッド × パスマトリックスと、文書化されたすべての変更エンドポイントをテストします。そこでの失敗はテスト失敗ではなく、セキュリティインシデントです。

これにより、エージェントにライブキャンペーンを渡しても安全です。分析は得られますが、権限は一切ありません。

決して行わないこと

  • キャンペーンのアクティブ化、一時停止、再開、スケジュール設定

  • リードの作成、更新、移動、結合、削除

  • 抑制リストへの追加、または抑制リストからの削除

  • メールの送信、返信、転送

  • 送信プラットフォーム内のあらゆる変更

これらへのコードパスは存在せず、トランスポート許可リストとMCP起動時アサーションという2つの独立したガードが、万一追加された場合にはフェイルクローズします。


終了コード

コード

意味

0

READY

1

READY_WITH_WARNINGS

2

NOT_READY

3

INCOMPLETE — 重要なチェックを実行できなかった

4

設定または入力エラー

5

プロバイダーまたは認証エラー

6

予期しない内部エラー

--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

これから4つのことが導かれ、それぞれにテストがあります。

  1. ブロッカーは常に NOT_READY を生成します。 数値がそれを上書きすることはできません。

  2. UNKNOWN は減点しません。 プロバイダーの障害が悪いキャンペーンのように見えてはなりません — 代わりに信頼度を下げます。

  3. NOT_APPLICABLE は何にも影響しません。

  4. すべての減点は明細化されています。 --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 MB ピーク

行はストリーミングされ、一括読み込みはされません。ページネーション、リトライ、送信者の並行性、出力サイズはすべて制限されています。


開発

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

パッケージ自体には実行時依存関係はありません。devグループはテストスイート、リンター、およびテストオラクルとしてのみ使用される2つのライブラリ — オプションのInstantlyプロバイダー用の httpx と、バンドルされたYAMLパーサーを差分テストするための PyYAML — のために存在します。

理由を知るまで間違いに見える規約は、CLAUDE.md に文書化されています。


ロードマップ

  • 同じ読み取り専用インターフェースの背後にある追加プロバイダー (Smartlead、HubSpot Sequences、Apollo)

  • ドメインレピュテーションとDNSレコードチェック (SPF、DKIM、DMARCアライメント)

  • PRアノテーション付きでCLIをラップするGitHub Action

  • ベースライン比較: 2つのレポートを差分し、前回の実行以降の変更点を表示

  • セグメントごとのしきい値。1つの設定で複数のモーションをカバー可能


コントリビューション

ルールは小さく、純粋で、独立してテスト可能です — 新しいルールは通常、クラス、docstring、そしていくつかのテストで構成されます。CONTRIBUTING.mdCODE_OF_CONDUCT.md を参照してください。

セキュリティ

脆弱性は非公開で報告してください: SECURITY.md。データが欠落しているときに PASS を返したルールは、セキュリティ問題として扱われます。

ライセンス

MIT。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