Salesforce

Use Salesforce CRM with Agno agents to query, create, and manage records.

Prerequisites

uv pip install -U agno simple-salesforce openai
export SALESFORCE_USERNAME="you@example.com"
export SALESFORCE_PASSWORD="your-password"
export SALESFORCE_SECURITY_TOKEN="token-from-email"
export SALESFORCE_DOMAIN="login"
export OPENAI_API_KEY="your_openai_api_key_here"

Example

cookbook/91_tools/salesforce_tools.py
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.salesforce import SalesforceTools

# Read-only agent (default)
read_only_agent = Agent(
    name="Salesforce Explorer",
    model=OpenAIChat(id="gpt-5.4-mini"),
    tools=[SalesforceTools()],
    instructions=[
        "Use describe_object to understand available fields before building queries.",
        "Use SOQL for precise structured queries, SOSL for full-text search across objects.",
    ],
    markdown=True,
)

# Full CRM agent with write operations enabled
full_crm_agent = Agent(
    name="Salesforce CRM Agent",
    model=OpenAIChat(id="gpt-5.4-mini"),
    tools=[
        SalesforceTools(
            enable_create_record=True,
            enable_update_record=True,
            enable_delete_record=True,
        )
    ],
    instructions=[
        "Always use describe_object to check required fields before creating records.",
        "Confirm with the user before deleting any records.",
    ],
    markdown=True,
)

if __name__ == "__main__":
    # Explore available objects
    read_only_agent.print_response(
        "List the queryable Salesforce objects in this org",
        stream=True,
    )

    # Query accounts
    read_only_agent.print_response(
        "Find the top 5 accounts by name using SOQL",
        stream=True,
    )

    # Describe an object's schema
    read_only_agent.print_response(
        "Describe the Contact object. What fields are required for creating a new contact?",
        stream=True,
    )

    # Search across objects
    read_only_agent.print_response(
        "Search for anything related to 'United' across all objects",
        stream=True,
    )

Authentication and result limits

The shown credentials use username/password login. If your org does not permit that login method, obtain a valid Salesforce session through your org's authentication flow and pass instance_url and session_id to each SalesforceTools constructor instead. Use SALESFORCE_DOMAIN="test" for a sandbox login.

Only read_only_agent is called. The configured write agent is unused, and its deletion-confirmation instruction is a model instruction; it does not pause a run through Agno's confirmation mechanism.

The toolkit defaults to at most 200 returned records and 100 schema fields. Check returned, totalSize, totalFields, and returnedFields before treating an answer as complete. Increase max_fields if required fields fall outside the returned schema. A SOQL response with done=False still needs pagination through Salesforce's API; this toolkit does not expose the continuation locator.

Run the Example

git clone https://github.com/agno-agi/agno.git
cd agno
git checkout d703c34f3abf3c41275d3fb2da6e0518a8881f24

# Create and activate virtual environment
./scripts/demo_setup.sh
source .venvs/demo/bin/activate

uv pip install -U simple-salesforce
python cookbook/91_tools/salesforce_tools.py

For details, see Salesforce Tools cookbook.