SObjectActions
クイックスタート(繰り返し)
scripts/setup.sh <org-alias> [--no-fixtures] [--no-eca] [--no-tests] [--no-smoke] [--assign user@example.com]デ。
パス | 目的 |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
| 呼び出し可能な |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| runFlow テストフィクスチャとして使用される小さな自動起動フロー |
| 任意: 2 つのレコードタイプ + 従属選択リスト + 権限セットを持つ |
| 共有ヘルパー: 型解決、JSON -> SObject、項目検証、ラベル検索、重複安全な DML |
| create/read/update/delete の 14 テスト |
| upsert/find/describe の 6 テスト |
| search/related/count/undelete/access の 7 テスト |
| clone/validate/aggregate/runFlow/urls の 7 テスト |
| 意図/ユーティリティツールの 11 テスト (合計カバレッジ約 97.5%) |
| 全ての 27 個の Apex アクションをツールに配線する MCP サーババー定義 (自前のパッケージディレクトリ: パッケージ化不可) |
| REST エンドツーエンドのスモークテスト (45 チエック) |
| 匿名 Apex スモークスクリプト |
| ソースから |
|
|
| 任意の組織へのワン・コマンドインストール+ 検証 |
| スクラッチからゴのブートストラップ; アンロックパッケージの作成/バージョン/インストール |
| 全てのアクションクラスへの実行アクセス権 (オブジェクト CRUD なし) |
| MCP 用の OAuth クライアント: |
| 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 サーバーを有効化する
セットアップ > MCP サーバー >
SObject Actions> 外部クライアントアプリ SObject Actions MCP Client(このリポジトリでデプロイされています)をリンク > 有効化。クライアント認証の詳細:
docs/CLIENT_AUTH.md。ユーザーに、対象となるオブジェクトに対する CRUD/FLS と Apex クラスへのアクセス権限を付与する権限セットを割当てます。ツールは 認証済みユーザーとして 実行されます。
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サーバーを有効化する
セットアップ > MCPサーバー >
SObject Actions> 外部クライアントアプリ SObject Actions MCP Client(このリポジトリでデプロイ済み)をリンク > 有効化。クライアント認証の詳細は
docs/CLIENT_AUTH.mdを参照してください。ユーザーに対象オブジェクトのCRUD/FLSおよびApexクラスへのアクセス権限を付与する権限セットを割り当てます。ツールは 認証済みユーザーとして 実行されます。
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名:Account、Case、Task、My_Object__c など。
Activity(ポリモーフィックな Task/Event)
Activity は直接作成・クエリできないため、「Task また Event」のエイアスとして扱われます。
入力スタイル | 具体的な型の決定方法 |
| SObject の実際の型から決定。Task/Event 以外は拒否される |
| 各要素には |
| Id のプリフィックス( |
したがって、objectApiName が "Activity" の場合は、1つのリクエストに Task と Event を混在させられます。
レコード入力(create / update)
任意の組み合わせを指定します。それらは次の順でマージされます:
フィールド | 型 | 対象 | 備考 |
| SObject | Flow | 型は |
| List<SObject> | Flow | 同上 |
| String | MCP / REST |
|
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:部分的な成喰が可能です。各失敗行はerrorsにrow <n>: <msg>として報告されます。true:いずれかの行で失敗するとリクエスト全体をロールバックします。failureCountには関数員、errorsには DML 例外のメッセージ入ります。
ラベル
recordLabels は recordIds とインデックスごとに1対1で対応します。ラベルの取得元は次の通りです:
オブジェクト | ラベル |
Case |
|
それ以外のオブジェクト | そのオブジェクトの describe 名フィールド( |
名前フィールドがない・読み取りアクセスがない | レコード Id |
作成・更新時のラベルは DML 実行後に再取得されます(CaseNumber 等の自動採番が反映されます)。削除時は削除前のラベルを取得します。
共通の出力
フィールド | 型 | 意味 |
| Boolean | リクエスト内の全行で成功した場合に真(read は「全 Id が見のされた款」) |
| Integer | 行数 |
| Integer | 行数 |
| List<String> | 対象 / レコードの Id を入力順で返す |
| List<String> |
|
| List<String> | 失敗した行の |
| String | 1 行で要約。例: |
| List<String> |
|
リクエストレベルの検証エラー(オブジェクト名の誤り、JSON の不正など)は isSuccess=false、failureCount=1、errors に1件に登録されます。その場合は DML は実行されません。同発呼び出しの他のリクエストには影響しません。
ツールリファレンス
createRecords / SObjectCreateAction
呼び出し可能なラベル:Create Records (Generic)、カテゴリ:SObject Actions。
入力:objectApiName(必須)、record、records<String>、recordsJson、allOrNone`。
出力:isSuccess、successCount、failureCount、recordIds、recordLabels、errors、message。
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)。
入力:
フィールド | 型 | 補足 |
| String(必須) |
|
| String | 単一の Id |
| List<String> | バルク。重複はまとめられます |
| List<String> | 任意。フィールド名とリレーションパス( |
出力:
フィールド | メモ |
| 要求されたすべてのIdが見つかり、表示可能な場合はtrue |
| |
| 見つかったレコード、入力順 |
| 見つかったレコードのJSON配列(シリアライズされたSObject、 |
| 最初の / 見つかったすべてのレコードをSObjectとして - Flow向け |
| 存在しない、または共有権限で表示できないId |
|
例:
{ "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(必須)、record、records、recordsJson、allOrNone。
すべての行には**Idを含める必要があります**。Idを含まない行があると、リクエスト全体が失敗します
(row <n>: Id is required for update.)。
出力:createと同じ形です(successCount、recordIds、recordLabels、...)。
ラベルは、コール内のすべての更新が適用された後のレコードの状態を反映します。
例:
{ "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(必須)、recordIds、record、records、allOrNone。
SObjectとして渡すレコードにはIdを含める必要があります。
出力:isSuccess、successCount、failureCount、recordIds、recordLabels(削除前に取得)、errors、message。
例:
{ "objectApiName": "Account", "recordIds": ["001...", "001..."] }{ "objectApiName": "Activity", "recordIds": ["00T...", "00U..."] }削除されたレコードはゴミ箱に入ります(標準のDatabase.deleteの見ハウフ)。カスケード削除は、プラットフォームのマスター詳細/検索ルールに従います。
upsertRecords / SObjectUpsertAction
呼び出し可能ラベル:Upsert Records (Generic)。
入力:objectApiName(必須)、externalIdField(オプション、デフォルトId)、record、records、recordsJson、allOrNone。
externalIdField はオブジェクト上の外部Id/idLookupフィールドである必要があります。Activity はサポートされており(attributes.typeでTask/Eで指定)、外部Idフィールドは具象型に存在している必要があります。
出力:isSuccess、successCount、failureCount、createdCount、updatedCount、recordIds、recordLabels、wasCreated[](recordIdsと対応)、errors、message。
例:
{ "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は許可されません。
入力:
フィールド | メモ | |||
| クエリ可能である必要があります。 | |||
|
| |||
| 全フィルターに適用される | |||
| 追加で返すフィールド。リレーションシップはpathは許可( | |||
|
|
| (原文の区切りを維持) | |
| 1〜200、デフォルト50。 |
上記の orderBy 行の実際の内容を正しく示すと:
| orderBy | "Field" または "Field ASC \| DESC" | |
値はバインド前にフィールド型に変換されます(日付YYYY-MM-DD、日時ISO-8601、数値、真偽値、Id)。すべての値はバインド変数(Database.queryWithBinds, USER_MODE)を介して渡されます。
出力:isSuccess、resultCount、recordIds、recordLabels、recordsJson、records(Flow)、soql(実行されたクエリ、値は:b0、:b1...として伏せられます)、errors、message(resultCount == 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設定時):
入力 | メモ |
|
|
| デフォルトtrue |
| フィールドAPI名またはラベルに対する大文字小文字を配別しないフィルター |
出力:objectApiName、objectLabel、keyPrefix、isCustom、isCreateable、Updateable、Deletable、Queryable、
labelFields(例:Caseの場合["CaseNumber","Subject"])、requiredFields(作成可能、非null許容、デフォルトなし)、fieldsJson(アクセス可能なフィールドのみ:apiName、label、type、required、createable、updateable、externalId、nameField、length、referenceTo[]、relationshipName、picklistValues[])、recordTypesJson(アクティブで非マスターの利用可能な型:id、developerName、name、isDefault)、childRelationshipsJson(relationshipName、childObject、field)、resultCount(返されたフィールド数)。
Listモード(objectApiNameが空の場合):
入力 | メモ |
| API名またはラベルに対する大文字小文字を切开ないフィルター |
| デフォルトfalse |
出力:objectsJson(アクセス可能な各オブジェクトのapiName、label、keyPrefix、isCustom、createable、queryable。カスタム設定とプレフィックスなしのシステムオブジェクトは除外)、resultCount。
例:
{ "objectApiName": "Case", "fieldNameContains": "status" }{ "objectApiName": "My_Object__c" }{ "objectNameContains": "invoice", "customOnly": true }searchRecords / SObjectSearchAction
呼び出し可能なラベル:Search Records (Generic)。SOSL全文検索です。語句はバインドされます(FIND :term)。
入力 | メモ |
| 最小2文字。 |
| デフォルト: |
|
|
| 追加フィールド。そのフィールドが存在するオブジェクトにのみ適用されます。 |
| オブジェクトあたり1〜200、デフォルト20。 |
出力:resultCount、recordIds、recordLabels、recordObjectNames(対応関係)、recordsJson、records。
{ "searchTerm": "acme*", "objectApiNames": ["Account","Contact"], "searchIn": "NAME", "fields": ["Phone","Email"] }relatedRecords / SObjectRelatedAction
呼び出し可能なラベル:Get Related Records (Generic)。
入力 | メモ |
| 親オブジェクトはIdから推測されます。 |
| 親オブジェクトの子のリレーション名( |
| findRecordsと同様(limitは50、最大200) |
出力:parentObjectApiName、childObjectApiName、result、recordIds、recordLabels、recordsJson、records。
{ "parentRecordId": "001...", "relationshipName": "Cases", "fields": ["Status","Priority"], "orderBy": "CreatedDate DESC", "limitCount": 10 }countRecords / SObjectCountAction
呼び出し可能なラベル:Count Records (Generic)。
項目 | メモ |
| Task/Event、Activityではない |
| findRecordsと同一 |
| 任意のグループ化可能なフィールド。最大200グループ、カウント降順。 |
出力: totalCount、groupValues[]、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: successCount、failureCount、recordIds、recordLabels (復元後)、errors、message。
1 つのリクエスト内の重複した Id は 1 つにまとめられます。すでに復元済みまたはパージ済みのレコードは行単位で失敗します。
{ "objectApiName": "Account", "recordIds": ["001..."] }checkAccess / SObjectAccessAction
呼び出し可能ラベル: Check Access (Generic)。すべての入力は省略可能。何も指定しない場合は「自分は誰か」を返します。
入力 | 備考 |
| CRUD チェック ( |
|
|
| 最大 200 件。 |
Outputs: userId、userName、loginUsername、profileId、profileName、userType、organizationId、timeZone、
objectApiName、canCreate/canRead/canUpdate/canDelete、fieldAccessJson、recordAccessJson、message。
{ "objectApiName": "Opportunity", "fields": ["Amount","StageName"], "recordIds": ["006..."] }cloneRecords / SObjectCloneAction
呼び出し可能ラベル: Clone Records (Generic)。
入力 | 備考 |
| Task/Event 混合の場合は |
| コピー元。見つからない / 非表示の Id は行ごとに失敗 |
| すべてのクローンに適用される JSON オブジェクト (フィール名は検証済み) |
| コピーしない項目 (例) |
|
作成可能・読み取り可能かつ自動番号・数式でないすべてのフィールドをコピーします。子レコードはクーンされません。Outputs: sourceRecordIds (対応)、recordIds、recordLabels、recordUrls、数、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)、record、records、recordsJson。
Ooutputs: isSuccess (全行が保存できるかどうか)、successCount、failureCount、rowResultsJson
([{row, valid, errors[]}])、errors、message (...Nothing was sure.`)。
注仍: DML はガバナー制限に含まれます。トランサクション内で消費された自動番号が再利用されることはありません。
{ "objectApiName": "Contact", "recordsJson": "[{\"LastName\":\"Ok\"},{\"FirstName\":\"No last name\"}]" }aggregateRecords / SObjectAggregationAction
呼び出可能ラベル: Aggregate Records (Generic)。
入力 | 備考 |
| Task/Event (Activity は不可) |
|
|
| findRecords と同様 |
| グループ化可なる 0-3 フィールド |
| ググループのみ (1-2000 |
Ooutput: resultCount、rowsJson (各行: 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)。
入力 | 備考 |
| 有効な AutoLaunched flow |
| 入力 (in) 変数 -> 値 の JSON obジェクト |
| 「出力可能」とマークされた変数を返すための指定 |
Outputs: interviewId、outputsJson、errors (フローのフォルトは Could not start flow ... またはフォルトのメッセージとして表われます)、message。フローの宣言されたランモー mode で、同一トランサクション内で実行されます。
{ "flowApiName": "SObjectActions_EchoFlow", "inputsJson": "{\"inputText\":\"hi\",\"inputNumber\":1}", "outputVariableNames": ["outputText","outputNumber"] }assignOwner / SObjectAssignOwnerAction
入力: objectName、recordIds、newOwnerId (005/00G) または newOwnerName (完全一致のユーザー表示名 / メンプ名、またはキュー名 / デベロパー名。複数解釈される名前は除外されます)、allOrNone。
Outpus: 解決された ownerId/ownerName、レコードごとの件数、recordIds、recordLabels、errors。
{ "objectApiName": "Case", "recordIds": ["500..."], "newOwnerName": "Tier 2 Support" }changeRecordType / SObjectRecordTypeAction
入力: objectName、recordIds、recordType (Id、DeveloperName または Name)、allOrNone。エラーには利用可な deベロパー名をが列挙されます。Outs: 解決された recordTypeId/recordTypeName、レコードごとの結果。
picklistValues / SObjectPickActionInput
入力: objectName、fieldApiName、includeInactive。Outs: values[]、labels[]、valuesJson
({value,label,active,default,validFor[]})、isRestricted、isDependent、controllingField、defaultValue。
値は obrganization-wide の field 定義を反映します (record type の value set は適用されません)。
logActivity / SObjectLogActivityAction
完了した Task を記録します。Inputs: subject (必須)、relatedRecordId (WhatId)、personRecordId (Contact/LeadどWhoId)、description、activityDate (デフォルト今日)、activityType、それの (デフォルトは最初の "done" ステータス)、priority、ownerId、extraFieldsJson。Outputs: recordId、recordUrl、status。
{ "subject": "Call with CFO", "relatedRecordId": "001...", "personRecordId": "003...", "description": "Discussed renewal", "activityType": "Call" }closeCase / SObjectCloseCaseAction
入力: caseIds、status (完了済 status である必要があります。デフォルトは最初の閉じた state)、comment (+ オフ + commentIsPublic)、extraFieldsJson、allOrNone。Oututs: 使用された status、ケース単位の件数、recordLabels (CaseNumber - Subject)。
convertLead / SObjectConvertLeadAction
入力: leadId、convertedStatus (デフォルトは最初の変換済 status)、accountId / contactId (既存にマージ)、createOpportunity (デフォルト true)、opportunityName、ownerId、sendEmailToOwner。Outputs: accountId、contactId、opportunityId + URL。
postChatter / SObjectPostAction
入力: recordId (任意のフィード有効レコードまたは User)、text、mentionUserIds。Outputs: feedItemId。対象オブジェクトにフィード追跡がない場合、明確なメッセージで失敗します。
addNote / SObjectAddNoteAction
入力: title、body (プレーンテキストまたは簡易 HTML)、recordIds、shareType (デフォルトの V / I / C)。ContentNote と ContentDocumentLink を作成します。org で Enhanced Notes が無効な場合、代わりに .html ファイルとして保存します (storedAsFile=true)。Outputs: noteId、リンクされた recordIds、storedAsFile。
attachFile / SObjectAttachFileAction
入力: fileName、textContent または base64Content、title、recordIds、shareType。Outputs: contentVersionId、contentDocumentId、リンクされた recordIds。大きな base64 ペイロードにはヒープ制限が適用されます (同期で約 6 MB)。
listFlows / SObjectListFlowsAction
一覧モード: nameContains、processType (デフォルト AutoLaunchedFlow、ALL)、includeInactive、limitCount -> flowsJson。
詳細モード: flowApiName -> variablesJson (apiName, dataType, isInput, isOutput, isCollection, objectType, description)。runFlow と組み合わせます。
recordSummary / SObjectSummaryAction
入力: recordId、fields (デフォルトはアクセス可能なすべてのフィールド)、relationshipNames (最大 10、デフォルトは存在する一般的なリレーション)、recentActivityLimit (0〜20、デフォルト 5)。
Outputs: objectApiName、recordLabel、recordUrl、ownerName、recordJson、relatedCountsJson ({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}を設定します。
フォールトパス: リクエストレベルの問題は 例外をスローしません。Success と Errors を確認してください。
想定外のプラットフォーム例外 (制限など) だけが 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...\"}]" }
] }SObjectReadAction、SObjectUpdateAction、SObjectDeleteAction も同じ構造です。
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 |
| 入力が不足している | API名を指定する |
| Typo / 表示されない | 色分のタイプとオブジェクトアクセスを確認する |
|
|
|
| 型が異なるSObject入力 | 入力の型を揃える |
| 型が異なる JSON 行 |
|
| 形式が不正な文字列 | JSON オブジェクトか配列であること、および正しくエスケープされていることを確認する |
| スカラー / その他のJSON |
|
| オブジェクトにないフィールド名 | API名を修正( |
| 値の型変換に失敗(不正な日付形式など) | ISO-8601 日付・日時を使い、型を正しくする |
| 操作対象がない |
|
| 有効な 15/18桁 Id ではない | Id を修正する |
| プリフィックスが誤っている |
|
| 更新行に Id がない |
|
| SObject 削除入力に Id がない |
|
|
| API名を修正する |
|
| 外部 Id フィールドか |
| 不正またはドット付きフィルタフィールド | 直接フィールドを使用する |
| ロングテキスト / 暗号化など | 別のフィールドでフィルタする |
|
|
|
| 型変換に失敗 | フィールドの型 / ISO 日付形式に合わせる |
| 範囲外 | 調節する |
| 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 でサーバーを再アクティブ化します。
This server cannot be installed
Maintenance
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
- AlicenseNot gradedqualityDmaintenanceEnables 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.1219MIT
- FlicenseNot gradedqualityBmaintenanceEnables interaction with Salesforce data and services via custom MCP tools, including account analytics, opportunity queries, case creation, and AI agent invocation.4
- AlicenseNot gradedqualityBmaintenanceProvides live-org context for AI assistants with tools to search skills, agents, templates, decision trees, and query Salesforce metadata (Apex, LWC, objects, fields, etc.) via MCP.15Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with Salesforce through MCP, supporting queries, records, metadata, and bulk operations with flexible OAuth authentication.MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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