salesforce-mcp-jsforce
This server is a lightweight, single-org Salesforce MCP server built on jsforce, providing read and write operations via SOQL, SOSL, and CRUD.
Tools:
salesforce_identity– Verify the authenticated connection and retrieve user, org, and instance details.salesforce_query– Execute SOQL queries to fetch records.salesforce_search– Perform SOSL full-text searches across objects.salesforce_list_objects– List all sObjects with key metadata.salesforce_describe_object– Get schema details of a specific object, including fields, data types, picklist values, and relationships.salesforce_get_record– Retrieve a single record by its 15- or 18-character ID, optionally specifying fields.salesforce_create_record– Create a new record on any object.salesforce_update_record– Update an existing record by ID.salesforce_delete_record– Delete a record by ID.
Additional features:
Read-only mode via
SF_READONLY=1disables create, update, and delete operations.Supports local stdio transport (e.g., Claude Code) or a streamable HTTP server.
Authentication via OAuth PKCE with token redaction, loopback-only callbacks, automatic refresh token renewal for stdio, and per-request credential handling in HTTP mode.
Provides tools for interacting with Salesforce, including SOQL queries, SOSL search, object description, and CRUD operations on records via the Salesforce REST API.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@salesforce-mcp-jsforceshow me the top 10 opportunities by amount"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
salesforce-mcp-jsforce
A lite, single-org Model Context Protocol server for Salesforce, built on jsforce.
Bring your own token. The server never stores a username or password. You authenticate once with OAuth; it holds an access token + instance URL (plus, for stdio, a refresh token).
Sign in once. An expired access token is renewed from the saved refresh token and the failed call retried, so a long-running client keeps working until the grant is revoked.
Two ways to run. Locally over stdio (for Claude Code and other MCP clients) or as a dedicated streamable-HTTP server where each request carries its own token.
Safe to host & open-source. No org-specific config, no multi-environment credential matrix, no destructive metadata tooling. Optional read-only mode.
Tools
Tool | Mode | Description |
| read | Identity of the supplied token (token validity check) |
| read | Run a SOQL query |
| read | Run a SOSL full-text search |
| read | List sObjects + key metadata |
| read | Trimmed describe of an sObject |
| read | Retrieve a record by Id |
| write | Create a record |
| write | Update a record |
| write | Delete a record |
Set SF_READONLY=1 to register the read tools only.
Related MCP server: Salesforce MCP Server
Quick start
npm install -g @imazhar101/salesforce-mcp-jsforce
# 1. Log in (PKCE against your External Client App)
salesforce-mcp-jsforce login --client-id <ECA_CONSUMER_KEY>
# sandbox: add --login-url https://test.salesforce.com
# 2. Use it from Claude Code
claude mcp add salesforce -- npx -y @imazhar101/salesforce-mcp-jsforcelogin opens a browser, completes the OAuth handshake, saves the token to
~/.config/salesforce-mcp-jsforce/token.json, and prints ready-to-paste config.
Sign out (and revoke the grant at Salesforce) with salesforce-mcp-jsforce logout.
Credentials
stdio — one of:
the token file written by
login(read automatically, renewed automatically), orSF_ACCESS_TOKEN+SF_INSTANCE_URLenvironment variables.
Env credentials win when both are present. They carry no refresh token, so they cannot be renewed — prefer the token file unless something else is minting short-lived tokens for you.
Token renewal
Salesforce access tokens expire on the org's session policy, typically hours.
When a call fails with INVALID_SESSION_ID, the server runs the refresh_token
grant, writes the new token back to the token file (atomically, 0600) and
retries the call once. Concurrent calls share a single refresh. Nothing is
retried a second time — if a freshly issued token is also rejected, the problem
is not token age.
Renewal needs refreshToken, clientId and loginUrl in the token file, which
login saves when the refresh_token scope is granted. HTTP callers and
gateway _sfAuth callers are passed through untouched: those tokens belong to
whoever minted them.
HTTP — per request, via headers:
X-SF-Access-TokenX-SF-Instance-UrlX-SF-Api-Version(optional)
Run as a dedicated HTTP server
PORT=3000 salesforce-mcp-jsforce httpStateless streamable-HTTP at POST /mcp; health probe at GET /health. Each
request is handled by a throwaway server instance keyed to its own token — no
caller state is shared. Put it behind TLS; the access token is a live credential.
It binds 127.0.0.1 by default and rejects requests whose Host/Origin
is not loopback, which is what stops a page in your browser from reaching it by
DNS rebinding. To expose it, set SF_MCP_HOST=0.0.0.0 and
SF_MCP_ALLOWED_HOSTS=your.host — deliberately, and behind a proxy that
authenticates, because this server authenticates nobody: it forwards whatever
token the request carries.
curl -s http://localhost:3000/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
-H "X-SF-Access-Token: $SF_ACCESS_TOKEN" \
-H "X-SF-Instance-Url: $SF_INSTANCE_URL" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Relay mode — route calls through an MCP gateway
By default this server talks straight to Salesforce. If it runs behind an MCP gateway that is supposed to govern data access, that traffic is invisible to it: no activity log, no scope enforcement, and read-only enforced only by a client-side env var the user can remove.
Relay mode fixes that without moving credentials off the machine. Set
SF_RELAY_URL and the server stops calling Salesforce itself — it forwards each
JSON-RPC request to the gateway, which runs the real server and applies its own
policy:
export SF_RELAY_URL=https://conduit.example.com/mcp/le-salesforce
salesforce-mcp-jsforce login # Salesforce — which data you may see
salesforce-mcp-jsforce login --gateway # gateway — who you are, for scopes + auditTwo independent credentials ride on every relayed request, each refreshing itself:
Header | Carries | Refreshed by |
| gateway identity, for scope checks and logging |
|
| Salesforce authorization |
|
The gateway stores no Salesforce credentials — it reads the X-SF-* headers
into a per-request injection and strips them before writing its activity log.
Your Salesforce refresh token stays on your machine, exactly as in direct mode.
The relay does not interpret the protocol: it forwards requests verbatim and
returns the gateway's reply unchanged, so it cannot drift out of sync with
whatever tools the gateway's copy of the server exposes. Each credential gets
exactly one retry, and only for the failure it can fix — a 401 renews the
gateway token, an expired-session payload renews the Salesforce one.
Scope denials are passed through untouched: the gateway answers 200 with a
JSON-RPC error so the client shows the reason rather than hanging, and that
message (Access denied: Missing required scope: …) is already the clearest
thing to show. A bare 403, which means something in front of the gateway
rejected the call, is surfaced with its status.
The MCP handshake (initialize, ping) is answered locally and never reaches
the gateway, so the server still connects when you are not signed in — the auth
error appears on the first real call, where your client can show it, instead of
the whole server failing with an unreadable code.
Sign out of the gateway alone with salesforce-mcp-jsforce logout --gateway
(this drops the local gateway token; it does not touch the Salesforce grant).
Environment variables
Credentials and tools
Var | Default | Purpose |
| — | stdio access token — wins over the token file, no renewal |
| — | stdio instance URL |
|
| REST API version |
| off |
|
login
Var / flag | Default | Purpose |
| — | ECA consumer key (required) |
|
| OAuth host; must be https (sandbox: |
|
| OAuth scopes — drop |
|
| Loopback callback port |
|
| Full callback URL; loopback hosts only |
| — | Confidential clients only; public PKCE apps omit it |
|
| How long to wait for the browser round trip |
The callback port and redirect URI must match what the Connected App registers.
Salesforce compares redirect_uri byte-for-byte, so a different port — or
127.0.0.1 where the app registered localhost — fails the flow with
redirect_uri_mismatch before the sign-in screen appears.
Server
Var | Default | Purpose |
|
| Token storage location |
|
| HTTP bind address |
| — | Extra |
|
| Request body ceiling |
|
| HTTP listen port |
Security model
The token grants exactly the permissions of the user who authorized it — the server adds no privilege.
In HTTP mode no credentials are persisted; the token lives only for the duration of one request.
The stdio token file is written
0600inside a0700directory, replaced atomically via a temp file + rename.Tokens are never logged and never printed by
login. Errors returned to the model are redacted (session ids, bearer/refresh tokens, OAuth form fields).OAuth login is PKCE with a
statecheck, requires an https login URL, and times out rather than waiting forever. The callback listens on the loopback interface only — both127.0.0.1and::1, sincelocalhostresolves to either depending on the machine — and a busy port is a hard error, never a silent fallback that would let another process receive the authorization code.--redirect-uriis restricted to loopback hosts.The browser is launched via
spawnwith argv — never a shell string, so nothing in the URL reaches a shell.The HTTP listener is loopback-only by default, validates
Host/Origin, and caps request bodies.logoutrevokes the grant at Salesforce, not just locally.Relay mode requires an https gateway URL (loopback excepted, for local gateways), so the bearer token is never sent in the clear. The gateway token file gets the same
0600/0700atomic write as the Salesforce one, and gateway errors are redacted before they reach the model — a gateway that echoes the request back cannot leak the Salesforce token into the transcript.
Known limitation: the refresh token is stored as plaintext JSON (0600 in a
0700 directory). That stops other local users, but not code running as you —
any process in your account can read it. An OS-keychain backend is tracked in
#13. Treat the
token file as a live credential, and run logout on a machine you are handing
off.
Build from source
npm install
npm run build
node dist/index.js --helpLicense
MIT
Available Tools
9 toolssalesforce_create_recordC
Create a new record on the given object.
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Field API name → value map for the new record | |
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. | |
| object_name | Yes | API name of the object, e.g. Contact |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description bears full responsibility. It only states 'create' but fails to disclose what happens after creation (e.g., returns record ID?), any permissions required, or error behavior. The agent cannot infer side effects or safety profile from this text alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that is to the point and free of filler. However, it is so minimal that it borders on under-specification rather than concise completeness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a create operation with no output schema, the description should at least hint at the return value (e.g., ID of created record). It does not. Also missing is any context about authentication (_sfAuth) or data validation. The description is incomplete for effective agent use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers 100% of parameters with descriptions. The description adds no extra meaning beyond the schema, but that is acceptable per guidelines. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Create') and the resource ('new record on the given object'), distinguishing it from sibling tools like update, delete, or query. However, it lacks specificity about which objects are supported beyond 'given object'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 vs alternatives like salesforce_update_record or salesforce_query. There are no prerequisites, limitations, or scenarios mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
salesforce_delete_recordB
Delete a record by Id.
| Name | Required | Description | Default |
|---|---|---|---|
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. | |
| record_id | Yes | The Id of the record to delete | |
| object_name | Yes | API name of the object |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must convey behavioral traits. It only says 'Delete' without mentioning side effects like irreversibility, cascading deletes, or authentication requirements beyond what's in schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence of 5 words is extremely concise. While more detail could be added, the current length is appropriate for a simple action, and the key elements are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description is incomplete. It does not hint at return values, error handling, or required permissions, which are needed for a deletion operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters are already described. The description adds minimal meaning beyond 'by Id' for record_id; does not elaborate on object_name or _sfAuth. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'Delete' and resource 'record', qualified by 'by Id'. It distinguishes from sibling tools like 'salesforce_get_record' or 'salesforce_update_record' by the delete action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives, no prerequisites or exclusions. The description lacks context such as depending on the record's existence or necessary permissions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
salesforce_describe_objectA
Describe an sObject: its fields, types, picklist values, and references (trimmed payload).
| Name | Required | Description | Default |
|---|---|---|---|
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. | |
| object_name | Yes | API name of the object, e.g. Account or Custom__c |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description mentions 'trimmed payload,' indicating a reduced response, but lacks details on error behavior, permissions, or rate limits. Annotations are absent, so the description carries the full burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no wasted words. Front-loaded with the primary action and content of the response.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with no output schema, the description covers the key output elements. Could mention the return type (metadata) explicitly, but it's mostly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema fully documents parameters. The description adds no new parameter-level meaning beyond stating the object name is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Describe an sObject' with specifics like fields, types, picklist values, and references. It distinguishes from sibling tools such as salesforce_list_objects and salesforce_get_record.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. Usage is implied as retrieving object metadata, but no exclusions or sibling comparisons are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
salesforce_get_recordB
Retrieve a single record by Id, optionally limited to specific fields.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional list of field API names; omit for all fields | |
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. | |
| record_id | Yes | The 15- or 18-char record Id | |
| object_name | Yes | API name of the object, e.g. Account |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It only states 'retrieve' (read-only implied), but doesn't disclose authentication requirements, rate limits, error handling, or what happens with invalid IDs. The _sfAuth parameter is explained in the schema but not in the description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single, front-loaded sentence of 12 words. No fluff. Every word is necessary and informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple retrieval tool with a well-described schema, the description is minimally adequate. However, it lacks usage guidance and behavioral context, which would help an agent decide when to invoke this tool over siblings like salesforce_query.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description repeats the purpose of record_id and fields ('by Id', 'optionally limited to specific fields') but adds no new semantic meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a single record by ID, with optional field limiting. The verb 'Retrieve' and resource 'single record' are specific, and the sibling tools include query (multiple records) and create/update/delete, so this is well differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus siblings like salesforce_query or salesforce_search. The description implies use for a single record by ID, but doesn't explicitly state when not to use it or suggest alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
salesforce_identityA
Return the identity (user, org, instance) of the supplied token. Use this to confirm the connection is authenticated.
| Name | Required | Description | Default |
|---|---|---|---|
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It states the tool returns identity and confirms authentication, implying it is a safe read operation. However, it does not disclose error behavior (e.g., invalid token) or the exact format of the returned data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences that immediately convey purpose and usage, with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and the description covers the main purpose, but without an output schema, it does not detail the return structure (e.g., fields under user, org, instance). This is a moderate gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one parameter (_sfAuth) with a detailed description indicating it is internal. The tool description does not mention parameters, but schema coverage is 100%, so the description adds minimal value. The baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns identity info (user, org, instance) and confirms authentication, distinguishing it from siblings like salesforce_create_record or salesforce_query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this to confirm the connection is authenticated,' providing clear usage context. It does not mention when not to use or alternatives, but that is less critical given the tool's simplicity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
salesforce_list_objectsA
List all sObjects available in the org with their key metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It does not disclose what 'key metadata' includes, authentication details beyond schema, rate limits, or return format. Minimal behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with verb and resource front-loaded. No extraneous words, every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity and no output schema, the description is minimally sufficient. However, it could specify typical return fields (e.g., name, label) to improve completeness for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers the only parameter (_sfAuth) at 100% with a description of its internal use. The tool effectively has no user-facing parameters, so description adds minimal extra meaning, which is acceptable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'list', resource 'all sObjects', and scope 'with their key metadata'. It distinguishes from siblings like 'salesforce_describe_object' which focuses on a single object and 'salesforce_query' which returns records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool vs alternatives like 'salesforce_describe_object'. Usage is implied as first step to discover available objects, but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
salesforce_queryC
Run a SOQL query and return matching records.
| Name | Required | Description | Default |
|---|---|---|---|
| soql | Yes | A SOQL query, e.g. SELECT Id, Name FROM Account LIMIT 10 | |
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must fully disclose behavior. It does not mention that SOQL is read-only, return format, or any side effects. The _sfAuth parameter is described in schema but the description adds no behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with minimal waste, but it is too brief and lacks structure. It is concise but at the expense of necessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no behavioral annotations, the description leaves out important context: read-only nature, result format, pagination, and authentication fallback. Incomplete for a query tool with no additional structured info.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with adequate descriptions for both parameters (soql example, _sfAuth internal note). The tool description does not add further meaning, meeting the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Run') and resource ('SOQL query'), making the purpose unambiguous. However, it does not differentiate from siblings like salesforce_search or salesforce_get_record, though SOQL is a distinct query language.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 such as salesforce_search or salesforce_get_record. The description simply states what it does without contextual usage advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
salesforce_searchB
Run a SOSL full-text search across objects.
| Name | Required | Description | Default |
|---|---|---|---|
| sosl | Yes | A SOSL search, e.g. FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name) | |
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries full responsibility for behavioral disclosure. It only states 'Run a SOSL full-text search', implying a read operation, but fails to mention important traits like return format, pagination, error handling, or authentication requirements beyond the schema. For a tool with no annotations, this is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no waste. It lacks structure (e.g., bullet points or sections), but it is appropriately sized for a simple tool. Slightly better structure could improve scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with no output schema and two parameters (one required), the description is minimal. It does not specify what the output contains (e.g., records, fields), how results are ordered, or limitations. Given sibling tools like 'salesforce_query' which likely have more detail, this description feels incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (both 'sosl' and '_sfAuth' are documented in the schema). The description adds no additional meaning beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Run a SOSL full-text search across objects' clearly states the verb (Run) and resource (SOSL full-text search across objects). It distinguishes from sibling tools like 'salesforce_query' (SOQL) and 'salesforce_get_record' (single record retrieval).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'SOSL full-text search' implies it is for cross-object full-text search, suggesting it should be used when querying multiple objects or fields with text matching, versus 'salesforce_query' which is for SOQL. However, no explicit when-to-use, when-not-to-use, or alternatives are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
salesforce_update_recordB
Update fields on an existing record.
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Field API name → new value map | |
| _sfAuth | No | Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds. | |
| record_id | Yes | The Id of the record to update | |
| object_name | Yes | API name of the object |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose behavioral traits such as whether partial updates are allowed, return value after update, or any side effects; the minimal description fails to compensate for the lack 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no wasted words, but it lacks additional detail that could improve clarity without adding verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description does not explain return values, error conditions, or authentication details beyond the schema; the tool has moderately complex parameters (including nested _sfAuth), requiring more complete context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters; the description adds no new meaning beyond what is in the schema, but baseline 3 is appropriate given high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Update fields on an existing record' uses a specific verb (Update) and resource (fields on an existing record), clearly distinguishing it from sibling tools like create, delete, or query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like salesforce_create_record or salesforce_query; no when-not or exclusion criteria are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.3.0- Changed
salesforce_create_record1 field changed- added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
- Changed
salesforce_delete_record1 field changed- added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
- Changed
salesforce_describe_object1 field changed- added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
- Changed
salesforce_get_record1 field changed- added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
- Changed
salesforce_identity2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
- Changed
salesforce_list_objects2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
- Changed
salesforce_query1 field changed- added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
- Changed
salesforce_search1 field changed- added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
- Changed
salesforce_update_record1 field changed- added
Input schema / properties / _sfAuthAdded value: +{ + "additionalProperties": false, + "description": "Internal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.", + "properties": { + "accessToken": { + "type": "string" + }, + "apiVersion": { + "type": "string" + }, + "instanceUrl": { + "type": "string" + } + }, + "required": [ + "accessToken", + "instanceUrl" + ], + "type": "object" +}
9 tool updates
v0.1.0- First observed
salesforce_create_record - First observed
salesforce_delete_record - First observed
salesforce_describe_object - First observed
salesforce_get_record - First observed
salesforce_identity - First observed
salesforce_list_objects - First observed
salesforce_query - First observed
salesforce_search - First observed
salesforce_update_record
TDQS
Scored across 9 tools
Each tool targets a clearly distinct Salesforce operation: authentication, SOQL query, SOSL search, object metadata listing, single-object description, and record CRUD. There is minimal risk of an agent selecting the wrong tool because the boundaries between query/search, list/describe, and get/query are well-defined.
All tools share the salesforce_ prefix and use snake_case, which creates a strong sense of uniformity. However, salesforce_identity, salesforce_query, and salesforce_search are bare verbs/nouns while the rest use a verb_noun pattern like salesforce_get_record, so there is a minor stylistic deviation.
Nine tools is a well-scoped set for a Salesforce MCP server. Each tool covers a distinct core capability without redundancy, and the count is within the ideal range for an agent to discover and use the full surface comfortably.
The server provides a complete lifecycle for records: get, create, update, and delete, plus query, search, and object metadata inspection. This covers the primary workflows an agent would need when interacting with Salesforce, with no obvious dead ends or missing essential operations.
Maintenance
Related MCP Connectors
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Run SOQL queries to explore and retrieve Salesforce data. Access accounts, contacts, opportunities…
- GentkeyOAuthcom.gentkey
One MCP URL for all your connectors — scoped writes, enforced constraints, and a full audit trail.
- OneOAuthai.withone
Search, document and execute authenticated API calls across 700+ apps via one MCP server
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceProvides read-only access to Salesforce orgs via MCP, enabling SOQL queries, sObject descriptions, and object listing using OAuth 2.0 Client Credentials.-
- FlicenseBqualityDmaintenanceA customizable MCP server for integrating Salesforce APIs with GenAI applications, supporting SOQL queries, record CRUD, metadata access, and more.136-
- AlicenseAqualityCmaintenanceEnables AI agents to interact with Salesforce through MCP, supporting queries, records, metadata, and bulk operations with flexible OAuth authentication.16MIT
- AlicenseNot gradedqualityDmaintenanceConnects any MCP-compatible AI assistant directly to a Salesforce org for querying data, exploring schema, running Apex, and managing deployments.18MIT