Skip to content
This repository was archived by the owner on Oct 27, 2026. It is now read-only.

Commit 9324afe

Browse files
Valerie Fanellecursoragent
andcommitted
docs: document all 11 Salesforce MCP custom OAuth scopes
The toolkit requests four write/read scopes that were missing from the auth provider page, and the samples told people to pass only read_account. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 89b0e6d commit 9324afe

1 file changed

Lines changed: 69 additions & 17 deletions

File tree

  • app/en/references/auth-providers/salesforce

‎app/en/references/auth-providers/salesforce/page.mdx‎

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -96,28 +96,32 @@ The Salesforce API requires the App developer to create [OAuth custom scopes](ht
9696

9797
The custom scopes required by the [Arcade Salesforce MCP Server](/resources/integrations/sales/salesforce) are listed below, along with their descriptions:
9898

99-
<Callout type="info">
100-
The custom scopes listed below are only required if you are using the [Arcade Salesforce MCP Server](/resources/integrations/sales/salesforce).
101-
102-
If you're creating your own [custom Salesforce tools](/build/create-tools/tool-basics/build-mcp-server) or using Arcade to authorize users and call Salesforce APIs directly, you are free to define custom scope(s) that fit best your application use cases. Observe that you must have at least one custom scope assigned to your Salesforce app in order to use the Salesforce API.
103-
104-
</Callout>
105-
10699
- `read_account`: Read access to account data.
107100
- `read_contact`: Read access to contact data.
108101
- `read_lead`: Read access to lead data.
109102
- `read_note`: Read access to note data.
110103
- `read_opportunity`: Read access to opportunity data.
111104
- `read_task`: Read access to task data.
105+
- `read_user`: Read access to user data.
112106
- `write_contact`: Write access to create contact.
107+
- `write_lead`: Write access to create/update leads.
108+
- `write_opportunity`: Write access to create/update opportunities.
109+
- `write_task`: Write access to create/update tasks.
113110

114111
Follow the [Create an OAuth Custom Scope](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_customscopes_create.htm&type=5) and [Assign an OAuth Custom Scope to an External Client App](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_customscopes_assign.htm&type=5) Salesforce documentation to understand how to define and assign these scopes to your Salesforce app.
115112

113+
<Callout type="info">
114+
If you use the [Arcade Salesforce MCP Server](/resources/integrations/sales/salesforce), you must create, assign, and request every custom scope in the list above. Salesforce requires at least one custom scope on the app. One scope is not enough for the MCP server.
115+
</Callout>
116+
117+
<Callout type="info">
118+
The authorize URL will still include Salesforce's built-in `api` and `refresh_token` scopes from [Create a Salesforce app](#create-a-salesforce-app), even if you only pass custom names to `auth.start()`. Those are not custom scopes. Don't create them in the custom-scope UI.
119+
</Callout>
120+
116121
<Callout>
117-
The scope names aren't really attached to any endpoint or action. It's the
118-
developer's job to honor the permissions communicated to the user when
119-
authorizing the app. You could, in theory, assign one single scope (e.g.
120-
`fullaccess`) and use it to query any Salesforce API endpoint.
122+
If you're creating your own [custom Salesforce tools](/build/create-tools/tool-basics/build-mcp-server) or using Arcade to authorize users and call Salesforce APIs directly, you are free to define custom scopes that fit your application. You must assign at least one custom scope to your Salesforce app.
123+
124+
For custom tools, the scope names aren't attached to any endpoint or action. Honor the permissions you communicate to the user when they authorize the app. You could assign one single scope (e.g. `fullaccess`) and use it to query any Salesforce API endpoint.
121125
</Callout>
122126

123127
## Configuring Salesforce Auth
@@ -243,15 +247,27 @@ client = Arcade(base_url="http://localhost:9099") # Automatically finds the `AR
243247
salesforce_provider_id = "salesforce"
244248
salesforce_org_subdomain = "salesforce-org-subdomain"
245249
user_id = "{arcade_user_id}"
246-
scopes = ["read_account"]
250+
scopes = [
251+
"read_account",
252+
"read_contact",
253+
"read_lead",
254+
"read_note",
255+
"read_opportunity",
256+
"read_task",
257+
"read_user",
258+
"write_contact",
259+
"write_lead",
260+
"write_opportunity",
261+
"write_task",
262+
]
247263
```
248264

249265
Here's a break down of each value:
250266

251267
- **`salesforce_provider_id`**: the ID you entered when setting up the [Salesforce auth provider](#configuring-salesforce-auth);
252268
- **`salesforce_org_subdomain`**: your [Salesforce Org Subdomain](#get-your-salesforce-org-subdomain);
253269
- **`user_id`**: an internal identifier for your application user (it could be an email address, a username, UUID, etc); for demonstration purposes, in this example, enter your own email address;
254-
- **`scopes`**: the list of scopes you want to request from the user; if you assigned the [custom scopes required by the Arcade Salesforce MCP Server](#create-and-assign-custom-scopes-to-your-external-client-app) use `["read_account"]` in this example.
270+
- **`scopes`**: the custom scopes to request from the user. Creating and assigning them on the Salesforce app is not enough. `auth.start()` only consents to this list. For the [Arcade Salesforce MCP Server](#create-and-assign-custom-scopes-to-your-external-client-app), pass every scope in the list above.
255271

256272
### Start the authorization process and wait for completion
257273

@@ -329,7 +345,19 @@ client = Arcade(base_url="http://localhost:9099") # Automatically finds the `ARC
329345
salesforce_provider_id = "salesforce"
330346
salesforce_org_subdomain = "salesforce-org-subdomain"
331347
user_id = "{arcade_user_id}"
332-
scopes = ["read_account"]
348+
scopes = [
349+
"read_account",
350+
"read_contact",
351+
"read_lead",
352+
"read_note",
353+
"read_opportunity",
354+
"read_task",
355+
"read_user",
356+
"write_contact",
357+
"write_lead",
358+
"write_opportunity",
359+
"write_task",
360+
]
333361

334362
# Start the authorization process
335363

@@ -410,15 +438,27 @@ const client = new Arcade((baseURL = "http://localhost:9099")); // Automatically
410438
const salesforceProviderId = "salesforce";
411439
const salesforceOrgSubdomain = "salesforce-org-subdomain";
412440
const userId = "{arcade_user_id}";
413-
const scopes = ["read_account"];
441+
const scopes = [
442+
"read_account",
443+
"read_contact",
444+
"read_lead",
445+
"read_note",
446+
"read_opportunity",
447+
"read_task",
448+
"read_user",
449+
"write_contact",
450+
"write_lead",
451+
"write_opportunity",
452+
"write_task",
453+
];
414454
```
415455

416456
Here's a break down of each value:
417457

418458
- **`salesforceProviderId`**: the ID you entered when setting up the [Salesforce auth provider](#configuring-salesforce-auth);
419459
- **`salesforceOrgSubdomain`**: your [Salesforce Org Subdomain](#get-your-salesforce-org-subdomain);
420460
- **`userId`**: an internal identifier for your application user (it could be an email address, a username, UUID, etc); for demonstration purposes, in this example, enter your own email address;
421-
- **`scopes`**: the list of scopes you want to request from the user; if you assigned the [custom scopes required by the Arcade Salesforce MCP Server](#create-and-assign-custom-scopes-to-your-external-client-app) use `["read_account"]` in this example.
461+
- **`scopes`**: the custom scopes to request from the user. Creating and assigning them on the Salesforce app is not enough. `auth.start()` only consents to this list. For the [Arcade Salesforce MCP Server](#create-and-assign-custom-scopes-to-your-external-client-app), pass every scope in the list above.
422462

423463
### Start the authorization process and wait for completion
424464

@@ -505,7 +545,19 @@ const client = new Arcade((baseURL = "http://localhost:9099")); // Automatically
505545
const salesforceProviderId = "salesforce";
506546
const salesforceOrgSubdomain = "salesforce-org-subdomain";
507547
const userId = "{arcade_user_id}";
508-
const scopes = ["read_account"];
548+
const scopes = [
549+
"read_account",
550+
"read_contact",
551+
"read_lead",
552+
"read_note",
553+
"read_opportunity",
554+
"read_task",
555+
"read_user",
556+
"write_contact",
557+
"write_lead",
558+
"write_opportunity",
559+
"write_task",
560+
];
509561

510562
// Start the authorization process
511563
let authResponse = await client.auth.start(userId, {

0 commit comments

Comments
 (0)