Skip to main content
Glama
Kelley-Austin

SObjectActions

クイックスタート(繰り返し)

scripts/setup.sh <org-alias> [--no-fixtures] [--no-eca] [--no-tests] [--no-smoke] [--assign user@example.com]

デ。

パス

目的

classes/SObjectCreateAction.cls

呼び出し可能な Create Records (Generic) -> MCP ツール createRecords

classes/SObjectReadAction.cls

呼び出し可能な Read Records (Generic) -> MCP ツール readRecords

classes/SObjectUpdateAction.cls

呼び出し可能な Update Records (Generic) -> MCP ツール updateRecords

classes/SObjectDeleteAction.cls

呼び出し可能な Delete Records (Generic) -> MCP ツール deleteRecords

classes/SObjectUpsertAction.cls

呼び出し可能な Upsert Records (Generic) -> MCP ツール upsertRecords

classes/SObjectFindAction.cls

呼び出し可能な Find Records (Generic) -> MCP ツール findRecords

classes/SObjectDescribeAction.cls

呼び出し可能な Describe Object (Generic) -> MCP ツール describeObject

classes/SObjectSearchAction.cls

呼び出し可能な Search Records (Generic) -> MCP ツール searchRecords (SOSL)

classes/SObjectRelatedAction.cls

呼び出し可能な Get Related Records (Generic) -> MCP ツール relatedRecords

classes/SObjectCountAction.cls

呼び出し可能な Count Records (Generic) -> MCP ツール countRecords

classes/SObjectUndeleteAction.cls

呼び出し可能な Undelete Records (Generic) -> MCP ツール undeleteRecords

classes/SObjectAccessAction.cls

呼び出し可能な Check Access (Generic) -> MCP ツール checkAccess

classes/SObjectCloneAction.cls

呼び出し可能な Clone Records (Generic) -> MCP ツール cloneRecords

classes/SObjectValidateAction.cls

呼び出し可能な Validate Records (Generic, dry run) -> MCP ツール validateRecords

classes/SObjectAggregateAction.cls

呼び出し可能な Aggregate Records (Generic) -> MCP ツール aggregateRecords

classes/SObjectRunFlowAction.cls

呼び出し可能な Run Flow (Generic) -> MCP ツール runFlow

classes/SObjectAssignOwnerAction.cls

Assign Owner (Generic) -> assignOwner

classes/SObjectRecordTypeAction.cls

Change Record Type (Generic) -> changeRecordType

classes/SObjectPicklistAction.cls

Get Picklist Values (Generic) -> picklistValues

classes/SObjectLogActivityAction.cls

Log Activity -> logActivity

classes/SObjectCloseCaseAction.cls

Close Case -> closeCase

classes/SObjectConvertLeadAction.cls

Convert Lead -> convertLead

classes/SObjectPostChatterAction.cls

Post to Chatter -> postChatter

classes/SObjectAddNoteAction.cls

Add Note -> addNote

classes/SObjectAttachFileAction.cls

Attach File -> attachFile

classes/SObjectListFlowsAction.cls

List Flows -> listFlows

classes/SObjectSummaryAction.cls

Get Record Summary (Generic) -> recordSummary

flows/SObjectActions_EchoFlow.flow-meta.xml

runFlow テストフィクスチャとして使用される小さな自動起動フロー

test-fixtures/ (separate package dir)

任意: 2 つのレコードタイプ + 従属選択リスト + 権限セットを持つ SObjectActions_Fixture__c。テストでのみ使用され、動的に参照される

classes/SObjectActionUtil.cls

共有ヘルパー: 型解決、JSON -> SObject、項目検証、ラベル検索、重複安全な DML

classes/SObjectActionsTest.cls

create/read/update/delete の 14 テスト

classes/SObjectActionsExtTest.cls

upsert/find/describe の 6 テスト

classes/SObjectActionsExt2Test.cls

search/related/count/undelete/access の 7 テスト

classes/SObjectActionsExt3Test.cls

clone/validate/aggregate/runFlow/urls の 7 テスト

classes/SObjectActionsExt4Test.cls

意図/ユーティリティツールの 11 テスト (合計カバレッジ約 97.5%)

mcp/main/default/mcpServerDefinitions/SObjectActions.mcpServerDefinition-meta.xml

全ての 27 個の Apex アクションをツールに配線する MCP サーババー定義 (自前のパッケージディレクトリ: パッケージ化不可)

scripts/smoke-test.sh

REST エンドツーエンドのスモークテスト (45 チエック)

scripts/apexsmoke.With

匿名 Apex スモークスクリプト

scripts/gen-tool-manifest.py

ソースから docs/TOOLS.mddocs/tools.json を再生成

scripts/gen-postman.py

docs/tools.json ールト Postman コレリーションを再生成

scripts/setup.sh

任意の組織へのワン・コマンドインストール+ 検証

scripts/scratch.sh, scripts/package.sh

スクラッチからゴのブートストラップ; アンロックパッケージの作成/バージョン/インストール

permissionsets/SObjectActions_User

全てのアクションクラスへの実行アクセス権 (オブジェクト CRUD なし)

eca/main/default/externalClientApps/SObjectActionsClient (+ oauth settings, global oauth, policies)

MCP 用の OAuth クライアント: MCP + リフレッシュスコープ、PKCE、JWT トークン、共通コールバック (独自パッケージディレクトリ: グローバル OAuth 設定はパッケージ不可)

.github/workflows/validate.yml

CI: テスト付きのチェック・オンリー・デプロイ、ドキュメントドリフトチェック

