mcpField
P
platform-apex-anonymous-run

platform-apex-anonymous-run

github.com/forcedotcom開発1.1k3.2k 回インストール1 日前に更新
リポジトリ

platform-apex-anonymous-run について

Salesforce CLI で匿名 Apex を実行し、コンパイル、実行結果、デバッグログを報告する Salesforce 開発者向けエージェントスキルです。データ変更の可能性を明示し、ロールバック検証や本番組織での確認手順を定めています。

主な機能

  1. 01Salesforce CLI による Apex 実行
  2. 02コンパイルエラーと実行時エラーの区別
  3. 03デバッグログの取得と提示
  4. 04検証スクリプトのセーブポイントとロールバック
  5. 05実行前の対象組織の確認

活用シーン

  1. 01接続済み組織での Apex スニペット実行
  2. 02データ変更をロールバックする検証
  3. 03匿名 Apex のコンパイル・実行エラーの調査

MCP 対応

Bash ツールと Salesforce CLI で実行するよう定めており、Apex の実行に MCP ツールを使うことを明示的に禁止しています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/forcedotcom/sf-skills --skill platform-apex-anonymous-run

インストール後、Claude Code で/platform-apex-anonymous-runを入力して読み込まれたか確認します。

詳細

platform-apex-anonymous-run

接続中の Salesforce 組織に対して sf apex run --file で匿名 Apex を実行し、デバッグログを取得して、コンパイル時と実行時の結果を開発者に説明します。

これは、VS Code の Execute Anonymous Apex(ドキュメントおよび選択範囲)コマンドに相当するエージェント側の機能です。

このスキルは生成ではなく実行を対象としています。.cls/.trigger ファイルを作成する場合は platform-apex-generate を、Apex 単体テストを実行する場合は platform-apex-test-run を使用してください。詳細なデバッグログ分析(ガバナの内訳、SOQL のループ内実行の検出)を行う場合は platform-apex-logs-debug に引き継いでください。


ツールの制限

sf apex run の実行には Bash ツールのみを使用し、スニペットの一時ファイルの作成には Write ツールを使用してください。実行に MCP ツールを使用しないでください。


匿名 Apex は読み取り専用ではありません

匿名 Apex は実行ユーザーの権限で実行され、DML、コールアウト、プラットフォームイベントの呼び出しを実行できます。開発者がそうでないと明示していない限り、実行のたびに書き込みが行われるものとして扱ってください。

  • 検証目的のスクリプト(「これをテストして」の場合に推奨): 本文をセーブポイントとロールバックで囲み、組織の状態が変更されないようにします。

    Savepoint sp = Database.setSavepoint();
    try {
        // ... code under test ...
    } finally {
        Database.rollback(sp);
    }
    
  • 本番組織に関する注意: 解決された <alias> が本番組織を指している場合(sf org display --json にスクラッチ組織やサンドボックスを示す情報がない場合)は、実行前に明確な警告を伝えてください。これは情報提供のみで、自動的にブロックされることはありません。本番環境で破壊的なスクリプトを実行する前には、必ず「はい、実行してください」という明示的な許可を待ってください。

  • 自分で生成しておらず、内容も提示されていない匿名 Apex は絶対に実行しないでください。開発者がスニペットを貼り付けた場合は、実行前にその内容を復唱し、確認してください。


ワークフロー

ステップ 1 — 対象組織を特定する

設定から有効な組織エイリアスを解決します。target-org が設定されている場合、コマンドから --target-org フラグを省略できますが、レポートには使用したエイリアスを必ず記載してください。

sf config get target-org --json

このスキルでは、<alias> は解決されたエイリアスまたはユーザー名を指します。target-org が設定されていない場合は開発者に確認し、暗黙的にデフォルトを使用しないでください。組織が認証されていない場合は、sf org login web で再認証するか、dx-org-switch スキルで組織を切り替えてください。

ステップ 2 — 入力モードを解決する
モード条件アクション
ファイルモード開発者が .apex で終わる既存のパス(または指定した任意のパス)を示す場合sf apex run --file <path> を直接実行します
スニペットモード開発者が会話に Apex コードを貼り付ける場合まず .sfdx/tmp/anon-<unix-ts>.apex に書き込み、その後 sf apex run --file <tmp-path> を実行します

スニペットにインラインフラグではなく一時ファイルを使う理由: 現在の sf apex run CLI がサポートするのは --file(および対話型 stdin)のみです。--apex-code フラグはありません。他のツールでインラインコードがサポートされている場合でも、複数行の Apex をインラインで渡すと、シェルのエスケープ処理で問題が起きやすくなります(文字列リテラル内のシングルクォート、バックスラッシュ、埋め込みの $ など)。任意のスニペットを確実に実行できる方法は、一時ファイルに書き込むことだけです。

