Skip to main content

Salesforce MCP Server

A custom-built, self-hosted MCP server that lets AI agents (Claude Desktop, Claude Code, the MCP Inspector, or any other MCP client) connect to Salesforce — to query, search, and modify data in an org.

Not a Salesforce product. This is an independent, personal learning project — not affiliated with, endorsed by, or supported by Salesforce, Inc. Full explanation: docs/ARCHITECTURE.md.

New to MCP? If "server," "client," and "tool call" aren't already familiar terms, read docs/MCP_PRIMER.md first — five minutes, and everything else here will make more sense.

Quickstart

You'll need: a Salesforce org with an External Client App set up — a free Developer Edition org works fine — and its Consumer Key in hand. docs/SETUP.md walks through creating that (10–15 min); do it first, then come back here.

Three ways to get a running server — pick whichever fits:

Option A — uvx (fastest; no clone, no venv; requires uv):

export SF_LOGIN_URL=https://your-domain.my.salesforce.com
export SF_CLIENT_ID=your-client-id
uvx --from sf-mcp-server sf-mcp-login   # one-time interactive login — opens your browser
uvx sf-mcp-server

(sf-mcp-login needs the explicit --from sf-mcp-serveruv only infers the package name from a bare command when they match, and this package provides two commands. sf-mcp-server matches its own package name, so it doesn't need --from.)

Or drop straight into an MCP client's config (Claude Desktop's claude_desktop_config.json, Claude Code's .mcp.json) with "command": "uvx", "args": ["sf-mcp-server"] and the same env vars, plus SF_PKCE_TOKEN_CACHE set to an absolute path (the client launches the server from its own working directory, not wherever you ran sf-mcp-login, so the default relative cache path won't be found otherwise) — see docs/USAGE.md for the full config example. That login step is only needed once — see docs/AUTHENTICATION.md for what it does and why, and for the alternative Client Credentials Flow (SF_CLIENT_SECRET, no login step) if you'd rather use a fixed service identity instead.