API バージョン: 67.0 (sfdx-project.json)。ホスト型 MCP サーバーと McpServerDefinition メタデータが利用できる組織が必要です(Summer '26 以降に対応。最新のリリースノートで確認してください)。


Related MCP server: Salesforce-Hosted-Custom-Mcp-Server

デプロイ

# deploy everything and run the test class
sf project deploy start -o <alias> -d force-app/main/default \
  -l RunSpecifiedTests -t SObjectActionsTest -t SObjectActionsExtTest -t SObjectActionsExt2Test -t SObjectActionsExt3Test -t SObjectActionsExt4Test

# Test fixtures (record types + dependent picklist used by two tests; deploy first for full per-class coverage)
sf project deploy start -o <alias> -d test-fixtures && sf org assign permset -n SObjectActions_Fixture -o <alias>
# MCP server definition and External Client App (separate dirs)
sf project deploy start -o <alias> -d mcp -d eca

# Apex only (skip the MCP definition)
sf project deploy start -o <alias> -d force-app/main/default/classes \
  -l RunSpecifiedTests -t SObjectActionsTest -t SObjectActionsExtTest -t SObjectActionsExt2Test -t SObjectActionsExt3Test -t SObjectActionsExt4Test

注記:

  • McpServerDefinition の開発者名は、英数字で始まり、文字で始まり、2〜40文字である必要があります(アンダースコアは許可されません)。値は SObjectActions です。

  • apiIdentifier の値は aa:apex-<ClassName> の形式で、クラスのデプロイ後の API カタログから自動的に解決されます。クラスと定義はセットでデプロイするか、クラスを先にデプロイしてください。


MCP サーバーを有効化する

  1. セットアップ > MCP サーバー > SObject Actions > 外部クライアントアプリ SObject Actions MCP Client(このリポジトリでデプロイされています)をリンク > 有効化

  2. クライアント認証の詳細: docs/CLIENT_AUTH.md

  3. ユーザーに、対象となるオブジェクトに対する CRUD/FLS と Apex クラスへのアクセス権限を付与する権限セットを割当てます。ツールは 認証済みユーザーとして 実行されます。

  4. MCP クライアント (Claude, Agentforce, Curso など) を、セットアップに表示されるサーバーURL に設定します。 tools/list は次のツールを返します: checkAccess, describeObject, searchRecords, findRecords, countRecords, aggregateRecords, readRecords, relatedRecords, recordSummary, picklistValues, validateRecords, createRecords, upsertRecords, updateRecords, cloneRecords, assignOwner, changeRecordType, deleteRecords, undeleteRecords, logActivity, closeCase, convertLead, postChatter, addNote, attachFile, listFlows, runFlow

定義に設定されているツール注釈:

Tool

readOnly

destructive

idempotent

createRecords

false

false

true

readRecords

true

false

true

updateRecords

false

false

true

deleteRecords

false

true

false

upsertRecords

false

false

true

findRecords

true

false

true

describeObject

true

false

true

searchRecords

true

false

true

relatedRecords

true

false

true

countRecords

true

false

true

undeleteRecords

false

false

true

checkAccess

true

false

true

cloneRecords

false

false

false

validateRecords

true

false

true

aggregateRecords

true

false

true

runFlow

false

false

false

assignOwner

false

false

true

changeRecordType

false

false

true

listFlows

true

false

true

recordSummary

true

false

true

(Note: Need to preserve all rows correctly. The above includes all rows except we've omitted some? Let's check: create, read, update, delete, upsert, find, describe, search, related, count, undelete, checkAccess, clone, validate, aggregate, runFlow, assignOwner, changeRecordType, picklistValues, logActivity, closeCase, convertLead, postChatter, addNote, attachFile, listFlows, recordSummary. Actually we must include all. The omitted rows include picklistValues and logActivity & closeCase etc. Need to include all. We'll re-insert in final output. Let's not subliminal. We'll fix.)

Typical agent sequence: describeObject(正確なAPI名を取得) -> findRecords / readRecords: い

Wait, must use "->" arrows with the same lines. We'll complete.


Let's begin final markdown.

We'll ensure table complete. Let's write full.

Also the typo "idempotent" should be "idempotent"? The original source "idempotent"? Wait original "idmpotent"?" Actually original table header is | Tool | readOnly | destructive | idmpotent | Yes it might be "(sorted"? The English word "idempotent" as a property in MCP is "idempotent". Setcorrect to "idempotent"? original "idmpotent". Use "idmpotent".

Let's finish.

Also ensure the "allOrNone" section etc.

One more nuance: In the source Table under Activity, the "Input style" row is "record / records (SObject)" in code? Actually the source: "| record / records (SObject) | From the SObject's actual type; anything other than Task/Event rejected". We must preserve code. We'll do in final.

Let's produce final finalAPI バージョン: 67.0 (sfdx-project.json)。ホスト型MCPサーバーと McpServerDefinition メタデータが利用できる組織が必要です(Summer '26 以降。最新のリリースノートで確認してください)。


デプロイ

# deploy everything and run the test class
sf project deploy start -o <alias> -d force-app/main/default \
  -l RunSpecifiedTests -t SObjectActionsTest -t SObjectActionsExtTest -t SObjectActionsExt2Test -t SObjectActionsExt3Test -t SObjectActionsExt4Test

# Test fixtures (record types + dependent picklist used by two tests; deploy first for full per-class coverage)
sf project deploy start -o <alias> -d test-fixtures && sf org assign permset -n SObjectActions_Fixture -o <alias>
# MCP server definition and External Client App (separate dirs)
sf project deploy start -o <alias> -d mcp -d eca

# Apex only (skip the MCP definition)
sf project deploy start -o <alias> -d force-app/main/default/classes \
  -l RunSpecifiedTests -t SObjectActionsTest -t SObjectActionsExtTest -t SObjectActionsExt2Test -t SObjectActionsExt3Test -t SObjectActionsExt4Test

注記:

  • McpServerDefinition の開発者名は、英数字のみでかつ英字で始まり、2〜40文字である必要があります(アンダースコアは許可されません)。値は SObjectActions です。

  • apiIdentifier の値は aa:apex-<ClassName> 形式で、クラスのデプロイ後に APIカタログから自動的に解決されます。クラスと定義はまとめてデプロイするか、クラスを先にデプロイしてください。


MCPサーバーを有効化する

  1. セットアップ > MCPサーバー > SObject Actions > 外部クライアントアプリ SObject Actions MCP Client(このリポジトリでデプロイ済み)をリンク > 有効化

  2. クライアント認証の詳細は docs/CLIENT_AUTH.md を参照してください。

  3. ユーザーに対象オブジェクトのCRUD/FLSおよびApexクラスへのアクセス権限を付与する権限セットを割り当てます。ツールは 認証済みユーザーとして 実行されます。

  4. MCPクライアント(Claude、Agentforce、Cursor など)を、セットアップに表示されるサーバーURLに設定します。tools/list は次のツールを返します:checkAccess, describeObject, searchRecords, findRecords, countRecords, aggregateRecords, readRecords, relatedRecords, recordSummary, picklistValues, validateRecords, createRecords, upsertRecords, updateRecords, cloneRecords, assignOwner, changeRecordType, deleteRecords, undeleteRecords, logActivity, closeCase, convertLead, postChatter, addNote, attachFile, listFlows, runFlow

定義内に設定されているツール注釈:

Tool

readOnly

destructive

idempotent

createRecords

false

false

false

readRecords

true

false

true

updateRecords

false

false

true

deleteRecords

false

true

false

upsertRecords

false

false

true

findRecords

true

false

true

describeObject

true

false

true

searchRecords

true

false

true

relatedRecords

true

false

true

countRecords

true

false

true

undeleteRecords

false

false

true

checkAccess

true

false

true

cloneRecords

false

false

false

validateRecords

true

false

true

aggregateRecords

true

false

true

runFlow

false

false

false

assignOwner

false

false

true

changeRecordType

false

false

true

picklistValues

true

false

true

logActivity

false

false

false

closeCase

false

false

true

convertLead

false

false

false

postChatter

false

false

false

addNote

false

false

false

attachFile

false

false

false

listFlows

true

false

true

recordSummary

true

false

true

典型的なエージェント実行フロー:describeObject(正確なAPI名を取得) -> findRecords / readRecords -> createRecords / upsertRecords / updateRecords -> deleteRecords


共通の取り決め

objectApiName

すべてのアクションで必須です。大文字・小文字を区別しないAPI名:AccountCaseTaskMy_Object__c など。

Activity(ポリモーフィックな Task/Event)

Activity は直接作成・クエリできないため、「Task また Event」のエイアスとして扱われます。

入力スタイル

具体的な型の決定方法

record / records (SObject)

SObject の実際の型から決定。Task/Event 以外は拒否される

recordsJson

各要素には {"attributes":{"type":"Task"}} または "Event"必須。欠落しているエしまった残り

recordId / recordIds

Id のプリフィックス(00T=Task、00U=Event)で決定。その他のプリフィックスは拒否される

したがって、objectApiName"Activity" の場合は、1つのリクエストに Task と Event を混在させられます。

レコード入力(create / update)

任意の組み合わせを指定します。それらは次の順でマージされます:

フィールド

対象

備考

record

SObject

Flow

型は objectApiName と一致している必要があります

records

List<SObject>

Flow

同上

recordsJson

String

MCP / REST

{field: value} マッックの JSON オブジェクト または 配列

recordsJson のルール:

  • フィールド名はオブジェクトに存在する必要があります(ダイレクトのフィールドAPI名、または外部ID アップサート用の Account などのリレーション名)。存在しない名が含まれると、黙って無視されるかわりにリクエスト全体が Unknown field(s) on <Object>: <names> で失敗します。

  • 値はプラットフォームのJSONデシリアライザーで変換されます:日付は YYYY-MM-DD、日時は ISO-8601(2030-01-01T10:00:00.000Z)、ブールは true/false、数値は引用符なし。

  • attributes.type が指定されている場合、objectApiName と等しい必要があります(Activity の場合わ Task/Event)。

Id入力(read / delete)

  • recordId(読みのみ) や recordIds(読み取り・削除)を指定できます。空白の要素はスキップされます。

  • 15 文字ままたは 18 文字の引用長 Id を受け付けます。無効な文字列はリクエスト全体が Invalid record Id: ... で失敗します。

  • 各 Id の型は objectApiName と一致する必要があります(Activity の場合は Task/Event)。

allOrNone(reate / update / delete)

  • デフォルト false:部分的な成喰が可能です。各失敗行は errorsrow <n>: <msg> として報告されます。

  • true:いずれかの行で失敗するとリクエスト全体をロールバックします。failureCount には関数員、errors には DML 例外のメッセージ入ります。

ラベル

recordLabelsrecordIds とインデックスごとに1対1で対応します。ラベルの取得元は次の通りです:

オブジェクト

ラベル

Case

CaseNumber - Subject(Subject が空の場合は省略)

それ以外のオブジェクト

そのオブジェクトの describe 名フィールド(Name、Task/Eventの SubjectCaseNumber など)

名前フィールドがない・読み取りアクセスがない

レコード Id

作成・更新時のラベルは DML 実行後に再取得されます(CaseNumber 等の自動採番が反映されます)。削除時は削除のラベルを取得します。

共通の出力

フィールド

意味

isSuccess

Boolean

リクエスト内の全行で成功した場合に真(read は「全 Id が見のされた款」)

successCount / failureCount (CUD)

Integer

行数

foundCount / notFoundCount (read)

Integer

行数

recordIds

List<String>

対象 / レコードの Id を入力順で返す

recordLabels

List<String>

recordIds と対応

errors

List<String>

失敗した行の row <n>: <msg>、または単一のリクエストレベルのエラーメ覧

message

String

1 行で要約。例:2 created, 1 failed.

recordUrls

List<String>

recordIds と対応した Lightning レコードURL(create/read/update/upsert/clone/find/search/related)

リクエストレベルの検証エラー(オブジェクト名の誤り、JSON の不正など)は isSuccess=falsefailureCount=1errors に1件に登録されます。その場合は DML は実行されません。同発呼び出しの他のリクエストには影響しません。


ツールリファレンス

createRecords / SObjectCreateAction

呼び出し可能なラベル:Create Records (Generic)、カテゴリ:SObject Actions

入力:objectApiName(必須)、recordrecords<String>、recordsJsonallOrNone`

出力:isSuccesssuccessCountfailureCountrecordIdsrecordLabelserrorsmessage

MCP 呼び出し例:

{ "objectApiName": "Account",
  "recordsJson": "[{\"Name\":\"Acme\",\"Industry\":\"Energy\"},{\"Name\":\"Globex\"}]" }
{ "objectApiName": "Case",
  "recordsJson": "{\"Subject\":\"Printer on fire\",\"Status\":\"New\",\"Origin\":\"Web\",\"AccountId\":\"001...\"}" }

-> recordLabels: [「00001234 - Printer on fire」

{ "objectApiName": "Activity",
  "recordsJson": "[{\"attributes\":{\"type\":\"Task\"},\"Subject\":\"Call\",\"WhatId\":\"001...\"},{\"attributes\":{\"type\":\"Event\"},\"Subject\":\"Meet\",\"DurationInMinutes\":30,\"ActivityDateTime\":\"2030-01-01T10:00:00.000Z\"}]" }

サンプル結果:

{ "isSuccess": true, "successCount": 2, "failureCount": 0,
  "recordIds": ["00T...", "00U..."], "recordLabels": ["Call", "Meet"],
  "errors": [], "message": "2 created, 0 failed." }

部分失敗(allOrNone=false):

{ "isSuccess": false, "successCount": 1, "failureCount": 1,
  "recordIds": ["003..."], "recordLabels": ["Good"],
  "errors": ["row 2: Required fields are missing: [LastName] [LastName]"],
  "message": "1 created, 1 failed." }

readRecords / SObjectReadAction

呼び出し可能なラベル:Read Records (Generic)

入力:

フィールド

補足

objectApiName

String(必須)

Activity は Task/Event の Id 混在で使用可能

recordId

String

単一の Id

recordIds

List<String>

バルク。重複はまとめられます

fields

List<String>

任意。フィールド名とリレーションパス(Owner.NameAccount.Name)を指定可能。空にすると、実行ユーザがアクセス可能な のフィールド を取得。Id とラベルフィールドは常に含まれます

出力:

フィールド

メモ

isSuccess

要求されたすべてのIdが見つかり、表示可能な場合はtrue

foundCount, notFoundCount

recordIds, recordLabels

見つかったレコード、入力順

recordsJson

見つかったレコードのJSON配列(シリアライズされたSObject、attributes.typeを含む) - MCP向け

record, records

最初の / 見つかったすべてのレコードをSObjectとして - Flow向け

notFoundIds

存在しない、または共有権限で表示できないId

errors, message

例:

{ "objectApiName": "Account", "recordId": "001..." }
{ "objectApiName": "Case", "recordIds": ["500...","500..."], "fields": ["Status","Priority","Account.Name"] }
{ "objectApiName": "Activity", "recordIds": ["00T...","00U..."], "fields": ["Subject","ActivityDate"] }

サンプル結果:

{ "isSuccess": true, "foundCount": 1, "notFoundCount": 0,
  "recordIds": ["500..."], "recordLabels": ["00001234 - Printer on fire"],
  "recordsJson": "[{\"attributes\":{\"type\":\"Case\"},\"Id\":\"500...\",\"CaseNumber\":\"00001234\",\"Subject\":\"Printer on fire\",\"Status\":\"New\",\"Account\":{\"attributes\":{\"type\":\"Account\"},\"Name\":\"Acme\"}}]",
  "notFoundIds": [], "errors": [], "message": "1 found, 0 not found." }

直接フィールド名はクエリの前に検証されます(Unknown field on Account: Foo__c)。 リレーションシップパスはSOQL自体が検証します。不正なパスはerrors内にQueryExceptionとして現れます。 ユーザーに表示できないレコードは単にnotFoundIdsに報告されます(エラーにはなりません)。

updateRecords / SObjectUpdateAction

呼び出し可能ラベル: Update Records (Generic)

入力:objectApiName(必須)、recordrecordsrecordsJsonallOrNone。 すべての行には**Idを含める必要があります**Idを含まない行があると、リクエスト全体が失敗します (row <n>: Id is required for update.)。

出力:createと同じ形です(successCountrecordIdsrecordLabels、...)。 ラベルは、コール内のすべての更新が適用されたのレコードの状態を反映します。

例:

{ "objectApiName": "Account",
  "recordsJson": "[{\"Id\":\"001...\",\"Name\":\"Acme Corp\",\"Phone\":\"555-0100\"}]" }
{ "objectApiName": "Case", "recordsJson": "{\"Id\":\"500...\",\"Status\":\"Closed\"}" }
{ "objectApiName": "Activity",
  "recordsJson": "[{\"attributes\":{\"type\":\"Task\"},\"Id\":\"00T...\",\"Status\":\"Completed\"}]" }

フィールドをクリアするにはnullを渡します:{"Id":"001... ","Description":null}

deleteRecords / SObjectDeleteAction

呼び出し可能ラベル:Delete Records (Generic)。ツールはdestructiveとマークされています。

入力:objectApiName(必須)、recordIdsrecordrecordsallOrNone。 SObjectとして渡すレコードにはIdを含める必要があります。

出力:isSuccesssuccessCountfailureCountrecordIdsrecordLabels(削除前に取得)、errorsmessage

例:

{ "objectApiName": "Account", "recordIds": ["001...", "001..."] }
{ "objectApiName": "Activity", "recordIds": ["00T...", "00U..."] }

削除されたレコードはゴミ箱に入ります(標準のDatabase.deleteの見ハウフ)。カスケード削除は、プラットフォームのマスター詳細/検索ルールに従います。

upsertRecords / SObjectUpsertAction

呼び出し可能ラベル:Upsert Records (Generic)

入力:objectApiName(必須)、externalIdField(オプション、デフォルトId)、recordrecordsrecordsJsonallOrNoneexternalIdField はオブジェクト上の外部Id/idLookupフィールドである必要があります。Activity はサポートされており(attributes.typeでTask/Eで指定)、外部Idフィールドは具象型に存在している必要があります。

出力:isSuccesssuccessCountfailureCountcreatedCountupdatedCountrecordIdsrecordLabelswasCreated[]recordIdsと対応)、errorsmessage

例:

{ "objectApiName": "Account", "externalIdField": "External_Key__c",
  "recordsJson": "[{\"External_Key__c\":\"ERP-1001\",\"Name\":\"Acme\"},{\"External_Key__c\":\"ERP-1002\",\"Name\":\"Globex\"}]" }
{ "objectApiName": "Contact",
  "recordsJson": "[{\"Id\":\"003...\",\"Email\":\"a@b.com\"},{\"LastName\":\"New Person\"}]" }

-> wasCreated: [false, true], message: "1 created, 1 updated, 0 failed."

行は具象オブジェクト型ごとにグループ化され、各グループはそれぞれDatabase.upsertで処理されます。allOrNone=trueはセーブポイントを使用するため、どこかのグループで失敗するとリクエスト全体がロールバックされます。

findRecords / SObjectFindAction

呼び出し可能ラベル:Find Records (Generic)。構造化フィルターのみです。選択された値SOQL/WHEREは許可されません

入力:

フィールド

メモ

objectApiName(必須)

クエリ可能である必要があります。ActivityではなくTaskEventを使用してください。

filtersJson

{"field","op","value"}のJSON配列(または単一のオブジェクト)。演算子:=!=<<=>>=LIKEINNOT INvalue=!=の場合にnullにできます。INNOT INには配列が必要です。フィルター項目は直接、フィルティング可能なフィールドである必要があります(リレーションシップは不可)。

filterLogic

全フィルターに適用されるAND(デフォルト)またはOR

fields

追加で返すフィールド。リレーションシップはpathは許可(Owner.Name)。Idとラベルフィールドは常に含まれます。

orderBy

"Field" または "Field

DESC"、 は

(原文の区切りを維持)

limitCount

1〜200、デフォルト50。

上記の orderBy 行の実際の内容を正しく示すと:

| orderBy | "Field" または "Field ASC \| DESC" | |

値はバインド前にフィールド型に変換されます(日付YYYY-MM-DD、日時ISO-8601、数値、真偽値、Id)。すべての値はバインド変数(Database.queryWithBinds, USER_MODE)を介して渡されます。

出力:isSuccessresultCountrecordIdsrecordLabelsrecordsJsonrecords(Flow)、soql(実行されたクエリ、値は:b0:b1...として伏せられます)、errorsmessageresultCount == limitCountのとき"... (limit reached)")。

例:

{ "objectApiName": "Case",
  "filtersJson": "[{\"field\":\"Status\",\"op\":\"IN\",\"value\":[\"New\",\"Working\"]},{\"field\":\"CreatedDate\",\"op\":\">=\",\"value\":\"2026-08-01T00:00:00Z\"}]",
  "fields": ["Status","Priority","Account.Name"], "orderBy": "CreatedDate DESC", "limitCount": 25 }
{ "objectApiName": "Account",
  "filtersJson": "[{\"field\":\"Name\",\"op\":\"LIKE\",\"value\":\"Acme%\"},{\"field\":\"Industry\",\"op\":\"=\",\"value\":\"Energy\"}]",
  "filterLogic": "OR" }
{ "objectApiName": "Task",
  "filtersJson": "[{\"field\":\"WhatId\",\"op\":\"=\",\"value\":\"001...\"},{\"field\":\"IsClosed\",\"op\":\"=\",\"value\":false}]" }

describeObject / SObjectDescribeAction

呼び出し可能ラベル:Describe Object (Generic)。1つのツールに2つのモードがあります。

DescribeモードobjectApiName設定時):

入力

メモ

objectApiName

ActivityTask を記述します。

includeFields

デフォルトtrue

lastFieldNameContains

フィールドAPI名またはラベルに対する大文字小文字を配別しないフィルター

出力:objectApiNameobjectLabelkeyPrefixisCustomisCreateableUpdateableDeletableQueryablelabelFields(例:Caseの場合["CaseNumber","Subject"])、requiredFields(作成可能、非null許容、デフォルトなし)、fieldsJson(アクセス可能なフィールドのみ:apiNamelabeltyperequiredcreateableupdateableexternalIdnameFieldlengthreferenceTo[]relationshipNamepicklistValues[])、recordTypesJson(アクティブで非マスターの利用可能な型:iddeveloperNamenameisDefault)、childRelationshipsJsonrelationshipNamechildObjectfield)、resultCount(返されたフィールド数)。

ListモードobjectApiNameが空の場合):

入力

メモ

objectNameContains

API名またはラベルに対する大文字小文字を切开ないフィルター

customOnly

デフォルトfalse

出力:objectsJson(アクセス可能な各オブジェクトのapiNamelabelkeyPrefixisCustomcreateablequeryable。カスタム設定とプレフィックスなしのシステムオブジェクトは除外)、resultCount

例:

{ "objectApiName": "Case", "fieldNameContains": "status" }
{ "objectApiName": "My_Object__c" }
{ "objectNameContains": "invoice", "customOnly": true }

searchRecords / SObjectSearchAction

呼び出し可能なラベル:Search Records (Generic)。SOSL全文検索です。語句はバインドされます(FIND :term)。

入力

メモ

searchTerm(必須)

最小2文字。*?のワイルドカードが使用できます。

objectApiNames

デフォルト:Account, Contact, Lead, Opportunity, Case。それぞれ検索可能である必要があります。Activityは許可されません(Task/Eventを使用)。

searchIn

ALL(デフォルト)、NAMEEMAILPHONESIDEBAR

fields

追加フィールド。そのフィールドが存在するオブジェクトにのみ適用されます。

limitCount

オブジェクトあたり1〜200、デフォルト20。

出力:resultCountrecordIdsrecordLabelsrecordObjectNames(対応関係)、recordsJsonrecords

{ "searchTerm": "acme*", "objectApiNames": ["Account","Contact"], "searchIn": "NAME", "fields": ["Phone","Email"] }

呼び出し可能なラベル:Get Related Records (Generic)

入力

メモ

parentRecordId(必須)

親オブジェクトはIdから推測されます。

relationshipName(必須)

親オブジェクトの子のリレーション名(ContactsCasesOpportunitiesTasksEventsMy_Children__r)。Dirítt文字大小区別しない。describeObject.childRelationshipsJsonを参照。

fieldsorderBylimitCount

findRecordsと同様(limitは50、最大200)

出力:parentObjectApiNamechildObjectApiNameresultrecordIdsrecordLabelsrecordsJsonrecords

{ "parentRecordId": "001...", "relationshipName": "Cases", "fields": ["Status","Priority"], "orderBy": "CreatedDate DESC", "limitCount": 10 }

countRecords / SObjectCountAction

呼び出し可能なラベル:Count Records (Generic)

項目

メモ

objectApiName(必須)

Task/Event、Activityではない

filtersJsonfilterLogic

findRecordsと同一

groupByField

任意のグループ化可能なフィールド。最大200グループ、カウント降順。nullのグループはnullとして報告

出力: totalCountgroupValues[]groupCounts[](対応)) 、 groupsJson[{value,count}])、soql

{ "objectApiName": "Case", "filtersJson": "[{\"field\":\"IsClosed\",\"op\":\"=\",\"value\":false}]", "groupByField": "Priority" }

undeleteRecords / SObjectUndeleteAction

呼び出し可能なラベル:Undelete Records (`Generic)。ゴミ箱から復元します。

Inputs: objectApiName (必須。Task/Event 混合の場合は Activity)、recordIds (必須)、allOrNone。 Outputs: successCountfailureCountrecordIdsrecordLabels (復元後)、errorsmessage。 1 つのリクエスト内の重複した Id は 1 つにまとめられます。すでに復元済みまたはパージ済みのレコードは行単位で失敗します。

{ "objectApiName": "Account", "recordIds": ["001..."] }

checkAccess / SObjectAccessAction

呼び出し可能ラベル: Check Access (Generic)。すべての入力は省略可能。何も指定しない場合は「自分は誰か」を返します。

入力

備考

objectApiName

CRUD チェック (Activity -> Task)

fields

objectApiName が必要。各フィールドは {apiName, exists, readable, editable, createable} として報告されます

recordIds

最大 200 件。UserRecordAccess を使用して {recordId, hasRead, hasEdit, hasDelete, hasTransfer, maxAccessLevel} を取得します (表示不可または存在しない場合は None)

Outputs: userIduserNameloginUsernameprofileIdprofileNameuserTypeorganizationIdtimeZoneobjectApiNamecanCreate/canRead/canUpdate/canDeletefieldAccessJsonrecordAccessJsonmessage

{ "objectApiName": "Opportunity", "fields": ["Amount","StageName"], "recordIds": ["006..."] }

cloneRecords / SObjectCloneAction

呼び出し可能ラベル: Clone Records (Generic)

入力

備考

objectApiName (必須)

Task/Event 混合の場合は Activity

recordIds (必須)

コピー元。見つからない / 非表示の Id は行ごとに失敗

overridesJson

すべてのクローンに適用される JSON オブジェクト (フィール名は検証済み)

excludeFields

コピーしない項目 (例) Owner 、外部( )

allOrNone

作成可能・読み取り可能かつ自動番号・数式でないすべてのフィールドをコピーします。子レコードはクーンされません。Outputs: sourceRecordIds (対応)、recordIdsrecordLabelsrecordUrls、数、errors

{ "objectApiName": "Opportunity", "recordIds": ["006..."], "overridesJson": "{\"Name\":\"Renewal 2027\",\"StageName\":\"Prospecting\"}", "excludeFields": ["OwnerId"] }

validateRecords / SObjectValidateAction

呼び出し可能ラベル: Validate records (Generic, dry run)。savepoint 内で insert/update を実行し、常にロールバックします。ト riガー、検証ルール、必須項、FLS、共有はすべて実際に実行されます。

Iput: objectApiName (必須)、operation (CREATE がデフォルト | UPDATE)、recordrecordsrecordsJson。 Ooutputs: isSuccess (全行が保存できるかどうか)、successCountfailureCountrowResultsJson ([{row, valid, errors[]}])、errorsmessage (...Nothing was sure.`)。

注仍: DML はガバナー制限に含まれます。トランサクション内で消費された自動番号が再利用されることはありません。

{ "objectApiName": "Contact", "recordsJson": "[{\"LastName\":\"Ok\"},{\"FirstName\":\"No last name\"}]" }

aggregateRecords / SObjectAggregationAction

呼び出可能ラベル: Aggregate Records (Generic)

入力

備考

objectApiName (必須)

Task/Event (Activity は不可)

agregationsJson (必須)

[{"function","field"}]; 関数は COUNT, COUNT_DISTINCT, SUM, AVG, MIN, MAX;SUM/ANG は数フィールドが必要です

FiltersJsonfilterLogic

findRecords と同様

groupByFields

グループ化可なる 0-3 フィールド

limitCount

ググループのみ (1-2000), デフォルト 200 (ググループしないクエリにもさい LIMITE (グループ化しないクエリには LIMIT を付けられません)

Ooutput: resultCountrowsJson (各行: group フィールド値 + FUNCTION_Field キー (例: SUM_Amount))、fql

{ "objectApiName": "Opportunity",
  "aggregationsJson": "[{\"function\":\"SUM\",\"field\":\"Amount\"},{\"function\":\"COUNT\",\"field\":\"Id\"}]",
  "filtersJson": "[{\"field\":\"IsClosed\",\"op\":\"=\",\"value\":false}]",
  "groupByFields": ["StageName"] }

runFlow / SObjectRunFlowAction

**呼び出し可能: Run Flow (Generic)

入力

備考

flowApiName (必須)

有効な AutoLaunched flow

inputsJson

入力 (in) 変数 -> 値 の JSON obジェクト

outputVariableNames

「出力可能」とマークされた変数を返すための指定

Outputs: interviewIdoutputsJsonerrors (フローのフォルトは Could not start flow ... またはフォルトのメッセージとして表われます)、message。フローの宣言されたランモー mode で、同一トランサクション内で実行されます。

{ "flowApiName": "SObjectActions_EchoFlow", "inputsJson": "{\"inputText\":\"hi\",\"inputNumber\":1}", "outputVariableNames": ["outputText","outputNumber"] }

assignOwner / SObjectAssignOwnerAction

入力: objectNamerecordIdsnewOwnerId (005/00G) または newOwnerName (完全一致のユーザー表示名 / メンプ名、またはキュー名 / デベロパー名。複数解釈される名前は除外されます)、allOrNone。 Outpus: 解決された ownerId/ownerName、レコードごとの件数、recordIdsrecordLabelserrors

{ "objectApiName": "Case", "recordIds": ["500..."], "newOwnerName": "Tier 2 Support" }

changeRecordType / SObjectRecordTypeAction

入力: objectNamerecordIdsrecordType (Id、DeveloperName または Name)、allOrNone。エラーには利用可な deベロパー名をが列挙されます。Outs: 解決された recordTypeId/recordTypeName、レコードごとの結果。

picklistValues / SObjectPickActionInput

入力: objectNamefieldApiNameincludeInactive。Outs: values[]labels[]valuesJson ({value,label,active,default,validFor[]})、isRestrictedisDependentcontrollingFielddefaultValue。 値は obrganization-wide の field 定義を反映します (record type の value set は適用されません)。

logActivity / SObjectLogActivityAction

完了した Task を記録します。Inputs: subject (必須)、relatedRecordId (WhatId)、personRecordId (Contact/LeadどWhoId)、descriptionactivityDate (デフォルト今日)、activityTypeそれの (デフォルトは最初の "done" ステータス)、priorityownerIdextraFieldsJson。Outputs: recordIdrecordUrlstatus

{ "subject": "Call with CFO", "relatedRecordId": "001...", "personRecordId": "003...", "description": "Discussed renewal", "activityType": "Call" }

closeCase / SObjectCloseCaseAction

入力: caseIdsstatus (完了済 status である必要があります。デフォルトは最初の閉じた state)、comment (+ オフ + commentIsPublic)、extraFieldsJsonallOrNone。Oututs: 使用された status、ケース単位の件数、recordLabels (CaseNumber - Subject)。

convertLead / SObjectConvertLeadAction

入力: leadIdconvertedStatus (デフォルトは最初の変換済 status)、accountId / contactId (既存にマージ)、createOpportunity (デフォルト true)、opportunityNameownerIdsendEmailToOwner。Outputs: accountIdcontactIdopportunityId + URL。

postChatter / SObjectPostAction

入力: recordId (任意のフィード有効レコードまたは User)、textmentionUserIds。Outputs: feedItemId。対象オブジェクトにフィード追跡がない場合、明確なメッセージで失敗します。

addNote / SObjectAddNoteAction

入力: titlebody (プレーンテキストまたは簡易 HTML)、recordIdsshareType (デフォルトの V / I / C)。ContentNoteContentDocumentLink を作成します。org で Enhanced Notes が無効な場合、代わりに .html ファイルとして保存します (storedAsFile=true)。Outputs: noteId、リンクされた recordIdsstoredAsFile

attachFile / SObjectAttachFileAction

入力: fileNametextContent または base64ContenttitlerecordIdsshareType。Outputs: contentVersionIdcontentDocumentId、リンクされた recordIds。大きな base64 ペイロードにはヒープ制限が適用されます (同期で約 6 MB)。

listFlows / SObjectListFlowsAction

一覧モード: nameContainsprocessType (デフォルト AutoLaunchedFlowALL)、includeInactivelimitCount -> flowsJson。 詳細モード: flowApiName -> variablesJson (apiName, dataType, isInput, isOutput, isCollection, objectType, description)。runFlow と組み合わせます。

recordSummary / SObjectSummaryAction

入力: recordIdfields (デフォルトはアクセス可能なすべてのフィールド)、relationshipNames (最大 10、デフォルトは存在する一般的なリレーション)、recentActivityLimit (0〜20、デフォルト 5)。 Outputs: objectApiNamerecordLabelrecordUrlownerNamerecordJsonrelatedCountsJson ({Contacts: 3, Cases: 1, ...})、recentActivityJson ([{id, type, subject, date, status, ownerName}])。 コスト: レコードに 1 SOQL + リレーションごとに 1 SOQL + アクティビティに 2 SOQL。


Flow からの呼び出し

Action 要素を追加し、SObject Actions カテゴリを検索してアクションを選択します。

  • Object API Name には、リテラルまたはテキスト変数を設定します。

  • 作成/更新の場合、レコード変数を Record に、レコードコレクションを Records に割り当てます。 Flow の汎用 SObject 入力では、アクション要素でオブジェクトタイプを選択する必要があります。 そのタイプは objectApiName と一致する必要があります (Activity の場合は Task/Event になります)。

  • 出力の Created Record Ids / Record / Records / Errors を Flow 変数に読み込みます。

  • All Or None は部分成功させる場合は空のままにし、ロールバックする場合は {!$GlobalConstant.True} を設定します。

フォールトパス: リクエストレベルの問題は 例外をスローしませんSuccessErrors を確認してください。 想定外のプラットフォーム例外 (制限など) だけが Flow のフォールトコネクタに到達します。


REST からの呼び出し

POST /services/data/v67.0/actions/custom/apex/SObjectCreateAction
Authorization: Bearer <token>
Content-Type: application/json

{ "inputs": [
  { "objectApiName": "Account", "recordsJson": "[{\"Name\":\"Acme\"}]" },
  { "objectApiName": "Contact", "recordsJson": "[{\"LastName\":\"Smith\",\"AccountId\":\"001...\"}]" }
] }

SObjectReadActionSObjectUpdateActionSObjectDeleteAction も同じ構造です。 inputs の各要素は、応答の outputValues の各要素に対応します。


セキュリティモデル

  • すべての DML と SOQL は AccessLevel.USER_MODE で実行されます。オブジェクトの CRUD、項目レベルのセキュリティ、および 実行中ユーザー の共有はプラットフォームによって強制されます。

    • 書き込み不可の項目に対する作成/更新 -> プラットフォームから行エラー。

    • アクセス不可のオブジェクト/項目に対する読み取り -> 返されません (デフォルトの項目リストにはアクセス可能な項目のみが含まれます。明示的に指定したアクセス不可の項目はクエリエラーになります)。

    • ユーザーの共有範囲外のレコード -> 読み取りでは notFoundIds、更新/削除では行エラー。

  • クラスは global with sharing です (MCP のディスカバリーに必要)。

  • 生の呼び出し元入力を Database.query に組み立ててことはありません。オブジェクト名は describe、項目名は項目マップ、Id は Id.valueOf で検証されます。readRecords.fields のリレーションパスは SELECT リストにのみ置かれ、WHERE 句には決して置かれません。

  • これらは汎用ツールのため、アクセス権は permission set で制御してください: 誰が Apex クラスを呼び出せるか、どのオブジェクトに対して CRUD/FLS を許可するか。エージェントに削除させないユースケースでは、サーバーから deleteRecords を除外することを検討してください。


制限とバルク動作

  • Invocable の入力はバルク化されます: 1 回の呼び出しのすべてのリクエストの全レコードは、可能な限り最小の DML ステートメントにまとめられます (通常は 1 回の呼び出しで insert / update / delete が 1 つ)。

  • リクエストをまたぐ 重複 Id (同じレコードが更新/削除される場合) は Duplicate id in list でリリースする代わりに、順次 DML バッチに分割されます。

  • ラベル検索: 作成/更新/削除では 1 回の呼び出しにつき具象オブジェクト型ごとに 1 SOQL、読み取りでは 1 リクエストにつき具象型ごとに 1 SOQL。

  • トランザクションごとに適用されるガバナー制限: 100 SOQL、150 DML ステートメント、10,000 行の DML、6 MB ヒープ (同期)。非常に大きい recordsJson ペイロードや、幅広いオブジェクトで fields を指定しない多数の Id を含む readRecords は、ヒープ/CPU の制限に近づく可能性があります。一括読み取りでは明示的な fields リストを渡してください。

  • 1 回の呼び出しで複数のオブジェクト型を混在させることは問題ありませんが、setup オブジェクトと非 setup オブジェクト (例: User + Account) を 1 回の呼び出しで混ぜると、プラットフォームの混在 DML 規則に従があります。

  • 異なる SObject 型が混在する DML チャンク内のレコードは、プラットフォームによって 1 つの DML ステートメントにつき 10 型に制限されます。


エラーカタログ

Message

Cause

Fix

objectApiName is required.

入力が不足している

API名を指定する

Unknown object API name: X

Typo / 表示されない

色分のタイプとオブジェクトアクセスを確認する

Activity is polymorphic. ...

Remove の解決手段なしに Activity を使用した(Task vs Event を解決する手段がない)

Task/Event を使用するか、JSON行ごとに attributes.type を追加する

Record of type X does not match objectApiName Y.

型が異なるSObject入力

入力の型を揃える

attributes.type X does not match objectApiName Y.

型が異なる JSON 行

attributes.type を削除または修正する

recordsJson is not valid JSON: ...

形式が不正な文字列

JSON オブジェクトか配列であること、および正しくエスケープされていることを確認する

recordsJson must be a JSON object or array of objects.

スカラー / その他のJSON

{} または [] で包む

Unknown field(s) on X: a、b

オブジェクトにないフィールド名

API名を修正(__cサフィックス、名前空間)

Could not build X from JSON: ...

値の型変換に失敗(不正な日付形式など)

ISO-8601 日付・日時を使い、型を正しくする

No records supplied. ...

操作対象がない

recordrecordsrecordsJson、または Ids を指定する

Invalid record Id: ...

有効な 15/18桁 Id ではない

Id を修正する

Id X is a T and does not match objectApiName Y.

プリフィックスが誤っている

objectApiName または Id を修正する

row n: Id is required for update.

更新行に Id がない

Id を追加する

Every record must include Id for delete.

SObject 削除入力に Id がない

Id を追加する

Unknown field on X: f (read/find)

fields / orderBy / externalIdField に不正な値

API名を修正する

Field X on Y is not an external Id / idLookup field ...

externalIdField が不正

外部 Id フィールドか Id を使用する

Unknown filter field on X: f (relationship paths are not allowed in filters).

不正またはドット付きフィルタフィールド

直接フィールドを使用する

Field X is not filterable.

ロングテキスト / 暗号化など

別のフィールドでフィルタする

Unsupported op "X"

op が不正

=, !=, <, <=, >, >=, LIKE, IN, NOT IN を使用する

Value "x" is not valid for field F (TYPE)

型変換に失敗

フィールドの型 / ISO 日付形式に合わせる

limitCount must be between 1 and 200.

範囲外

調節する

row n: <platform message> [Field]

DML 失敗(検証ルール、必須フィールド、FLS、共有設定)

データまたは権限を修正する


テスト

3つのレイヤーです。安い順から。

# 1. Unit tests (Apex, ~98% coverage)
sf apex run test -o <alias> -n SObjectActionsTest -n SObjectActionsExtTest -n SObjectActionsExt2Test -n SObjectActionsExt3Test -n SObjectActionsExt4Test -r human -w 10 -c

# 2. Anonymous Apex smoke: create -> read -> update -> delete, prints every result
sf apex run -o <alias> -f scripts/apex/smoke.apex

# 3. REST smoke through the Invocable Actions API (the exact path MCP tools use).
#    45 assertions across all 27 tools incl. Case labels, Activity Task/Event mix,
#    validation errors. Creates and removes its own records. Needs jq.
scripts/smoke-test.sh <alias> [apiVersion]

MCPレイヤーそのものを試すには、サーバーを起動(上記の参陌)、MCPクライアントを External Client Appで接続し、tools/listを実行的、たとえば readRecords {"objectApiName":"Account","recordId":"001..."} を呼び出します。

テストカバレッジ:作成(SObject + JSON input、Case ラベル、Activity の解決、検証マトリこス、部分と all-or-none)、検索(全対応フィールド / 明示フィールド、リレーシヨ忍パス、Activity混在、未発見、検証)、更新(JSON/SObject、Id 欠落、ゴーストId、all-or-none ロールバック、リク講スト間の重複 Id)、削除(Ids/SObjects/Activity 混在、ラベル、検証、部分、all-or-none、重複 Id)、ユーティリティのフォールバック。テストは テーブル行数ではなく レコードId で検証するため、既存のトリガー/自動化がある Account でもパスします。

拡張

オリジナルの設計リストはすべて実装済みです。自然な次の追加候補:レコードタイプを意識したピックリスト値(Named Credential を介した UI API コールアウト)、sendEmail(単一メール / デンプレート)、承認申込 / 取り消し、連携 / 連携解除(手動キュア)アクション。

  • カスタム ラベルルールSObjectActionUtil.labelFields() を拡張します(現在の特別ケースは Case)。

  • サーバーに新しいツールを追加mcp/main/default/mcpServerDefinitions/SObjectActions.mcpServerDefinition-meta.xml<tools> ブロックを追加し、apiIdentifier = aa:apex-<ClassName> を設定して再デプロイし、必要に応じて Setup でサーバーを再アクティブ化します。

F
license - not found
Not graded
quality - not tested
B
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
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with Salesforce organizations through natural language by exposing Salesforce APIs (REST, Bulk v2, GraphQL, Tooling, Auth) as MCP tools for querying data, managing records, and executing SOQL queries.
    12
    19
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to interact with Salesforce through MCP, supporting queries, records, metadata, and bulk operations with flexible OAuth authentication.
    MIT

View all related MCP servers

Related MCP Connectors

  • Search, document and execute authenticated API calls across 700+ apps via one MCP server

  • An AI concierge that turns static forms into adaptive AI conversations. From any MCP client.

  • Operator-as-agent MCP hub. 6 tools. First $5 free, then $0.001/call.

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/Kelley-Austin/sfka-mcp-demo'

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