| name | salesforce |
| description | Query and manage Salesforce CRM data via the Salesforce CLI (`sf`). Run SOQL/SOSL queries, inspect object schemas, create/update/delete records, bulk import/export, execute Apex, deploy metadata, and make raw REST API calls. |
| homepage | https://developer.salesforce.com/tools/salesforcecli |
| metadata | {"clawdbot":{"emoji":"☁️","requires":{"bins":["sf"]},"install":[{"id":"npm","kind":"node","package":"@salesforce/cli","bins":["sf"],"label":"Install Salesforce CLI (npm)"}]}} |
| permissions | [{"exec":"Runs the Salesforce CLI for authenticated CRM queries, metadata inspection, and administrative tasks."},{"file_write":"Writes query exports or import files only when the user asks for saved artifacts."},{"network":"Uses the authenticated Salesforce org connection through the Salesforce CLI."}] |
Salesforce Skill
Use the Salesforce CLI (sf) to interact with Salesforce orgs. The CLI must be authenticated before use. Always add --json for structured output.
If the sf binary is not available, stop and ask the user to install the Salesforce CLI using the repo's declared install metadata or the official Salesforce CLI guide. After the CLI is available, authenticate with sf org login web before touching org data.
Safety Boundaries
- Do not create, update, delete, deploy, or execute Apex without explicit user confirmation.
- Do not reveal access tokens, auth URLs, refresh tokens, or verbose org-display output in chat.
- Do not export data to files unless the user asked for a saved artifact or bulk workflow.
- Do not target a production org by default when sandbox or staging access is available.
Authentication and Org Management
Log in (opens browser)
sf org login web --alias my-org
Other login methods:
sf org login jwt --client-id <consumer-key> --jwt-key-file server.key --username user@example.com --alias my-org
sf org login access-token --instance-url https://mycompany.my.salesforce.com
sf org login sfdx-url --sfdx-url-file authUrl.txt --alias my-org
Manage orgs
sf org list --json
sf org display --json
sf org display --target-org my-org --json
sf org display --target-org my-org --verbose --json
sf org open
sf org open --target-org my-org
sf org logout --target-org my-org
Configuration and aliases
sf config set target-org my-org
sf config list
sf config get target-org
sf alias set prod=user@example.com
sf alias list
Querying Data (SOQL)
Standard SOQL queries via the default API:
sf data query --query "SELECT Id, Name, Email FROM Contact LIMIT 10" --json
sf data query --query "SELECT Id, Name, Amount, StageName FROM Opportunity WHERE StageName = 'Closed Won'" --json
sf data query --query "SELECT Id, Name, (SELECT LastName, Email FROM Contacts) FROM Account LIMIT 5" --json
sf data query --query "SELECT Id, Name, Account.Name FROM Contact" --json
sf data query --query "SELECT Id, Name FROM Account WHERE Name LIKE '%Acme%'" --json
sf data query --query "SELECT Id, Name, CreatedDate FROM Lead WHERE CreatedDate = TODAY" --json
sf data query --query "SELECT Id, Name, Amount FROM Opportunity ORDER BY Amount DESC LIMIT 20" --json
sf data query --query "SELECT Id, Name FROM Account" --all-rows --json
sf data query --file query.soql --json
sf data query --query "SELECT Id, Name, Status FROM ApexClass" --use-tooling-api --json
sf data query --query "SELECT Id, Name, Email FROM Contact" --result-format csv --output-file contacts.csv
sf data query --query "SELECT Id, Name FROM Account" --target-org my-org --json
For queries returning more than 10,000 records, use Bulk API instead:
sf data export bulk --query "SELECT Id, Name, Email FROM Contact" --output-file contacts.csv --result-format csv --wait 10
sf data export bulk --query "SELECT Id, Name FROM Account" --output-file accounts.json --result-format json --wait 10
Text Search (SOSL)
SOSL searches across multiple objects at once:
sf data search --query "FIND {John Smith} IN ALL FIELDS RETURNING Contact(Name, Email), Lead(Name, Email)" --json
sf data search --query "FIND {Acme} IN NAME FIELDS RETURNING Account(Name, Industry), Contact(Name)" --json
sf data search --file search.sosl --json
sf data search --query "FIND {test} RETURNING Contact(Name)" --result-format csv
Single Record Operations
Get a record
sf data get record --sobject Contact --record-id 003XXXXXXXXXXXX --json
sf data get record --sobject Account --where "Name=Acme" --json
sf data get record --sobject Account --where "Name='Universal Containers' Phone='(123) 456-7890'" --json
Create a record (confirm with user first)
sf data create record --sobject Contact --values "FirstName='Jane' LastName='Doe' Email='jane@example.com'" --json
sf data create record --sobject Account --values "Name='New Company' Website=www.example.com Industry='Technology'" --json
sf data create record --sobject TraceFlag --use-tooling-api --values "DebugLevelId=7dl... LogType=CLASS_TRACING" --json
Update a record (confirm with user first)
sf data update record --sobject Contact --record-id 003XXXXXXXXXXXX --values "Email='updated@example.com'" --json
sf data update record --sobject Account --where "Name='Old Acme'" --values "Name='New Acme'" --json
sf data update record --sobject Account --record-id 001XXXXXXXXXXXX --values "Name='Acme III' Website=www.example.com" --json
Delete a record (require explicit user confirmation)
sf data delete record --sobject Account --record-id 001XXXXXXXXXXXX --json
sf data delete record --sobject Account --where "Name=Acme" --json
Bulk Data Operations (Bulk API 2.0)
For large datasets (thousands to millions of records):
Bulk export
sf data export bulk --query "SELECT Id, Name, Email FROM Contact" --output-file contacts.csv --result-format csv --wait 10
sf data export bulk --query "SELECT Id, Name FROM Account" --output-file accounts.json --result-format json --wait 10
sf data export bulk --query "SELECT Id, Name FROM Account" --output-file accounts.csv --result-format csv --all-rows --wait 10
sf data export resume --job-id 750XXXXXXXXXXXX --json
Bulk import
sf data import bulk --file accounts.csv --sobject Account --wait 10
sf data import resume --job-id 750XXXXXXXXXXXX --json
Bulk upsert
sf data upsert bulk --file contacts.csv --sobject Contact --external-id Email --wait 10
Bulk delete
sf data delete bulk --file records-to-delete.csv --sobject Contact --wait 10
Tree export/import (for related records)
sf data export tree --query "SELECT Id, Name, (SELECT Name, Email FROM Contacts) FROM Account" --json
sf data export tree --query "SELECT Id, Name FROM Account" --plan --output-dir export-data
sf data import tree --files Account.json,Contact.json
sf data import tree --plan Account-Contact-plan.json
Schema Inspection
sf sobject describe --sobject Account --json
sf sobject describe --sobject MyCustomObject__c --json
sf sobject describe --sobject ApexClass --use-tooling-api --json
sf sobject list --json
sf sobject list --sobject custom --json
sf sobject list --sobject standard --json
Execute Apex Code
sf apex run --file script.apex --json
sf apex run
sf apex run test --test-names MyTestClass --json
sf apex get test --test-run-id 707XXXXXXXXXXXX --json
sf apex list log --json
sf apex get log --log-id 07LXXXXXXXXXXXX
REST API (Advanced)
Make arbitrary authenticated REST API calls:
sf api request rest 'services/data/v62.0/limits' --json
sf api request rest '/services/data/' --json
sf api request rest '/services/data/v62.0/sobjects/Account' --method POST --body '{"Name":"REST Account","Industry":"Technology"}' --json
sf api request rest '/services/data/v62.0/sobjects/Account/001XXXXXXXXXXXX' --method PATCH --body '{"BillingCity":"San Francisco"}' --json
sf api request graphql --body '{"query":"{ uiapi { query { Account { edges { node { Name { value } } } } } } }"}' --json
sf api request rest '/services/data/v62.0/limits' --header 'Accept: application/xml'
sf api request rest '/services/data/v62.0/limits' --stream-to-file limits.json
Metadata Deployment and Retrieval
sf project deploy start --source-dir force-app --json
sf project deploy start --metadata ApexClass:MyClass --json
sf project retrieve start --metadata ApexClass --json
sf project deploy report --job-id 0AfXXXXXXXXXXXX --json
sf project generate --name my-project
sf project list ignored --json
Diagnostics
sf doctor
sf version
sf whatsnew
Common SOQL Patterns
SELECT COUNT() FROM Contact WHERE AccountId = '001XXXXXXXXXXXX'
SELECT StageName, COUNT(Id), SUM(Amount) FROM Opportunity GROUP BY StageName
SELECT Id, Name FROM Lead WHERE CreatedDate = LAST_N_DAYS:30
SELECT Id, Name FROM Account WHERE Id IN (SELECT AccountId FROM Contact WHERE Email LIKE '%@acme.com')
SELECT Id, Who.Name, Who.Type FROM Task WHERE Who.Type = 'Contact'
SELECT Id, Name, Amount FROM Opportunity WHERE Amount > 10000 AND StageName != 'Closed Lost' AND CloseDate = THIS_QUARTER
Guardrails
- Always use
--json for structured, parseable output.
- Never create, update, or delete records without explicit user confirmation. Describe the operation and ask before executing.
- Never delete records unless the user explicitly requests it and confirms the specific record(s).
- Never bulk delete or bulk import without user reviewing the file/query and confirming.
- Use
LIMIT on queries to avoid excessive data. Start with LIMIT 10 and increase if the user needs more.
- For queries over 10,000 records, use
sf data export bulk instead of sf data query.
- When the user asks to "find" or "search" a single object, use SOQL
WHERE ... LIKE '%term%'. When searching across multiple objects, use SOSL via sf data search.
- Use
--target-org <alias> when the user has multiple orgs; ask which org if ambiguous.
- If authentication fails or a session expires, guide the user through
sf org login web.
- Bulk API 2.0 has SOQL limitations (no aggregate functions like
COUNT()). Use standard sf data query for those.
- When describing objects (
sf sobject describe), the JSON output can be very large. Summarize the key fields, required fields, and relationships for the user rather than dumping the raw output.