SfSkills Domains Docs GitHub

Home / agentforce / salesforce-mcp-server-setup

salesforce-mcp-server-setup

Use this skill to install and configure the salesforce-mcp-lib Apex package and npm stdio proxy so that an MCP client (Claude Desktop, Cursor, ChatGPT) can call Salesforce org data and logic via the Model Context Protocol. Trigger keywords: MCP server, salesforce-mcp-lib, Claude Desktop Salesforce, MCP proxy setup, Apex JSON-RPC, MCP Connected App. NOT for writing the Apex tool classes the server exposes — use agentforce/mcp-tool-definition-apex. NOT for choosing between MCP, REST and Platform Events for external AI access — use architect/ai-agent-org-integration-architecture.

Open the skill folder on GitHub


Salesforce MCP Server Setup

This skill activates when a practitioner needs to install the salesforce-mcp-lib open-source package (MIT license, https://github.com/Damecek/salesforce-mcp-lib) and configure its two-component architecture — the Apex 2GP unlocked package running inside the org plus the Node.js stdio proxy running on the developer machine — so that an MCP-capable AI client such as Claude Desktop or Cursor can call Salesforce org data and business logic through the standardized Model Context Protocol.

This skill covers the self-hosted salesforce-mcp-lib bridge (Apex REST + Node.js stdio proxy). Salesforce also ships Hosted MCP Servers (GA, Spring '26) — OAuth-backed MCP tools with no JSON-RPC code of your own. Route new work to Hosted MCP when standard/custom servers cover the surface; use salesforce-mcp-lib when you need a bespoke Apex REST tool chain the hosted catalog does not expose.


Before Starting

Gather this context before working on anything in this domain:

ContextWhat to confirm
Org API versionsalesforce-mcp-lib requires API 65.0+ (Spring '25+). Confirm with sf org display --target-org YOUR_ORG.
Node.js versionThe npm proxy requires Node.js >= 20. Run node --version to confirm.
Connected AppOAuth 2.0 Client Credentials Flow enabled. The proxy authenticates as a service account — no named user, browser, or interaction.
Endpoint URLOne Apex REST class serves as the MCP entry point. The URL mapping you choose (e.g. /mcp/v1) becomes the --endpoint flag value.
Package IDCurrent installable 2GP Apex package ID: 04tdL000000So9xQAC. Always verify against the GitHub release page before installing in production.

Core Concepts

Two-Component Architecture

salesforce-mcp-lib splits into an org-side Apex component and a client-side Node.js component. Neither works without the other.

MCP Message Flow

MCP Client (Claude/Cursor)
  ↓ JSON-RPC 2.0 over stdio
npm proxy (salesforce-mcp-lib)
  ↓ OAuth 2.0 Client Credentials → access token
  ↓ HTTPS POST /services/apexrest/mcp/v1
Apex REST endpoint (your org)
  ↓ McpServer.handleRequest()
  ↓ registered McpToolDefinition / McpResourceDefinition / McpPromptDefinition
  ↑ JSON-RPC response

Understanding this flow is essential for debugging: authentication errors come from the proxy layer; logic errors come from the Apex layer.

Four-Layer Security Model

Security is enforced at four independent layers:

  1. OAuth 2.0 scopes on the Connected App — restrict which API surfaces the service account can reach.
  2. Profile permissions — the Connected App's run-as profile controls field and object access.
  3. Permission Sets — additional fine-grained access layered on top of the profile.
  4. Sharing rules — Apex running without without sharing respects the platform's record visibility rules.

If you omit without sharing on your Apex endpoint class, record access is governed by sharing rules for the Connected App user. This is almost always the correct default. Add with sharing explicitly if you want to enforce the strictest user-context access rules for the service account.


Common Patterns

Pattern: Full Stack Setup (Apex Package + npm Proxy + Claude Desktop)

When to use: You are setting up salesforce-mcp-lib for the first time in an org and want Claude Desktop to be able to call Salesforce tools.

How it works:

  1. Install the Apex package: sf package install --package 04tdL000000So9xQAC --target-org YOUR_ORG --wait 10
  2. Create an Apex REST endpoint class in your org (see templates/).
  3. Create a Connected App with OAuth 2.0 Client Credentials Flow enabled. Note the Client ID and Client Secret.
  4. Add the Claude Desktop config block to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) with the correct --instance-url, --client-id, --client-secret, and --endpoint values.
  5. Restart Claude Desktop and verify the MCP tools appear in the Tools panel.

Why not the alternative: Using the Salesforce REST API directly from an MCP client requires custom OAuth handling in every client. The npm proxy abstracts that into a one-time configuration step.

Pattern: Environment Variable Configuration (CI/CD-Friendly)

When to use: You want to avoid embedding secrets in the claude_desktop_config.json or share configuration across team members.

How it works: The npm proxy reads all flags from environment variables: SF_INSTANCE_URL, SF_CLIENT_ID, SF_CLIENT_SECRET, SF_ENDPOINT, and optionally SF_LOG_LEVEL. Set these in a .env file (gitignored) or in your CI environment, then reference them in the args block using your shell's expansion syntax.


Decision Guidance

SituationRecommended ApproachReason
First time setup in a sandboxInstall package, create endpoint, test with --log-level debugDebug logging shows each JSON-RPC exchange so you can confirm the handshake works
Production deploymentUse environment variables instead of inline secrets in config filesSecrets in config files risk accidental git exposure
Multiple tools from one orgRegister all tools in a single Apex endpoint classOne endpoint = one Connected App = one proxy instance; simpler to manage
Tool needs record-level access controlUse default sharing (no without sharing) on the Apex classPlatform sharing rules control visibility without custom code
Need to expose resources (documents, records)Extend McpResourceDefinition or McpResourceTemplateDefinitionResources are read-only by MCP spec; use tools for write operations

Step-by-step instructions for an AI agent or practitioner working on this task:

  1. Verify prerequisites — confirm sf org display shows API version 65.0+, confirm node --version shows >= 20, and confirm you have Salesforce CLI installed.
  2. Install the Apex package — run sf package install --package 04tdL000000So9xQAC --target-org YOUR_ORG --wait 10. Confirm installation with sf package installed list --target-org YOUR_ORG.
  3. Create the Apex REST endpoint — deploy an Apex class with @RestResource(urlMapping='/mcp/v1') and a @HttpPost method that instantiates McpServer, registers tools, and calls server.handleRequest(RestContext.request, RestContext.response).
  4. Create the Connected App — enable OAuth 2.0 Client Credentials Flow, assign a run-as user (service account profile), and capture the Client ID and Client Secret.
  5. Wire the npm proxy — add the mcpServers.salesforce block to the MCP client's config file with all four required flags (--instance-url, --client-id, --client-secret, --endpoint).
  6. Smoke-test the connection — restart the MCP client, open the tools panel, and confirm the registered tools appear. Use --log-level debug to inspect the JSON-RPC handshake if tools do not appear.
  7. Harden for production — move secrets to environment variables, restrict Connected App scopes to the minimum required, confirm the run-as profile has only the necessary object permissions.

Review Checklist

Run through these before marking work in this area complete:


Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems:

  1. Apex stateless execution — The McpServer handler chain is rebuilt on every HTTP request. Do not store state in static variables expecting it to persist across MCP calls. Each tool invocation is a fresh Apex transaction.
  2. Connected App propagation delay — After enabling OAuth 2.0 Client Credentials Flow on a Connected App, Salesforce can take up to 10 minutes to propagate the change to all auth servers. The proxy will return 401 during this window. Wait and retry before debugging further.
  3. API version on the endpoint — The @RestResource URL mapping does not include an API version. The Connected App's OAuth token is issued for the org's default API version. If you need a specific version, include it in your endpoint path explicitly.
  4. Sharing context of the run-as user — The Client Credentials flow runs as the Connected App's run-as user. SOQL queries inside your Apex tools will be governed by that user's sharing access unless you explicitly use without sharing. Unexpected empty result sets are almost always a sharing-context mismatch.

Output Artifacts

ArtifactDescription
Installed Apex packagesalesforce-mcp-lib 2GP classes available for extension in the target org
Apex REST endpoint classThe entry point that McpServer.handleRequest() is called from
Claude Desktop config blockThe mcpServers JSON stanza wiring the proxy to the org
Connected AppOAuth 2.0 service account credentials for the proxy


Official Sources Used

Package files