build-mule-integration について
build-mule-integrationは、データフロー、API、イベント駆動プロセスを構築する開発者向けの、Mule統合の作成・変更スキルです。Exchangeでコネクターを調査し、新規プロジェクト生成前に承認を得て、ビルドで変更を検証します。
主な機能
- 01Mule・CLI・Java環境の検証
- 02Exchangeコネクターの検索と説明
- 03設計後にユーザー承認を取得
- 04MuleプロジェクトとフローXMLの生成
- 05Mavenビルドによる変更検証
活用シーン
- 01SalesforceとSlack間のデータ同期
- 02定期ポーリングやイベント駆動フローの作成
- 03既存Muleプロジェクトのコネクターやフローの変更
- 04REST APIやWebhookの統合構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mulesoft/ mulesoft-dx --skill build-mule-integrationインストール後、Claude Code で/build-mule-integrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
lib/anypoint.mjsexchange-rank.mjsfsx.mjsnearest.mjsplatform.mjspom.mjstemplate-rank.mjsreferences/connector-catalog.mdjdbc-drivers.mdtemplate-project-creation.mdscripts/.gitattributesbuild_deps.mjsbuild_gav.mjscommit_connectors.mjsdescribe_connector.mjsget_latest_connector.mjsmaybe_add_http_connector.mjspick_connector.mjssearch_templates.mjsvalidate_before_build.mjsvalidate_prerequisites.mjswrite_mule_artifact_env.mjs詳細
Mule Developer
インテリジェントなコネクタ検出とデータ駆動型の XML 生成を活用して、プロフェッショナルな Mule インテグレーションを構築します。
このスキルを使用する場面
ユーザーから次のような依頼があった場合に、このスキルを使用してください:
- 「Mule アプリ/インテグレーション/フローを作成して」
- 「X と Y の間のインテグレーションを構築して」
- 「X から Y にデータを同期して」(例:「Salesforce から Slack」「MySQL から Salesforce」)
- 「Salesforce にクエリして」「Slack 通知を送信して」
- 「ジョブをスケジュールして」「N 分ごとにデータをポーリングして」
- 「Webhook を作成して」「イベント駆動型フローを構築して」
トリガーキーワード: create、build、integrate、sync、connect · mule、integration、flow、app、project · salesforce、slack、servicenow、jira、netsuite · mysql、postgresql、database · api、http endpoint、rest api · schedule、poll、every N minutes · alert、notify、webhook。
まず Exchange を検索して、システム固有のコネクタを探してください。ほとんどの SaaS アプリケーションには専用のコネクタがあります。
前提条件
anypoint-cli-v4 --version
anypoint-cli-v4 dx --help
echo $JAVA_HOME && java -version # Java 11+
anypoint-cli-v4 conf
ツールが不足している場合:
npm install -g @mulesoft/anypoint-cli-v4
npm install -g @salesforce/anypoint-cli-dx-mule-plugin
anypoint-cli-v4 conf username <username>
anypoint-cli-v4 conf password <password>
同梱スクリプト
このスキルには、scripts/ 配下に小さな Node スクリプト(*.mjs、ESM、npm 依存関係なし)が含まれています。Bash ツールで node scripts/<name>.mjs ... を実行して呼び出してください。内容を回答に直接記述しないでください。スクリプトは出力をディスクに保存するため、後続の手順で機械的に利用できます。また、Bash ツールの呼び出しが返ると消えてしまうシェル変数に依存しません。
| スクリプト | 目的 | 出力先 |
|---|---|---|
scripts/validate_prerequisites.mjs | ステップ 1 — ツールチェーン(CLI、DX プラグイン、Java 11 以降、JAVA_HOME、Mule ランタイムの有無)を検証します。検証のみ | tmp/mule-dev-env.json(ワークスペース相対パス。mule_version、runtime_path、errors[] などを含みます) |
scripts/get_latest_connector.mjs <search> [nickname] | ステップ 3 — Exchange を検索し、順位付けしたコネクター候補を出力します(groupId:assetId:version、1 行につき 1 件、スコアや推奨候補の表示なし)。何も書き込みません。 | 標準出力のみ |
scripts/pick_connector.mjs <nickname> <gav> | ステップ 3 — 推論または AskUserQuestion の後、エージェントが選択した GAV をドラフトとして記録します | tmp/connector-choices/<nickname>.json({groupId, assetId, version}) |
scripts/commit_connectors.mjs | ステップ 8(TDD 承認後)— tmp/connector-choices/ 配下のすべてのドラフトを、Phase 2 が読み取る固定済みの tmp/connector-versions/ ディレクトリに移します | tmp/connector-versions/*.json |
scripts/build_gav.mjs <json> | 保存されたコネクター JSON を groupId:assetId:version 形式の文字列に変換します | 標準出力 |
scripts/build_deps.mjs [versions-dir] | ステップ 8 — tmp/connector-versions/ 内のすべてのコネクター固定情報を読み込み、dx mule project create --dependencies にそのまま使える、カンマ区切りの GAV 文字列を出力します。db-driver.json と、固定情報ではないファイルは除外します。 | 標準出力 |
scripts/write_mule_artifact_env.mjs <project-dir> [env-json] | ステップ 8(dx mule project create の直後)— 検証済みの mule_version と java_version を tmp/mule-dev-env.json からプロジェクトの mule-artifact.json(minMuleVersion と javaSpecificationVersions)に書き込み、ほかのキーは保持します。冪等です。 | <project-dir>/mule-artifact.json |
scripts/describe_connector.mjs <nickname> [--type operation|source --name <name>] | ステップ 4(フラグなし)/ステップ 13(フラグあり)— 下書きの GAV に対して dx mule describe-connector を実行し、完全な JSON を保存してダイジェストを標準出力に表示し、さらに .errorTypes をステップ 16 のバリデーター用に tmp/connector-errors/ にキャッシュします | tmp/connector-metadata/<nick>[-<name>].json + tmp/connector-errors/<nick>[.<name>].json + 標準出力にダイジェスト |
scripts/validate_before_build.mjs <project-dir> | ステップ 16 の Maven 実行前 — エラータイプの許可リスト(クラスター D)、名前空間と依存関係の整合性(クラスター A2–A5)、正規の XSD URL 形式 | 標準エラー出力 + 最初の違反時にゼロ以外の終了コード |
scripts/maybe_add_http_connector.mjs --project <dir> <providers...> | Phase 2 — OAuth プロバイダーが選択されている場合に HTTP コネクターが存在するかを防御的に確認します。<dir>/pom.xml を編集します | <dir>/pom.xml |
scripts/search_templates.mjs <search-term> | ステップ 1b(テンプレートパス)— 並列呼び出し(スコープなし+組織スコープ)で、Anypoint Exchange にある type == "template" のアセットを検索し、重複を除去してトークンの重なり順に並べ、上位 10 件に description、minMuleVersion、sourceLocation を追加します。 | 標準出力に単一の JSON 配列(最大 10 行、プライベート優先)。一致なしの場合は 1 で終了します。 |
ワークフローの構成(2つのフェーズ)
このワークフローには、明示的なユーザー承認ゲートで区切られた2つのフェーズがあります。
- フェーズ1:技術設計(ステップ1~7)。 システムを特定し、Exchangeを検索し、コネクタについて説明し、トリガーとプロバイダーを選択して、技術設計の概要を提示し、ユーザーの承認を待ちます。フェーズ1では、ユーザーのプロジェクトディレクトリには何も書き込みません。すべての成果物はワークスペース相対パスの下に保存されます:
tmp/mule-dev-env.json(validate_prerequisites.mjsが管理する環境キャッシュ)、tmp/connector-choices/*.json(コネクタ選択のドラフト)、およびtmp/connector-metadata/*.json。フェーズ2が読み込むピン留め済みのtmp/connector-versions/*.jsonディレクトリに内容が追加されるのは、ステップ7の承認後にcommit_connectors.mjsが実行されてからです。 - フェーズ2:ビルド(ステップ8~18)。 実際のプロジェクトを作成し、設定とフローXMLを生成し、ビルドを実行して、完了を宣言します。ユーザーのプロジェクトディレクトリに触れるのはフェーズ2だけです。
ステップ7の承認ゲートを明示的に通過するまで、フェーズ2を開始してはなりません。フェーズ1を省略すること、または「HTTPを使えばよい」という単一の判断にまとめてしまうことは、このスキルで最も影響の大きい失敗モードであり、2フェーズ構成はそれを防ぐためにあります。
更新モード(既存プロジェクトの変更)
確認可能な判定基準: ワークスペースに pom.xml と src/main/mule/*.xml がすでに存在する場合、新しいプロジェクトを作成するのではなく、既存のプロジェクトを変更しています。これは、設定の名前変更、コネクタ操作の追加や入れ替え、フローの編集、<logger>/<set-variable> の追加、接続プロパティの変更、将来のステップに備えた pom.xml への依存関係の追加など、あらゆる対象の変更に当てはまります。
更新モードでは:
-
dx mule project createは実行せず、ファイルをゼロから再生成しないでください。 プロジェクト作成の手順(ステップ 8 のdx mule project create)は省略してください。既存のファイルを読み込み、Edit/replace_in_fileで変更をその場で適用し、無関係なフロー、設定、要素はすべて保持してください。フェーズ 1 のゲートに対する開始点: ユーザーが具体的に指定した自己完結型のその場での編集(この設定の名前変更、ここへのロガーの追加、この操作の入れ替えなど)では、ステップ 7 の TDD 承認ゲートは不要です。直接編集し、その後ビルドしてください。上記の「ステップ 7 の承認ゲートが完了するまでフェーズ 2 を開始してはならない」というルールは、新規プロジェクトの作成に適用されるものであり、更新モードの編集には適用されません。ただし、変更がコネクタに関係する場合は、以下の関連するコネクタ調査手順(項目 2)を実行してください。依頼内容が大規模または曖昧(ユーザーが変更対象の要素を指定せず、結果だけを説明している)な場合は、実施予定の編集内容を簡潔にまとめて提示し、編集前に確認を得てください。ただし、TDD の一式や新規プロジェクトは必要ありません。
-
コネクタに関する作業では、必ず事実に基づく手順を踏んでください。 コネクタ、操作、ソース、または接続プロバイダーを追加または入れ替える場合は、編集前にバージョン確認のため
get_latest_connector.mjsを、操作/設定/プロバイダーのメタデータ確認のためdescribe_connector.mjsを必ず実行してください。これはステップ 3~6/13 の要件と同じです。コネクタのバージョン、操作名、接続属性を記憶に頼ってハードコードしてはなりません。実際の GAV と要素名/属性名は、トレーニング時の知識ではなく、スクリプトから取得してください。 -
新規プロジェクトの場合と同様に、ステップ 16(ビルド)→ステップ 17(クリーンアップ)→ステップ 18(完了)を必ず実施してください。 変更がどれほど小さくても、
mvn clean packageを実行してBUILD SUCCESSを確認することは必須です。設定の名前変更、ロガーの 1 行挿入、pom への依存関係追加も、すべてビルドを壊す可能性がある変更です。壊れていないことを証明できるのはビルドだけです。
mvn clean package が BUILD SUCCESS を返すまで、変更は完了していません。 これは例外なく更新モードにも適用されます。
- 「単なるテキスト編集/名前変更/要素の追加です」――それでもビルドしてください。小さな編集でもビルドを壊すことがあります(設定名を変えると
config-refs が未解決になり、新しいxmlnsを依存関係なしで追加すると XSD の解決に失敗します)。 - 「追加した依存関係は将来のステップ用で、まだ使っていません」――それでもビルドしてください。解決できない、または誤記のある GAV は、コネクタがフローに接続されているかどうかにかかわらず、ビルドに失敗します。
- 「これは本当の意味でフロー生成タスクではないので、ビルド手順は適用されません」――適用されます。どのような種類の変更でも、プロジェクトへの変更にはすべて、検証済みのビルドが必要です。
- 「ファイルを編集しました。変更が正しいのは明らかです」――正しさを証明する唯一のものは、
mvn clean packageのターミナル出力です。ビルドせずに完了を宣言すると、壊れたプロジェクトを気付かれないまま納品することになります。
完了を宣言しようとしているのに、直近の応答で mvn clean package を実行して BUILD SUCCESS を確認していない場合は、そこで止めてください。まずビルドを実行してください(ステップ 16)。
ワークフロー全体の規律(フェーズ 1 の前にお読みください)
- ビルド → クリーンアップ → 完了の分離(ステップ 16 → ステップ 17 → ステップ 18)。 3 回の応答を順番に行い、それぞれでツールを 1 回だけ呼び出します。まず
mvn clean package、次にrm -r tmp/、最後に完了シグナルを送ります。まとめて実行しないでください。次に進む前に、各結果を待ってください。 - 1 回の応答につき
mvnの実行は 1 回だけです。 修正後にビルドを再実行する場合、その応答ではmvnコマンドだけを出力してください。追加の編集、後続のシェルコマンド、完了シグナルをまとめて実行しないでください。 - 「完了」と宣言できるのは、ビルドがすでに成功している場合だけです。
mvn clean packageを実行した応答の結果がBUILD SUCCESSだった場合にのみ、完了を宣言できます。 - コネクターのバージョンは、ステップ 3 のフローからのみ取得します。
references/connector-catalog.mdやトレーニング時の記憶、推測からバージョンを転記しないでください。ステップ 3 では 3 つのスクリプトを順に使います。get_latest_connector.mjsは候補を順位付きで表示します(標準出力のみ。バージョン固定用ファイルは作成しません)。pick_connector.mjs <nickname> <gav>は選択した行をtmp/connector-choices/に下書きとして記録し、commit_connectors.mjs(ステップ 8、TDD 承認後の最初のアクション)はすべての下書きをtmp/connector-versions/に昇格させます。dx mule project create --dependenciesまたはpom.xmlに渡す GAV はすべて、scripts/build_deps.mjs(ステップ 8 で--dependencies全体を作成する場合)またはscripts/build_gav.mjs(フェーズ 2 の別の箇所で単一コネクターの GAV を作成する場合)を使用し、tmp/connector-versions/*.jsonファイルから取得する必要があります。カタログのバージョンは変動するスナップショットです。バージョンの取得元ではなく、コネクターの識別情報を確認するためだけに使用してください。 - どのコネクターを選ぶか決めるのはスクリプトではなく、エージェントです。
get_latest_connector.mjsは、スコア、絵文字、「最有力候補」を示すサインを付けず、順位付きのリストをそのまま出力するよう意図的に設計されています。行が 1 つなら、選択は明らかです。複数行ある場合は、ユーザーが指定したシステムに合うものをエージェントが判断する必要があります。また、その行が同じ製品ファミリーの実際のバリエーションを表している場合(Slack のmule4-slack-connectorとmule-slack-connector、FTP と FTPS、Dynamics 365 と Dynamics GP/NAV/BC、IBM MQ と Solace と JMS)は、エージェントが推測するのではなく、AskUserQuestionを使ってユーザーに判断を委ねてください。プロンプトを 1 回追加するコストは 1 ターンですが、間違ったバリエーションを黙って選ぶコストは、フェーズ 2 全体の書き直しです。 - 根拠なしに HTTP を代替手段として使ってはいけません。 システムを「専用コネクターが存在しないため HTTP を使用」と判断できるのは、
scripts/get_latest_connector.mjs <system>を実行して一致するものが 0 件だった場合(終了コード 1)、または順位付きリストのすべての行が明らかに別の製品である場合に限ります(mule/connectorのようなノイズワード以外に、システム名と共通するトークンがassetIdにない場合)。検索を実行する前に HTTP を答えとして宣言することは禁止されています。Exchange には、トレーニング時の知識だけに頼ると見落としやすい、数百もの SaaS 製品向け専用コネクターがあります。確認にはヘルパースクリプトを正としてください。専用コネクターなら、メタデータの検出、型付きの操作、適切な認証が利用できます。HTTP では、生のリクエスト処理をユーザー自身が手作業で組み立てる必要があります。そのため、気づかれないまま HTTP に切り替えることは、無難な選択ではなく、明確な機能損失です。groupIdが UUID である順位付きの行(例:a50e4364-a38c-4340-b05a-c1f8ebed0748:…)は、ユーザーの組織が Exchange に非公開で公開したコネクターです。ノイズではなく、第一候補として扱ってください。わざわざ非公開コネクターを公開した組織は、たいていそれを使ってほしいと考えています。内部エンドポイント、カスタム認証、または公開コネクターでは対応できない標準的な実装経路を提供している場合が多いためです。
フェーズ 1:技術設計
ステップ 1:前提条件の検証
前提条件の検証スクリプトを実行します。このスクリプトは検証のみを行います。前提条件の検証結果を現在のワークスペースにある tmp/mule-dev-env.json に書き込みます。ステップ 8 では、そこから mule_version を読み取ります。
node scripts/validate_prerequisites.mjs
スクリプトがゼロ以外の終了コードを返した場合は、このスキルの以降の処理をすべて中止し、ユーザーに tmp/mule-dev-env.json の errors 配列に基づいて対処するよう伝えてください。代替の Mule バージョンを推測してはいけません。ランタイムが検出されない場合、mule_version は空です。
validate_prerequisites.mjs のチェック項目:Anypoint CLI v4 がインストールされていること · DX プラグインが利用可能であること · JAVA_HOME が設定されていること · Java 11 以降であること · ~/.mule-dx/config.json:.runtimePath または ~/AnypointCodeBuilder/runtime/mule-* 配下で Mule ランタイムが検出されること。ランタイムやその他のツールが不足している場合、スクリプトはエラーを報告し、適切にインストールするために必要なコマンドを実行するようユーザーに伝えます。
ステップ 1b:プロジェクトソースの決定
新しいプロジェクトを作成する場合は、必ずこれを尋ねてください。 前提条件を満たした後、ユーザーがプロジェクトをどのように作成するかを確認します。
<ask_followup_question>
<question>I can create this project in one of three ways. Which would you prefer?</question>
<options>["I want to generate from scratch without a template.", "I want to use organizational templates from Anypoint Exchange.", "I have a local template file (.jar or .zip) I want to use."]</options>
</ask_followup_question>
回答に基づく処理:
- Exchange または Local テンプレート →
references/template-project-creation.mdを読み、適切なフロー(Exchange E1~E4、または Local L1~L4)に従います。サブスキルの最後に、明示的な続行するか停止するかのプロンプト(ステップ E5/L5)が表示されます。ユーザーが「停止」を選んだ場合は、<attempt_completion>を使って完了を宣言します。「続行」を選んだ場合は、ここに戻ってステップ 2 に進みます。 - Scratch → ステップ 2 に進みます。コネクタの検出によって
--dependenciesが決まった後、ステップ 8 でプロジェクトを作成します。
このステップを完全に省略する場合:
- ユーザーが既存のプロジェクトで作業している場合(新規作成ではなく、フローを変更/更新する場合)
ステップ 2:システムとトリガーのヒントの特定
[ブロッカー]ステップ 2 では、ユーザーに質問してはいけません。 ここでは <ask_followup_question> または <AskUserQuestion> を出力しないでください。トリガーの決定は、コネクタのメタデータがディスク上に保存された後、ステップ 5 で行います。今質問すると、実際のコネクタソースではなく、一般的な選択肢(HTTP Listener/Scheduler)を提示することになり、このワークフローが防ぐべき最も重大なアンチパターンを招きます。
回答文に 2 つの記録を含めてください。これらは通常の文章であり、思考ブロックでもツール呼び出しでもありません。そのため、後続のステップとユーザーが確認できます。
1. システムの一覧。 正確なシステム名を特定します。つまり、ソースシステム(データの取得元)とターゲットシステム(データの送信先)です。一般的な用語(チャット、チケット管理、決済、コマース)ではなく、具体的な名前(Slack、Jira、ServiceNow、Stripe、Shopify)を使います。この一覧にあるすべての名前をステップ 3 で検索します。各検索では、ディスク上に tmp/connector-choices/<nick>.json の下書きが作成される必要があります(エージェントは順位付けされた一覧から選び、pick_connector.mjs を呼び出します)。
アンチパターン — 送信先名からバックエンドを推測する。 プロンプトにキュー、トピック、バスなどのメッセージング送信先が記載されている場合、送信先の名前を表す文字列(例:foo.queue、orders.topic、events-stream)はラベルであり、テクノロジーではありません。どのブローカーが背後にあるかを示すものではありません。プロンプトに明示的な名前がない限り、特定のブローカー(Anypoint MQ、Kafka、IBM MQ、Solace、SQS など)をシステムの一覧に追加してはいけません。プロンプトに「キュー」/「トピック」とだけ書かれている場合、または送信先の名前だけが記載されている場合は、システムを messaging broker (backend unspecified) として一覧に記載し、ステップ 3 でユーザーに確認する計画を立てます。バックエンドを選ぶのはエージェントではなく、ユーザーです。これが重要な理由:ブローカーを暗黙に選択すると、フェーズ 2 で誤ったコネクタファミリーを前提にすることになり、修正するにはフェーズ 2 を全面的に書き直す必要があります。
2. トリガーのヒント。 1〜2文で、フローの開始条件や実行間隔を示す、ユーザープロンプト内のそのままの表現を記載してください。たとえば、「3秒ごと」、「新しいStripeの課金をリッスンする」、*「顧客を取得するためにGETリクエストを送信する」*などです。まだ分類しないでください。クラスのラベルも、判断ツリーも、「つまりトリガーは……」も不要です。ステップ5では、まだ存在しないコネクターのメタデータに基づいてトリガーを判断します。今トリガーを確定すると、クラスを通じて暗黙のうちに確定する場合であっても、ステップ4で生成される実際の sources[]に対するエージェントの判断が偏りがちです。
プロンプトにトリガーの記述がない場合、または送信側の処理(「リクエストを送信する」「取得する」「呼び出す」など)のみが記載されている場合は、その旨を明示してください。「明示的なトリガーの表現はありません。送信側の処理のみの記述です。」ステップ5のメタデータ優先の手順で対応します。
システムごとのコネクター戦略:
- 主要なSaaSプラットフォーム(Salesforce、ServiceNow、NetSuite、Workday)→ ステップ3で専用コネクターを検索します。
- 標準プロトコル(Database、JMS、FTPS、SFTP)→ ステップ3でプロトコル固有のコネクターを検索します。
- 中堅市場向けSaaS(Stripe、Shopify、HubSpot、Twilio、Plaidなど)→ ステップ3で専用コネクターを検索します。これらにコネクターがないと決めつけないでください。Exchangeには、これらの多くに専用コネクターがあります。「Stripe/ShopifyなどはREST APIのみのシステム」という学習データに基づく直感は当てになりません。判断基準となるのは検索結果です。
- バックエンドが明示されているキューまたはPub/Sub(「Kafka topic」、「IBM MQ」、「SQS」、「Solace」)→ ステップ3で該当する専用コネクターを検索します。
- バックエンドが明示されていないキューまたはPub/Sub(プロンプトに「queue」や「topic」、またはブローカーテクノロジーを指定しない宛先名のみが含まれる場合)→ 上記のステップ2のアンチパターンに従い、宛先名からバックエンドを判断しないでください。ステップ3では、
AskUserQuestionでユーザーにバックエンド(任意のブローカープロバイダー経由のJMS、Kafka、IBM MQ、Solace、SQSなど)を選んでもらいます。ユーザーが選択を拒否した場合に限り、mule-jms-connectorを既定値として使用してください。JMSはあらゆるブローカーに適合する汎用プロトコル層であり、ブローカーはステップ6で接続プロバイダー(active-mq、active-mq-nct、generic)を使って選択します。 - 不明/不明瞭なシステムやカスタムの社内API → それでもステップ3では、まずExchangeを検索します。HTTPを代替手段として使うのは、ステップ3の検索で関連しそうな結果が何も見つからなかった場合に限ります。
ステップ2の次に実行するツール呼び出しは、必ずSystemsリストにあるシステムを対象とするget_latest_connector.mjsにしてください。ask_followup_questionでも、describe-connectorでも、その他のものでもありません。ステップ3は必ず次に実行する手順です。
ステップ 3:Exchange でコネクターを検索し、選定して、選択内容をドラフトする
ステップ 3 は、ステップ 2 で指定されたシステムごとに 1 回 実行する、次の 3 つの手順からなるループです。
get_latest_connector.mjsで候補を 一覧表示 します。- どの行が適切か 判断 します。選択が明らかな場合は、その場で理由を説明します。同じシステムファミリーの実際のバリエーションである行が並ぶ場合は、
AskUserQuestionを使います。 pick_connector.mjsで選んだ GAV を ドラフト します。ドラフトはtmp/connector-choices/<nick>.jsonに保存され、フェーズ 1 の間はそのまま維持されます。
スクリプトが選択結果を決めることはありません。絵文字も、スコアも、出力に「Picked」という行もありません。一覧に 1 行だけある場合、出力の形は「1 行」です。複数行ある場合は「複数行」となり、名前を読んで意図を考えるか、エスカレーションするための合図です。
必須の検索ルール。 ステップ 2 で指定されたすべてのシステムについて、get_latest_connector.mjs を実行してください。トレーニングデータでの認知度から専用コネクターはないと思われるシステムも対象です。スクリプトを実行せずに「システム X には専用コネクターがない」と判断することは禁止されています。このルールにより、HTTP への暗黙のフォールバックを防ぎます。ワークフロー全体の規律にある「証拠なしで HTTP にフォールバックしない」を参照してください。
検索語の広さ。 mule-amazon-s3-connector や mule-db-connector のように接尾辞を限定した語よりも、常に広いシステム名(databricks、aws-storage、snowflake、database、salesforce)を優先してください。狭い語では、assetId に公開コネクター名との共通トークンがない、組織内限定のコネクターが見つからない場合があります。たとえば、mule-amazon-s3-connector で検索しても、非公開の mule-plugin-aws-storage-api は表示されません。また、mule-db-connector では非公開の <uuid>:mule-plugin-customer-warehouse-database は表示されません。後述の「一般的な検索語」表は、よく知られたシステムを検索する際の出発点となるヒントであり、制約ではありません。広い語でノイズが多い場合は、いつでもより狭い語で再検索できます。
バージョンの唯一の正しい情報源に関するルール(必須):
- コネクターのバージョン番号の情報源として認められるのは、現在のセッションでライブの Exchange を対象に実行した
get_latest_connector.mjsの結果のみです。この結果をpick_connector.mjsで記録し、後でcommit_connectors.mjsによってtmp/connector-versions/に反映します。これはdx mule project create --dependencies、pom.xmlの<dependency>ブロック、およびバージョンを記載するほかのすべての箇所に等しく適用されます。 references/connector-catalog.mdのバージョンを貼り付けないでください。このカタログは、使用するコネクターの特定(アセット ID、目的)に役立つものです。記載されたバージョン番号は、最新の状態を保つための最善の努力によるスナップショットであり、古くなる可能性があります。- 記憶や推測からバージョンを作らないでください。Exchange のバージョン番号は予測できません。
- 対応する
tmp/connector-choices/<name>.jsonのドラフトがディスク上に存在する前に、バージョンを記載しないでください。
手順 1 — 一覧表示
指定されたシステムごとに 1 回実行します。ニックネームはドラフトと後の固定名に使われるため、短い名前を選び、一貫して使用してください。
node scripts/get_latest_connector.mjs mule-salesforce-connector sfdc
標準出力の形式は、推定される適合度の高い順に、1 行につき 1 つの GAV です。
com.mulesoft.connectors:mule-salesforce-connector:11.1.0
com.mulesoft.connectors:mule-salesforce-analytics-connector:4.1.0
com.mulesoft.connectors:mule-salesforce-composite-connector:2.5.2
com.mulesoft.connectors:mule-salesforce-marketing-cloud-connector:5.0.0
終了コード 0 は 1 行以上が返されたことを示します。終了コード 1 は Mule 4 拡張機能が見つからなかったことを示します。この場合、このシステムは HTTP にフォールバックする領域として扱う必要があります(ワークフロー全体の規律を参照してください)。
Move 2 — 決定して確認する
一覧を確認します。ケースは次の2つです。
ケース A — 1行のみ。 一致する Mule 4 拡張機能が1つだけです。選択内容を1文でインラインに伝え(「HTTP に一致するのは org.mule.connectors:mule-http-connector:1.11.1 のみです」)、Move 3 に進みます。
ケース B — 同じシステムファミリーの実際のバリアントが複数行ある。 assetId がユーザーのシステムを表しているとは考えにくい行はノイズなので、論理的に除外します。ユーザーのシステムに対して論理的に絞り込んだ後も選択肢が複数残る場合(例:Salesforce の検索結果に mule-salesforce-connector と、Analytics/Composite/Marketing Cloud などの Salesforce サブ製品が含まれている場合)は、必ず AskUserQuestion で確認します。ユーザーの確認が必要となる、よくあるバリアントファミリーは次のとおりです。
slack→mule-slack-connector(コミュニティ版、v4.x)対mule4-slack-connector(MuleSoft プレミアム版、v2.x)。OAuth の形式も操作も異なり、どちらかがもう一方の「新しいバージョン」というわけではありません。ftp→mule-ftp-connector(通常の FTP)対mule-ftps-connector(TLS)。必ず確認し、セキュリティのベストプラクティスとして FTPS を提案します。ibm-mq対solace対kafka対jms— プロンプトにある宛先名(例:foo.queue、bar.topic)だけでは、バックエンドを特定できません。プロンプトでブローカーテクノロジーが明示されていない場合は、これらを選択肢として提示し、必ず確認します。ユーザーが選択を見送った場合は、汎用プロトコルのフォールバックとしてmule-jms-connectorを使用します。microsoft-dynamics-*— 365、GP、NAV、365-Business-Central、CRM は、それぞれ異なる製品であり、ユーザーが同じ意味で指定している可能性があります。oracle-ebs対oracle-ebs-122— EBS の異なるメジャーバージョンです。- assetId に対象システム名が含まれ、バリアントのサフィックス、プロトコルを示す識別子、メジャーバージョンを示す識別子、または
mule4-とmule-のプレフィックスだけが異なるペア。 - 同じシステムファミリーの公開コネクタとプライベート(UUID の groupId)コネクタ。例:
snowflakeの検索結果にcom.mulesoft.connectors:mule4-snowflake-connectorと<uuid>:mule-plugin-snowflake-sys-api-jsonの両方が表示される場合。組織が公開したアセットには通常、何らかの理由(カスタム認証、内部エンドポイント、公開コネクタのラッパー)があります。そのため、同じランキング済みリストにプライベートな代替候補がある場合、公開版を黙って選択してはいけません。両方を提示し、AskUserQuestionでユーザーに選んでもらいます。
確認が必要な場合のプロンプト形式:
<ask_followup_question>
<question>Two Mule 4 Slack connectors exist on Exchange. Which should this integration use?</question>
<options>[
"org.mule.connectors:mule-slack-connector:4.3.2 — community Slack connector",
"com.mulesoft.connectors:mule4-slack-connector:2.0.1 — MuleSoft premium Slack connector",
"Other — describe which Slack variant you need"
]</options>
</ask_followup_question>
選択肢が複数ある場合は、ユーザーに確認します。誤ったバリアントを黙って選ぶと、Phase-2 での書き直しが必要になります。
ユーザーのプロンプトでバリアントが明示されている場合(「BC ではなく Dynamics 365 コネクタを使用する」、「プレミアム版の Slack コネクタのみ」など)は、その指定に従い、質問せずに進めます。
Move 3 — 下書きを作成する
選択した GAV を下書きとして記録します。これはべき等であり、Step 4 または Step 5 のメタデータから、より適切な候補が判明した場合は、別の GAV で再実行できます。
node scripts/pick_connector.mjs sfdc com.mulesoft.connectors:mule-salesforce-connector:11.1.0
node scripts/pick_connector.mjs slack com.mulesoft.connectors:mule4-slack-connector:2.0.1
node scripts/pick_connector.mjs jms org.mule.connectors:mule-jms-connector:1.10.3
# → tmp/connector-choices/{sfdc,slack,jms}.json now each contain {groupId, assetId, version}
Step 4 のメタデータダイジェストを確認した後に下書きが誤っていると気付いた場合は、修正した GAV で pick_connector.mjs を再実行します。下書きは、Step 8 で commit_connectors.mjs が確定するまで変更可能です。
Phase 1 で固定ではなく下書きにする理由。 ユーザーが Technical Design Summary を確認する前に、コネクタの選択が tmp/connector-versions/ に書き込まれると、エージェントも、後続のすべてのチェックも、その選択が確定済みであるかのように扱います。TDD の承認まで選択を下書きとして保持することで、設計全体を変更可能な状態に保ち、承認ゲートを実際の確定時点にできます。
スクリプトが内部で適用する選択ルール
(参考情報です。再実装する必要はありません。リストは推定される優先度の高い順ですが、順序はあくまで目安であり、必須ではありません。)
"type": "extension"(Mule 4 互換)のみを対象とします。Mule 3 のtype=connectorアセット、テンプレート、サンプル、rest-apis は除外されます。- アセットが
type="extension"であれば、どの groupId も対象になります。ランキングでは、3 段階の優先順位(com.mulesoft.connectors>org.mule.connectors> その他)により、ファーストパーティのコネクタが上位になります。 - 各
(groupId, assetId)グループ内で最新のセマンティックバージョンを対象とします。 - 検索語とのトークン重複度でスコアを計算します。同点の場合は、優先度の高い groupId と短い assetId を上位にします。スコアは並べ替えにのみ使用され、出力されることはありません。
- 2 ページ(offsets 0 と 200)を並列で取得するため、
salesforceのような幅広い検索でも、1 ページだけの場合のように候補が漏れることはありません。
よく使われる検索語
よく知られたシステムについての検索のヒントです。それ以外の場合、特にユーザーの組織にプライベートコネクタがある可能性があるシステムについては、まずシステム名で検索してください。
| システム | 検索語 |
|---|---|
| Salesforce | salesforce |
| データベース | database |
| HTTP | http |
| NetSuite | netsuite |
| ServiceNow | servicenow |
| Amazon S3 | amazon |
| JMS | jms |
| Slack | slack(Slack の両方のバリアントが返されます。上記の曖昧なケースです) |
リストにないシステムは、システム名を使って動的に検索してください(例:stripe、shopify、hubspot、databricks、snowflake)。命名パターンを決めつけたり、そのシステムにコネクタがないと判断したりしないでください。システム名を使った、より幅広い検索語では、同じドメインでユーザーの組織が公開しているプライベート(UUID の groupId)コネクタも見つかります。mule-<name>-connector のような範囲の狭い検索語では、見つからないことがよくあります。
ステップ 4:コネクターを記述する
ステップ 3 で解決した各コネクターについて、完全なメタデータを取得し、ラッパースクリプトが出力するダイジェストを確認してください。describe-connector のパイプラインを手作業で記述するのではなく、describe_connector.mjs を使用してください。ラッパーはプローブのパスを解決し、後続のステップで使う完全な JSON を保存するだけでなく、sources[] と configs[] も標準出力に表示するため、ステップ 5 で必要になる情報を確認できます。
node scripts/describe_connector.mjs sfdc # nickname from Step 3
node scripts/describe_connector.mjs stripe
node scripts/describe_connector.mjs http
各実行では、tmp/connector-metadata/<nickname>.json(完全なレスポンス。フェーズ 2 で再利用されます)が書き込まれ、次のような形式のダイジェストが出力されます。
{
"namespace_prefix": "stripe",
"sources": [
"on-canceled-subscription-listener",
"on-new-charge-listener",
...
],
"configs": [
{ "name": "config", "providers": ["api-key"] }
],
"operations_count": 335,
"operations_sample": ["createV13dSecure", "..."]
}
返される sources[] 配列を確認してください。 このリストは、コネクターがサポートする実際のネイティブトリガーの一覧であり、ステップ 5 の分岐に使用します。ダイジェストを読み飛ばして次の describe_connector.mjs 呼び出しに進まないでください。各コネクターが公開するソースを把握しているかどうかで、ステップ 5 のトリガー判定が決まります。ダイジェストは、その情報を得る最も手軽な方法です。
スクリプトは、コネクター全体に適用されるエラータイプの許可リストも tmp/connector-errors/<nickname>.json に書き込みます。ステップ 16 のバリデーターがこのディレクトリを読み取るため、手動で実行する必要はありません。
公開不備からの自動復旧。 コネクターの最新の公開バージョンが不完全な成果物である場合があります。jar に、コネクター自身の mule-artifact.json がエクスポート対象として宣言しているクラスが含まれていないため、describe-connector が利用可能な出力なしでゼロ以外の値を返して終了します。下書きの GAV がステップ 3 のもの(tmp/connector-choices/ の下書き)で、概要の記述に失敗した場合、ラッパーはそのアセットのほかの公開バージョンを自動的に一覧表示し、不具合のあるバージョンより下で最も新しい動作するバージョンを再試行し、そのバージョンに合わせて下書きを更新したうえで、⚠️ … fell back to working version <v> という行を出力します。これは不具合のある公開への機械的な対処であり、別バリアントの選択ではありません。コネクターの識別情報は変わりません。この警告が表示された場合、更新されたバージョンはステップ 8 の commit_connectors.mjs を通じて自動的に pom に反映されます。対応は不要です。動作する以前のバージョンが存在しない場合、スクリプトは引き続き失敗して終了コード 1 を返します。その場合は、コネクターが本当に利用できないものとして扱ってください。
完全なレスポンスが必要な場合(たとえば、oauth-callback-config の childElements[] を調べる場合)は、tmp/connector-metadata/<nickname>.json を直接読み取ってください。
手動での代替手順 — 何らかの理由でラッパーを利用できない場合は、手作業で同じ処理を再現できます。フェーズ 1 では下書きファイルが正となり、build_gav.mjs はどちらの場所も受け付けます。
NODE_NO_WARNINGS=1 anypoint-cli-v4 dx mule describe-connector \
--connector "$(node scripts/build_gav.mjs tmp/connector-choices/sfdc.json)" \
--output json > tmp/connector-metadata/sfdc.json
jq '{namespace: .namespace.prefix, sources, configs: [.configs[] | {name, providers: [.connectionProviders[]?]}]}' tmp/connector-metadata/sfdc.json
ただし通常はラッパーを使用してください。3 行ではなく 1 行で済み、追加の呼び出しをしなくても、今回のターンのツール出力でソースリストを確認できます。
ステップ 5:トリガーを選択する
すべてのトップレベルフロー(サブフローまたは<flow-ref>の参照先ではないもの)には、トリガーが必ず 1 つ必要です。ステップ 5 では、プロンプト文面から直感で判断するのではなく、コネクターのメタデータに基づいて、どのトリガーを使うかを決定します。
[BLOCKER] 決定前に調査するゲート。 インラインで決定する場合もAskUserQuestionで尋ねる場合も、トリガーを確定する前に、ステップ 2 の Systems リストにある名前付きシステムのすべてについて、次の両方が満たされている必要があります。
tmp/connector-choices/<nick>.jsonがディスク上に存在する(ステップ 3、pick_connector.mjsを使用)。tmp/connector-metadata/<nick>.jsonがディスク上に存在する(ステップ 4)。
さらに、sources[]の内容を確認できる状態にしておく必要があります。次を実行してください。
for f in tmp/connector-metadata/*.json; do
echo "--- $f ---"
jq '{namespace: .namespace.prefix, sources}' "$f"
done
ステップ 5 を開始する応答内で実行し、出力を確認してください。これは、ステップ 4 でdescribe_connector.mjsのダイジェストにコネクターごとに表示されたものと同じデータですが、ここで再度出力することで、決定の直前にすべてのコネクターのソースを並べて確認できます。現在のツール出力にそれらのリストがない状態で、トリガーを確定しないでください。過去のターンはすぐにコンテキストから外れます。
このゲートが必要な理由:エージェントがsource[]を確認する前にトリガーを確定すると、通常はhttp:listenerをデフォルトとして選び(プロンプトを Webhook とみなし)、ステップ 4 で取得した実際のコネクターソースを黙って無視してしまいます。コネクターがサポートするトリガーの正式な一覧は、そのコネクターのsource[]配列です。ステップ 5 ではプロンプト文面の直感ではなく、その一覧に基づいて分岐してください。
判断の手順(順番に評価)
以下の段階を順番に確認してください。各段階は可能な経路の 1 つです。「フォールバック」の優先順位はありません。前提条件がすべて一致した最初の経路を選択します。
段階 1 — コネクターソースの経路
対象となる各コネクターについて、ダイジェストのsource[]を確認します。名前がユーザーの明示したニーズに関係している可能性があるソース(名詞の一致:「product」、「order」、「charge」、「customer」など、および動詞の接頭辞との整合性:on-new-*、on-updated-*、on-modified-*、on-*-arrived、poll-*、*-listener、*-trigger)について、統合されたdescribe-connectorコマンドに--type sourceを指定して、構造を確認します。
NODE_NO_WARNINGS=1 anypoint-cli-v4 dx mule describe-connector \
--connector "$(node scripts/build_gav.mjs tmp/connector-choices/<nick>.json)" \
--type source \
--name <source-name> \
--output json
すべてのソースに対してsource-detailを呼び出さないでください。上記の名詞と動詞の接頭辞の確認に基づき、ユーザーの意図に合う可能性のあるソースだけを対象にしてください。ソースの多いコネクター(Shopify、Salesforce など)では、これにより CLI 呼び出しを 7 回以上から 1〜2 回に減らせます。
返された構造を、名前だけではなく、ユーザーの意図と照らし合わせてください。
- ソースの
childElements[]にscheduling-strategy要素が含まれている場合、これはポーリングソースです。コネクター自体がネイティブに実行間隔を処理します。ユーザーのプロンプトで実行間隔(「N ごと」、「毎日」、「毎時」など)が指定され、該当するソースがポーリングソースであれば、実行間隔はソースの<scheduling-strategy>子要素内に設定します。**別のトップレベルの<scheduler>を併用しないでください。**正しい構造の例:<shopify:on-updated-product-trigger config-ref="shopifyConfig"> <scheduling-strategy> <fixed-frequency frequency="3000" startDelay="5000"/> </scheduling-strategy> </shopify:on-updated-product-trigger> - ソースに
scheduling-strategy子要素がなく、イベント(on-new-*、on-modified-*)を公開する場合、これはイベントソースです。そのまま使用し、トップレベルのスケジューラーは不要です。 - ソースの構造に
listenerConfig参照が含まれている場合、これはWebhook レシーバーです。「エンドポイントでコールバックを受信する」というプロンプトに適しています。
ユーザーの意図に構造が合うソースが 1 つだけで、その一致を 1 文で説明できる場合は、そのコネクターソースをインラインで確定します。ソース名を挙げ、その理由を 1 行で述べて選択を伝えてください。
2 つ以上のソースがユーザーの意図に対する構造の確認を通過した場合、またはユーザーの表現から希望するソースの意味が本当に曖昧な場合は、AskUserQuestionで質問します。選択肢には、一般的なプレースホルダーではなく、実際のソース名を記載してください。
<ask_followup_question>
<question>Which Salesforce event should trigger this flow?</question>
<options>[
"salesforce:replay-topic-listener — subscribe to a Salesforce streaming topic",
"salesforce:modified-object-listener — fire when a record of a given sObject is modified",
"Other — pick a different source"
]</options>
</ask_followup_question>
対象となるコネクターのいずれにも構造の確認を通過するソースがない場合は、段階 2 に進みます。
Rung 2 — 汎用スケジューラーパス
次の条件に当てはまる場合は、このパスを選択します。
- ユーザーの意図に合うコネクターソースがない(Rung 1 で候補を調べた結果、一致するものがなかった)、かつ
- プロンプトで実行間隔が指定されている(「N ごと」「毎日」「毎時」「…ごとにポーリング」など)、かつ
- フロー本体がコネクターの操作を呼び出す(イベント駆動ではない)。
<scheduler> と <fixed-frequency> または <cron> を使用します。選択した内容をインラインで明記してください。
却下した理由を記録します。 このパスを選択する場合は、Rung 1 のソースを却下した理由を 1 文で記載してください。例:「Shopify の on-updated-product-trigger は『3 秒ごと』に一致しますが、ユーザーは『前回のポーリング以降に更新されたもの』ではなく、カスタムの日付範囲で取得することを求めているため、汎用の <scheduler> と shopify:product-list のほうが適切です。」Step 7 の TDD でこのリストが必要になるため、理由が明確なうちに記録してください。
Rung 3 — HTTP Listener パス
次の条件に当てはまる場合は、このパスを選択します。
- プロンプトで「エンドポイントを公開」「HTTP リクエストを受信」「REST API を提供」「/path で webhook」などが明示されている、かつ
- 対象範囲内に webhook 形式の受信側コネクターソースがない。
<http:listener> を使用します。選択した内容をインラインで明記してください。検討したコネクターソースと、却下した理由を記録してください(Step 7 を参照)。
Rung 4 — ユーザーに確認する
Rung 1~3 のいずれにも明確に該当しない場合は、このパスを選択します。たとえば、実行間隔もエンドポイントに関する記述もない、送信のみのプロンプト(「リクエストを送信」「取得」「検索」など)の場合です。対象範囲内のコネクターの実際の sources[] に加えて、Scheduler と HTTP Listener から選択肢を作成し、AskUserQuestion を使用します。
<ask_followup_question>
<question>The prompt describes outbound calls but does not name a trigger. What should start this flow?</question>
<options>[
"Scheduler — run on a time-based schedule",
"HTTP Listener — receive an inbound HTTP request",
"<connector>:<source-name> — native event from one of the connectors in scope (list any that apply based on sources[])",
"Other — please describe"
]</options>
</ask_followup_question>
決定後
選択したトリガー、それを所有するコネクター(該当する場合)、および Rung 2 または Rung 3 の場合は、検討したコネクターソースのリストと、それぞれを却下した理由を 1 行ずつ記録します。Step 7 の TDD でこのリストを提示するため、記録がない場合は TDD が不完全となり、Phase 2 を開始できません。
[BLOCKER] このステップでユーザーへの確認が求められた場合は、Step 6 に進む前にユーザーの応答を待ってください。
ステップ 6:接続プロバイダーを選択する
実際に選択肢がある場合にのみ、ユーザーに尋ねてください。 各コネクターについて、ステップ 4 で取得した configs[] のメタデータ、特にフェーズ 2 で呼び出す予定の操作を所有する設定の connectionProviders リストを確認します。
判断ルール:
- 複数の設定または複数のプロバイダーがある →
AskUserQuestionを必ず使用してください。ユーザーの選択によって、ステップ 11 のconfig-detail呼び出しに渡すconfig-nameと--connection-providerの両方、およびステップ 12 で記述する XML 構造が決まります。 - 設定がちょうど 1 つで、プロバイダーもちょうど 1 つ → 質問をしてはいけません。1 行で選択内容を伝え(「
s3:config[connection]を使用します — コネクターが提供する唯一の選択肢です」)、そのまま進めます。単一の「選択肢」を提示する質問は、無意味な形式のように見え、会話のターンを無駄にします。
実際の Exchange メタデータに基づく例:
| コネクター | configs × プロバイダー | 対応 |
|---|---|---|
| S3 コネクター | config[connection] | 伝えて、質問はしません |
| VM コネクター | config[connection] | 伝えて、質問はしません |
| HTTP コネクター | listener-config[listener-connection]、request-config[request-connection] | 設定はリスナーとリクエストに 1 対 1 で対応します。これはユーザーの希望ではなく、フローの形(トリガーかアウトバウンド呼び出しか)で決まります。伝えて、質問はしません。 |
| ストリーム用と非ストリーム用の設定を持つ複数設定コネクター | config[basic, role]、streams-config[streams] | 質問します — ユースケースに合う操作を持つ設定を選び、その設定にプロバイダーが複数ある場合は、プロバイダーも選びます。 |
| basic/OAuth/JWT/クライアントクレデンシャルを提供するコネクター | config[basic, oauth-user-pass, jwt, oauth-client-credentials] | 質問します — 認証情報のモデルが異なる実質的な選択肢です。 |
| データベースコネクター | config[my-sql-connection, oracle-connection, data-source-connection, generic-connection, ...] | プロバイダーについて質問し、同じステップで JDBC ドライバーの GAV を解決します(下記「ステップ 6b — JDBC ドライバーの解決」を参照)。ステップ 9 は機械的な pom.xml の編集です。 |
質問する場合は、 実際の選択肢のみを提示してください(「不明な場合は……」といった文言を付け足さないでください)。例:
このコネクターには 4 つの接続プロバイダーがあります。このインテグレーションではどれを使用しますか?
basic— ユーザー名 + パスワード + セキュリティトークンoauth-user-pass— ユーザー認証情報を使用した OAuthjwt— JWT ベアラートークン(サーバー間)oauth-client-credentials— OAuth クライアントクレデンシャル
実際には唯一の選択肢であるものを、「推奨」という選択肢として提示しないでください。選択肢が 1 つしかない場合は、尋ねないでください。
各コネクターについて、選択した (config-name, connection-provider) のペアを保存し、フェーズ 2 で CLI を再度呼び出す必要がないよう、describe-connector の connection-provider 出力を保持してください。フラグの意味に関する注意: --name には接続プロバイダー名を、--config-name には設定名を指定します。逆にしやすいため注意してください。
NODE_NO_WARNINGS=1 anypoint-cli-v4 dx mule describe-connector \
--connector "$(node scripts/build_gav.mjs tmp/connector-choices/sfdc.json)" \
--type connection-provider \
--name basic-connection \
--config-name sfdc-config \
--output json > tmp/connector-metadata/sfdc-config.json
ステップ 6b — JDBC ドライバーの解決(スコープに mule-db-connector が含まれる場合のみ)
mule-db-connector は、ステップ 6 のプロバイダー選択について、さらに確認が必要な唯一のケースです。プロバイダーの選択で決まるのは XML 接続要素(<db:my-sql-connection>、<db:generic-connection> など)だけですが、JDBC ドライバー JAR は別の Maven アーティファクトであり、<sharedLibrary> を通じてコネクターと一緒に配置する必要があります。ステップ 6 で両方を解決しておけば、ステップ 7 の設計概要にドライバーの完全な groupId:artifactId:version を記載でき、ステップ 9 では追加の確認なしに機械的に pom.xml を編集できます。
ステップ 6 のプロバイダー回答に応じて分岐します:
| 選択されたプロバイダー | 正規テーブルからのドライバー自動指定(ステップ 9) | 確認 |
|---|---|---|
my-sql | com.mysql:mysql-connector-j:8.4.0(8.4 LTS。9.x には JDK 21 が必要) | 不要 — その場で通知 |
oracle | com.oracle.database.jdbc:ojdbc11:23.9.0.25.07(Java 17 以降) | 不要 — その場で通知 |
mssql | com.microsoft.sqlserver:mssql-jdbc:13.4.0.jre11(Java 17 以降) | 不要 — その場で通知 |
generic かつ対象データベースが PostgreSQL と特定できる場合(ユーザーのプロンプトで Postgres が指定されている、前のターンで Postgres が指定されている、または JDBC URL のプレースホルダーに jdbc:postgresql:// が示されている) | org.postgresql:postgresql:42.7.11 — 正規の generic の組み合わせ | 不要 — その場で通知 |
generic かつ対象が別のデータベース、または未指定の場合(H2、Snowflake、SAP HANA、Vertica、不明なデータベース、またはユーザーがデータベース名を指定していない場合) | 自動指定できません — generic-connection は任意の JDBC URL を受け付けるため、ドライバーを特定できるのは対象データベースだけです。ユーザーが generic を選択した場合は、正規の選択肢について references/jdbc-drivers.md を確認してから、最も一般的な generic の対象である Postgres を先頭に記載して確認してください。 | 必要 |
data-source | 自動指定できません — ドライバーはコンテナーから提供されるか、明示的な <sharedLibrary> 宣言で指定されます。確認してください。 | 必要 |
derby | 複数アーティファクトで JDK に依存 — 選択された場合は、組み込みとネットワーククライアントの違い、および Java 17 と Java 8 のバージョンマトリックスについて references/jdbc-drivers.md を確認してください。embedded と client のどちらにするか確認してください。 | 必要 |
ルール:対象データベースが上記の最初の行(my-sql、oracle、mssql、または postgres を使う generic)のいずれかであれば、確認は不要です。自動指定してその場で通知してください。 確認が必要なのは、正規ではない generic の対象と、もともと複数の選択肢があるプロバイダー(data-source、derby)に限ります。
確認が必要な分岐では、すべて同じ形式のプロンプトを使用します:
<ask_followup_question>
<question>You picked <provider> for <database>; which JDBC driver should ship as a sharedLibrary?</question>
<options>[
"<canonical-option-1 from the reference file> — <one-line purpose>",
"<canonical-option-2> — ...",
"Other — I will provide a groupId:artifactId:version"
]</options>
</ask_followup_question>
ステップ 9 のためにステップ 6 で記録する内容:
{groupId, artifactId, version} のタプルを 1 つ以上と、ドライバークラスを保存しておきます。これにより、ステップ 9 で再度確認せずに <dependency> と <sharedLibrary> のペアを出力できます。コネクターの選択情報と同じ場所にサイドカーファイルを作成します:
# example: after Step 6 picks my-sql
cat > tmp/connector-choices/db-driver.json <<'JSON'
{
"dependencies": [
{ "groupId": "com.mysql", "artifactId": "mysql-connector-j", "version": "8.4.0" }
],
"driverClass": "com.mysql.cj.jdbc.Driver"
}
JSON
derby:embedded の場合、このファイルには 3 つのエントリーが含まれます。PostgreSQL を使う generic の場合は 1 つです。ステップ 9 の適用処理はこのファイルを読み取り、含まれるすべてのエントリーを pom.xml に適用します。
ドライバーの選択内容は技術設計に含めます。ステップ 7 では「ビルド時の追加項目」に表示し、ステップ 7 でユーザーが承認することで、ステップ 9 による pom.xml の編集が許可されます。
Step 7: 技術設計の概要を提示する
[ブロッカー]ステップ 1~6 が完了してからのみ提示してください。 すべてのコネクターについて GAV が作成され(tmp/connector-choices/*.json)、メタデータが取得され(tmp/connector-metadata/*.json)、すべての設定でプロバイダーが選択されている必要があります。いずれかが不足している場合は、該当するステップに戻ってください。概要の中で「TBD」として済ませてはいけません。
**Technical Design Summary**
**User Requirement:** "<original user prompt, verbatim>"
**Project Context:**
- Project directory: <absolute path where Phase 2 will create the project>
- Work type: <New / Modification / Post-scaffolding>
- Mule runtime: <mule_version from tmp/mule-dev-env.json>
- Java: <java_version>
**Trigger:**
- Selected: <element name> from <connector or built-in source>
(e.g., "shopify:on-updated-product-trigger with fixed-frequency 3000ms" or "salesforce:replay-topic-listener from mule-salesforce-connector:10.15.7" or "Built-in Scheduler, every 5 minutes")
- Sources considered: list the `sources[]` entries that were examined via `source-detail` (if any), with one line each
stating why the source was chosen OR dismissed. If the selected trigger is `<scheduler>` or `<http:listener>` and any
in-scope connector has a `sources[]` entry, at least one rejection line is required — a TDD whose "Sources considered"
is empty while a connector source exists is incomplete, and Phase 2 cannot start.
Example:
- `shopify:on-updated-product-trigger` — SELECTED: polling source with `scheduling-strategy` child, matches "every 3 seconds" intent.
- `shopify:on-new-product-trigger` — dismissed: fires only on creation, user wants updates too.
- `shopify:on-updated-customer-trigger` — dismissed: wrong object (product, not customer).
**Required Connectors:**
1. <System Name>: <GAV> [com.mulesoft.connectors | org.mule.connectors | third-party]
- Purpose: <one line>
- Config: <config-name> | Provider: <provider-name>
2. ...
**Build-time additions (auto):**
- `mule-http-connector` — included if the trigger is HTTP Listener OR any Step 6 provider is OAuth-family (callback listener)
- JDBC driver(s) — included if `mule-db-connector` is in scope. List **every** `groupId:artifactId:version` recorded in `tmp/connector-choices/db-driver.json` from Step 6b, plus the driver class. Vague phrasing like "PostgreSQL JDBC driver included" is not acceptable here — the user is approving an explicit build edit and needs the exact coordinates.
Example:
- `org.postgresql:postgresql:42.7.11` (driver class `org.postgresql.Driver`) — added as `<dependency>` and `<sharedLibrary>` in `pom.xml`.
**Built-in processors anticipated (if applicable):**
- DataWeave, Logger, error handlers
続いて、明示的な承認を求めてください。
<ask_followup_question>
<question>Please review the technical design above. Proceed to build (Phase 2)?</question>
<options>[
"Yes, proceed to build.",
"No, I want to change the plan.",
"No, cancel generation."
]</options>
</ask_followup_question>
[ブロッカー]ステップ 8 に進む前に、「はい。ビルドに進んでください。」という明示的な承認を待ってください。 「いいえ。計画を変更したいです。」の場合は、どの部分(トリガー、コネクター、プロバイダー)かを尋ね、該当するステップに戻ってください。「いいえ。生成をキャンセルします。」の場合は、ワークフローを丁寧に終了してください。
このゲートが重要な理由:フェーズ 1 は、暗黙の HTTP フォールバック、誤ったコネクターのバリアント、誤ったトリガー、または確認質問の不足を見つける最後の機会です。フェーズ 2 が始まるとプロジェクトのスケルトンがディスク上に作成され、やり直しには全員にとってより多くの手間がかかります。概要はユーザーが方針を修正する機会です。「いいえ。計画を変更したいです。」を例外ではなく、第一級の選択肢として尊重してください。
承認後、ステップ 8 で最初に行う操作は commit_connectors.mjs の実行です。このスクリプトは、フェーズ 1 で作成した tmp/connector-choices/ 内のすべてのドラフトを、dx mule project create と pom.xml が読み込む固定済みの tmp/connector-versions/ ディレクトリに昇格させます。省略しないでください。固定ファイルがない場合、フェーズ 2 で後から実行する build_deps.mjs / build_gav.mjs の呼び出しは失敗します。
出力: 進行に対するユーザーの承認。
フェーズ 2:ビルド
Step 8: プロジェクトの作成
最初の操作 — フェーズ 1 のドラフトを固定済みバージョンに昇格させます。 ユーザーは TDD を承認したため、tmp/connector-choices/ 内のすべてのコネクター選択が正式なものになりました。まとめて昇格させます。
node scripts/commit_connectors.mjs
# → copies every tmp/connector-choices/*.json → tmp/connector-versions/*.json
# → exits 1 if no drafts exist (means Step 3 was skipped for some system)
次に tmp/mule-dev-env.json を読み込んで Mule のバージョンを確認し、build_deps.mjs を使ってディスク上の固定ファイルから --dependencies 文字列全体を出力してください。以前のツール出力から GAV を再入力したり、コネクターごとに $(build_gav.mjs ...) をインラインで指定したりしてはいけません。
MULE_VERSION=$(jq -r '.mule_version' tmp/mule-dev-env.json)
NODE_NO_WARNINGS=1 anypoint-cli-v4 dx mule project create <project-name> \
--group-id com.example \
--mule-version "$MULE_VERSION" \
--dependencies "$(node scripts/build_deps.mjs)" \
--skip-environment
build_deps.mjs は tmp/connector-versions/*.json 内のすべての固定ファイルを読み込み、ステップ 6b の JDBC ドライバーのサイドカーファイル(db-driver.json)を除外して、GAV をカンマ区切りで連結した文字列を出力します。このディレクトリ内の固定ファイルは自動的にすべて含まれます。以下のルールに従って追加した http.json も含まれます。
次に必ず行う操作 — mule-artifact.json を検証済み環境に合わせます。 スキャフォルダーが <project-name>/mule-artifact.json に書き込むデフォルトの minMuleVersion と javaSpecificationVersions は、必ずしもステップ 1 で検証したランタイムおよび Java のバージョンと一致しません。PRD は、スキルが両方を確認して更新することを求めています。dx mule project create が正常に完了した直後に、書き込みスクリプトを実行して、記述子に tmp/mule-dev-env.json から解決した環境を反映してください。
node scripts/write_mule_artifact_env.mjs <project-name>
write_mule_artifact_env.mjs は tmp/mule-dev-env.json から mule_version と java_version を読み込み、minMuleVersion と javaSpecificationVersions(Java のメジャーバージョンのみ)を <project-name>/mule-artifact.json に書き込みます。記述子にすでにあるその他のキーはすべて保持されます。この操作は冪等で、再実行しても安全です。ランタイムと Java の値を反映するために mule-artifact.json を手作業で編集してはいけません。値が記憶や後のビルド失敗への対処ではなく、検証済みの環境から取得されるよう、このステップを実行してください。
N 個の $(build_gav.mjs …) 置換をインラインで記述せず、ラッパーを 1 つ使う理由: 上記の呼び出しルールに従ってスクリプトの絶対パスを使う場合、インラインの $(…) はそれぞれ約 165 文字になります。そのため、コネクターを 4 つ使うプロジェクトでは dx mule project create コマンドが 1000 文字を超えます。Dev Agent のターミナルハーネスは、コマンドが非常に長いと完了マーカーを失い、2 分のタイムアウトが発生するまでターン全体が停止します。build_deps.mjs を使えば、対象のコネクター数にかかわらずコマンドを約 250 文字以内に抑えられます。
承認済みの Technical Design Summary に記載されているすべてのコネクターは、build_deps.mjs の実行前に tmp/connector-versions/ にピン留めされている必要があります — commit_connectors.mjs がすでに配置しています。TDD で明示されているシステムに加えて、コネクターが追加されるケースが 2 つあります。
| 条件 | 追加されるコネクター |
|---|---|
Step 5 で選択したトリガーが HTTP Listener(フローに <http:listener> が含まれる) | mule-http-connector |
| Step 6 で OAuth 系のプロバイダー(OAuth、JWT、auth-code)のいずれかを選択した | mule-http-connector(OAuth コールバック用) |
イベントリスナーソースのトリガー(例:<s3:new-object-listener>、<salesforce:replay-topic-listener>) | ソースを所有するコネクター以外は不要 — すでに TDD に含まれています |
いずれかの HTTP トリガー条件に該当し、Step 3 ですでに HTTP を選択していない場合は、dx mule project create の前に get_latest_connector.mjs mule-http-connector http + pick_connector.mjs http <gav> + commit_connectors.mjs を実行してください。そうすると、build_deps.mjs がディレクトリをスキャンするときに tmp/connector-versions/http.json が存在します。これがないと、Can't resolve http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd のような初回ビルドエラーが発生します — 自動修復可能ですが、1 ターン余計にかかります。
バージョンの正本(Step 3 から): --dependencies のすべての GAV は、tmp/connector-versions/*.json ファイルから取得する必要があります。--dependencies 文字列に com.mulesoft.connectors:mule-amazon-s3-connector:6.6.0 のようなバージョンを直接記述しないでください — build_deps.mjs を介さず、直接指定したバージョンがヘルパーの返すバージョンと異なる場合、mvn clean package は「not found」エラーで失敗します。また、そのバージョンが架空の場合、修復できないことがよくあります。
作成されるプロジェクト構成:
pom.xml(依存関係を含む Maven 設定)mule-artifact.json(アーティファクトのメタデータ。上記のwrite_mule_artifact_env.mjsステップにより、minMuleVersionとjavaSpecificationVersionsは検証済み環境に合わせられています)src/main/mule/<project-name>.xml(フロー定義)src/main/resources/(設定ファイル)
Step 9: JDBC ドライバーを pom.xml に適用する
ドライバーの GAV は Step 6b ですでに選定され、Step 7 でユーザーの承認を得ています。Step 9 では tmp/connector-choices/db-driver.json を読み込み、すべてのエントリーを <project-name>/pom.xml に適用します。1 つのエントリーにつき、<dependency> ブロックと <sharedLibrary> ブロックがそれぞれ 1 つ生成されます。mule-db-connector が対象範囲に含まれていない場合は、このステップ全体をスキップしてください。
mule-db-connector が対象範囲に含まれているにもかかわらず tmp/connector-choices/db-driver.json がない場合は、Step 6b に戻ってください — ここでドライバーを捏造したり、時期尚早に決めつけたりしないでください。
db-driver.json の dependencies[] 配列にあるすべてのエントリーについて、次の両方を追加します。
<dependencies>内の<dependency>。サイドカーファイルの記述をそのまま使用します。
<dependency>
<groupId>{groupId}</groupId>
<artifactId>{artifactId}</artifactId>
<version>{version}</version>
</dependency>
mule-maven-pluginの<configuration><sharedLibraries>内の<sharedLibrary>—groupIdとartifactIdは上記の<dependency>からそのままコピーします(ここではバージョンは指定しません)。
<configuration>
<sharedLibraries>
<sharedLibrary>
<groupId>{groupId}</groupId>
<artifactId>{artifactId}</artifactId>
</sharedLibrary>
</sharedLibraries>
</configuration>
ステップ 10:HTTP コネクターの確認(OAuth/HTTP Listener の防御的チェック)
ステップ 8 の --dependencies には、ステップ 5 で HTTP Listener を選択した場合、またはステップ 6 で OAuth 系のプロバイダーを選択した場合、すでに mule-http-connector が含まれています。これはフェーズ 1 の承認済み TDD で明らかになっています。このステップは、通常は防御的な何もしないチェックです。何らかの理由で TDD が HTTP の追加を見落としていないか、ヘルパーを実行して確認します。
選択したプロバイダーのいずれも oauth|jwt|auth-code|authorization-code に一致せず、トリガーも HTTP Listener ではない場合は、このステップを完全にスキップしてください。「念のため」に実行すると、1 ターンを消費します。
OAuth/HTTP Listener の場合は、冪等なヘルパーを実行します。
node <skill-dir>/scripts/maybe_add_http_connector.mjs \
--project ./<project-name> \
"oauth-user-pass" # one argument per Step-6 provider
<skill-dir> は、「skill is now active」メッセージで指定された絶対パス(この SKILL.md が格納されているディレクトリ)です。絶対パスを使用すると、相対パスでの実行時に発生する「No such file or directory」エラーを避けられます。
プロバイダー引数が oauth、jwt、auth-code、authorization-code のいずれかに(大文字と小文字を区別せずに)一致する場合、スクリプトは次の処理を行います。
- エージェントがすでにステップ 3 で HTTP を選択している場合は
<project-name>/tmp/connector-choices/http.jsonを再利用します。それ以外の場合はget_latest_connector.mjs mule-http-connector httpを実行し、pick_connector.mjs http <gav>を使って最上位の行を候補として提示します。HTTP は検索対象が明確なため、ユーザーへの確認は不要です。 <project-name>/pom.xmlの</dependencies>の前に<dependency>ブロックを挿入します(<classifier>mule-plugin</classifier>を含めます)。- HTTP コネクターがすでに存在する場合は何もしません。
手動での代替手順 — コネクターのドキュメントに「callback URL」または「redirect URI」と記載されている場合、あるいはステップ 11 の config-detail に oauth-callback-config 子要素が表示される場合も、HTTP コネクターを追加してください。HTTP コネクターがないと、ビルドは次のエラーで失敗します:The content of element '<connector>:<connection-provider>' is not complete。
ステップ 11:構成の詳細を取得する
フェーズ 1 のステップ 6 で、config-detail の出力はすでに tmp/connector-metadata/<nickname>-config.json に保存されています。そこから読み込みます。
cat tmp/connector-metadata/sfdc-config.json
キャッシュファイルが見つからない場合に限り、CLI を再実行してください(フェーズ 1 が正しく実行されていれば、この事態は発生しないはずです)。フラグの意味に関する注意: --name は接続プロバイダー、--config-name は構成を指定します。
NODE_NO_WARNINGS=1 anypoint-cli-v4 dx mule describe-connector \
--connector "$(node scripts/build_gav.mjs tmp/connector-versions/sfdc.json)" \
--type connection-provider \
--name basic-connection \
--config-name sfdc-config \
--output json
レスポンスの形式(同じ attributes + childElements のパターン):
{
"name": "sfdc-config",
"prefix": "salesforce",
"elementName": "sfdc-config",
"attributes": [ { "attributeName": "name", "required": true } ],
"childElements": [
{ "paramName": "expirationPolicy", "prefix": "salesforce", "elementName": "expiration-policy" }
],
"connectionProviders": [
{
"name": "basic-connection",
"prefix": "salesforce",
"elementName": "basic-connection",
"attributes": [
{ "attributeName": "username", "required": true },
{ "attributeName": "password", "required": true },
{ "attributeName": "securityToken", "required": true }
],
"childElements": [
{ "paramName": "reconnection", "prefix": "mule", "elementName": "reconnection" }
]
}
]
}
選択した接続プロバイダーの attributes と childElements の両方を確認してください。
jq '.connectionProviders[0].childElements[] | select(.paramName == "oauthCallbackConfig")' tmp/connector-metadata/sfdc-config.json
接続プロバイダーには、次のいずれか 2 つのパターンがあります。
-
属性パターン(例:Salesforce の basic-connection):
<salesforce:basic-connection username="${salesforce.username}" password="${salesforce.password}" securityToken="${salesforce.securityToken}" /> -
子要素パターン(例:Slack OAuth):
<slack:slack-auth-connection> <slack:oauth-authorization-code consumerKey="${slack.consumerKey}" consumerSecret="${slack.consumerSecret}" /> </slack:slack-auth-connection>
XML を生成する場合: attributes に項目がある場合は、接続要素に属性を使用します。attributes が空で childElements に項目がある場合は、入れ子の子要素を使用します。構造をハードコードしないでください。必ずメタデータを使用してください。
ステップ 12:構成ファイルを作成する
ステップ 11 のメタデータに基づいて、構成ファイルを作成します。
src/main/resources/config.yaml — 必須の属性と子要素のパラメーターを抽出し、プレースホルダーを出力します。
salesforce:
username: "[email protected]"
password: "password"
securityToken: "token"
slack:
consumerKey: "your-consumer-key"
consumerSecret: "your-consumer-secret"
構成 XML — 構造はすべてメタデータに基づきます。
<configuration-properties file="config.yaml" />
<salesforce:sfdc-config name="salesforceConfig">
<salesforce:basic-connection
username="${salesforce.username}"
password="${salesforce.password}"
securityToken="${salesforce.securityToken}" />
</salesforce:sfdc-config>
<slack:config name="slackConfig">
<slack:slack-auth-connection>
<slack:oauth-authorization-code
consumerKey="${slack.consumerKey}"
consumerSecret="${slack.consumerSecret}" />
<slack:oauth-callback-config
listenerConfig="HTTP_Listener_config"
callbackPath="/slack/callback"
authorizePath="/slack/authorize" />
</slack:slack-auth-connection>
</slack:config>
<http:listener-config name="HTTP_Listener_config">
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
メタデータから childElements[] の項目をすべて生成してください。接続プロバイダーの elementName、attributes[] 配列、およびすべての childElements[] 項目が対象です。OAuth コネクターでは、oauth-callback-config に http:listener-config を参照する listenerConfig 属性が必要です。必須の childElements がないと、ビルドに失敗します。
ステップ 13:操作/ソースの詳細を取得する
フローで呼び出すすべての操作について、メタデータを取得します。
node scripts/describe_connector.mjs sfdc --type operation --name query
レスポンス形式(config-detail と同じ attributes + childElements のパターン):
{
"name": "query",
"prefix": "salesforce",
"elementName": "query",
"attributes": [
{ "attributeName": "config-ref", "required": true },
{ "attributeName": "target" },
{ "attributeName": "targetValue", "defaultValue": "#[payload]", "expressionRequired": true }
],
"childElements": [
{ "paramName": "salesforceQuery", "prefix": "salesforce", "elementName": "salesforce-query", "required": true }
]
}
イベント駆動型トリガーの場合(ステップ 5 で選択したトリガーがコネクターソースであり、組み込みの Scheduler または汎用 HTTP Listener ではない場合)、ソースの詳細も取得します。
node scripts/describe_connector.mjs sfdc --type source --name replay-topic-listener
同じ attributes + childElements 構造です。required: true の属性と子要素をすべて必ず含めてください。
スクリプトは tmp/connector-errors/<nick>.<op>.json(操作ごとのエラーサブセット)にも書き込み、ステップ 4 の呼び出し結果は tmp/connector-errors/<nick>.json(コネクター全体のエラーの和集合)に書き込みます。これらのファイル内のエラータイプのみが、ステップ 14 の <on-error-propagate type="..."> および <on-error-continue type="..."> で使用できる NS:ID 文字列です。コネクターの用語から識別子を推測してはいけません。SFTP:FILE_NOT_FOUND は実在せず、正しい名前は SFTP:FILE_DOESNT_EXIST です。
<raise-error> には、より厳格なルールがあります。 スローできるのは MULE:* エラー、または APP:* のようなカスタム名前空間のみで、コネクターの名前空間(例:EC2:*、SFTP:*、SALESFORCE:*)は使用できません。コネクターのエラータイプは <on-error-*> ハンドラーで捕捉できますが、スローはできません。再試行上限に達したエラーをスローする必要がある場合は、<raise-error type="EC2:RETRY_EXHAUSTED"> ではなく、<raise-error type="MULE:RETRY_EXHAUSTED"> を使用してください。ステップ 16 のバリデーターは、両方のルールを機械的に検証します。
操作 XML を生成する(例):
<salesforce:query config-ref="salesforceConfig">
<salesforce:salesforce-query>
SELECT Id, Name, Amount, StageName
FROM Opportunity
WHERE StageName = 'Closed Won' AND CloseDate = TODAY
</salesforce:salesforce-query>
</salesforce:query>
ステップ 14:完全なフローを生成する
Step 11、13 のメタデータを使用して、src/main/mule/<project-name>.xml に完全なフローを生成します。ハードコードされた構造は使用しないでください。
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:salesforce="http://www.mulesoft.org/schema/mule/salesforce"
xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/salesforce http://www.mulesoft.org/schema/mule/salesforce/current/mule-salesforce.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
<configuration-properties file="config.yaml" />
<salesforce:sfdc-config name="salesforceConfig">
<salesforce:basic-connection
username="${salesforce.username}"
password="${salesforce.password}"
securityToken="${salesforce.securityToken}" />
</salesforce:sfdc-config>
<flow name="integration-flow">
<scheduler>
<scheduling-strategy>
<fixed-frequency frequency="300000"/>
</scheduling-strategy>
</scheduler>
<salesforce:query config-ref="salesforceConfig">
<salesforce:salesforce-query>
SELECT Id, Name, Amount FROM Opportunity WHERE StageName = 'Closed Won'
</salesforce:salesforce-query>
</salesforce:query>
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
</mule>
xsi:schemaLocation の構築ルール:
xsi:schemaLocation には、pom.xml に対応する <dependency> があるモジュールまたはコネクターの名前空間ごとに、エントリーを正確に 1 つ含めてください(core、ee/core、および各コネクター(http、salesforce、db、anypoint-mq など))。各エントリーは、名前空間 URI に続けて、その XSD の URL を空白で区切って記述します。
xsi:schemaLocation に含めてはならない名前空間(以下に列挙したものに限定):
| 名前空間 | xmlns:* 宣言 | schemaLocation から除外する理由 |
|---|---|---|
doc (http://www.mulesoft.org/schema/mule/documentation) | doc:name / doc:description を使用する場合は必須(Step 15) | この URL に XSD は存在しません。doc:* 属性は mule-core の anyAttribute によって受け入れられます。schemaLocation エントリーを追加すると、process-classes で mvn clean package が Can't resolve …/mule-documentation.xsd により失敗します。 |
xsi (http://www.w3.org/2001/XMLSchema-instance) | xsi:schemaLocation 属性自体を使用するために必須 | xsi は W3C 標準の名前空間であり、Mule スキーマではありません。 |
名前空間と依存関係の整合性: xmlns:X で名前空間を宣言しているものの、pom.xml に対応する <dependency> がない場合、正しい対処は依存関係を追加するか、名前空間を削除することです。存在しない XSD を指す schemaLocation エントリーを追加してはいけません。根本原因は異なりますが、上記の mule-documentation.xsd と同じ種類の失敗を招きます。この規則は、mule-scripting、mule-objectstore、mule-validation、mule-http の各名前空間が、対応するコネクターの依存関係なしで宣言されている場合にも適用されます。
生成ルール:
- すべてのタグに、メタデータの
elementNameをそのまま使用します - すべての属性に、メタデータの
attributeNameをそのまま使用します required: trueの属性と子要素をすべて含めます- メタデータに記載された正しい名前空間プレフィックスを使用します
- Step 12 の
config-ref名を参照します - 子要素は
childElements[]配列の正確な順序で生成します — XSD スキーマでは厳密な順序が適用されます - メタデータにないラッパー要素を追加しないでください(例:
<reconnection-strategy><reconnect>ではなく<reconnect>を使用します) - 再接続設定は、操作レベルではなく、config の接続レベルに配置します(メタデータで明示的に操作レベルに含まれている場合を除く)
pom.xmlのモジュール/コネクターの<dependency>リストからxsi:schemaLocationを構築し、docやxsiは決して含めないでください。上記のルールを参照してください。
ステップ 15:キャンバスに表示される要素に doc:name と doc:description を追加する
フローキャンバス上にノードとして表示されるすべての XML 要素には、doc:name 属性と doc:description 属性を必ず設定してください。doc:description はキャンバスのノードラベルとして表示され(設定されている場合は doc:name より優先されます)、簡潔で意味のある内容にしてください。
前提条件 — 名前空間の宣言:
doc:* 属性を使用するには、<mule> ルートに xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" が必要です(ステップ 14 を参照)。これがないと、すべての doc:name で The prefix "doc" for attribute "doc:name" associated with an element type "..." is not bound が発生します。修正するには、xmlns:doc 属性を追加します。ステップ 14 の xsi:schemaLocation の構築ルールに従い、mule-documentation を xsi:schemaLocation に追加しないでください。
config-detail、operation-detail、source-detail のメタデータから返される description フィールド、XML の構造と要素の目的、フローのコメント、統合全体のコンテキストをもとに、説明を推測してください。
ルール:
- 汎用的なドキュメントではなく、この統合における要素の目的を説明する、人が読んで理解できる文にします
- 125 文字以内 — キャンバス上でラベルを読みやすく保ちます
- 能動態で、要素の動作を具体的に記述します
- エンドポイント、オブジェクトの種類、フィールド名、スケジュール間隔など、関連する詳細を含めます
doc:descriptionと併せて、短いラベルとしてdoc:nameを追加します
キャンバスに表示される以下の種類の要素に doc:name と doc:description を追加します:
| 要素の種類 | 例 |
|---|---|
| フロー/サブフロー | <flow>、<sub-flow> |
| ソース/トリガー | <http:listener>、<scheduler>、<salesforce:modified-object-listener> |
| 操作/プロセッサー | <logger>、<set-variable>、<set-payload>、<ee:transform>、<http:request>、<salesforce:query>、<flow-ref>、任意のコネクター操作 |
| スコープ/コンテナー | <choice>、<scatter-gather>、<round-robin>、<first-successful>、<foreach>、<until-successful>、<parallel-foreach>、<try> |
| 分岐/ルート | <when>、<otherwise>、<route> |
| グローバル設定 | <salesforce:sfdc-config>、<http:listener-config>、<configuration-properties> |
キャンバスにレンダリングされない内側のプロパティ要素には doc:description を追加しないでください:
<scheduling-strategy>、<fixed-frequency>、<cron><http:body>、<http:headers>、<http:query-params><reconnection>、<reconnect><non-repeatable-stream>、<repeatable-in-memory-stream>- 操作固有の子コンテンツ要素(例:
<salesforce:salesforce-query>、<slack:chatpost-message-content>) - Transform の内側の要素(
<ee:message>、<ee:set-payload>、<ee:variables>、<ee:set-variable>)
例 — 変更後(doc:name と doc:description を設定):
<flow name="contact-sync-flow"
doc:name="Contact Sync Flow"
doc:description="Receives HTTP requests and syncs modified Salesforce contacts to Slack">
<http:listener config-ref="httpConfig" path="/contacts" allowedMethods="GET"
doc:name="HTTP GET /contacts"
doc:description="Receives incoming HTTP GET requests on the /contacts endpoint" />
<salesforce:query config-ref="salesforceConfig"
doc:name="Query modified contacts"
doc:description="Queries Salesforce for Contact records modified since the last sync">
<salesforce:salesforce-query>
SELECT Id, Name, Email FROM Contact WHERE LastModifiedDate > :lastSync
</salesforce:salesforce-query>
</salesforce:query>
<choice
doc:name="Contacts found?"
doc:description="Routes processing based on whether any modified contacts were returned">
<when expression="#[sizeOf(payload) > 0]"
doc:name="Has contacts"
doc:description="Processes each contact when results are not empty">
<foreach
doc:name="For each contact"
doc:description="Iterates through each modified contact to send to Slack">
<ee:transform
doc:name="Map to JSON"
doc:description="Transforms Salesforce Contact into a simplified JSON structure with id, name, and email">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
payload map { id: $.Id, name: $.Name, email: $.Email }]]></ee:set-payload>
</ee:message>
</ee:transform>
<slack:create-chatpost-message config-ref="slackConfig"
doc:name="Post to Slack"
doc:description="Sends the transformed contact data as a message to the configured Slack channel">
<slack:chatpost-message-content>#[payload]</slack:chatpost-message-content>
</slack:create-chatpost-message>
</foreach>
</when>
<otherwise
doc:name="No contacts"
doc:description="Handles the case when no modified contacts are found">
<logger level="INFO" message="No contacts found"
doc:name="Log no contacts"
doc:description="Logs that no modified contacts were found in this request" />
</otherwise>
</choice>
</flow>
ステップ 16:ビルドして検証する
ビルド前の検証
ビルド応答で最初のツール呼び出しとして、次を実行します。
node <skill-dir>/scripts/validate_before_build.mjs ./<project-name>
バリデーターは3つの静的チェック(エラー種別の許可リスト、名前空間と依存関係の整合性、標準的なXSD URLの形式)を実行し、違反があると終了コード1で終了します。失敗した場合は、報告された問題を修正し(Step 14を再確認)、バリデーターを再実行してください。終了コード0になってから、mvn clean package を実行します。これにより、1つの応答につきコマンドを1つだけ実行するルールが維持されます。バリデーターとmvnは別々の応答で実行してください。
cd <project-name>
mvn clean package
成功時の成果物:target/<project-name>-1.0.0-SNAPSHOT-mule-application.jar。
ビルドしてから検証する手順(手順を省略しないでください):
- この応答では、唯一のツール呼び出しとして
mvn clean packageを実行します。完了通知や、後続のls、その他のツール呼び出しを併せて含めないでください。ビルド出力を待ってください。 - mvn clean packageが成功するまで、必ず待ってください。ビルドの完了を推測してはいけません。ターミナル出力だけを唯一の根拠としてください。
- 出力を確認します。
- 最後の行のブロックに
BUILD SUCCESSが含まれている場合は、Step 17(クリーンアップ)に新しい応答で進みます。 - 最後の行のブロックに
BUILD FAILUREが含まれている場合は、Failed to execute goal ...で始まる[ERROR]行を探し、根本原因を診断して、問題のあるファイルを編集します(該当する前のStepを再確認してください。たとえば、XML構造ならStep 14、ドキュメント属性と名前空間ならStep 15)。その後、この手順のStep 1に戻ります。問題の診断と適切な修正には、必ず「ベストプラクティス」セクションに従ってください。解決策を推測してはいけません。常に、tmp/フォルダー内のコネクタメタデータのソースとオペレーションを信頼できる情報源として参照してください。
- 最後の行のブロックに
pom.xml、フローXML、または設定XMLを編集した場合は、Edit、Write、<write_to_file>、<replace_in_file> のいずれを使用した場合でも、完了を宣言する前に必ず mvn clean package を再実行してください。これは、どの編集ツールを使った場合にも例外なく適用されます。変更に使ったツールによって、この要件が変わることはありません。再検証せずに編集すると、壊れたビルドが気付かれないまま納品されます。
Step 17:ワークスペースの tmp/ をクリーンアップする
前提条件: 直前の応答がStep 16に従ったビルド応答であり、その出力に BUILD SUCCESS が含まれている必要があります。そうでない場合は、Step 17に進まず、Step 16に戻ってください。
ワークスペース相対の tmp/ ディレクトリには、Phase 1からPhase 2への連携状態が保存されています。これには、tmp/mule-dev-env.json、tmp/connector-choices/、tmp/connector-versions/、tmp/connector-metadata/、tmp/connector-errors/ に加えて、get_latest_connector.mjs と describe_connector.mjs が書き込む tmp/mule-dev-*-XXXXXX スクラッチファイルが含まれます。ビルドに成功すれば、これらのファイルは役目を終えています。これらは各ステップ間で状態を引き継ぐためだけに存在し、ユーザーが必要とする成果物ではありません。
次のコマンドを、専用の応答で唯一のツール呼び出しとして実行し、ディレクトリを削除します。
rm -r tmp/
ルール:
- ワークスペースのルートにある
tmp/だけを削除してください。
ステップ 18:完了を宣言する
前提条件: 直前の 2 つの応答は、(a)BUILD SUCCESS を返すビルド応答(ステップ 16 に従う)で、その直後に(b)rm -r tmp/ を実行したクリーンアップ応答(ステップ 17 に従う)である必要があります。どちらか一方でも欠けている場合は、ステップ 18 に進まず、欠けているステップに戻ってください。成功したか失敗したかにかかわらず、最後に必ず tmp/ フォルダーをクリーンアップしてください。
規律:
- この応答で実行するツール呼び出しは、完了シグナルだけです。 ここで
mvnを実行しないでください。後続のシェルコマンドも追加しないでください。ビルドは前の応答ですでに実行され、検証済みです。 BUILD FAILUREの後は、後続の編集で解決すると考えていても、完了を宣言しないでください。独立した応答でmvn clean packageを再実行し(ステップ 16)、BUILD SUCCESSを確認してから、次の応答で完了を宣言してください。- 最新のビルドが実際には実行されていない場合(例:コマンドを表示したものの、結果が返ってきていない場合)は、完了を宣言しないでください。独立した応答で再実行し、結果を待ってください。
完了メッセージの内容 — 簡潔にしてください。 ユーザーはファイルとビルドログを確認できます。完了メッセージは、ビルドが成功したことを示すものであり、宣伝文ではありません。次の内容だけを正確に含めてください。
- 成功したビルド成果物のパス:
target/<project-name>-1.0.0-SNAPSHOT-mule-application.jar - インテグレーションの内容を説明する一文(例:「S3 を 5 秒ごとにポーリングし、新しいオブジェクトのイベントを JMS キューに送信します」)。
- ユーザーが入力する必要のある
config.yamlのキー(認証情報、バケット名、キュー名)— 短い箇条書きリストにしてください。これは、ディスク上では確認できない唯一の情報です。
次のものは含めないでください:「実装済み機能」の詳細なセクション、秘匿化した JSON ペイロードの例、「次のステップ」(ユーザーは準備ができたらデプロイします)、要約表。
ベストプラクティス
1. 動的なコネクターバージョン。 完全な要件については、ステップ 3 の「バージョンの信頼できる情報源のルール」を参照してください。
- ✅ フェーズ 1:
get_latest_connector.mjs mule-salesforce-connector sfdc→ 一覧表示 →pick_connector.mjs sfdc <gav>→tmp/connector-choices/sfdc.jsonにドラフトを作成 - ✅ フェーズ 2:
commit_connectors.mjs(ステップ 8 の最初のアクション)→dx mule project create --dependencies文字列にはbuild_deps.mjsを使用するか、別の場所で単一の GAV を使う場合はbuild_gav.mjs tmp/connector-versions/<name>.jsonを使用 - ❌ ハードコードされた値:
com.mulesoft.connectors:mule-salesforce-connector:10.20.0 - ❌
references/connector-catalog.mdからの貼り付け(これはスナップショットのみのため、情報が古くなります) - ❌ GAV に検索語だけを指定:
salesforce
2. メタデータ駆動の XML 生成。 XML を手動で記述しないでください。必ず operation-detail、config-detail、source-detail のメタデータを使用してください。
attributes→ タグの XML 属性(attributeNameをそのまま使用)childElements→ ネストされた XML 要素(タグにはprefix:elementNameを使用)required: trueの属性と子要素をすべて必ず含めてください- 特に必要でない限り、オプションの項目は省略できます
description→ パラメーターの機能を把握するために使用allowedValues→ 値を制限defaultValue→ 許容できる場合は省略
3. 毎回、システム専用コネクターを最初に検索します。 HTTP にフォールバックする前に、必ず Exchange で専用コネクターを検索してください。ここでいう「前に」とは文字どおり先に検索するという意味であり、「判断を書き込む前に」という意味ではありません。このスキルの規律では、tmp/connector-choices/ にあるフェーズ 1 のドラフト(またはコミット後に tmp/connector-versions/ に固定されたコネクター)だけが「システム X は対応済み」と宣言する根拠になります。また、ヘルパースクリプトが終了コード 1 で終了したことだけが、「専用コネクターがないため、HTTP にフォールバックする」と宣言する根拠になります。
4. 生成前にメタデータを検証します。 機能には describe-connector を、正確な仕様には config-detail/operation-detail/source-detail を使用してください。
一般的な統合パターン
#1 HTTP API → クエリ → レスポンス: http:listener → salesforce:query → ee:transform → response(コンポーネント:HTTP + Salesforce/データベース)
#2 スケジュール済み同期 → クエリ → 変換 → 通知: scheduler → salesforce:query → ee:transform → slack:post-message(コンポーネント:スケジューラー + Salesforce + Slack)
#3 スケジュール済み同期 → クエリ → 変換 → バッチ挿入: scheduler → query → ee:transform → foreach → db:insert(コンポーネント:スケジューラー + ソースシステム + データベース)
#4 イベントリスナー → 変換 → ダウンストリームシステム: <connector>:<event-source> → ee:transform → target-connector operation(コンポーネント:ネイティブリスナーを備えたソースシステム + ターゲットシステム)。このパターンは、ソースコネクタが sources[] に実際のイベントソースを公開している場合に最適です。スケジューラーでポーリングするのではなく、そちらを使用してください。
トラブルシューティング
JAVA_HOME が設定されていない場合: export JAVA_HOME=$(/usr/libexec/java_home -v 11)
anypoint-cli-v4 が見つからない場合: npm install -g @mulesoft/anypoint-cli-v4
DX プラグインが見つからない場合: npm install -g @salesforce/anypoint-cli-dx-mule-plugin
コネクタが見つからない場合: スペルを確認してください · mule-<name>-connector と mule4-<name>-connector を試してください · Mule 4 との互換性を確認してください。
誤ったコネクタが選択された場合: 具体的な検索語を使用してください(http ではなく mule-http-connector)。scripts/get_latest_connector.mjs はトークンの重複度でスコアを付け、少なくとも1つのトークンが一致する必要があります。無効な検索ではランダムな結果を返さず、終了コード 1 で終了します。
ランタイムパスが必要な場合: dx mule describe-connector または関連コマンドを初めて使用すると、ランタイムの場所を尋ねられます。パスは ~/.mule-dx/config.json に保存されます。
データベースドライバーが見つからない場合: Step 6b で tmp/connector-choices/db-driver.json が記録されていない場合は、Step 6b に戻って選択してください(プロバイダーが generic/data-source/derby の場合はプロンプトが表示されます)。サイドカーファイルが存在するのに pom.xml にエントリがない場合は、Step 9 に戻ってください。このファイルを読み取り、各エントリを <dependency> と <sharedLibrary> のペアとして適用します。Step 9 でドライバーの GAV を推測してはいけません。
The mule application does not contain the following shared libraries: [<artifactId>:<groupId>]: <dependency> ブロックはありますが、mule-maven-plugin 内の対応する <sharedLibrary> ブロックがないか、groupId/artifactId が一致していません。各ドライバー依存関係には両方が必要です。Step 9 を参照してください。
Derby ドライバーの構成: references/jdbc-drivers.md を参照してください。Derby 10.15 以降は複数のアーティファクトに分割されているため(埋め込みの場合は derby + derbyshared + derbytools、ネットワーククライアントの場合は derbyclient + derbyshared)、<sharedLibrary> リストには1つではなく複数のエントリがあります。
クイックリファレンス
以下の <skill-dir> は、「skill is now active」メッセージで指定された絶対パスです。一貫して使用してください。相対パス ../scripts/... を組み立ててはいけません。
# Step 1: validate toolchain (CLI, DX plugin, Java 11+, Mule runtime presence) - Validation-only
node <skill-dir>/scripts/validate_prerequisites.mjs
# Step 3: connector search — list, decide, draft (one loop per system; search
# EVERY named system including mid-market SaaS; don't pre-judge as "no connector")
node <skill-dir>/scripts/get_latest_connector.mjs <search-term> [<nickname>] # prints ranked GAVs to stdout
# ... agent reads list, decides (or AskUserQuestion for real variant ambiguity), then:
node <skill-dir>/scripts/pick_connector.mjs <nickname> <groupId:assetId:version> # drafts to tmp/connector-choices/
# Step 4: describe connectors (Phase 1 — wrapper saves JSON + echoes sources[] digest)
node <skill-dir>/scripts/describe_connector.mjs <nickname> # one per connector
# Step 6: connection-provider detail (Phase 1 — also cached for Phase 2).
# Flag semantics: --name = connection provider, --config-name = config name.
GAV_A="$(node <skill-dir>/scripts/build_gav.mjs tmp/connector-choices/a.json)"
NODE_NO_WARNINGS=1 anypoint-cli-v4 dx mule describe-connector --connector "$GAV_A" \
--type connection-provider --name <prov> --config-name <name> --output json \
> tmp/connector-metadata/a-config.json
# Step 8: promote drafts to pinned versions, then create the real project (Phase 2)
node <skill-dir>/scripts/commit_connectors.mjs # tmp/connector-choices/ → tmp/connector-versions/
MULE_VERSION=$(jq -r '.mule_version' tmp/mule-dev-env.json)
NODE_NO_WARNINGS=1 anypoint-cli-v4 dx mule project create <name> \
--group-id com.example \
--mule-version "$MULE_VERSION" \
--dependencies "$(node <skill-dir>/scripts/build_deps.mjs)" \ # reads every tmp/connector-versions/*.json pin
--skip-environment # scratch projects don't need environment resolution
node <skill-dir>/scripts/write_mule_artifact_env.mjs <name> # align mule-artifact.json minMuleVersion/javaSpecificationVersions
# Step 10: OAuth → HTTP defensive check (only when Step 6 chose OAuth/JWT/auth-code
# or the trigger is HTTP Listener)
node <skill-dir>/scripts/maybe_add_http_connector.mjs --project ./<name> "<provider1>" "<provider2>"
# Step 13: operation / source details (Phase 2 — wrapper saves JSON + caches errorTypes)
node <skill-dir>/scripts/describe_connector.mjs <nickname> --type operation --name <op>
node <skill-dir>/scripts/describe_connector.mjs <nickname> --type source --name <src>
# Step 16: pre-mvn validation — error-type whitelist + namespace↔dep parity + XSD shape
node <skill-dir>/scripts/validate_before_build.mjs ./<project>