Repository navigation
Releases
v0.5.2
What's Changed
- fix(relay): answer the MCP handshake locally by @imazhar101 in #21
Full Changelog: v0.5.1...v0.5.2
v0.5.1
What's Changed
- fix(relay): renew expired Salesforce sessions instead of dead-ending by @imazhar101 in #19
Full Changelog: v0.5.0...v0.5.1
v0.5.0 — relay mode
Relay mode
Setting SF_RELAY_URL makes this server stop calling Salesforce and forward each JSON-RPC request to an MCP gateway route instead, so the gateway executes the call under its own policy.
Without it, a local stdio server is invisible to the gateway that is meant to govern it: no activity log, no scope enforcement, and read-only resting on a client-side env var the user can remove.
export SF_RELAY_URL=https://conduit.example.com/mcp/le-salesforce
salesforce-mcp-jsforce login # Salesforce — which records 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 |
|---|---|---|
Authorization: Bearer … |
gateway identity → scope checks + audit | login --gateway grant |
X-SF-Access-Token / X-SF-Instance-Url |
Salesforce authorization | login grant |
The Salesforce refresh token stays on the user's machine — the gateway stores no Salesforce credential.
Direct mode is unchanged. With SF_RELAY_URL unset, every existing path behaves exactly as before.
Notes
- The relay does not interpret the protocol: requests are forwarded verbatim and replies returned unchanged, so it cannot drift out of sync with whatever tools the gateway's copy exposes.
- One retry per credential, only for the failure it can fix —
401renews the gateway token, an expired-session payload renews the Salesforce token.403is reported as a missing scope. - Gateway error bodies are redacted before reaching the model.
- New:
login --gateway,logout --gateway.
Internal
- Shared loopback authorization-code capture between both logins (dual-stack bind,
statecheck,EADDRINUSEhard-fail, timeout in one place). writeSecretFileextracted, so the gateway token gets the same atomic0600-in-0700write as the Salesforce token.
Full changelog: v0.4.2...v0.5.0
v0.4.2
What's Changed
- docs: correct and complete the README (v0.4.2) by @imazhar101 in #15
Full Changelog: v0.4.1...v0.4.2
v0.4.1
What's Changed
- chore: set up Prettier and format the repo by @imazhar101 in #10
- fix(auth): renew expired sessions instead of forcing a re-login; harden the token path (v0.4.0) by @imazhar101 in #8
- fix(login): restore the localhost redirect URI broken in 0.4.0 (v0.4.1) by @imazhar101 in #12
Full Changelog: v0.3.0...v0.4.1
v0.3.0
What's Changed
- fix(login): exit after callback; add --quiet (v0.3.0) by @imazhar101 in #6
Full Changelog: v0.2.0...v0.3.0
v0.2.0
What's Changed
- feat: per-request _sfAuth for gateway BYO passthrough (v0.2.0) by @imazhar101 in #4
Full Changelog: v0.1.0...v0.2.0
v0.1.0
First release of @imazhar101/salesforce-mcp-jsforce — a lite, single-org Salesforce MCP server built on jsforce.
- Bring-your-own OAuth token (no server-side credentials).
- Runs over stdio (Claude Code) or as a dedicated streamable-HTTP server.
- Tools: identity, SOQL query, SOSL search, list/describe objects, get record, and create/update/delete (gated by
SF_READONLY). - PKCE
logincommand for first-time auth.
Published to npm: https://www.npmjs.com/package/@imazhar101/salesforce-mcp-jsforce