The Salesforce DX MCP Server is the single most productive addition to my developer workflow in 2026. Once it’s wired up, the AI editor I’m already using — Claude Code in my case, Cursor for a couple of my teammates — can deploy metadata, run anonymous Apex, fire SOQL, execute tests, and spin up scratch orgs without me leaving the editor.
But the setup has sharp edges. This guide walks through the path I’d recommend, and flags the footguns I’ve personally hit.
You need Node 20+, the Salesforce CLI (sf), and at least one org already authorized with sf org login web. The MCP server is listed as a pilot / beta service under Salesforce’s Beta Services Terms — don’t make it a hard dependency for anything critical yet.
The Mental Model
The MCP server is a local Node process launched by your editor. It speaks MCP over stdio, and it delegates to the Salesforce CLI (and some Salesforce REST APIs) using the auth you’ve already set up. That means there is no new auth story — if sf org display works, MCP will work.
Step 1 — Authorize the Orgs You Want Reachable
You want one clear default and, optionally, a named Dev Hub:
# Default target org (your usual sandbox or scratch org)
sf org login web --alias MyDevOrg --set-default
# Optional Dev Hub
sf org login web --alias MyDevHub --set-default-dev-hubConfirm with:
sf org listDo not authorize production orgs into the same profile you use for MCP-backed development. The single biggest category of MCP mistakes is “Claude picked the wrong alias and deployed against prod.” Keep prod in a separate OS user, a separate sf config profile, or don’t auth it at all on that machine.
Step 2 — Write Your MCP Config
For Claude Code, add an .mcp.json at the root of your Salesforce project:
{
"mcpServers": {
"Salesforce DX": {
"command": "npx",
"args": [
"-y", "@salesforce/mcp",
"--orgs", "DEFAULT_TARGET_ORG",
"--toolsets", "orgs,metadata,data,users,testing"
]
}
}
}For Cursor, the equivalent goes into ~/.cursor/mcp.json (or the project-level .cursor/mcp.json):
{
"mcpServers": {
"Salesforce DX": {
"command": "npx",
"args": [
"-y", "@salesforce/mcp@latest",
"--orgs", "DEFAULT_TARGET_ORG",
"--toolsets", "orgs,metadata,data,users,testing"
]
}
}
}Restart the editor. You should now see “Salesforce DX” as an MCP server with tools available.
Step 3 — Pick the Right Toolsets
The server bundles tools into 14 toolsets. Enabling all of them pollutes the model’s context and expands your attack surface. Enable only what you need.
Toolsets cheat sheet
| Toolset | What it gives you | When to enable |
|---|---|---|
core | Baseline housekeeping tools | Always |
orgs | List, describe, open authorized orgs | Always |
metadata | Deploy / retrieve metadata | Day-to-day dev |
data | SOQL, SOSL, DML | Any time you query or update records |
users | User / permission lookups | Admin-adjacent work |
testing | Run Apex tests, view coverage | Any time you ship Apex |
code-analysis | Static analysis, anti-pattern scans | Code review, hardening |
lwc-experts | LWC scaffolding and PRD-to-component | LWC development |
aura-experts | Aura migration help | Legacy cleanup |
devops | Pipeline / release helpers | CI/CD authors |
mobile, mobile-core | Mobile-specific scaffolding | Mobile projects |
enrichment | Extra context tools | Research sessions |
scale-products, experts-validation | Specialty validation | As documented |
Start with orgs,metadata,data,users,testing and add more as real needs appear. You’ll hit very few “missing tool” situations with that baseline, and the LLM’s tool-selection quality goes up when there are fewer options to weigh.
Step 4 — Understand the Critical Flags
| Flag | What it does | My recommendation |
|---|---|---|
--orgs | Which orgs the server can reach | Use a specific alias or DEFAULT_TARGET_ORG |
--toolsets | Which tool groups to load | Least-privilege — add as needed |
--tools | Load only named tools | Use for very locked-down setups |
--allow-non-ga-tools | Enables beta / pilot tools | Off unless you know what you’re doing |
--dynamic-tools | Tools load on demand | Only in VS Code / Cline today |
--debug | Verbose logging | On while you’re getting set up |
--no-telemetry | Disable usage telemetry | Per your org’s policy |
--orgs ALLOW_ALL_ORGS looks convenient — the server can reach anything in your CLI profile. It’s a trap in practice. You will eventually chat with Claude about one org while your default alias is pointing at another, and the tool call will silently use the wrong target. Stick to named aliases.
Step 5 — Sanity-Check It Works
Once the editor is restarted, ask it something concrete:
“List the Apex classes in my default org that haven’t been modified in the last year.”
Or:
“Run an anonymous Apex block that counts Accounts created this quarter.”
If the tools are wired correctly, the editor will surface a tool-call approval and — assuming you allow it — return real data.
If it doesn’t, the most common fixes are:
node --version— you need 20+sf org display— confirm the alias exists- Re-run
npx @salesforce/mcpmanually in a terminal and watch the log for the actual error - Delete the npx cache:
npx -y clear-npx-cacheand retry
Step 6 — Make It Safe for a Team
For a team rollout, I hand each developer a version-controlled .mcp.json per project rather than a shared global one. This keeps org scoping explicit in the repo, and every project’s tool surface stays documented and reviewable.
I keep a separate OS user on my machine for production work. That user has the prod alias; my normal user doesn’t. This makes “Claude accidentally touched prod” structurally impossible — the alias isn’t there to pick.
Real-World Scenario
Problem: A teammate had DEFAULT_TARGET_ORG pointing at a partial-copy sandbox for most of the day. Near EOD, they switched to a scratch org for a small fix and forgot to switch back before asking the AI to “deploy the trigger we just changed.” The MCP server deployed into the scratch org and the fix looked good. Next morning, QA reported the sandbox bug was still there.
Root cause: DEFAULT_TARGET_ORG is mutable state outside the editor. The AI had no idea it had changed.
Fix: Use explicit aliases in --orgs (e.g., --orgs MyDevOrg) so the server is pinned to a known org regardless of what sf config is currently set to. If you truly need to switch, edit .mcp.json and restart the server. Making that friction visible is the point.
What About Prompt Injection?
MCP tools are powerful. An attacker who can place content in front of the model (a crafted case comment, a malicious README, a pasted log) can in principle try to steer the model into calling tools it shouldn’t.
Two defences that are worth the small effort:
- Least-privileged toolsets. A server that only exposes
data,metadata,orgscan’t ship destructive DevOps commands. - Explicit approvals for write tools. Claude Code and Cursor both let you require approval on tool calls. Turn it on for anything in the
metadata,data, anddevopstoolsets.
If you’ve set this up for your team, did you keep the toolset list tight or go broad — and why?
How did this article make you feel?
Comments
Salesforce Tip