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 "Install 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
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"}'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.
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
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables lead management and permission set operations on Salesforce through the MCP protocol.
- 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.137
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with Salesforce through MCP, supporting queries, records, metadata, and bulk operations with flexible OAuth authentication.MIT
Related MCP Connectors
Run SOQL queries to explore and retrieve Salesforce data. Access accounts, contacts, opportunities…
Search, document and execute authenticated API calls across 700+ apps via one MCP server
Run SOQL queries against your Salesforce org to retrieve records and insights. Explore objects, fi…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/imazhar101/salesforce-mcp-jsforce'
If you have feedback or need assistance with the MCP directory API, please join our Discord server