Advertisement

Integration Scenario

Salesforce MCP OAuth Fails Due to Dynamic Callback Port in Claude Code

7 June 2026 · 5 min read · Intermediate

The situation

You added a Salesforce Hosted MCP Server in Claude Code and triggered authentication. The Salesforce consent screen opens correctly — but after approving, the browser shows “site cannot be reached” and Claude Code never completes the flow. Repeating the attempt uses a completely different port each time: localhost:41991, then localhost:40892, then localhost:39756.


Root cause

Claude Code assigns a random available port on each OAuth attempt. The redirect_uri it sends to Salesforce — for example http://localhost:40892/callback — does not match the registered callback URL on your External Client App (http://localhost:38000/callback), so the redirect fails.

This is not a Salesforce configuration error. The ECA is set up correctly. The fix is one flag.


Resolution

Step 1 — Remove the existing entry

claude mcp remove sf-sobject-reads

Step 2 — Re-add with a pinned callback port

claude mcp add --transport http --scope user \
  --client-id "<YOUR_CONSUMER_KEY>" \
  --callback-port 38000 \
  sf-sobject-reads \
  https://api.salesforce.com/platform/mcp/v1/platform/sobject-reads

The --callback-port 38000 flag pins the OAuth listener to port 38000 on every run, matching http://localhost:38000/callback registered on your ECA.

Port 38000 must be free when Claude Code starts its listener. Run lsof -i :38000 (macOS/Linux) to confirm the port is available.

Step 3 — Restart Claude Code

MCP config is cached at startup. Quit and relaunch:

claude

Step 4 — Authenticate

Run /mcp → select the server → Authenticate → approve in browser → redirect lands on http://localhost:38000/callback → flow completes → server status changes to connected.


Verification

claude mcp list

All servers should show ✓ Connected.

To re-add all servers at once with the correct port, use the bulk-add commands in the main setup guide.


Troubleshooting reference

SymptomFix
redirect_uri_mismatchECA still propagating — wait 5–30 min after creation or edits
Browser opens then errors instantly--callback-port does not match the ECA’s localhost callback URL
Server shows “needs auth” after restartToken expired — re-authenticate via /mcp
Need to remove a serverclaude mcp remove <name>

Advertisement

Frequently asked questions

Why does Salesforce MCP OAuth authentication fail in Claude Code?

Claude Code picks a random available port on each OAuth attempt. The redirect_uri it sends to Salesforce does not match the fixed callback URL registered on the External Client App, so Salesforce rejects the redirect.

How do I fix the dynamic callback port issue in Claude Code MCP setup?

Remove the existing MCP server entry and re-add it using the --callback-port 38000 flag. This pins the OAuth callback to port 38000 on every run, matching the http://localhost:38000/callback URL registered on your External Client App.

Why does Claude Code need a restart after changing MCP configuration?

Claude Code caches MCP configuration at startup. Changes to callbackPort or client credentials do not take effect in a running session — a full restart is required.

What does --scope user do in the claude mcp add command?

It stores the MCP server configuration in ~/.claude.json, making it available in every project on that machine rather than scoping it to a single project directory.

How do I verify the callback port is correctly pinned?

Run claude mcp list. All connected servers should show checkmarks. Confirm the registered ECA callback URL http://localhost:38000/callback matches the --callback-port value used during claude mcp add.

Advertisement