変更を加える前に、CLI のフラグを確認してください。

sf apex run --help

サポートされているフラグ(執筆時点):--file/-f、--target-org/-o、--api-version、--json、--flags-dir。フラグを作り出さないでください。依頼された内容が一覧にない場合は、推測せずに開発者に伝えてください。

ステップ 3 — トレースフラグを設定する(有用なログを得るため)

実行ユーザーに対して TraceFlag が有効になっている場合(またはストリーミングテールがアタッチされている場合)に限り、sf apex run はデバッグログを返します。推奨手順は、開発者に別のターミナルでログをテールしてもらうことです。

sf apex tail log --target-org <alias> --color

これにより、実行ユーザーに対して有効期間の短い TraceFlag が自動作成され、匿名 Apex の実行中にログがストリーミングされます。開発者がコピーして貼り付けられるよう、レポートでこの方法について伝えてください。

トレースフラグを設定しない場合でも、sf apex run はコードを実行し、コンパイル時と実行時のステータスを返します。ただし、デバッグログ本文は取得できないか、内容が少なくなります。

ステップ 4 — スニペットモード:一時ファイルを書き込む

貼り付けられたスニペットが入力された場合にのみ適用されます。

mkdir -p .sfdx/tmp
TS=$(date +%s)
# write the snippet content to .sfdx/tmp/anon-${TS}.apex via the Write tool, NOT via shell heredoc

スニペットをそのまま保持するため、エージェントの Write ツールを使用してください(ヒアドキュメントは使用しないでください)。ヒアドキュメントを使うと、内容に追加のシェル展開が適用されます。レポートで、解決した一時ファイルのパスを開発者に伝えてください。実行後に一時ファイルを自動削除しないでください。確認できるよう、.sfdx/tmp/ に残しておきます。.sfdx/ ディレクトリは、慣例的に Git の管理対象外に設定されています。

ステップ 5 — 実行
sf apex run --file <path> --target-org <alias> --json
  • 常に --json を指定してください。人間向けの形式の出力では、コンパイルエラーと実行時エラーが混在します。
  • target-org がすでに設定されている場合は、--target-org を省略できますが、使用したエイリアスを記録してください。
  • コンパイルエラーがある場合、コマンドはゼロ以外の終了コードで終了します。標準出力と解析済みの JSON の両方を取得してください。
ステップ 6 — JSON レスポンスを解析する

sf apex run --json のレスポンスの形式(関連フィールド):

{
  "status": 0,
  "result": {
    "compiled": true,
    "success": true,
    "compileProblem": "",
    "exceptionMessage": "",
    "exceptionStackTrace": "",
    "line": -1,
    "column": -1,
    "logs": "...full debug log text..."
  }
}

判断ツリー:

compiledsuccess意味表示する内容
false—コンパイル失敗compileProblem、line、column、該当するソース行
truefalse実行時例外exceptionMessage、exceptionStackTrace、およびログ末尾
truetrue成功System.debug でスクリプトが出力した内容(logs から抽出)

(トップレベルの)status !== 0 は、CLI 自体のエラー(未認証、ファイルが見つからない、ネットワークエラーなど)を意味します。未加工のエラーを表示して、そこで終了してください。

ステップ 7 — デバッグログを表示する
  • 短いログ(約 200 行未満): フェンス付きコードブロックで囲み、ログ本文をレポートに直接記載してください。
  • 長いログ: ログを .sfdx/tmp/anon-<ts>.log に書き込み、そのパスをレポートしてください。末尾の 30 行を要約として直接記載してください。
  • ログが空、または見つからない場合: 有効な TraceFlag がない可能性があります。ステップ 3 のセットアップに関するヒントを表示し、返されたコンパイル/実行時のステータスをもとに処理を進めてください。

ログに以下のパターンがある場合は強調してください。

パターン重要な理由
LIMIT_USAGE_FOR_NS の行ガバナー消費量のスナップショットです。上限に近い SOQL/DML/CPU の使用を示します
EXCEPTION_THROWN匿名ブロック内で捕捉されなかった例外です
FATAL_ERROR回復不能なエラーです。末尾のブロック全体を表示してください
ループ内の SOQL_EXECUTE_BEGIN が 1 回を超えるループ内 SOQL のヒントです(platform-apex-logs-debug に引き継いでください)
DML_BEGIN の回数が多いDML をまとめていないことを示すヒントです

ここではログ全体の解析を試みないでください。シグナルのみを示し、詳細な分析は platform-apex-logs-debug に引き継いでください。

