Skip to main content
Glama
imazhar101

salesforce-mcp-jsforce

by imazhar101

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

salesforce_identity

read

Identity of the supplied token (token validity check)

salesforce_query

read

Run a SOQL query

salesforce_search

read

Run a SOSL full-text search

salesforce_list_objects

read

List sObjects + key metadata

salesforce_describe_object

read

Trimmed describe of an sObject

salesforce_get_record

read

Retrieve a record by Id

salesforce_create_record

write

Create a record

salesforce_update_record

write

Update a record

salesforce_delete_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-jsforce

login 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), or

  • SF_ACCESS_TOKEN + SF_INSTANCE_URL environment 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-Token

  • X-SF-Instance-Url

  • X-SF-Api-Version (optional)

Run as a dedicated HTTP server

PORT=3000 salesforce-mcp-jsforce http

Stateless 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 + audit

Two independent credentials ride on every relayed request, each refreshing itself:

Header

Carries

Refreshed by

Authorization: Bearer …

gateway identity, for scope checks and logging

login --gateway grant

X-SF-Access-Token / X-SF-Instance-Url

Salesforce authorization

login grant

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

SF_ACCESS_TOKEN

stdio access token — wins over the token file, no renewal

SF_INSTANCE_URL

stdio instance URL

SF_API_VERSION

62.0

REST API version

SF_READONLY

off

1 strips write tools

login

Var / flag

Default

Purpose

SF_CLIENT_ID / --client-id

ECA consumer key (required)

SF_LOGIN_URL / --login-url

https://login.salesforce.com

OAuth host; must be https (sandbox: test.salesforce.com)

SF_SCOPE / --scope

api refresh_token

OAuth scopes — drop refresh_token and renewal stops

SF_CALLBACK_PORT / --port

1717

Loopback callback port

SF_REDIRECT_URI / --redirect-uri

http://localhost:<port>/callback

Full callback URL; loopback hosts only

SF_CLIENT_SECRET / --client-secret

Confidential clients only; public PKCE apps omit it

SF_LOGIN_TIMEOUT_MS

300000

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

SF_MCP_CONFIG_DIR

~/.config/salesforce-mcp-jsforce

Token storage location

SF_MCP_HOST

127.0.0.1

HTTP bind address

SF_MCP_ALLOWED_HOSTS

Extra Host/Origin values the HTTP server accepts

SF_MCP_MAX_BODY_BYTES

1048576

Request body ceiling

PORT

3000

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 0600 inside a 0700 directory, 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 state check, requires an https login URL, and times out rather than waiting forever. The callback listens on the loopback interface only — both 127.0.0.1 and ::1, since localhost resolves 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-uri is restricted to loopback hosts.

  • The browser is launched via spawn with 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.

  • logout revokes 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/0700 atomic 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 --help

License

MIT

Available Tools

9 tools
salesforce_create_recordC

Create a new record on the given object.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataYesField API name → value map for the new record
_sfAuthNoInternal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.
object_nameYesAPI name of the object, e.g. Contact

TDQS

C2.9/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

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 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
_sfAuthNoInternal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.
record_idYesThe Id of the record to delete
object_nameYesAPI name of the object

TDQS

B3.1/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
_sfAuthNoInternal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.
object_nameYesAPI name of the object, e.g. Account or Custom__c

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
fieldsNoOptional list of field API names; omit for all fields
_sfAuthNoInternal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.
record_idYesThe 15- or 18-char record Id
object_nameYesAPI name of the object, e.g. Account

TDQS

B3.3/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
_sfAuthNoInternal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
_sfAuthNoInternal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.

TDQS

A3.5/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
soqlYesA SOQL query, e.g. SELECT Id, Name FROM Account LIMIT 10
_sfAuthNoInternal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.

TDQS

C2.8/5.0
Behavior2/5

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.

Conciseness3/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

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 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_update_recordB

Update fields on an existing record.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataYesField API name → new value map
_sfAuthNoInternal: per-request Salesforce credentials injected by an MCP gateway. Leave unset in direct use — the server falls back to env/token-file creds.
record_idYesThe Id of the record to update
object_nameYesAPI name of the object

TDQS

B3.1/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

  1. 9 tool updatesv0.3.0
    • Changedsalesforce_create_record1 field changed
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
    • Changedsalesforce_delete_record1 field changed
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
    • Changedsalesforce_describe_object1 field changed
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
    • Changedsalesforce_get_record1 field changed
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
    • Changedsalesforce_identity2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
    • Changedsalesforce_list_objects2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
    • Changedsalesforce_query1 field changed
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
    • Changedsalesforce_search1 field changed
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
    • Changedsalesforce_update_record1 field changed
      • addedInput schema / properties / _sfAuth
        Added 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"
        +}
  2. 9 tool updatesv0.1.0
    • First observedsalesforce_create_record
    • First observedsalesforce_delete_record
    • First observedsalesforce_describe_object
    • First observedsalesforce_get_record
    • First observedsalesforce_identity
    • First observedsalesforce_list_objects
    • First observedsalesforce_query
    • First observedsalesforce_search
    • First observedsalesforce_update_record

TDQS

A3.6/5.0

Scored across 9 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness5/5

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

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Provides read-only access to Salesforce orgs via MCP, enabling SOQL queries, sObject descriptions, and object listing using OAuth 2.0 Client Credentials.
    -
  • F
    license
    B
    quality
    D
    maintenance
    A customizable MCP server for integrating Salesforce APIs with GenAI applications, supporting SOQL queries, record CRUD, metadata access, and more.
    13
    6
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI agents to interact with Salesforce through MCP, supporting queries, records, metadata, and bulk operations with flexible OAuth authentication.
    16
    MIT