Agent skill
salesforce-query
Query Salesforce data using natural language. Supports Accounts, Opportunities, Contacts, Leads, and Cases. Use when user asks to find, show, list, or retrieve Salesforce records.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/salesforce-query
SKILL.md
Salesforce Natural Language Query
Execute natural language queries against Salesforce and display results as formatted tables.
Supported Objects
- Account: Companies and organizations
- Opportunity: Sales deals and opportunities
- Contact: Individual people
- Lead: Potential customers
- Case: Customer support cases
How to Use This Skill
Step 1: Get Bearer Token (First Query Only)
On the first query in a session, ask the user for:
- Instance URL: Their Salesforce instance (e.g.,
https://yourorg.my.salesforce.com) - Bearer Token: A valid bearer token or session ID
How to Obtain a Bearer Token:
Option A: Session ID (Recommended - Quick & Simple)
- Log into Salesforce
- Open Developer Console (Setup → Developer Console)
- Execute Anonymous → Enter:
System.debug(UserInfo.getSessionId()); - Click Execute
- Check Logs → Copy the session ID
- Note: Session expires after 2 hours of inactivity
Option B: OAuth Token (Via External OAuth Flow)
- If you have an existing OAuth setup, use the access token
- Obtain via your own Connected App or external OAuth provider
- This skill does NOT manage OAuth flows - tokens must be pre-obtained
Token Validation (Optional):
python scripts/validate_token.py <instance_url> <bearer_token>
- Verifies token is valid
- Shows API usage limits
- Returns success/error
Token Format: Scripts accept tokens in any format:
Bearer xxxOAuth xxxxxx(plain token - will be prefixed with 'Bearer ' automatically)
Remember these credentials for the entire chat session. Don't ask again unless they fail.
Step 2: Understand the Query
Analyze the natural language query to:
- Identify which Salesforce object(s) are needed
- Determine filters, conditions, or relationships
- Identify if clarification is needed (ambiguous terms, missing context)
If ambiguous: Use AskUserQuestion to clarify before proceeding.
Step 3: Fetch Object Schema
Use the describe.py script to fetch field metadata for needed objects.
Command:
python scripts/describe.py "<instance_url>" "<bearer_token>" "<ObjectName>"
Intelligent field selection: Only fetch schemas if you need to verify field names or understand relationships. For simple queries with common fields, you can skip this step.
Common fields by object:
- Account: Id, Name, Type, Industry, Phone, Website, BillingCity, BillingState, Owner.Name
- Opportunity: Id, Name, StageName, Amount, CloseDate, Probability, Account.Name, Owner.Name
- Contact: Id, Name, Email, Phone, Title, Account.Name, Department, Owner.Name
- Lead: Id, Name, Email, Status, Company, Phone, Industry, Owner.Name
- Case: Id, CaseNumber, Subject, Status, Priority, Origin, Account.Name, Contact.Name, Owner.Name
Step 4: Generate SOQL Query
Translate the natural language query into SOQL using the schema information.
SOQL Best Practices:
- Always include
Idin SELECT - For related objects, use dot notation:
Account.Name,Owner.Name - Use proper WHERE clause syntax
- Date literals:
TODAY,THIS_WEEK,THIS_MONTH,THIS_QUARTER,THIS_YEAR - Comparison operators:
=,!=,>,<,>=,<=,LIKE,IN - Logical operators:
AND,OR,NOT - String values must be in single quotes:
'United Oil & Gas' - For partial matches use LIKE:
Name LIKE '%Oil%'
Common SOQL Patterns:
Find by name:
SELECT Id, Name, Industry FROM Account WHERE Name LIKE '%Oil%'
Find with related object:
SELECT Id, Name, StageName, Amount, Account.Name
FROM Opportunity
WHERE Account.Name LIKE '%United Oil%'
Date-based queries:
SELECT Id, Name, CloseDate FROM Opportunity
WHERE CloseDate = THIS_QUARTER
Multiple conditions:
SELECT Id, Name, Amount FROM Opportunity
WHERE Amount > 100000 AND StageName = 'Negotiation'
Order and limit:
SELECT Id, Name, Amount FROM Opportunity
ORDER BY Amount DESC
LIMIT 10
Step 5: Validate SOQL Syntax
Before executing, perform basic syntax validation:
- Check for balanced parentheses
- Verify SELECT, FROM are present
- Ensure field names look valid
- Check that string values are quoted
If validation fails: Fix the SOQL or ask for clarification.
Step 6: Display SOQL to User
Show the generated SOQL to the user for transparency:
Generated SOQL:
SELECT Id, Name, StageName, Amount, CloseDate, Account.Name
FROM Opportunity
WHERE Account.Name LIKE '%United Oil & Gas%'
ORDER BY CloseDate DESC
Step 7: Execute Query
Run the query using query.py script.
Command:
python scripts/query.py "<instance_url>" "<bearer_token>" "<SOQL_QUERY>"
Important: Make sure to properly escape the SOQL query string in the command line.
Step 8: Format and Display Results
Parse the JSON response and format as a markdown table.
For successful queries:
- Show total count:
Found X records: - Create markdown table with relevant columns
- Always include Id, Name (if available), and URL
- The URL column should be formulated as:
instance_url + "/" + Id - Include other fields from the SELECT clause
- Format numbers, dates appropriately
- Truncate long text fields if needed
Example output:
Found 3 opportunities:
| Id | Name | URL | Stage | Amount | Close Date | Account |
|---|---|---|---|---|---|---|
| 006xx01 | Platform Modernization | https://yourorg.my.salesforce.com/006xx01 | Prospecting | $250,000 | 2024-06-30 | United Oil & Gas |
| 006xx02 | Equipment Upgrade | https://yourorg.my.salesforce.com/006xx02 | Negotiation | $500,000 | 2024-08-15 | United Oil & Gas |
| 006xx03 | Safety System | https://yourorg.my.salesforce.com/006xx03 | Closed Won | $150,000 | 2024-03-01 | United Oil & Gas |
For empty results:
No records found matching your query.
For errors:
- Explain what went wrong
- Show the error message from Salesforce
- Suggest corrections if applicable
Error Handling
Authentication Errors (401)
- Session ID expired or invalid
- Ask user for new credentials
SOQL Syntax Errors
- Show the error message
- Explain what's wrong
- Suggest corrected SOQL
Field Not Found Errors
- The field doesn't exist on the object
- Fetch schema to verify available fields
- Regenerate SOQL with correct fields
No Results
- Query is valid but returned no records
- Simply state "No records found"
- Don't auto-retry unless user asks
Advanced Query Patterns
Querying Related Records
-- Opportunities with Account details
SELECT Id, Name, Amount, Account.Name, Account.Industry
FROM Opportunity
-- Contacts with Account details
SELECT Id, Name, Email, Account.Name, Account.Type
FROM Contact
Aggregations (if needed)
-- Count opportunities by stage
SELECT StageName, COUNT(Id)
FROM Opportunity
GROUP BY StageName
-- Sum of amounts
SELECT SUM(Amount)
FROM Opportunity
WHERE StageName = 'Closed Won'
Subqueries
-- Opportunities for specific accounts
SELECT Id, Name, Amount
FROM Opportunity
WHERE AccountId IN (
SELECT Id FROM Account WHERE Industry = 'Technology'
)
Example Interactions
Example 1: Simple Query
User: /salesforce-query show me all accounts in California
Claude: [If first query, asks for credentials]
Claude: Generated SOQL:
SELECT Id, Name, Type, Industry, Phone, BillingCity, BillingState
FROM Account
WHERE BillingState = 'CA'
Claude: [Executes and shows table]
Example 2: Complex Query with Relationships
User: /salesforce-query show high-value opportunities closing this quarter
Claude: Generated SOQL:
SELECT Id, Name, StageName, Amount, CloseDate, Account.Name, Owner.Name
FROM Opportunity
WHERE Amount > 100000
AND CloseDate = THIS_QUARTER
ORDER BY Amount DESC
Claude: [Executes and shows table]
Example 3: Ambiguous Query
User: /salesforce-query find John
Claude: I need clarification:
- Are you looking for a Contact, Lead, or Account named John?
- Should I search in the name field, or also email?
- Do you want exact match or partial match?
Tips for Accurate Results
- Be specific: "Show opportunities for United Oil & Gas" is better than "show opportunities"
- Use proper object names: "accounts" not "companies", "opportunities" not "deals"
- Specify timeframes: "this month", "this quarter", "last year"
- Include sorting/limits: "top 10 by amount", "most recent cases"
- Clarify relationships: "contacts from California accounts" vs "California contacts"
Limitations
- Query timeout: 2 minutes maximum
- Result limit: 2000 records maximum (pagination handled automatically)
- Objects: Limited to Account, Opportunity, Contact, Lead, Case
- Custom fields: Supported but must exist in your org
- SOSL: Not supported (only SOQL)
Troubleshooting
Script not found errors: Ensure Python scripts exist at:
scripts/describe.pyscripts/query.py
Module not found errors: Install dependencies:
pip install requests
Permission errors: Ensure user's profile has read access to the queried objects
Ready to query Salesforce! Provide your natural language query and I'll handle the rest.
Didn't find tool you were looking for?