Metadata-Version: 2.5
Name: sf-mcp-server
Version: 0.1.0
Summary: An independent, open-source MCP server for Salesforce (REST, Bulk API 2.0, Composite) — not a Salesforce product.
Project-URL: Homepage, https://github.com/sudhakar6/salesforce-mcp-server
Project-URL: Repository, https://github.com/sudhakar6/salesforce-mcp-server
Project-URL: Documentation, https://github.com/sudhakar6/salesforce-mcp-server/tree/main/docs
Project-URL: Issues, https://github.com/sudhakar6/salesforce-mcp-server/issues
License: MIT
License-File: LICENSE
Keywords: ai-agents,mcp,model-context-protocol,salesforce,soql
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: fastavro>=1.9
Requires-Dist: grpcio>=1.66
Requires-Dist: httpx>=0.27
Requires-Dist: mcp[cli]>=2.1.0
Requires-Dist: protobuf>=5
Requires-Dist: python-dotenv>=1.0
Requires-Dist: starlette>=0.37
Requires-Dist: uvicorn>=0.30
Provides-Extra: codegen
Requires-Dist: grpcio-tools>=1.66; extra == 'codegen'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# 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](docs/ARCHITECTURE.md#not-a-salesforce-product).

> **New to MCP?** If "server," "client," and "tool call" aren't already
> familiar terms, read [docs/MCP_PRIMER.md](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](https://developer.salesforce.com/signup) works
fine — and its Consumer Key in hand. [docs/SETUP.md](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](https://docs.astral.sh/uv/getting-started/installation/)):

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

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 — see
[docs/USAGE.md](docs/USAGE.md) for full client config examples. That login
step is only needed once — see [docs/AUTHENTICATION.md](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`):

```bash
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`):

```bash
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](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](https://github.com/modelcontextprotocol/inspector) or Claude
Desktop at it and actually try a tool — see [docs/USAGE.md](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](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](docs/DEPLOYMENT.md).

## What it can do

- **Query & search** — `sf_query` (SOQL, auto-paginated), `sf_search` (SOSL)
- **Record CRUD** — `sf_get_record`, `sf_create_record`, `sf_update_record`,
  `sf_upsert_record` (by external ID), `sf_delete_record`
- **Bulk API 2.0** — `sf_bulk_query`, `sf_bulk_load`, for record volumes too
  large for the one-record-per-call REST tools above
- **Composite** — `sf_composite`, to bundle several sub-requests into one
  atomic call
- **Describe/discovery** — `sf_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}`)
- **Ops** — `sf_api_usage` (quick API-limit check), `sf_org_health` (fuller
  report: org info, all limits, and license seat usage)
- **Custom APIs** — `sf_call_apex_rest` calls any custom Apex REST endpoint
  (`@RestResource`) your org exposes, no code changes needed — see
  [docs/USAGE.md](docs/USAGE.md#calling-a-custom-apex-rest-api)
- **Prompts** — ready-made task templates for common requests:
  `summarize_account`, `draft_followup_email`, `data_hygiene_check` — see
  [docs/USAGE.md](docs/USAGE.md#prompts)
- **Platform events / Change Data Capture** — `sf_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](docs/USAGE.md#subscribing-to-platform-events)
- **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](docs/USAGE.md#elicitation)
- **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](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](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](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

```bash
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](docs/USAGE.md))
and Docker-build-and-curl (plumbing only — see [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md#build-and-run-locally-first)).

## Documentation

Read in this order if you're getting started:

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

## License

[MIT](LICENSE)
