Skip to main content
ClaudeWave
WYRE-AI avatar
WYRE-AI

salesforce-mcp

View on GitHub

MCP server for Salesforce CRM, scoped to the WYRE Gateway BYOC use case. Six tools: search/describe/query/aggregate/dml/sosl.

MCP ServersOfficial Registry0 stars1 forks● TypeScriptNOASSERTIONUpdated today
ClaudeWave Trust Score
72/100
· OK
Passed
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Documented (README)
Flags
  • !Licence file present but not machine-readable
Last scanned: 10/17/2026
Install in Claude Code / Claude Desktop
Method: Manual
Claude Code CLI
git clone https://github.com/WYRE-AI/salesforce-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "salesforce-mcp": {
      "command": "node",
      "args": ["/path/to/salesforce-mcp/dist/index.js"],
      "env": {
        "SALESFORCE_CLIENT_SECRET": "<salesforce_client_secret>",
        "SALESFORCE_INSTANCE_URL": "<salesforce_instance_url>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Clone https://github.com/WYRE-AI/salesforce-mcp and follow its README for install instructions.
Detected environment variables
SALESFORCE_CLIENT_SECRETSALESFORCE_INSTANCE_URL
Use cases

MCP Servers overview

# salesforce-mcp

> MCP (Model Context Protocol) server for Salesforce CRM, scoped to the WYRE Gateway BYOC use case.

A focused HTTP MCP server that exposes a Salesforce org's CRM data surface to Claude (and other MCP clients) through the [WYRE MCP Gateway](https://mcp.wyre.ai/). Built for the multi-tenant gateway pattern: credentials are injected per-request via HTTP headers, no startup secrets are baked into the container.

## Scope discipline

This package intentionally ships a **narrow tool surface** — six CRM data tools — and deliberately omits the Apex code-management / custom-object-creation / EXECUTE_ANONYMOUS surfaces that broader Salesforce MCP servers include. The use case is read/write access to standard CRM objects (Accounts, Contacts, Opportunities, Leads, Cases). Customers who need DX or admin tooling should use the official `@salesforce/mcp` package instead.

## Tools

| Tool | Purpose |
| --- | --- |
| `salesforce_search_objects` | Find standard + custom objects by partial name. |
| `salesforce_describe_object` | Full schema (fields, picklists, relationships) for an object. |
| `salesforce_query_records` | Execute SOQL with relationship traversal. |
| `salesforce_aggregate_query` | SOQL GROUP BY / COUNT / SUM / AVG / MIN / MAX. |
| `salesforce_dml_records` | Insert / update / delete / upsert records. |
| `salesforce_search_all` | Cross-object SOSL search. |

## Run modes

- **`http` (default)**: listens on `:8080`, exposes `/mcp` (JSON-RPC) + `/health`. Per-request credentials from `X-Salesforce-*` headers. This is the gateway deployment shape. HTTP refuses to start unless `CONDUIT_S2S_SECRET` is a real secret.
- **`stdio`**: traditional MCP client transport (Claude Desktop / Cursor). Credentials read once from env. The stdio transport does not use `CONDUIT_S2S_SECRET`.

Copy [`.env.example`](.env.example) and set the variables below. Leave `CONDUIT_S2S_SECRET` empty in that file.

| Variable | Required | Description |
| --- | --- | --- |
| `SALESFORCE_CLIENT_ID` / `SALESFORCE_CLIENT_SECRET` / `SALESFORCE_INSTANCE_URL` | For stdio and `AUTH_MODE=env` | Client Credentials flow. |
| `SALESFORCE_USERNAME` / `SALESFORCE_PASSWORD` / `SALESFORCE_TOKEN` | For username-password | Used when `SALESFORCE_AUTH_FLOW=username_password`. The token is optional if the org uses IP allowlisting. |
| `MCP_TRANSPORT` | No | `http` (default) or `stdio`. |
| `AUTH_MODE` | No | `gateway` (image and Compose default) or `env`. Gateway mode requires the `X-Salesforce-*` headers on each `/mcp` request and never falls back to `SALESFORCE_*`. `env` uses those variables only after S2S auth succeeds. |
| `CONDUIT_S2S_SECRET` | Yes for HTTP | Service-to-service secret. HTTP logs an error and exits non-zero when this is empty or a known placeholder (`changeme`, `placeholder`, `your-s2s-secret`, `secret`, `password`, `test`, an unresolved `${...}` template, and the other stand-ins in `src/s2s-verify.ts`). Never commit a real value. |
| `MCP_ALLOW_INSECURE_DEV` | No | Set to exactly `1` only for local development to start HTTP without a usable secret. The process logs a warning, does not check `X-Gateway-S2S`, and listens on `127.0.0.1` only. A non-loopback `MCP_HTTP_HOST` is ignored and the override is logged. |
| `MCP_HTTP_HOST` | No | Bind address when a usable `CONDUIT_S2S_SECRET` is set. When unset, a configured secret keeps `HOST` (default `0.0.0.0`). Without a usable secret the listener is `127.0.0.1`. The container image sets `0.0.0.0`. |
| `PORT` | No | HTTP port. Defaults to `8080`. |
| `HOST` | No | Fallback bind address when `MCP_HTTP_HOST` is unset and a secret is configured. Defaults to `0.0.0.0`. |

`/health` stays unauthenticated and does not read credentials.

```bash
# HTTP mode (exits unless CONDUIT_S2S_SECRET is a real secret)
CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" PORT=8080 MCP_TRANSPORT=http AUTH_MODE=gateway npm start

# Local HTTP only, without a service-to-service secret (always binds 127.0.0.1)
MCP_ALLOW_INSECURE_DEV=1 MCP_TRANSPORT=http npm start

# stdio mode (env-baked, local testing; no S2S secret)
MCP_TRANSPORT=stdio \
SALESFORCE_AUTH_FLOW=client_credentials \
SALESFORCE_CLIENT_ID=... SALESFORCE_CLIENT_SECRET=... \
SALESFORCE_INSTANCE_URL=https://yourorg.my.salesforce.com \
node dist/entry.js
```

## Header contract (gateway mode)

Every `/mcp` request must include a valid `X-Gateway-S2S` header when `CONDUIT_S2S_SECRET` is set. Gateway mode also requires the credential headers for the chosen flow. A request missing them returns `401` and does not fall back to `SALESFORCE_*` in the process environment.

| Header | Required? | Notes |
| --- | --- | --- |
| `X-Gateway-S2S` | Yes when the S2S secret is set | `t=<unix seconds>,v1=<hex hmac-sha256>`. See [X-Gateway-S2S signing](#x-gateway-s2s-signing). |
| `X-Salesforce-Auth-Mode` | optional | `client_credentials` (default) or `username_password`. |
| `X-Salesforce-Client-Id` | for client_credentials | Connected App consumer key. |
| `X-Salesforce-Client-Secret` | for client_credentials | Connected App consumer secret. |
| `X-Salesforce-Instance-Url` | for client_credentials | Customer's My Domain URL (e.g. `https://acmecorp.my.salesforce.com`). |
| `X-Salesforce-Username` | for username_password | Salesforce user. |
| `X-Salesforce-Password` | for username_password | Salesforce password. |
| `X-Salesforce-Token` | for username_password | Security token (required unless IP allowlisted). |

Per-request authentication means the same container instance can service many customers without restart — each MCP `tools/call` builds a fresh `jsforce.Connection` from the headers on that request.

### X-Gateway-S2S signing

`v1` is HMAC-SHA256, hex-encoded, of the ASCII string `t=<unix seconds>` (the same `t=` prefix that starts the header), keyed with `CONDUIT_S2S_SECRET`. The timestamp must be within 300 seconds of the server clock. A missing or invalid header returns HTTP 401. The secret is never written to logs or the response body.

```bash
t=$(date +%s)
v1=$(printf 't=%s' "$t" | openssl dgst -sha256 -hmac "$CONDUIT_S2S_SECRET" | awk '{print $NF}')
curl -sS http://127.0.0.1:8080/mcp \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -H "X-Gateway-S2S: t=${t},v1=${v1}" \
  -H "X-Salesforce-Client-Id: ..." \
  -H "X-Salesforce-Client-Secret: ..." \
  -H "X-Salesforce-Instance-Url: https://yourorg.my.salesforce.com" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```

## Salesforce Connected App setup

For Client Credentials flow (the recommended path):

1. Salesforce Setup → App Manager → New Connected App.
2. Under **API (Enable OAuth Settings)**: turn on **Enable OAuth Settings** and **Enable Client Credentials Flow**.
3. Save, wait ~5 minutes for propagation.
4. Manage → Edit Policies → Client Credentials Flow → set a **Run As** user (the API calls run with that user's permissions).
5. Copy the Consumer Key and Consumer Secret from the Connected App into the gateway BYOC fields as `clientId` and `clientSecret`.
6. Set `instanceUrl` to the customer's My Domain URL (Setup → My Domain).

## Build

```bash
npm install
npm run build
```

## Container

The image listens on `0.0.0.0` inside the container (`MCP_HTTP_HOST`) and defaults to `AUTH_MODE=gateway`. Publish the port on loopback and pass the S2S secret. In gateway mode, Salesforce credentials arrive on each request as headers; they are not read from the environment.

```bash
docker build -t salesforce-mcp:dev .
docker run --rm \
  -e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
  -p 127.0.0.1:8080:8080 \
  salesforce-mcp:dev
curl -s http://127.0.0.1:8080/health
```

Compose refuses to start when `CONDUIT_S2S_SECRET` is unset, sets `AUTH_MODE=gateway`, publishes `127.0.0.1:8080:8080`, and does not inject `SALESFORCE_*`:

```bash
CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" docker compose up
```

Single-tenant HTTP (`AUTH_MODE=env`) still requires the S2S secret, then uses `SALESFORCE_*`:

```bash
docker run --rm \
  -e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
  -e AUTH_MODE=env \
  -e SALESFORCE_AUTH_FLOW=client_credentials \
  -e SALESFORCE_CLIENT_ID=your-value \
  -e SALESFORCE_CLIENT_SECRET=your-value \
  -e SALESFORCE_INSTANCE_URL=https://yourorg.my.salesforce.com \
  -p 127.0.0.1:8080:8080 \
  salesforce-mcp:dev
```

The published image lives at `ghcr.io/wyre-ai/salesforce-mcp` with `:latest`, `:sha-<short_sha>`, and `:v<version>` tags.

## License

Apache-2.0.

What people ask about salesforce-mcp

What is WYRE-AI/salesforce-mcp?

+

WYRE-AI/salesforce-mcp is mcp servers for the Claude AI ecosystem. MCP server for Salesforce CRM, scoped to the WYRE Gateway BYOC use case. Six tools: search/describe/query/aggregate/dml/sosl. It has 0 GitHub stars and its last recorded update is dated 2026-10-17.

How do I install salesforce-mcp?

+

You can install salesforce-mcp by cloning the repository (https://github.com/WYRE-AI/salesforce-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is WYRE-AI/salesforce-mcp safe to use?

+

Our security agent has analyzed WYRE-AI/salesforce-mcp and assigned a Trust Score of 72/100 (tier: OK). See the full breakdown of passed checks and flags on this page.

Who maintains WYRE-AI/salesforce-mcp?

+

WYRE-AI/salesforce-mcp is maintained by WYRE-AI. The last recorded GitHub activity is dated 2026-10-17, with 3 open issues.

Are there alternatives to salesforce-mcp?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy salesforce-mcp to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: WYRE-AI/salesforce-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/wyre-ai-salesforce-mcp)](https://claudewave.com/repo/wyre-ai-salesforce-mcp)
<a href="https://claudewave.com/repo/wyre-ai-salesforce-mcp"><img src="https://claudewave.com/api/badge/wyre-ai-salesforce-mcp" alt="Featured on ClaudeWave: WYRE-AI/salesforce-mcp" width="320" height="64" /></a>

More MCP Servers

salesforce-mcp alternatives