Option B — Python from source (for contributing, or if you'd rather not use uv):

git clone <this-repo-url> && cd salesforce-mcp-server
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env   # fill in SF_LOGIN_URL / SF_CLIENT_ID
python -m salesforce_mcp.login   # one-time interactive login — opens your browser
python -m salesforce_mcp.server

Option C — Docker (no Python setup needed; requires Docker installed and running — check with docker info):

git clone <this-repo-url> && cd salesforce-mcp-server
docker build -t salesforce-mcp-server .
docker run --rm -i \
  -e SF_LOGIN_URL=https://your-domain.my.salesforce.com \
  -e SF_CLIENT_ID=your-client-id \
  -e SF_CLIENT_SECRET=your-client-secret \
  -e SF_AUTH_FLOW=client_credentials \
  -e MCP_TRANSPORT=stdio \
  salesforce-mcp-server

Docker explicitly pins SF_AUTH_FLOW=client_credentials here rather than using the default interactive login — there's no browser or display inside a container for that flow to use. See docs/AUTHENTICATION.md if you actually want PKCE in a container anyway (mount a pre-existing .salesforce_pkce_token.json from the host).

Whichever you pick, that's it running. Next: point the MCP Inspector or Claude Desktop at it and actually try a tool — see docs/USAGE.md.

Quick note on that -e MCP_TRANSPORT=stdio flag in Option C: Python vs. Docker and stdio vs. HTTP are two separate choices, not tied together — Python defaults to stdio and Docker's image defaults to HTTP purely for convenience, but all four combinations actually work. See docs/MCP_PRIMER.md#the-two-transports-stdio-and-streamable-http for what each transport actually is and why. For hosting this on a network instead of running it locally, see docs/DEPLOYMENT.md.

What it can do

  • Query & searchsf_query (SOQL, auto-paginated), sf_search (SOSL)
  • Record CRUDsf_get_record, sf_create_record, sf_update_record, sf_upsert_record (by external ID), sf_delete_record
  • Bulk API 2.0sf_bulk_query, sf_bulk_load, for record volumes too large for the one-record-per-call REST tools above
  • Compositesf_composite, to bundle several sub-requests into one atomic call
  • Describe/discoverysf_describe_object, sf_list_objects (trimmed fields + optional name_contains/custom_only filters, so it doesn't dump 800+ objects' full raw metadata), also available as MCP Resources (salesforce://objects, salesforce://schema/{sobject})
  • Opssf_api_usage (quick API-limit check), sf_org_health (fuller report: org info, all limits, and license seat usage)
  • Custom APIssf_call_apex_rest calls any custom Apex REST endpoint (@RestResource) your org exposes, no code changes needed — see docs/USAGE.md
  • Prompts — ready-made task templates for common requests: summarize_account, draft_followup_email, data_hygiene_check — see docs/USAGE.md
  • Platform events / Change Data Capturesf_subscribe_platform_event replays a bounded batch of events from a platform event or CDC channel, honoring Salesforce's 72-hour Pub/Sub API retention window — see docs/USAGE.md
  • Elicitation — confirms before an unscoped sf_query/sf_search or any delete (sf_delete_record, sf_bulk_load(operation="delete")); disable with SF_ELICITATION_ENABLED=false — see docs/USAGE.md
  • Two auth options — the default interactive "Login with Salesforce" (OAuth Authorization Code + PKCE, per-user), via python -m salesforce_mcp.login or the in-session sf_login tool, or the OAuth Client Credentials Flow (one fixed service identity) for headless/shared use, switched with SF_AUTH_FLOW=client_credentials — see docs/AUTHENTICATION.md
  • Resilient by default — retries transient (5xx / REQUEST_LIMIT_EXCEEDED) Salesforce errors automatically; every other error comes back as a clean, readable message instead of a stack trace

Every tool above talks to a standard Salesforce API out of the box — none of them are specific to any one org. Two ways to add your own: call sf_call_apex_rest (works today, zero code) or add a first-class tool of your own — docs/EXTENDING.md is a step-by-step guide.

Running it remotely (cloud)

The same server also runs as a container behind a network-reachable Streamable HTTP endpoint, for when you want an agent that isn't on the same machine to reach it. This has been built and run locally with Docker and confirmed working — it has not yet been deployed to a real cloud account. docs/DEPLOYMENT.md has the full picture, including that caveat up front, plus two ready-to-try recipes (GCP Cloud Run, AWS App Runner).

Tests

pytest tests/ -v      # all Salesforce calls are mocked with respx — no live org needed
ruff check src tests

This is the automated suite — fast, no Salesforce org or Docker required. There are two other, manual checks, each testing something different: Inspector-against-a-real-org (functional — see docs/USAGE.md) and Docker-build-and-curl (plumbing only — see docs/DEPLOYMENT.md).

Documentation

Read in this order if you're getting started:

# Doc For
1 docs/MCP_PRIMER.md New to MCP — what a server/client/tool call actually is
2 docs/SETUP.md Creating the Salesforce org + integration, .env config
3 docs/AUTHENTICATION.md Both auth flows side by side — Client Credentials vs. "Login with Salesforce" (PKCE)
4 docs/USAGE.md Running it — Claude Desktop, Claude Code, MCP Inspector, example prompts
5 docs/DEPLOYMENT.md Hosting it in the cloud instead of locally
6 docs/EXTENDING.md Adding your own tool for a custom API
7 docs/RELEASING.md Maintainers only — how a PyPI release actually gets published
8 docs/ARCHITECTURE.md Optional — how and why it was built this way

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sf_mcp_server-0.1.1.tar.gz (91.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sf_mcp_server-0.1.1-py3-none-any.whl (53.0 kB view details)

Uploaded Python 3

File details

Details for the file sf_mcp_server-0.1.1.tar.gz.

File metadata

  • Download URL: sf_mcp_server-0.1.1.tar.gz
  • Upload date:
  • Size: 91.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sf_mcp_server-0.1.1.tar.gz
Algorithm Hash digest
SHA256 f3fad8cb8c935d2f9046bf536a5f0e54912e8c29e4ac6bad30602c00a5610b21
MD5 f0b0a2c87fa4173fc095e0d02a57ba47
BLAKE2b-256 4bff49716c13d6e4b4e36850e62c9553b786b48a9c76c4ad9f27072d04b65d41

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_mcp_server-0.1.1.tar.gz:

Publisher: publish.yml on sudhakar6/salesforce-mcp-server

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sf_mcp_server-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: sf_mcp_server-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 53.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sf_mcp_server-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 522de4e3261348163bfd462d744a1322bfc971829692b7b4430616a98c62e72e
MD5 da02d902763689ba032993a27b5440e7
BLAKE2b-256 c81751e89e549e0b3272230910523e4b672adf722bce4c60d8a529821aea20a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_mcp_server-0.1.1-py3-none-any.whl:

Publisher: publish.yml on sudhakar6/salesforce-mcp-server

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page