The server implements 17 Salesforce integration tools with visible input schemas and descriptions, but falls short of production quality on several critical dimensions. Naming is functional but not optimized for LLM intent clarity (e.g., 'sf_sobject_get' vs. 'get_sobject'). Descriptions are present but frequently generic and lack actionable guidance (e.g., 'Describe an SObject' tells the LLM WHAT but not WHEN or WHY to call it). Output schemas are not documented, the code returns raw API responses without specifying structure for downstream tool chaining. Error handling lacks recovery guidance (raw Salesforce errors are returned verbatim). Parameters lack detailed format constraints (e.g., 'soql' param has no guidance on valid SOQL syntax, query limits, or expected return structure). Several tools combine multiple concerns (sf_sobject_get accepts optional 'fields' but no guidance on whether omitting it returns all fields or a default set). Pagination is implemented for queries but not exposed as parameters in sf_query_simple. Authentication is handled server-side (good), but no security declarations in tool metadata. Overall, the definitions are functional for a developer familiar with Salesforce APIs, but they do not meet the LLM-optimization bar of the rubric (pattern:tool-description, pattern:constrained-input, pattern:recovery-guide).
Tools (17)
sf_batch_insertwriteauth50/100
Batch insert records (Composite API)
sf_generate_custom_applicationwrite50/100
Generate a basic Lightning App (CustomApplication) metadata file in temp workdir
sf_get_sobject_describeread onlyauth50/100
Describe an SObject (get metadata about fields, relationships, etc.)
sf_limitsread onlyauthsource verified60/100
Muestra límites de la org (API limits, etc.)
sf_project_deploywriteauth50/100
Deploy metadata using sf project deploy start (allowlisted parameters only)
sf_project_retrieveread onlyauth50/100
Retrieve metadata using sf project retrieve start (allowlisted parameters only)
Output schemas not documented. Tools return data but LLM cannot infer field names, types, or structure for downstream chaining. Prevents agents from extracting IDs, references, or metadata needed for follow-up calls.
Descriptions are generic and lack LLM-actionable guidance. Most descriptions under 70 characters explain WHAT but not WHEN to call the tool. Missing dependency hints (e.g., 'Call sf_get_sobject_describe first to see available fields'). No error recovery guidance.
Add formal output schemas for all tools. Specify fields, types, and examples in tool definitions. E.g., sf_query should document: 'Returns {records: [{...fields...}], totalCount: number, nextCursor?: string, done: boolean}'. This enables agents to extract IDs and chain calls.
Expand all descriptions to 100-200 characters with explicit WHEN/WHY guidance. E.g., 'Query Account records with SOQL. Call this to search by name, type, or custom fields before retrieving details with sf_sobject_get.' Include typical use cases and required parameters.
Add dependency hints in descriptions. E.g., sf_sobject_get: 'Get a single record by ID. If you only have a name, call sf_query first. Common next step: sf_sobject_update to modify the record.'
Document parameter format constraints in descriptions. E.g., 'soql: Valid SOQL query (max 20k chars, no INSERT/UPDATE/DELETE). Example: SELECT Id, Name FROM Account WHERE Name LIKE \'%Acme%\'. Returns up to 2000 records; use pagination for larger result sets.'
Consolidate sf_query and sf_query_simple into a single tool with an optional 'limit' parameter. Explain the distinction clearly (or remove duplication entirely). Use consistent naming: 'query_sobjects' instead of 'sf_query'.
Add recovery guidance to error handling. E.g., on 404: 'Record not found. Verify the ID with sf_query using the sobject type and a filter (e.g., Name = \'...\'). Or use sf_sobject_describe to see available fields for searching.'
Add destructiveHint, readOnlyHint, and idempotentHint annotations to all tools in metadata. Mark sf_sobject_delete, sf_sobject_update, sf_project_deploy as destructive. Mark sf_query, sf_sobject_get as read-only. Clarify idempotency for upsert operations.
Score history
Overall score trend
↑ 42 points across a rubric change (v1 → v2)
42/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
F
42
2026-07-28+
v2
2026-03-09
F
0
-
v1
read onlyauth50/100
Execute simple SOQL query (returns raw JSON)
sf_sobject_createwriteauth50/100
Create a new record
sf_sobject_deletedestructiveauth50/100
Delete a record by ID
sf_sobject_getread onlyauth50/100
Get a single record by ID
sf_sobject_updatewriteauth50/100
Update an existing record
sf_sobject_upsertwriteauth50/100
Upsert (create or update) a record using external ID
sf_tooling_create_anonymous_apexwriteauth50/100
Execute anonymous Apex code (one-shot execution)
sf_tooling_get_sourceread onlyauth50/100
Retrieve Apex class or trigger source code via Tooling API
Destructive tools (sf_sobject_delete, sf_tooling_update_source, sf_project_deploy) lack confirmation/dry-run guidance. No warning that these operations are irreversible. No mention of compensation (e.g., ability to restore deleted records or rollback deployments).
Parameter descriptions lack format constraints and validation rules. 'soql' params have no guidance on valid SOQL syntax, query limits, or expected behavior. 'fields' param in sf_sobject_get has no explanation of format (comma-separated? array?) or behavior if omitted.
Duplicate/overlapping tool names create LLM confusion. 'sf_query' vs 'sf_query_simple', the distinction is never explained. Both accept a soql param; LLM cannot determine when to use which. Similarly, 'sf_sobject_get' vs 'sf_get_sobject_describe' have inconsistent naming styles.
No error recovery guidance in any tool. Salesforce API errors (401, 404, 400, etc.) are returned verbatim without LLM-actionable context. No suggestion of what to try next (e.g., 'Record not found, verify record ID with sf_query').
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Server explicitly declares these features are false. Without annotations, clients cannot determine risk level, agents may treat destructive operations as read-only or vice versa.
Pagination in sf_query implemented server-side (max 10 pages, 2000 records) but not exposed to LLM. sf_query_simple has no pagination support. SOQL_MAX_RECORDS limit of 2000 is reasonable but agent cannot request fewer records upfront to control token cost.
No idempotency guarantees or guidance. Tools like sf_sobject_create and sf_batch_insert lack mention of what happens on retry (duplicate inserts?). Agents may retry failed operations, causing duplicate records.
No permission/scope declarations in tool metadata. No guidance on what Salesforce permissions are required to call each tool (e.g., 'Requires read:contacts' for queries, 'Requires write:accounts' for updates). Prevents least-privilege agent configuration.
Add dry-run or confirmation parameters to destructive tools (sf_sobject_delete, sf_tooling_update_source, sf_project_deploy). E.g., sf_sobject_delete: add optional 'confirm=true' parameter with description 'If false, returns what would be deleted without executing.' This prevents accidental data loss.
Document pagination explicitly. Add 'page_size' and 'offset' or 'cursor' parameters to sf_query and sf_batch_insert. Allow agents to control result size and cost. E.g., 'page_size: Number of records per page (1-2000, default 100)'.
Add permission scope declarations. Document in each tool description what Salesforce object/field permissions are required. E.g., sf_sobject_create: 'Requires write:Account or write:<SObjectType> permission.'
Clarify idempotency. E.g., sf_sobject_upsert: 'Idempotent: calling with the same external ID and fields produces no change on retry. sf_sobject_create: NOT idempotent, retrying will insert a duplicate record. Use upsert or check for existence first.'
Reduce verbosity of Salesforce API responses. Strip audit fields (CreatedDate, LastModifiedBy), pagination internals, and metadata the agent doesn't need. Return only the fields relevant to the user's intent. This reduces token cost and improves signal.
Ensure output includes chaining references. E.g., sf_sobject_create should return {id, type, ...created_fields} so the agent can immediately call sf_sobject_update with the same id. Do not omit type or id from responses.
Add examples of valid inputs in parameter descriptions for enums or constrained values. E.g., sf_project_deploy testLevel: 'One of: NoTestRun (fastest), RunLocalTests (safer), RunAllTestsInOrg (comprehensive), RunSpecifiedTests (use --tests param). Default: RunLocalTests.'
Document expected return values for all tools. E.g., sf_tooling_create_anonymous_apex: 'Returns {success: boolean, logs?: string, error?: string}'. This prevents agents from guessing at response structure.
Add role-based access control (RBAC) checks inside tools. Verify the agent/user has permission to call each tool before executing. Log authorization decisions for audit trails.
Implement rate limiting on tools to prevent runaway agent retries from overwhelming Salesforce APIs. Return a clear 'Rate limit exceeded' error with backoff guidance (e.g., 'Retry after 60 seconds') instead of a generic HTTP 429.