ステップ 8 — レポートする
Anonymous Apex run: <one-line summary — file or snippet, success or failure>
Org: <alias>  (mode: scratch | sandbox | production)
Source: <file path or temp path for snippet>
Compile: success | <error + line:column>
Runtime: success | <exception type + message>
Limits: <CPU=x/10000ms, SOQL=y/100, DML=z/150>  (only when log includes LIMIT_USAGE_FOR_NS)
Log: <inline | path .sfdx/tmp/anon-<ts>.log>
Rollback: applied | not applied | n/a
Next: <suggested follow-up>

例

例 1 — ファイルモード

"scripts/seed-test-data.apex をデフォルトの組織に対して実行してください。"

  1. sf config get target-org --json から <alias> を解決します。
  2. ファイルが存在することを確認します。存在しない場合は、そこで終了し、file not found を表示します。
  3. sf apex run --file scripts/seed-test-data.apex --target-org <alias> --json を実行します。
  4. JSON を解析します。コンパイル/実行時のステータス、ログ末尾、組織モードを報告します。
  5. 次のように提案します。「これで実データがシードされ、保存せずに確認したい場合は、ロールバック用のラッパーを使用して再実行してください(スニペットモード)。」
例 2 — スニペットモード(読み取りクエリ)

"System.debug([SELECT count() FROM Account]); を実行して、件数を教えてください。"

  1. <alias> を解決します。
  2. スニペットをそのまま提示し、確認します。
  3. スニペットを .sfdx/tmp/anon-<ts>.apex に書き込みます(Write ツール)。
  4. sf apex run --file .sfdx/tmp/anon-<ts>.apex --target-org <alias> --json を実行します。
  5. result.logs を解析し、件数の USER_DEBUG 行を抽出します。
  6. 次のように報告します。「Account の件数 = N。ソース:.sfdx/tmp/anon-<ts>.apex(参照用に保持しています)。」
例 3 — ロールバックによる検証

「この Apex が Contact を正しくアップサートしてから、ロールバックすることをテストしてください。」

  1. <alias> を解決します。本番環境の場合は、実行前に注意を促します。

  2. 開発者のスニペットをラップします。

    Savepoint sp = Database.setSavepoint();
    try {
        // ---- developer snippet begins ----
        Contact c = new Contact(LastName = 'Smoke', Email = '[email protected]');
        upsert c Email;
        System.debug('Upserted: ' + c.Id);
        // ---- developer snippet ends ----
    } finally {
        Database.rollback(sp);
        System.debug('Rolled back savepoint.');
    }
    
  3. .sfdx/tmp/anon-<ts>.apex に書き込み、実行して JSON を解析します。

  4. コンパイル/実行時のステータス、ログに記録されたアップサート済みの Id、Rollback: applied を報告します。


失敗モード

症状原因復旧方法
No authorization information found for ...組織が認証されていない、またはエイリアスが誤っていますsf org list --json を実行します。sf org login web で再認証するか、dx-org-switch を使用します
ENOENT: no such file or directory, open '<path>'.apex ファイルのパスが誤っているか、現在の作業ディレクトリからの相対パスが誤っています絶対パスを確認して再実行します
JSON の compileProblem が空ではないApex のコンパイルエラーですcompileProblem、line、column を表示し、該当行を示して修正方法を提案します
exceptionMessage を含む success: false匿名ブロック内で実行時例外が発生しています例外の種類、メッセージ、スタックを表示し、ガバナーカウントがあれば表示します
成功しているのに logs フィールドが空実行ユーザーに有効な TraceFlag がありません開発者に、別のターミナルで sf apex tail log --target-org <alias> を実行してから再実行するよう伝えます
result がなく status !== 0実行前に CLI、ネットワーク、または認証で失敗しています標準エラー出力をそのまま表示し、むやみに再試行しないでください
未認識のフラグエラーインストール済み CLI と仕様が一致していませんsf apex run --help を再確認し、フラグを推測して追加しないでください

ルール

  • 常に --json を渡してください。
  • <alias> は設定または開発者から取得し、ハードコードしないでください。
  • --apex-code のようなインラインフラグは使用しないでください。現在の CLI ではサポートされておらず、エスケープ処理にも適していません。必ず --file を使用してください。
  • 貼り付けられたスニペットは、実行前に必ず開発者にそのまま返して確認を求めてください。
  • 検証用スクリプトでは、デフォルトで Database.setSavepoint() と Database.rollback() で囲んでください。
  • 本番組織では注意を促してください。ただし、自動的に実行をブロックしないでください。判断は開発者に委ねられています。
  • .sfdx/tmp/ 内の一時ファイルを自動削除しないでください。
  • このスキルは匿名 Apex を実行しますが、.cls/.trigger ファイルの作成、デプロイ、テストは行いません。その場合は platform-apex-generate、デプロイスキル、または platform-apex-test-generate に引き継いでください。
  • ログを詳細に分析する場合は、platform-apex-logs-debug に引き継いでください。

コメント