Skip to main content
Glama

salesforce_query

Execute SOQL queries to retrieve and analyze Salesforce data in JSON format, enabling direct access to organization records and information.

Instructions

Run a SOQL query and return JSON rows

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
argsYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
recordsYes
total_sizeYes

Implementation Reference

  • The core asynchronous handler function for the 'salesforce_query' MCP tool. It uses SalesforceClient to run the SOQL query and returns results as QueryResult.
    async def salesforce_query(args: QueryArgs) -> QueryResult:
        sf = SalesforceClient.from_env()
        rows = await sf.run_soql(args.soql)
        if args.max_records is not None:
            rows = rows[: args.max_records]
        return QueryResult(total_size=len(rows), records=rows)
  • Pydantic models for input (QueryArgs: soql and optional max_records) and output (QueryResult: total_size and records list) schema validation.
    class QueryArgs(BaseModel):
        soql: str = Field(..., description="SOQL query string")
        max_records: int | None = Field(None, ge=1, le=50000)
    
    
    class QueryResult(BaseModel):
        total_size: int
        records: List[Dict[str, Any]]
  • Module register function using FastMCP @tool decorator to define and register the salesforce_query tool.
    def register(mcp: FastMCP) -> None:
        @mcp.tool(
            name="salesforce_query", description="Run a SOQL query and return JSON rows"
        )
        async def salesforce_query(args: QueryArgs) -> QueryResult:
            sf = SalesforceClient.from_env()
            rows = await sf.run_soql(args.soql)
            if args.max_records is not None:
                rows = rows[: args.max_records]
            return QueryResult(total_size=len(rows), records=rows)
  • sfmcp/server.py:23-33 (registration)
    Top-level registration in server.py: imports tool_query from .tools.query and calls tool_query.register(mcp) to activate the salesforce_query tool among others.
    def _register_all() -> None:
        tool_query.register(mcp)
        tool_describe.register(mcp)
        tool_list_objects.register(mcp)
        tool_list_flows.register(mcp)
        tool_list_reports.register(mcp)
        tool_list_dashboards.register(mcp)
        tool_describe_flow.register(mcp)
        # res_saved_queries.register(mcp)
        # prm_opps_by_stage.register(mcp)
  • Key helper method in SalesforceClient that executes the SOQL query using Salesforce CLI subprocess and parses the JSON response to return records.
    async def run_soql(self, soql: str) -> List[Dict[str, Any]]:
        """Run a SOQL query and return the records"""
        command = [
            "sf",
            "data",
            "query",
            "--target-org",
            self._org_alias,
            "--query",
            soql,
            "--result-format",
            "json",
        ]
        result = await self._run_cli_command(command)
    
        if "result" in result and "records" in result["result"]:
            return result["result"]["records"]  # type: ignore[no-any-return]
        else:
            raise Exception("Unexpected response format from Salesforce CLI")
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but only states the basic action and output format. It lacks critical behavioral details: whether this is read-only or mutative, authentication requirements, rate limits, error handling, or pagination for large result sets. The description is minimal and doesn't compensate for the absence of annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste. It's front-loaded with the core action and outcome, making it easy to parse. Every word earns its place, though it may be overly concise given the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (executing queries in Salesforce), no annotations, and 0% schema coverage, the description is incomplete. However, the presence of an output schema mitigates the need to explain return values. The description covers the basic purpose but lacks sufficient context for safe and effective use without additional documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description provides no parameter information beyond implying 'args' is for the query. It doesn't explain what 'QueryArgs' contains (e.g., query string, filters), syntax examples, or constraints. The description fails to compensate for the low schema coverage, leaving parameters largely undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Run') and resource ('SOQL query') with the outcome ('return JSON rows'). It distinguishes from siblings like 'salesforce_describe' and 'salesforce_list_objects' by focusing on query execution rather than metadata operations. However, it doesn't specify what type of data the query targets (e.g., objects, records).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like 'salesforce_describe' or 'salesforce_list_objects'. The description implies it's for executing queries but doesn't specify scenarios, prerequisites, or exclusions. The agent must infer usage from tool names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/mattmahowald/sfmcp'

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