# developer Hosted Mcp Servers - Full Documentation # Activate MCP Servers MCP servers are disabled in your org by default and must be enabled by an administrator before clients can connect. This is a security measure — capabilities that expose org data to external systems require an intentional administrator action to activate. > **Warning:** If you don't enable your MCP servers, clients will not be able to connect, even with correct authentication. ## Enable Servers 1. From Setup, in the Quick Find box, enter **MCP Servers**, and then select **MCP Servers** under API Catalog. 2. Review the list of available servers. 3. Enable the servers your team needs by toggling them on. > **Note:** It can take up to 2 minutes for a server to become active after you enable it. ## Next Steps After enabling your MCP servers, proceed to [connect your MCP client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/client-connection/client-connection-overview.md). # Agentforce Expose Agentforce agents and Prompt Builder templates as MCP tools to allow external AI assistants to invoke Salesforce's native AI capabilities as part of their workflow. This creates a pathway for tools such as Slackbot, ChatGPT, or Claude to delegate specialized tasks to Agentforce agents or execute prompt templates server-side, rather than attempting to replicate that logic themselves. Choose this approach when you want external AI assistants to use domain-specific agents that you built in Salesforce, or when you need prompt templates to execute server-side with access to Salesforce data and the Einstein Trust Layer. ## Prerequisites - **Use the new Agent Script Builder:** Only Agentforce agents created using the new [Agent Script Builder](https://help.salesforce.com/s/articleView?id=ai.agent_setup_create_upgrade.htm&type=5) can be exposed as MCP tools. Legacy agents must be [upgraded to the new builder](https://help.salesforce.com/s/articleView?id=ai.agent_setup_create_upgrade.htm&type=5) before they can be used with custom MCP servers. ## How It Works You configure agent-backed and prompt-backed tools [through the custom server Setup UI](https://help.salesforce.com/s/articleView?id=platform.api_catalog_manage_salesforce_hosted_mcp_servers.htm&type=5). Select the backing type (Agentforce Agent or Prompt Template), select which agent or template to expose, name the tool, provide a description, and publish. When you configure an Agentforce agent as an MCP tool, you create a bridge that allows external AI assistants to invoke that agent through the MCP protocol. **Tool selection is critical:** External AI models (such as Claude, ChatGPT, or other MCP clients) select which tool to call based entirely on the tool's name and description. You must be deliberate when configuring these fields. If the name or description is vague, generic, or doesn't clearly signal what the tool does, the external model skips over it and attempts to fulfill the request using other tools or its own capabilities—even when your agent is the best choice. When you configure an agent or prompt template as an MCP tool, invest time in writing a clear, specific name and description that accurately reflects what the tool does and when it should be invoked. Well-defined tool metadata is what makes the external model route requests correctly. For guidance on writing effective tool definitions, see the [tool use best practices](https://platform.claude.com/docs/en/agents-and-tools/tool-use/define-tools#best-practices-for-tool-definitions) in Anthropic's developer guide. When an assistant invokes an agent tool, Salesforce routes the request to the specified Agentforce agent, which processes it using its configured instructions, actions, and knowledge sources. When an assistant invokes a prompt template tool, Salesforce executes the template server-side via the Generations API, applies the Einstein Trust Layer, and returns the result. ## When to Use This **Use Agentforce agents as MCP tools when:** - You built specialized Agentforce agents with domain expertise, specific instructions, or access to proprietary knowledge that external AI assistants can invoke. - You want external assistants to delegate tasks to Salesforce instead of performing those tasks themselves using primitive tools like record queries. - You need the external assistant to trigger multi-step workflows or complex decision logic that an Agentforce agent already encapsulates. **Use Prompt Builder templates as MCP tools when:** - Your organization has invested in Prompt Builder templates and you want agents in external systems to execute those templates autonomously as part of multi-step workflows. - You need the prompt to run server-side with access to Salesforce data, rather than requiring the external assistant to retrieve that data and pass it through its own context. - You want to apply the Einstein Trust Layer—grounding, toxicity detection, and other safeguards that Prompt Builder provides. **Use [Apex Actions](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/invocable-actions.md) or [Flows](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/flows.md) instead when:** - The operation is a deterministic business process (updating records, running validation, triggering approvals) rather than generating content or reasoning through a problem. - You need precise, step-by-step control rather than LLM-driven reasoning. ## Example Use Cases **Agentforce agents:** - **Support triage agent**: An external AI assistant in Slack invokes an Agentforce support agent to analyze a case description, determine severity, suggest troubleshooting steps, and identify the right team to route the case to — leveraging the agent's training on historical case data and org-specific knowledge. - **Account research agent**: A sales rep using ChatGPT asks about a customer's contract status and renewal likelihood. ChatGPT invokes an Agentforce account intelligence agent that has access to opportunity history, past interactions, and account health metrics, and returns a summary with recommendations. **Prompt templates:** - **Meeting summary generation**: An AI assistant in Slack invokes a Prompt Builder template that pulls recent activity records for an account, formats them according to the template's instructions, and generates talking points for an upcoming meeting — all server-side, with the Einstein Trust Layer applied. - **Email drafting**: A sales rep working in an external tool asks Claude to draft a follow-up email. Claude invokes a Prompt Builder template designed for email generation, passing in the opportunity ID. The template retrieves relevant data from Salesforce, applies the org's tone and formatting guidelines, and returns a draft. ## Create Task-Specific Tools A single Agentforce agent often handles multiple distinct tasks. For example, a sales-oriented agent might both schedule meetings and predict when deals will close. Even though the same agent performs both functions, create separate MCP tools for each task — one named and described for scheduling meetings, another for deal forecasting — both pointing to the same underlying agent. This approach makes tool selection more reliable. External AI assistants choose tools based on name and description. A focused, task-specific tool name like "Schedule Customer Meeting" is easier for an assistant to match to user intent than a generic "Sales Agent" tool that does many things. When the tool name and description clearly signal what the tool does, the assistant is more likely to invoke it at the right time — and less likely to invoke it when a different tool would be better. This is especially important as you add more tools to a custom server. Clear, specific tool names help agents navigate larger tool sets. Keep tool descriptions synchronized with the underlying agent's behavior. When you update an agent's instructions or capabilities, review the MCP tool descriptions in Setup to ensure they accurately reflect what the agent does. Stale descriptions can lead to incorrect tool selection. ## Limitations - Only agents created with the new Agent Script Builder are supported. Legacy agents created with earlier builder versions must be upgraded to the new builder format before they can be exposed as MCP tools. - Agentforce agents and Prompt Builder templates must be explicitly configured as tools in a custom MCP server. They are not automatically available. - Agent and prompt execution runs in the authenticated user's context—sharing rules, field-level security, and Einstein Trust Layer policies apply. - The inputs that the agent or prompt template requires become the tool's parameter schema. Complex or ambiguous input requirements make the tool harder for external assistants to invoke correctly. # Apex Actions Apex Actions — also commonly known as Invocable Actions — can be exposed as custom MCP tools, giving agents access to business logic your team has already written in Apex. Any Apex class with a `global` method annotated `@InvocableMethod` is eligible. The agent calls the tool; the Apex code runs server-side with full platform access. Apex Actions are the right choice when you need tools that go beyond reading or writing a single record: a tool that generates a quote from an opportunity (multi-step with validation), escalates a case through an approval process, or enriches a contact by calling an external data service. Because the logic lives in Apex, it can do anything the platform supports — and the admin controls exactly which actions are exposed. ## How It Works You configure Apex Action-backed tools through the custom server Setup UI — select Apex Action as the backing type, choose the action to expose, name the tool, provide a description, and publish. See [Custom MCP Servers](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/custom-servers.md) for the full configuration walkthrough. When an agent invokes the tool, Salesforce executes the Apex method server-side with the provided inputs and returns the output variables defined by the method's schema. ## When to Use This **Use Apex Actions when:** - The operation requires complex server-side logic — conditional branching, multi-step orchestration, external API calls, or data validation that's difficult to express as a single REST call or declarative flow. - You have existing `@InvocableMethod` classes that implement business processes agents should be able to trigger. **Use [Flows](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/flows.md) instead when:** - The business process is owned by admins and maintained in Flow Builder. Flows are easier to modify without a developer and don't require a code deployment to update. - The logic is straightforward enough to express declaratively. ## Example Use Cases - **Quote generation**: An agent reviewing an opportunity invokes an Apex Action that runs the quoting logic — applying product rules, pricing tiers, and approval thresholds — and returns a draft quote ID, rather than requiring the agent to replicate that logic itself. - **Case escalation**: An agent triaging support cases invokes an escalation action that applies the org's routing rules, updates the case record, notifies the assigned team, and logs an audit entry — all in one tool call. - **Contact enrichment**: An agent onboarding a new lead invokes an Apex Action that calls an external data service, retrieves firmographic data, and writes it back to the record — handling authentication and error cases in the Apex layer. ## Limitations - Only Apex classes with a `global` method annotated `@InvocableMethod` can be exposed as MCP tools through this backing type. - Apex Actions run as the authenticated user — governor limits and sharing rules apply the same as they would for any Apex execution triggered by that user. - The Apex method's input and output variables define the tool's parameter schema. Methods with complex or nested types may require additional consideration to ensure the tool is easy for agents to call correctly. - Updating the underlying Apex class (adding parameters, changing types) requires updating the tool configuration in Setup to stay in sync. # APIs from API Catalog The Salesforce API Catalog is a curated registry of REST API endpoints that admins can map to custom MCP tools through the Setup UI. Rather than writing integration code, you select an endpoint from the catalog, configure its parameters, and publish it as a named tool on a custom server. ## How It Works You configure API Catalog-backed tools through the custom server Setup UI. Browse or search the catalog for an endpoint, set any fixed parameters, name the tool, and publish. When an agent invokes the tool, the MCP server makes the corresponding REST API call using the authenticated user's credentials. All calls respect the user's object permissions and field-level security. ## When to Use This **Use API Catalog tools when:** - The operation exists as a Salesforce REST endpoint that isn't covered by the standard pre-configured servers (SObject tools, Invocable Actions, Data 360, or Tableau). - You're working with product-specific Connect APIs (Billing, CPQ, Field Service, Health Cloud, etc.) that have structured endpoints beyond basic SObject CRUD. **Use [Invocable Actions](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/invocable-actions.md) instead when:** - The operation requires server-side logic that isn't expressed as a single REST API call — for example, multi-step business logic, conditional branching, or operations that need to span multiple calls. - You want admin-maintainable automation using Flow Builder rather than a fixed API endpoint. ## Example Use Cases - **Billing operations**: An agent helping sales reps answer customer billing questions invokes a Salesforce Billing API endpoint to retrieve invoice status, payment history, or outstanding balance — without giving the agent broad SObject access to billing records. - **Field Service scheduling**: An agent coordinating field service appointments invokes a Field Service Connect API to check technician availability and schedule a visit, using the structured scheduling endpoints rather than direct SObject manipulation. ## Limitations - Only endpoints registered in the API Catalog are available for selection. Not every Salesforce API endpoint is cataloged at GA — coverage expands over time. - Fixed parameters are set at configuration time and cannot be overridden by the agent at runtime. Parameters left open can be passed by the agent at call time. - Each tool maps to a single REST endpoint. Operations that require multiple API calls should use Flows or Invocable Actions, which can orchestrate multiple calls server-side. - API Catalog tools run as the authenticated user — the same permissions and rate limits apply as they would to any REST API call made by that user. ## See Also [Manage Salesforce Hosted MCP Servers in API Catalog](https://help.salesforce.com/s/articleView?id=platform.api_catalog_manage_salesforce_hosted_mcp_servers.htm&type=5) # Archive Connect > **Beta:** The Headless 360 MCP Server is a Beta Service, available starting in July 2026. You can choose to try this Beta Service at your sole discretion. Any use of the Beta Service is subject to the applicable [Beta Services Terms](https://www.salesforce.com/company/legal/agreements/). Archive Connect tools are accessed through the Headless 360 MCP Server — they are not a separately hosted MCP server. These tools expose Archive data management capabilities to AI agents: search, restoration, analysis, and compliance operations on archived records in the Archive app. Use these tools to: - **Search archived data** — Find archived records by object type, field values, and date ranges without unarchiving them to live storage - **Unarchive records** — Move archived records back into live Salesforce storage for active business processes - **Analyze org storage** — Run storage analysis to identify archivable data and get storage recommendations for your org - **Anonymize personal data** — Mask PII in archived records to comply with privacy regulations while maintaining record structure - **Manage data erasure requests** — Process Right To Be Forgotten (RTBF) requests by permanently deleting archived records ## Prerequisites - **API version:** v67.0 and later - **Archive license** enabled in your org - **Permissions:** - `Archive Admin` permission set for comprehensive access to all Archive operations - Or specific permissions based on operations (see [Archive Admin Permissions](https://help.salesforce.com/s/articleView?id=sf.archive_admin_permissions.htm&type=5) for details) - Object-level and field-level security applies to all operations - **MCP client** installed and configured with OAuth authentication For setup instructions, see [Set Up Your Org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/setup/setup-overview.md). ## Server URL Archive Connect tools are accessed through the Headless 360 MCP Server. - **Production:** `https://api.salesforce.com/platform/mcp/v1/platform/headless-360` - **Sandbox/Scratch:** `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/headless-360` Use the Headless 360 server's **Discover** tool to find Archive Connect operations at runtime. ## Activate the Headless 360 Server 1. From Setup, in the Quick Find box, enter `MCP Servers`, and then select **MCP Servers**. 2. Find **headless-360** in the list of servers. 3. Click **Activate**. Once activated, use the server's **Discover** tool to find Archive Connect operations. ## Example Prompts - "Search for archived Cases with Status 'Closed' created in January 2024." - "Unarchive Account records for Acme Corporation that were archived in Q1 2024." - "Run the storage analyzer to identify which objects are consuming the most storage." - "Submit an RTBF erasure request for archived records matching customer@example.com." - "Anonymize PII in archived Case records associated with Account ID 001xx000003DGbXXXX." ## Available Tools Archive Connect provides 13 tools for managing archived data through the Headless 360 MCP Server. Tools are organized by capability: search, storage analysis, unarchive, compliance operations, and job monitoring. ### 1. run-archive-global-search — search archived records Searches archived records by object type, filters, date ranges, and sort criteria. **Internal name:** `run-archive-global-search` Request Schema: ```json { "type": "object", "properties": { "sobjectName": { "type": "string", "description": "API name of the sObject to search in the archive." }, "filters": { "type": "array", "description": "At least 1 filter condition required; up to 6 allowed. Each filter is {field, value}. Filters are combined with AND logic.", "minItems": 1, "maxItems": 6 }, "dateRange": { "type": "object", "description": "Single date range {field, from, to}. Both from and to must be full ISO-8601 datetime strings (e.g., '2020-01-01T00:00:00Z').", "properties": { "field": { "type": "string" }, "from": { "type": "string", "format": "date-time" }, "to": { "type": "string", "format": "date-time" } } }, "dateRanges": { "type": "array", "description": "Array of date ranges, each {field, from, to}. Use the special field name 'archive_date' to filter by archive date.", "items": { "type": "object", "properties": { "field": { "type": "string" }, "from": { "type": "string", "format": "date-time" }, "to": { "type": "string", "format": "date-time" } } } }, "fields": { "type": "array", "description": "Field API names to return in the result set.", "items": { "type": "string" } }, "pageSize": { "type": "integer", "description": "Number of records per page. Maximum 1000, default 25.", "minimum": 1, "maximum": 1000, "default": 25 }, "sortDirection": { "type": "string", "description": "Sort order. Accepts 'asc' or 'desc' (case-insensitive), default 'asc'.", "enum": ["asc", "desc", "ASC", "DESC"], "default": "asc" } }, "required": ["sobjectName", "filters"], "additionalProperties": false } ``` Returns HTTP 201 with `{records[], total_result_count, scroll_id, errorMessage, statusCode}`. The `errorMessage` is null on success. When `scroll_id` is `"-1"`, there are no more pages. ### 2. get-archive-global-search-next-page — paginate search results Retrieves the next page of archived record search results using a scroll cursor from the previous search. **Internal name:** `get-archive-global-search-next-page` Request Schema: ```json { "type": "object", "properties": { "scrollId": { "type": "string", "description": "The scroll cursor returned from the previous search response." } }, "required": ["scrollId"], "additionalProperties": false } ``` Returns next page of search results with structure `{records[], total_result_count, scroll_id, errorMessage, statusCode}`. ### 3. run-archive-global-search-with-sharing-rules — search with sharing rules enforced Archive search optimized for Agentforce agents. Enforces sharing rules and returns results in a rich-text summary format. **Internal name:** `run-archive-global-search-with-sharing-rules` Request Schema: ```json { "type": "object", "properties": { "objectName": { "type": "string", "description": "API name of the sObject to search." }, "filtersJson": { "type": "string", "description": "JSON-encoded object map of fieldName→value, e.g., '{\"Subject\":\"Foo\",\"Status\":\"New\"}'. Must be an object, not an array." }, "dateField": { "type": "string", "description": "API name of the date field for temporal filtering." }, "startDate": { "type": "string", "description": "Start date for the search window (ISO 8601 format)." }, "endDate": { "type": "string", "description": "End date for the search window (ISO 8601 format)." }, "maxResults": { "type": "integer", "description": "Maximum number of records to return. Default 100.", "default": 100 } }, "required": ["objectName", "filtersJson"], "additionalProperties": false } ``` Returns `{isSuccess, totalResultCount, records, recordsJson, errorMessage, message, warnings}`. The `records` field contains a rich-text summary of ~5 key fields per record. The `recordsJson` field contains HTML-entity-encoded JSON. The `warnings` field contains schema-validation and auto-fix advisories. **Note:** Check the `isSuccess` field, not the HTTP status code. Validation failures return HTTP 201 with `isSuccess: false`. ### 4. get-organization-archive-storage-used — get storage consumption Returns the current archive storage consumption across storage tiers. **Internal name:** `get-organization-archive-storage-used` Request Schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` Returns `{usedStorage[4], availableStorage[4]}`. Two parallel arrays where indices 0/1 represent general storage and 2/3 represent archive-tier storage. Values are in bytes. **Note:** Interpret per-index rather than as a flat metric. Each index represents a different storage tier and shouldn't be summed together. ### 5. run-analyzer — trigger storage analysis Triggers the archive analyzer to run immediately and generate a storage readiness report. **Internal name:** `run-analyzer` Request Schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` Returns `{isRunning, message}`. The `isRunning` field is always null; read the `message` field for human-readable status. **Note:** This is a write operation that is idempotent and non-destructive. ### 6. get-analyzer-report — retrieve analyzer report Retrieves the latest analyzer report showing archive readiness and storage recommendations. **Internal name:** `get-analyzer-report` Request Schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` Returns `{topRecords[], topFiles[], fileGeneralStorage, dataGeneralStorage, createdDateReport}`. Each item in `topRecords` and `topFiles` contains `{objectName, objectLabel, objectIcon, size, count, usagePercent}`. Storage objects contain `{storageUsed, storageRemaining, usagePercent}`. The `createdDateReport` is in `"DD/MM/YYYY HH:MM:SS"` format. ### 7. run-unarchive — unarchive records Unarchives archived records back into live Salesforce storage based on search criteria. **Internal name:** `run-unarchive` Request Schema: ```json { "type": "object", "properties": { "sobjectName": { "type": "string", "description": "API name of the sObject to unarchive." }, "filters": { "type": "array", "description": "Filter criteria identifying which archived records to unarchive." }, "dateRange": { "type": "object", "description": "Single date range {field, from, to} with full ISO-8601 datetime strings. Omitting this parameter unarchives records based on filters alone with no date constraints.", "properties": { "field": { "type": "string" }, "from": { "type": "string", "format": "date-time" }, "to": { "type": "string", "format": "date-time" } } } }, "required": ["sobjectName", "filters"], "additionalProperties": false } ``` Returns `{body, errorMessage, statusCode}`. The `body` contains unarchive job details including job ID. **Note:** This is a write operation that is potentially long-running. Maximum 1000 matched records per request. Maximum 50 unarchive requests per hour per org. Restores the entire archived hierarchy of each matched record. ### 8. run-rtbf — submit RTBF erasure request Submits a Right To Be Forgotten (RTBF) data erasure request for archived records matching the specified criteria. **Internal name:** `run-rtbf` Request Schema: ```json { "type": "object", "properties": { "criteria": { "type": "array", "description": "Array of {sobject, field, value} criteria. Maximum 10 criteria per request, one per object type. Field and object names are case-insensitive.", "maxItems": 10, "items": { "type": "object", "properties": { "sobject": { "type": "string" }, "field": { "type": "string" }, "value": { "type": "string" } } } } }, "required": ["criteria"], "additionalProperties": false } ``` Returns `{body.request_id, errorMessage, statusCode}`. The `request_id` is a UUID used to track the request via `get-rtbf-status`. **Warning:** Not reversible. RTBF erasure permanently deletes the matched archived hierarchy. Maximum 10,000 root records erased per org per day. Deletes the entire archived hierarchy of each matched record. Values must be exact matches, not partial. The criterion's record type must have been archived as a root record. ### 9. get-rtbf-status — poll RTBF request status Polls the status of an RTBF data erasure request to confirm whether personal data has been purged from the archive. **Internal name:** `get-rtbf-status` Request Schema: ```json { "type": "object", "properties": { "requestId": { "type": "string", "description": "The request UUID returned by run-rtbf." } }, "required": ["requestId"], "additionalProperties": false } ``` Returns `{body, errorMessage, statusCode}`. The `body` contains RTBF request status details. ### 10. run-masking — submit PII masking request Submits a masking request to irreversibly anonymize PII in archived records matching the criteria. **Internal name:** `run-masking` Request Schema: ```json { "type": "object", "properties": { "criteria": { "type": "array", "description": "Array of {sobject, field, value} criteria identifying archived records to anonymize. Same structure as RTBF criteria.", "items": { "type": "object", "properties": { "sobject": { "type": "string" }, "field": { "type": "string" }, "value": { "type": "string" } } } } }, "required": ["criteria"], "additionalProperties": false } ``` Returns `{body.request_id, errorMessage, statusCode}`. The `request_id` is a UUID used to track the masking job via `get-masking-status`. **Warning:** Not reversible. Anonymization is permanent; original PII values cannot be recovered. Replaces detected PII field values with placeholders (e.g., `"redacted@example.com"`). Permanent and one-time per record. Duplicate requests on an already-masked record are ignored. PII fields are auto-detected; you cannot choose specific fields. Records under legal hold or retention lock are excluded. Cascades to child records in the same hierarchy. Shares the 10,000/day rate limit with RTBF operations. Requires org entitlement; without it, returns `VALIDATION_ERROR` "Masking not allowed for this org". ### 11. get-masking-status — poll masking request status Polls the status of a masking request to confirm when PII anonymization has completed. **Internal name:** `get-masking-status` Request Schema: ```json { "type": "object", "properties": { "requestId": { "type": "string", "description": "The masking request UUID returned by run-masking." } }, "required": ["requestId"], "additionalProperties": false } ``` Returns `{body, errorMessage, statusCode}`. The `body` contains masking request status details. Status reaches `"HANDLED"` when anonymization completes. ### 12. get-archive-execution-details-streaming-url — get job execution log URL Generates a presigned download URL for an archive job's execution details log file. **Internal name:** `get-archive-execution-details-streaming-url` Request Schema: ```json { "type": "object", "properties": { "reportType": { "type": "string", "description": "The ArchiveActivity Type of the job.", "enum": [ "Archive", "Unarchive", "Analyzer", "Purge", "Export-to-external-bucket", "Export-and-download" ] }, "requestId": { "type": "string", "description": "The ArchiveActivity Id of a completed, log-producing job (the '8qv...' key)." }, "sobjectName": { "type": "string", "description": "API name of the sObject associated with the archive job. The backend can self-resolve this." } }, "required": ["reportType", "requestId"], "additionalProperties": false } ``` Returns `{url}`. If `url` is not null, it contains a time-limited presigned download URL. If `url` is null, no log was resolved. ### 13. get-archive-failed-records-streaming-url — get failed records log URL Generates a presigned download URL for an archive job's failed records log file. **Internal name:** `get-archive-failed-records-streaming-url` Request Schema: ```json { "type": "object", "properties": { "reportType": { "type": "string", "description": "The ArchiveActivity Type of the job.", "enum": [ "Archive", "Unarchive", "Analyzer", "Purge", "Export-to-external-bucket", "Export-and-download" ] }, "requestId": { "type": "string", "description": "The ArchiveActivity Id of a completed job (the '8qv...' key)." }, "sobjectName": { "type": "string", "description": "API name of the sObject associated with the archive job." } }, "required": ["reportType", "requestId"], "additionalProperties": false } ``` Returns `{url}`. If `url` is not null, it contains a time-limited presigned download URL. If `url` is null, no failed-records log was resolved. ## Understand How Security Works Every Archive Connect operation runs as the authenticated user through an External Client App with the `mcp_api` scope. Object permissions (CRUD), field-level security (FLS), sharing rules, and user permissions all apply. If you can't perform an action in Salesforce, your agent can't perform it through the MCP server. The audit trail attributes every action to you. For full guidance, see [Security Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/security-best-practices.md) and [General Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/general-best-practices.md). **Important for compliance operations:** The RTBF and masking tools are destructive and irreversible. Configure your MCP client to require explicit approval before executing these operations. ## Usage Limits The Archive Connect API has the following operational constraints: ### Rate Limits - **Unarchive requests:** Maximum 50 requests per hour per org. Each request can match up to 1,000 records. - **RTBF and masking operations:** Combined maximum of 10,000 root records erased or masked per org per day. - **Search filters:** Maximum 6 filter conditions per search request. - **RTBF and masking criteria:** Maximum 10 criteria per request, one per object type. ### Operational Constraints - **Unarchive scope:** Restores the entire archived hierarchy of each matched record, not just the root record. - **RTBF and masking scope:** Deletes or anonymizes the entire archived hierarchy of each matched record. - **Masking permanence:** Anonymization is permanent and one-time per record. Duplicate masking requests on already-masked records are ignored. - **RTBF permanence:** Data erasure is not reversible. RTBF permanently deletes matched archived records. - **Legal holds:** Records under legal hold or retention lock are excluded from masking operations. - **Masking entitlement:** Masking operations require org entitlement. Without it, requests return `VALIDATION_ERROR` "Masking not allowed for this org". - **Exact value matching:** RTBF and masking criteria require exact field value matches, not partial matches. - **Root record requirement:** For RTBF, the criterion's record type must have been archived as a root record. ## Related Resources - [Headless 360 MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/headless-360-mcp.md) - [Data 360 MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/data360-mcp.md) - [Standard MCP Servers Reference](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/servers-reference.md) # Authentication Issues Use this section if your client reaches the server but cannot complete sign-in. ## Step 1: Verify external client app configuration If your client requires an external client app, make sure that setup exactly matches the Salesforce Hosted MCP Server requirements. ## Step 2: If using Vibes If you are using Vibes as your MCP client, an external client app is not required. Follow Vibes documentation for setup and troubleshooting. ## Step 3: Verify callback/redirect URL Make sure the callback (redirect) URL in your client exactly matches what is configured in Salesforce. ## Step 4: Confirm OAuth support Your MCP client must support an OAuth flow compatible with Salesforce Hosted MCP Servers. ## Step 5: Isolate client-specific problems Try the same connection/sign-in in Postman or MCP Inspector. - If it works there, review your MCP client's authentication setup. # Backup and Recover MCP Server The `platform/backup-and-recover` server exposes Salesforce Backup and Recover operations to AI agents over the Model Context Protocol (MCP). It gives an agent grounded, consequence-aware tools to discover and inspect backups, read the org's ingestion policy and retention rules, review Backup and Recover audit history, start on-demand backups, and drive the guided restore workflow — all scoped to the calling user's org. This server is the single unified home for the full Backup and Recover tool surface. The read/write distinction is expressed per tool through tool annotations rather than through separate servers. Every destructive operation is deliberately kept off the MCP surface. ## Use This Server To - Discover and inspect backups, including per-object detail and status - Read the org's backup ingestion policy, retention rules, and audit history - Start an on-demand backup and poll it to completion - Drive the guided restore workflow: compare two backups, inspect the differences, refine the record selection, and confirm the selection counts - Review restore results after a restore runs on the non-MCP surface ## Prerequisites - **API version:** v67.0 and later - **Backup and Recover Data** and **Backup and Recover Files add-on licenses** enabled in your org - **Permissions:** - `BackupAndRecoverSuperAdmin` permission set for comprehensive access to all Backup and Recover operations - Or specific permissions based on operations (see [Backup and Recover Next Permissions](https://help.salesforce.com/s/articleView?id=xcloud.backup_recover_permissions.htm&type=5) for details) - Object-level and field-level security applies to all operations - **External Client App** configured with the `mcp_api` scope - **MCP client** installed and configured with OAuth authentication For setup instructions, see [Set Up Your Org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/setup/setup-overview.md). ## Server URL - **Production:** `https://api.salesforce.com/platform/mcp/v1/platform/backup-and-recover` - **Sandbox/Scratch:** `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/backup-and-recover` ## Example Prompts - "Show me the most recent backups for my org and their status." - "Start a full on-demand backup and let me know when it finishes." - "Compare my two most recent backups and show me what changed on Account and Contact." - "Select all Technology-industry Accounts from the compare for restore, then confirm the counts." - "Show me the results of the last restore, broken down by object." ## Available Tools The `platform/backup-and-recover` server provides 22 tools: 6 backup reads, 1 backup write, 13 recover reads, and 2 recover writes. All tool calls are scoped to the caller's org. The IDs shown in the examples are illustrative. ### Understand the Tool Annotations Each tool carries annotations that describe its behavior. The hints are set explicitly so that serialized annotations carry concrete boolean values. | Archetype | `readOnly` | `idempotent` | `destructive` | `openWorld` | Applied to | | ---------------- | :--------: | :----------: | :-----------: | :---------: | ------------------------------------------- | | Read-only | `true` | `true` | `false` | `true` | All 19 read tools | | Additive | `false` | `false` | `false` | `true` | `enqueue_backup`, `create_compare_activity` | | Update-selection | `false` | `true` | `false` | `true` | `update_selection_records` | The `update_selection_records` tool overwrites the prior selection but is deliberately not marked destructive, because the selection overlay is preview state, not customer data. ### Backup Reads Use these tools to discover backups and read the org's backup policy, retention rules, and audit history. #### `get_backups` Lists backups for the org with optional pagination and sort. Use this first to discover backup IDs. ```json { "tool": "get_backups", "parameters": { "pageNumber": 1, "pageSize": 20, "sort": "startTimestamp", "sortDir": "DESC" } } ``` #### `get_backup_by_id` Returns the current state of one backup, including status, counts, and per-object detail. Use this as the polling tool after you start a backup. ```json { "tool": "get_backup_by_id", "parameters": { "backupId": "0Bh000000000001" } } ``` #### `get_backup_objects` Returns the per-object breakdown of a backup, with an optional `objectType` filter and pagination. ```json { "tool": "get_backup_objects", "parameters": { "backupId": "0Bh000000000001", "objectType": "Account", "pageNumber": 1, "pageSize": 50 } } ``` #### `get_latest_policy` Returns the current backup ingestion policy, including schedules, exclusions, and file and attachment inclusion. ```json { "tool": "get_latest_policy", "parameters": {} } ``` #### `get_retention_rules` Returns the current retention rules, mapping cadence to retention years. ```json { "tool": "get_retention_rules", "parameters": {} } ``` #### `get_audit_events` Returns Backup and Recover audit events, most recent first, paginated. ```json { "tool": "get_audit_events", "parameters": { "pageNumber": 1, "pageSize": 25 } } ``` ### Backup Writes #### `enqueue_backup` **Mutating and additive.** Starts a new on-demand backup of the configured policy. This tool is asynchronous: it returns a `backupId` immediately, so poll `get_backup_by_id` for completion. The object scope is policy-driven — the tool runs the configured policy and doesn't let the caller choose objects. On-demands are limited to three calls per day, including calls made from the UI or API. ```json { "tool": "enqueue_backup", "parameters": {} } ``` The response returns a `backupId` with a `queued` flag. When the backup isn't queued, the response includes an `enqueueRejectionReason`, such as `DELTA_REQUIRES_FULL_COMPLETED`, `SAME_TYPE_AND_CONTENT_ALREADY_QUEUED`, or `DAILY_ON_DEMAND_LIMIT_REACHED`. Then poll: ```json { "tool": "get_backup_by_id", "parameters": { "backupId": "" } } ``` ### Recover Reads Use these tools to list recover activities, inspect compare results, and review restore results. #### `get_activities` Lists recover activities (compare, restore, download), most recent first. ```json { "tool": "get_activities", "parameters": { "pageNumber": 1 } } ``` #### `get_restore_with_hierarchy` Returns the state of one restore-with-hierarchy activity. Use this as a polling tool. ```json { "tool": "get_restore_with_hierarchy", "parameters": { "activityId": "" } } ``` #### `get_compare_activity` Returns the state of one compare activity, including the from and to backups and the objects in scope. Use this as a polling tool after you create a compare. ```json { "tool": "get_compare_activity", "parameters": { "activityId": "" } } ``` #### `get_compare_activity_summaries` Returns per-object change counts for a compare activity, with an optional `searchTerm` and pagination. ```json { "tool": "get_compare_activity_summaries", "parameters": { "activityId": "", "searchTerm": "Account", "pageNumber": 1, "pageSize": 25 } } ``` #### `get_restore_activity_record_selection_metadata` Returns record-selection metadata and preview for a restore activity. ```json { "tool": "get_restore_activity_record_selection_metadata", "parameters": { "activityId": "" } } ``` #### `get_selection_counts_by_type` Returns selected-for-restore counts split by changed and deleted, for one object. ```json { "tool": "get_selection_counts_by_type", "parameters": { "activityId": "", "objectName": "Account" } } ``` #### `get_restore_result_counts` Returns per-status insert and update result counts for one object on a restore activity. ```json { "tool": "get_restore_result_counts", "parameters": { "activityId": "", "objectName": "Account" } } ``` #### `get_restore_activity` Returns the flat (non-hierarchy) restore rollup plus per-object breakdown. ```json { "tool": "get_restore_activity", "parameters": { "activityId": "" } } ``` #### `get_activity` Performs a generic single-activity lookup of any type, for when the activity type is unknown. ```json { "tool": "get_activity", "parameters": { "activityId": "" } } ``` #### `get_hierarchy_summary` Returns per-node-path deleted and modified counts and preview/restore status. ```json { "tool": "get_hierarchy_summary", "parameters": { "activityId": "", "nodePaths": ["Account", "Account:Contact"] } } ``` #### `get_restore_activity_summary` Returns the per-object restore summary (updated, inserted, failed), paginated and filterable. ```json { "tool": "get_restore_activity_summary", "parameters": { "activityId": "", "searchTerm": "Account", "pageNumber": 1, "pageSize": 25 } } ``` #### `get_restore_activity_object_results` Returns per-record restore results for one object, including new and old IDs, status, and insert or update. ```json { "tool": "get_restore_activity_object_results", "parameters": { "activityId": "", "objectName": "Account", "pageNumber": 1, "pageSize": 50, "searchTerm": "" } } ``` #### `get_restore_with_hierarchy_results` Returns per-record results for one node path in a restore-with-hierarchy activity. The `type` parameter selects the tab: `inserted` for the hierarchy-tree view, `updated` for the flat view. ```json { "tool": "get_restore_with_hierarchy_results", "parameters": { "activityId": "", "nodePath": "Account:Contact", "type": "inserted", "pageNumber": 1, "pageSize": 50 } } ``` ### Recover Writes #### `create_compare_activity` **Mutating and additive.** Creates a compare that diffs two backups. This tool is asynchronous: it returns an `activityId` immediately, so poll `get_compare_activity` for completion. Pass `"objects": ["all"]` to compare every object present in both backups. The `activityType` parameter defaults to `COMPARE` (data); use `COMPARE_METADATA` for a metadata compare. ```json { "tool": "create_compare_activity", "parameters": { "fromBackupId": "0Bh000000000001", "toBackupId": "0Bh000000000009", "objects": ["Account", "Contact"], "activityType": "COMPARE" } } ``` #### `update_selection_records` **Mutating (overwrites the prior selection) and idempotent.** Updates which records are selected for restore on a COMPARE activity through batch filter and change expressions. When multiple batches match the same record, the last matching batch wins. The only supported change is `fieldName=selectedForRestore` with a value of `true` or `false`. Re-applying the same payload is idempotent. Passing a RESTORE activity ID returns HTTP 422. ```json { "tool": "update_selection_records", "parameters": { "activityId": "", "objectName": "Account", "batches": [ { "filterExp": [{ "fieldName": "Industry", "operator": "EQUALS", "value": "Technology" }], "changeExp": [{ "fieldName": "selectedForRestore", "value": "true" }] } ] } } ``` ### Guided Restore Workflow The recover tools are designed to be used in sequence. The MCP surface guides a restore up to the selection step; the restore itself runs on the non-MCP surface. 1. **Create a compare** with `create_compare_activity` to diff two backups. Capture the returned `activityId`. 2. **Poll the compare** with `get_compare_activity`, then read per-object change counts with `get_compare_activity_summaries`. 3. **Update the selection** with `update_selection_records` to mark records for restore. 4. **Confirm the selection counts** with `get_selection_counts_by_type` and `get_restore_activity_record_selection_metadata` before you restore. Executing the restore is intentionally not an MCP tool. After you confirm the selection, trigger the restore through the product UI or another non-MCP surface. After a restore runs, review the results with the recover read tools, such as `get_restore_activity`, `get_restore_activity_summary`, and `get_restore_activity_object_results`. ## Limitations - **No destructive tools.** Abort backup, upsert policy, and create retention rules aren't exposed. There's no MCP confirmation primitive to gate them safely, and narrowing retention or overwriting policy can cause delayed or immediate data loss, so these operations stay off the MCP surface. - **No restore execution, retry, or download.** Restore execute, retry, download, and the legacy bulk selection edit aren't registered for this milestone. The MCP surface guides a restore up to the selection step; execution happens on the non-MCP surface. - **Asynchronous operations and a 30-second response budget.** The `enqueue_backup` and `create_compare_activity` tools return immediately and don't wait for completion. Poll for long-running state with `get_backup_by_id`, `get_compare_activity`, and `get_restore_with_hierarchy`. Tools don't block on a single long-running request. - **The selection tool is COMPARE-only.** The `update_selection_records` tool supports COMPARE activities only. Passing a RESTORE activity ID returns HTTP 422. - **`update_selection_records` overwrites.** It overwrites the prior selection (last matching batch wins) and supports only `selectedForRestore=true|false`. It's idempotent, but not marked destructive, because the selection overlay is preview state, not customer data. - **The object scope of `enqueue_backup` is policy-driven.** It runs the configured policy (available in the `get_latest_policy` tool) and doesn't let the caller choose objects. ## Understand How Security Works Every Salesforce Hosted MCP transaction runs as the authenticated user, scoped through an External Client App. Object permissions (CRUD), field-level security (FLS), sharing rules, profile permissions, and permission sets all apply. If you can't perform an action in Salesforce, your agent can't perform it through the MCP server. The audit trail attributes every action to you. This server takes a defense-in-depth approach to the restore workflow: every destructive operation is kept off the MCP surface, and the additive and update-selection tools are annotated so that clients can gate them. As a best practice, configure your MCP client to require your approval before it runs a tool that changes data, such as `enqueue_backup`, `create_compare_activity`, and `update_selection_records`. The Backup and Recover server follows the same practices that apply across all Salesforce Hosted MCP servers. For full guidance, see Security Best Practices and General Best Practices in the guides. ## Related Resources - [Standard MCP Servers Reference](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/servers-reference.md) - [Salesforce Hosted MCP Servers on GitHub](https://github.com/forcedotcom/mcp-hosted) # Best Practices Follow these best practices to deploy and use MCP servers securely and effectively within Salesforce's governance model. ## In This Section - **[General Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/general-best-practices.md)** — Core principles for deploying MCP servers, controlling access, designing tools, and keeping humans in the loop - **[Security Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/security-best-practices.md)** — Security model, authentication requirements, incremental permission strategies, and audit practices # Configure Agentforce Vibes Agentforce Vibes is a Visual Studio Code extension with native Salesforce authentication. Out of the box hosted MCP servers appear automatically in the Agentforce Vibes MCP Servers panel. You don't need to enter a consumer key or configure OAuth credentials. They are available for use as soon as they are enabled in the org. ## Prerequisites Before connecting to a hosted MCP server: - Install the Agentforce Vibes extension with a Salesforce DX project open. See [Install Agentforce Vibes Extension](https://developer.salesforce.com/docs/platform/agentforcevibes/guide/afv-extension-setup.html). - Connect to a Salesforce org in VS Code. See [Change or Open Your Default Org](https://developer.salesforce.com/docs/platform/sfvscode-extensions/guide/default-org.html). - Ask your admin to enable the hosted MCP server in your org. See [Set Up Your Org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/setup/activate-mcp-servers.md). ## Enable a Hosted MCP Server 1. Open the Agentforce Vibes panel in VS Code. 2. Click the **Toolkit** tab. 3. Click **MCP Servers**. 4. Under the **Salesforce Platform** group, find the hosted MCP server your admin enabled. 5. Click the server to open its detail view. 6. Toggle the server on. A green **Connected** status and tool count confirms a successful connection. If the connection fails, see [Troubleshooting](https://developer.salesforce.com/docs/platform/agentforcevibes/guide/afv-troubleshooting.html). ## Configure Tool Permissions (Optional) After connecting, use the MCP server details in Agentforce Vibes to select permissions for that server. ## Test the Connection Test the connection using Agentforce Vibes' chat features. See [Test Your MCP Client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/testing/test-connection.md) for prompt examples. ## See Also - [MCP Servers](https://developer.salesforce.com/docs/platform/agentforcevibes/guide/afv-mcp-servers.html) - [Salesforce Hosted MCP Servers](https://developer.salesforce.com/docs/platform/hosted-mcp-servers) # Configure ChatGPT ChatGPT supports MCP servers via their developer mode. Refer to OpenAI's documentation on that feature set for more information. OpenAI sometimes uses different terms like "connector" or "app." ## Setup Steps 1. Go to **Settings → Apps → Create App**. 2. Enter a name for the connector (for example, `SalesforceTest`). 3. Enter the server URL, substituting the `SERVER-NAME` from the list of available servers. **Server URL format:** - For **All production Orgs**: `https://api.salesforce.com/platform/mcp/v1/` - For **sandbox or Scratch Orgs**: `https://api.salesforce.com/platform/mcp/v1/sandbox/` **Example:** To use the `platform/sobject-all` server in a sandbox org: ``` https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-all ``` 4. Under **Authentication**, click **Advanced settings**: - Set **Registration Method** to **User-defined OAuth client**. - Copy the **Callback URL** provided by ChatGPT. Use this URL when configuring your External Client App. - Paste the consumer key that you copied from the external client app in **OAuth Client ID**. - Paste the consumer secret that you copied from the external client app in **OAuth Client Secret**. ChatGPT lists this field as optional, but Salesforce requires it. - Uncheck the **OIDC enabled** checkbox. 5. Click **Create**. ChatGPT will redirect to the org containing the External Client App created in the previous step. If you've logged in already, the user challenge is skipped and the flow proceeds forward, obtaining an access token and sending it back to ChatGPT. ## Testing the Connection You can now test the client's connection to the MCP server using ChatGPT's chatbot features. As of this writing, you'll need to explicitly select Salesforce under the plus (+) button in the prompt. See [Test Your MCP Client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/testing/test-connection.md) for example prompts to verify your connection. # Configure Claude Since Anthropic authored the original MCP specification, Claude has strong support for the MCP protocol and works well for developer testing. These setup steps apply to **Claude.ai** and the **Claude Desktop** app. **Claude Code** inherits the same connection, so after you add the connector, it's also available to Claude Code. ## Setup Steps 1. In the left sidebar, click **Customize**. 2. Click **Connectors**, then click **Add** and select **Add custom connector**. 3. Enter a name for the connector. The name is shown in the connectors list. 4. Enter the server URL, substituting the `SERVER-NAME` from the list of available servers. **Server URL format:** - For a **All production orgs**: `https://api.salesforce.com/platform/mcp/v1/` - For **sandbox or scratch orgs**: `https://api.salesforce.com/platform/mcp/v1/sandbox/` **Example:** To use the `platform/sobject-all` server in a scratch org: ``` https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-all ``` 5. Click **Continue**. 6. Under **OAuth client**, select **Use your own OAuth client**. 7. In **OAuth Client ID**, paste the consumer key that you copied from the external client app. This is the public identifier from the app's OAuth settings, not an API key or token. 8. Leave **OAuth Client Secret** blank, unless your authorization server requires one. 9. Click **Connect** next to the connector you created. Claude will redirect to the org containing the External Client App created in the previous step. If you've logged in already, the user challenge is skipped and the flow proceeds forward, obtaining an access token and sending it back to Claude. ## Configure Tool Permissions (Optional) If authentication completes successfully, you can click **Configure** to configure the tools available in the MCP server you've chosen, allowing you to adjust permission settings. ## Testing the Connection You can now test the client's connection to the MCP server by using Claude's chatbot features. See [Test Your MCP Client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/testing/test-connection.md) for prompt examples. ## See Also - [Connect Claude with Salesforce Hosted MCP Servers](https://developer.salesforce.com/blogs/2026/05/connect-claude-with-salesforce-hosted-mcp-servers) # Configure Cursor (Developer Mode) Cursor is an AI-driven code editor that supports MCP. ## Setup Steps 1. Select **Cursor | Settings | Cursor Settings | Tools & MCP**. 2. Click **New MCP Server**. This creates a file called `mcp.json`. 3. Replace the contents of the `mcp.json` file with this code: ```json { "mcpServers": { "Salesforce": { "url": "https://api.salesforce.com/platform/mcp/v1/", "auth": { "CLIENT_ID": "CONSUMER-KEY" } } } } ``` **Server URL format:** - For **All production orgs**: `https://api.salesforce.com/platform/mcp/v1/` - For **sandbox or scratch orgs**: `https://api.salesforce.com/platform/mcp/v1/sandbox/` **Example:** To use the `platform/sobject-all` server in a scratch org: ``` https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-all ``` 4. Replace placeholder values in the `mcp.json` file: - Replace `` with a server name from the list of available servers (e.g., `platform/sobject-all`) - Replace `CONSUMER-KEY` with the consumer key that you saved from the external client app ## Example Configuration This example `mcp.json` file is configured to connect Cursor to the `platform/sobject-all` server in a scratch org: ```json { "mcpServers": { "Salesforce": { "url": "https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-all", "auth": { "CLIENT_ID": "123my456consumer7890key" } } } } ``` ## Testing the Connection You can now test the client's connection to the MCP server using Cursor's sidebar. The sidebar uses a natural language chatbot-style interface. See [Test Your MCP Client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/testing/test-connection.md) for example prompts to verify your connection. # Configure Postman Postman can be configured to authenticate with the Salesforce hosted MCP server using OAuth 2.0 with PKCE (Proof Key for Code Exchange). ## Setup Steps 1. Open Postman and create a new request. 2. Click the icon next to the label **Untitled Request** and select **MCP**. 3. In the main text input below the Untitled Request label, switch the dropdown value from **STDIO** to **HTTP** and paste the URL of your chosen MCP server. **Server URL format:** - For a **All production orgs**: `https://api.salesforce.com/platform/mcp/v1/` - For **sandbox or scratch orgs**: `https://api.salesforce.com/platform/mcp/v1/sandbox/` **Example:** To use the `platform/sobject-all` server in a sandbox org: ``` https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-all ``` 4. Navigate to the **Authorization** tab. 5. Set **Auth Type** to **OAuth 2.0**. 6. Set **Add authorization data to** to **Request Headers**. 7. Click **Configure New Token** in the right-hand pane and enter the following values: - **Token Name**: Enter a descriptive name (example: `Postman Sandbox`) - **Header Prefix**: Enter `Bearer` - **Grant Type**: Select **Authorization Code (With PKCE)** - **Callback URL**: Leave the callback URL in place, and ensure it matches the callback URL in the External Client App - Desktop Postman: `https://oauth.pstmn.io/v1/callback` - Web browser Postman: `https://oauth.pstmn.io/v1/browser-callback` - Check the box for **Authorize using browser** - **Auth URL**: Enter the authorization URL based on org type: - Production orgs: `https://login.salesforce.com/services/oauth2/authorize` - Sandbox/scratch org: `https://test.salesforce.com/services/oauth2/authorize` - **Access Token URL**: Enter the token URL based on org type: - Production orgs: `https://login.salesforce.com/services/oauth2/token` - Sandbox/scratch org: `https://test.salesforce.com/services/oauth2/token` - **Client ID**: Paste the consumer key that you saved from the external client app - **Client Secret**: Leave this blank (PKCE enables you to omit the client secret) - **Code Challenge Method**: Select **SHA-256** - **Code Verifier**: Leave blank (automatically generated) - **Scope**: `mcp_api refresh_token` - **State**: Leave blank - **Client Authentication**: Select **Send client credentials in body** 8. Click **Get New Access Token**. A browser window opens for Salesforce authentication. 9. Log in with your Salesforce credentials if needed, and authorize the application when prompted. > **Note:** You may need to enable pop-up windows in your browser. 10. When you return to Postman, click the **Use Token** button if presented with the Manage Access Tokens modal window so that Postman can capture and use the token. ## Next Steps You can now test the connection to the MCP server using Postman's request features. See [Testing with Postman](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/testing/postman-testing.md) for examples. # Connecting an MCP Client Connecting a client to a Salesforce Hosted MCP Server is a process that involves both Salesforce Setup and your selected client application. ## Overview To connect an MCP client, follow these steps in order: 1. **[Create an External Client App](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/setup/create-external-client-app.md)** — Register an External Client App (ECA) in your org to handle OAuth authentication. Each MCP server configuration links to one ECA. Note: You can't use Connected Apps for MCP authentication. **note:** Registering an ECA is not a requirement for Agentforce Vibes. Salesforce Platform MCP servers are auto-enabled in Agentforce Vibes. 2. **Configure Your MCP Client** — Add the MCP server URL and your External Client App's consumer key to your selected client. Detailed instructions are available for: - [Postman](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/postman.md) - [Claude](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/claude.md) - [ChatGPT](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/chatgpt.md) - [Cursor](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/cursor.md) - [Agentforce Vibes](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/afv.md) 3. **[Test Your MCP Client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/testing/test-connection.md)** — Verify the connection - issue a natural language request through the client's chat interface and check for a response. ## Quick Start with Postman > **Tip:** Before connecting a full LLM client, consider testing with [Postman](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/postman.md) first. Postman calls MCP tools directly and returns raw JSON without LLM interpretation so you can verify authentication, server connections, and tool responses before adding an AI model. Postman supports OAuth 2.0 with PKCE natively and doesn’t require any additional software. It's the recommended first step for developers evaluating the integration. ## Tested Clients Salesforce has tested these MCP clients. Other clients that support OAuth 2.0 Authorization Code with PKCE should also work. | Client | Notes | | ----------- | ----------------------------------------------------------------------- | | **Claude** | Native MCP connector support; no additional software required | | **ChatGPT** | Supported via developer mode and connectors (a.k.a. apps) | | **Cursor** | Native OAuth support; no additional software required | | **Postman** | Best tool for initial testing and debugging; recommended starting point | | **Agentforce Vibes** | Auto-enabled; no additional software required | # Contact Support Still stuck? Prepare to contact Salesforce Support. ## Information to provide When contacting Salesforce Support, include: - The server URL that you used - Whether you're using a Sandbox or Scratch Org - The MCP client name and version - The exact error message (copy/paste or screenshot) - The time and time zone when the issue occurred - If the issue reproduces in Postman or MCP Inspector - Which steps you've already tried in the troubleshooting guide ## Where to get help Contact Salesforce Support through your organization's support channels. # Content Read-Only MCP Server The `platform/content-readonly` server provides read-only access to Salesforce CMS through MCP, so agents can search for, access, and read enhanced CMS content, folders, workspaces, and channels. Use this server to: - Summarize an existing CMS content item - Help an author find existing content before they make changes elsewhere - Find translated versions of a content item - Answer questions about what CMS content is published where - Get details about an enhanced CMS workspace or channel When agents need to create or modify Salesforce CMS content, workspaces, folders, or channels, see the [Content Write MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/content-write.md). ## Prerequisites - **API version:** v67.0 and later - **External Client App** configured with the `mcp_api` scope - **Agentforce Vibes** set up and connected to your Salesforce org **note:** Currently, Agentforce Vibes is the only supported MCP client for this server. To use this MCP server, make sure that Digital Experiences is enabled in your org. Users must have access to Salesforce CMS in the org to be able to access CMS through the server. For example, to get details about a CMS workspace or content from a CMS workspace via the MCP server, the user must be a contributor for that workspace. See [Contributors and Roles](https://help.salesforce.com/s/articleView?id=xcloud.cms_access_control_overview.htm) in Salesforce Help for more information. For setup instructions, see [Set Up Your Org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/setup/setup-overview.md). ## Server URL Use these server URLs to access the production and sandbox versions of the `content-readonly` server. - **Production:** `https://api.salesforce.com/platform/mcp/v1/platform/content-readonly` - **Sandbox/Scratch:** `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/content-readonly` ## Activate the Server 1. From Setup, in the Quick Find box, enter `MCP Servers`, and then select **MCP Servers**. 2. Find **content-readonly** in the list of servers. 3. Click **Activate**. ## Example Prompts - "What CMS workspaces do I have access to?" - "Find all news articles mentioning 'open enrollment' in the Benefits workspace." - "Show me the French version of this content item." - "What content is currently published on our public website channel?" - "Get the sharing settings for the Marketing Assets folder." ## Available Tools The `content-readonly` server provides the following tools. ### `get_cms_workspace` Gets the details of a single CMS workspace given its ID, including the workspace name, type, and default language. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/spaces/{contentSpaceId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentSpace). **Inputs:** | Parameter | Type | Required | Description | | ---------------- | ------ | -------- | --------------------------- | | `contentSpaceId` | string | Yes | The ID of the CMS workspace | **Outputs:** An array of details about the CMS workspace including its name, type, and default language. ### `get_cms_workspaces` Lists all enhanced CMS workspaces in the org that the current user can access. Returns each workspace's ID, name, and type. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/spaces/`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentSpaceCollection). **Inputs:** | Parameter | Type | Required | Description | | -------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `nameFragment` | string | No | The name fragment to filter spaces that contain the value in the workspace name. | | `spaceType` | string | No | Type of CMS workspace to filter by. Enum: `App_Dev`, `Content`, `Enablement`, `Experience`, `ExperienceContainer`, `Fragment_Space`, `Gen_AI`, `Library`, `Marketing`, `SalesEngagement`, `Web_App`. | | `page` | integer | No | Number of the page you want returned. Starts at 0. If you don’t specify a value or if you specify 0, the first page is returned. | | `pageSize` | integer | No | Specifies the number of items per page. Valid values are 1–250. If you don't specify a value, the default size is 25. | | `businessUnitId` | string | No | The ID of the Marketing business unit by which to filter workspaces | | `businessUnitStatus` | string | No | The status of the Marketing business unit by which to filter workspaces | | `hasBusinessUnit` | boolean | No | Filters workspaces by whether they're associated with a business unit (`true`) or not (`false`) | **Outputs:** An array of enhanced CMS workspaces with ID, name, and type. ### `get_cms_channels_for_workspace` Lists all the channels that are associated with a specific CMS workspace for the given workspace ID. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/spaces/{contentSpaceId/channels}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentSpaceChannels). **Inputs:** | Parameter | Type | Required | Description | | ---------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- | | `contentSpaceId` | string | Yes | The ID of the CMS workspace | | `page` | integer | No | Number of the page you want returned. Starts at 0. If you don’t specify a value or if you specify 0, the first page is returned. | | `pageSize` | integer | No | Specifies the number of items per page. Valid values are from 1-250. If you don't specify a value, the default size is 25. | **Outputs:** An array of channels associated with the CMS workspace, each with ID, name, and type. ### `search_content_cms_workspaces` Searches for CMS content in enhanced CMS workspaces and folders by keyword, optionally filtered by workspace, folder, content type, or language. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/items/search`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentSearchItems). **Inputs:** | Parameter | Type | Required | Description | | ------------------------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `queryTerm` | string | Yes | A list of up to 50 search terms, separated by space | | `contentSpaceOrFolderIds` | array of strings | Yes | The ID of the CMS workspace or folder in which to search for content | | `contentTypeFQN` | string | No | The fully qualified name of the content type used to restrict the search | | `languages` | array of strings | No | A list of up to 10 languages or `All` to search for all languages. Specify each language as a language only, such as `en`, or as a language and locale, such as `en_US`. The search returns only exact matches and only languages that the workspace supports. If unspecified, the workspace's default language is used. | | `page` | integer | No | Number of the page you want returned. Starts at 0. If you don’t specify a value or if you specify 0, the first page is returned. | | `pageSize` | integer | No | Specifies the number of items per page. Valid values are from 1-250. If you don't specify a value, the default size is 25. | | `scope` | string | No | The text search scope for items. Possible values include "`All`" or "`TitleOnly`." If unspecified, defaults to `All`. If you specify a folder ID, you can’t restrict the search scope. | **Outputs:** A paginated list of CMS keyword-based search result items. ### `get_cms_content_item` Gets a single CMS content item by its content key or ID, and returns the content item and any translated variants. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/contents/{contentKeyOrId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentDocument). **Inputs:** | Parameter | Type | Required | Description | | ---------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `contentKeyOrId` | string | Yes | The content key or ID of the CMS content item | | `contentVersion` | string | No | The content version of the CMS content item | | `language` | string | No | The language locale of the managed content, for example, `en_US`. If you don't specify version or if you specify a `version` corresponding to the latest `version`, the document is returned in the fallback language, if available, or in the primary language of the workspace. If you specify a `version` that isn’t the latest version and isn’t available for the language, an error is returned. If you don’t specify a language, the document is returned in the primary language of the workspace. | | `variantVersion` | string | No | The variant version of the content item | **Outputs:** The CMS content item and its variants. ### `get_cms_content_variant` Gets a single CMS content variant by its variant ID. A variant is one language rendition of a content item, for example, a French version, and it contains the content item's body and field values in that language. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/contents/variants/{variantId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentVariant). **Inputs:** | Parameter | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------- | | `variantId` | string | Yes | The ID of the CMS content variant | **Outputs:** The content variant, including its language, body, and field values. ### `get_cms_folder` Gets the details of a single CMS folder from an enhanced CMS workspace by the folder ID. Returns the folder name, creation date, permissions, and parent folder, if applicable. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/folders/{folderId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/CMS-Managed-Content-Resources/operation/getManagedContentSpaceFolder). **Inputs:** | Parameter | Type | Required | Description | | ----------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------- | | `folderId` | string | Yes | The ID of the CMS folder | | `contextContentSpaceId` | string | No | The ID of the context workspace. Specify to get folder hierarchy information starting from the root of the context workspace. | **Outputs:** The folder name, creation date, permissions, and parent folder. ### `get_cms_folder_sharing_details` Gets the sharing and permission settings for a CMS folder, including which users, groups, or roles have access and their permission levels. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/folders/{folderId}/shares`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getMCSFolderShareCollection). **Inputs:** | Parameter | Type | Required | Description | | ---------- | ------ | -------- | -------------------- | | `folderId` | string | Yes | ID of the CMS folder | **Outputs:** The sharing and permission settings for the folder, by user, group, or role. ### `get_cms_channels` Lists all CMS channels in the org that the current user can access. Returns each channel's ID, name, and type. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/channels`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentChannels). **Inputs:** | Parameter | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `page` | integer | No | Number of the page you want returned. Starts at 0. If you don’t specify a value or if you specify 0, the first page is returned. | | `pageSize` | integer | No | Specifies the number of items per page. Valid values are from 1 through 250. If you don't specify a value, the default size is 25. | | `showDetails` | boolean | No | Specifies whether to show the channels’ detailed information (`true`) or summary information only (`false`). If you don't specify a value, the default is `false`. | **Outputs:** An array of CMS channels with ID, name, and type. ### `get_cms_channel` Gets the details of a CMS channel by its ID, including the channel name and type. This tool returns the channel's authoring and configuration record. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/channels/{channelId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentChannel). **Inputs:** | Parameter | Type | Required | Description | | ----------- | ------ | -------- | ------------------------- | | `channelId` | string | Yes | The ID of the CMS channel | **Outputs:** The CMS channel name, type, and authoring configuration details. ### `get_cms_channel_delivery_detail` Gets the delivery details of a CMS channel by its ID. This tool describes the channel as content consumers see it at run time. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/delivery/channels/{channelId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentDeliveryChannel). **Inputs:** | Parameter | Type | Required | Description | | ----------- | ------ | -------- | --------------------- | | `channelId` | string | Yes | ID of the CMS channel | **Outputs:** The delivery-side details of the channel. ### `search_content_cms_channels` Searches for and retrieves published, non-media content in Salesforce CMS by using keywords or taxonomy terms. This tool retrieves only non-media content such as news (`sfdc_cms__news`), from public CMS channels that are accessible to the current user. **Inputs:** | Parameter | Type | Required | Description | | -------------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `searchKeyword` | string | No | A list of up to 10 OR-separated concrete nouns extracted from the user's natural language query. | | `searchLanguage` | string | No | The locale of the content to search for, by using underscore format (for example, `en_US`, `es_MX`, `fr_FR`). Default is `en_US`. | | `channelIds` | string | No | A list of one or more IDs of CMS channels where the search happens. | | `channelType` | string | No | The type of channel where the search happens. This parameter limits the action to search for published content only within channels of the specified type. | | `contentAccessScope` | string | No | This parameter limits the search to channels with the specified content access scope. The only supported value is `Public`, which restricts the search to publicly accessible channels. | | `taxonomyExpression` | string | No | A stringified JSON expression derived from the user's natural language query that filters content by descriptive qualities, styles, moods, or categories (for example, `{"OR": ["term1", "term2"]}`). Use `{}` if no taxonomies apply. | | `contentTypeFqn` | string | No | A list of one or more non-media content type fully qualified names (FQN). | | `pageOffset` | integer | No | A page of results when the search returns multiple content items. | | `searchLimit` | integer | No | The maximum number of content items shown on a single page when the search returns multiple content items. | **Outputs:** An array of published, non-media content items from public CMS channels that match the search query. ### `search_media_cms_channels` Searches for and retrieves published media assets in Salesforce CMS by using keywords or taxonomy terms. This tool retrieves only published media content, such as images (`sfdc_cms__image`), videos (`sfdc_cms__video`), documents (`sfdc_cms__document`), and audio (`sfdc_cms__audio`), from public CMS channels that are accessible to the current user. **Inputs:** | Parameter | Type | Required | Description | | -------------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `searchKeyword` | string | No | A list of up to 10 OR-separated concrete nouns extracted from the user's natural language query. Use domain-specific synonyms, leave empty if the query contains no concrete nouns. | | `searchLanguage` | string | No | The locale of the content to search for, by using underscore format (for example, `en_US`, `es_MX`, `fr_FR`). Default is `en_US`. | | `channelIds` | string | No | A list of one or more IDs of CMS channels where the search happens. | | `channelType` | string | No | The type of channel where the search happens. This parameter limits the action to search for published content only within channels of the specified type. | | `contentAccessScope` | string | No | This parameter limits the search to channels with the specified content access scope. The only supported value is `Public`, which restricts the search to publicly accessible channels. | | `taxonomyExpression` | string | No | A stringified JSON expression derived from the user's natural language query that filters content by descriptive qualities, styles, moods, or categories (for example, `{"OR": ["term1", "term2"]}`). Use `{}` if no taxonomies apply. | | `contentTypeFqn` | string | No | A list of one or more content type fully qualified names (FQN). | | `pageOffset` | integer | No | A page of results when the search returns multiple content items. | | `searchLimit` | integer | No | The maximum number of content items shown on a single page when the search returns multiple content items. | **Outputs:** An array of published media assets from public CMS channels that match the search query. ### `get_published_cms_content_from_channel` Lists the CMS content published to a specific CMS channel. Filter the results by content type, language, publish date, and show paginated results. Use this tool to read live, published CMS content from a channel. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/delivery/channels/{channelId}/contents`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentsDelivery). **Inputs:** | Parameter | Type | Required | Description | | -------------------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `channelId` | string | Yes | ID of the CMS channel | | `contentKeys` | array of strings | No | Comma-separated list of up to 50 content keys. Specify either managed content IDs or content keys. | | `contentTypeFQN` | string | No | Fully qualified name of the managed content type. | | `expandReferences` | boolean | No | Specifies whether to include details of references (`true`) or summaries of references (`false`) in the response body. If unspecified, the default value is `false`. | | `includeContentBody` | boolean | No | Specifies whether to return the content body (`true`) or the content summary (`false`). If unspecified, the default value is `false`. | | `language` | string | No | Language locale for the managed content, for example, `en_US`. If the requested translation isn't available, the language defaults to the configured fallback language or the channel's default language. If the content isn't available in the fallback language and the channel's default language, we return an error. | | `managedContentIds` | array of strings | No | Comma-separated list of up to 100 managed content IDs. Specify either managed content IDs or content keys. | | `page` | integer | No | Number of the page you want returned. Starts at 0. If you don't specify a value or if you specify 0, the first page is returned. | | `pageSize` | integer | No | Specifies the number of items per page. Valid values are from 1 through 250. If unspecified, the default size is 25. If you specify `true` for `expandReferences` or `includeContentBody`, the maximum page size you can specify is 25. | | `publishEndDate` | string | No | ISO 8601 formatted publish end date. | | `publishStartDate` | string | No | ISO 8601 formatted publish start date. | | `referenceDepth` | integer | No | An integer 0–3 specifying the depth of references. If you specify 0, the `references` property of the Managed Content Delivery Document Collection response body is null. If unspecified, the default value is 0. | | `referencesAsList` | boolean | No | Specifies whether to return the references as a list in the `referencesList` property of the Managed Content Delivery Document Collection response body (`true`). If you specify `false`, the references are returned as key-value pairs in the `references` property. If unspecified, the default value is `false`. | | `showAbsoluteUrl` | boolean | No | Specifies whether to show absolute URLs in the response body (`true`) or not (`false`). If you don't specify a value, the default is `false`. | **Outputs:** A paginated array of published content variants for the CMS channel. ### `get_published_cms_content_from_site` Lists all the CMS content published to a specific Experience Cloud site. Filter the results by content type, language, publication date, and show paginated results. Use this tool to read live, published CMS content on a site. Inputs and outputs mirror the [Connect REST API at `GET /connect/sites/{siteId}/cms/delivery/contents`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentsDelivery). **Inputs:** | Parameter | Type | Required | Description | | -------------------- | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `siteId` | string | Yes | ID of the Experience Cloud site | | `contentKeys` | array of strings | No | Comma-separated list of up to 50 content keys. Specify either managed content IDs or content keys. | | `contentTypeFQN` | string | No | Fully qualified name of the managed content type. | | `expandReferences` | boolean | No | Specifies whether to include details of references (`true`) or summaries of references (`false`) in the response body. If unspecified, the default value is `false`. | | `includeContentBody` | boolean | No | Specifies whether to return the content body (`true`) or the content summary (`false`). If unspecified, the default value is `false`. | | `language` | string | No | Language locale for the managed content, for example, `en_US`. If the requested translation isn't available, the language defaults to the configured fallback language or the site's default language. If the content isn't available in the fallback language and the site's default language, we return an error. | | `managedContentIds` | array of strings | No | Comma-separated list of up to 100 managed content IDs. Specify either managed content IDs or content keys. | | `page` | integer | No | Number of the page you want returned. Starts at 0. If you don't specify a value or if you specify 0, the first page is returned. | | `pageSize` | integer | No | Specifies the number of items per page. Valid values are from 1 through 250. If unspecified, the default size is 25. If you specify `true` for `expandReferences` or `includeContentBody`, the maximum page size you can specify is 25. | | `publishEndDate` | string | No | ISO 8601 formatted publish end date. | | `publishStartDate` | string | No | ISO 8601 formatted publish start date. | | `referenceDepth` | integer | No | An integer 0–3 specifying the depth of references. If you specify 0, the `references` property of the Managed Content Delivery Document Collection response body is null. If unspecified, the default value is 0. | | `referencesAsList` | boolean | No | Specifies whether to return the references as a list in the `referencesList` property of the Managed Content Delivery Document Collection response body (`true`). If you specify `false`, the references are returned as key-value pairs in the `references` property. If unspecified, the default value is `false`. | | `showAbsoluteUrl` | boolean | No | Specifies whether to show absolute URLs in the response body (`true`) or not (`false`). If you don't specify a value, the default is `false`. | **Outputs:** A paginated array of published content variants for the site. ### `get_published_cms_content_item_from_site` Gets a single item of published CMS content from an Experience Cloud site given the content key or ID. This tool returns the published variant as content consumers see it at run time. Inputs and outputs mirror the [Connect REST API at `GET /connect/sites/{siteId}/cms/delivery/contents/{contentKeyOrId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentDelivery). **Inputs:** | Parameter | Type | Required | Description | | ---------------- | ------ | -------- | ------------------------------------- | | `siteId` | string | Yes | ID of the Experience Cloud site | | `contentKeyOrId` | string | Yes | Content key or ID of the content item | **Outputs:** The published content variant. ### `get_published_cms_collection_from_site` Gets a published CMS collection from an Experience Cloud site given the collection key or ID. This tool also lists all content items contained in the collection. Inputs and outputs mirror the [Connect REST API at `GET /connect/sites/siteId/cms/delivery/collections/{collectionKeyOrId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentCollectionDelivery). **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | --------------------------------------------------------------------------------------------------- | | `siteId` | string | Yes | ID of the Experience Cloud site | | `collectionKeyOrId` | string | Yes | Collection key or ID. A collection key is a unique identifier such as MCA4CCV5QS2BAB5H7YRCRPTCWGZQ. | **Outputs:** The collection and the published content items it contains. ### `get_published_cms_content_item_from_channel` Gets a single item of published CMS content from a CMS channel given the content key or ID. Returns the published variant as content consumers see it at run time. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/delivery/channels/{channelId}/contents/{contentKeyOrId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentDelivery). **Inputs:** | Parameter | Type | Required | Description | | ------------------ | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `channelId` | string | Yes | The ID of the CMS channel | | `contentKeyOrId` | string | Yes | The content key or ID of the content item | | `contentVersion` | integer | No | The content version of the CMS content item | | `expandReferences` | boolean | No | Specifies whether to include details of references (`true`) or summaries of references (`false`) in the response body. If unspecified, the default value is `false`. | | `language` | string | No | The language locale for the managed content, for example, `en_US`. If the requested translation isn't available, the language defaults to the configured fallback language or the channel's default language. | | `referenceDepth` | integer | No | An integer 0–3 specifying the depth of references. If you specify 0, the `references` property of the response body is null. If unspecified, the default value is 0. | | `referencesAsList` | boolean | No | Specifies whether to return the references as a list in the `referencesList` property of the response body (`true`), or as key-value pairs in the `references` property (`false`). If unspecified, the default value is `false`. | | `showAbsoluteUrl` | boolean | No | Specifies whether to show absolute URLs in the response body (`true`) or not (`false`). If you don't specify a value, the default is `false`. | **Outputs:** The published content variant. ### `get_published_cms_collection_from_channel` Gets a published CMS collection from a CMS channel given the collection key or ID. This tool also lists all content items contained in the collection. Inputs and outputs mirror the [Connect REST API at `GET /connect/cms/delivery/channels/{channelId}/collections/{collectionKeyOrId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/getManagedContentCollectionDelivery). **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------- | | `channelId` | string | Yes | The ID of the CMS channel | | `collectionKeyOrId` | string | Yes | The collection key or ID. A collection key is a unique identifier such as MCA4CCV5QS2BAB5H7YRCRPTCWGZQ. | | `language` | string | No | The language locale for the managed content collection, for example, `en_US`. | | `pageSize` | integer | No | The number of items to fetch per page. The default is 50. | | `pageToken` | integer | No | The page of items to fetch. | **Outputs:** The collection and the published content items it contains. ### `search_electronic_media` Searches for and retrieves media assets, such as image files, across Salesforce CMS and any connected third-party CMS or digital asset management (DAM) systems. This tool uses Data 360 hybrid search (vector search and keyword search) to find media. To use this tool, deploy the CMS Base Data Kit in your org so that agents can find the most relevant content. See [Deploy and Set Up the CMS Base Data Kit](https://help.salesforce.com/s/articleView?id=xcloud.cms_base_data_kit_setup.htm) in Salesforce Help. **Inputs:** | Parameter | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `searchQuery` | string | Yes | The natural language query that the user provides. The action uses this query to retrieve relevant digital content or electronic media. | | `channelType` | string | Yes | This parameter limits the search to content or media published to channels of the specified channel type. The only supported channel type is `PublicUnauthenticated`. This channel type searches content across all public channels. | | `contentAccessScope` | string | No | This parameter limits the search to channels with the specified content access scope. The only supported value is `Public`, which restricts the search to publicly accessible channels. | **Outputs:** An array of matching media assets from Salesforce CMS and connected third-party sources. ### `get_brand_instructions` Gets specific instructions that tell Agentforce Vibes how to extract and apply a brand from Salesforce CMS. This tool executes an invocable action to get instructions that specialize in applying branding to apps or sites. Call this tool before you call any other brand tools. **Inputs:** None **Outputs:** Instructions for extracting and applying a brand from Salesforce CMS. ### `get_content_types_for_workspace` List the content types supported by a Salesforce CMS workspace. Identify the workspace by supplying exactly one of: a base type developer name, such as `content`, `marketing`, or `fragment_space`; the ID of a content space; or the ID of a CMS folder. The supported content types are derived from the modules that the workspace defines or has installed. This tool returns a list of content types, each with a namespace prefix, developer name, title, and description. **Inputs:** | Parameter | Type | Required | Description | | ------------------------------ | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `baseType` | string | No | The base type developer name of the workspace (for example, `content`, `marketing`, `fragment_space`). The supported content types are derived from the modules that this base type defines. Specify at most one of `baseType`, `spaceId`, or `folderId`. All three can be omitted only if `typeClassFullyQualifiedNames` or `mixinTypeFullyQualifiedNames` is provided instead (when enabled for the org). | | `spaceId` | string | No | The ID of a content space. The supported content types are derived from the modules installed on this space. Specify at most one of `baseType`, `spaceId`, or `folderId`. All three can be omitted only if `typeClassFullyQualifiedNames` or `mixinTypeFullyQualifiedNames` is provided instead (when enabled for the org). | | `folderId` | string | No | The ID of a CMS folder. Its owning content space is resolved first, then the supported content types are derived from the modules installed on that space. Specify at most one of `baseType`, `spaceId`, or `folderId`. All three can be omitted only if `typeClassFullyQualifiedNames` or `mixinTypeFullyQualifiedNames` is provided instead (when enabled for the org). | | `typeClassFullyQualifiedNames` | array of strings | No | A list of type-class fully qualified names (or IDs) to scope the returned content types. Combines with the types the workspace already supports when both are present, but can also be provided on its own to scope the query even when the workspace resolves no content types. Ignored unless this feature is enabled for the org. | | `mixinTypeFullyQualifiedNames` | array of strings | No | A list of mixin-type fully qualified names (or IDs) to scope the returned content types to those types that carry the given mixin. Combines with the types the workspace already supports when both are present, but can also be provided on its own to scope the query even when the workspace resolves no content types. Ignored unless this feature is enabled for the org. | **Outputs:** An array of content types, each with a namespace prefix, developer name, title, and description. ## Understand How Security Works Every Salesforce Hosted MCP transaction runs as the authenticated user, scoped through an External Client App with the `mcp_api` scope. Object permissions (CRUD), field-level security (FLS), sharing rules, profile permissions, and permission sets all apply. If you can't perform an action in Salesforce, your agent can't perform it through the MCP server. The audit trail attributes every action to you. The Content Read-Only server follows the same practices that apply across all Salesforce Hosted MCP servers. For full guidance, see [Security Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/security-best-practices.md) and [General Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/general-best-practices.md). ## Related Resources - [Content Write MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/content-write.md) - [Standard MCP Servers Reference](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/servers-reference.md) - [_Connect REST API Developer Guide_: Enhanced CMS Workspace Resources](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources) # Content Write MCP Server The `platform/content-write` server exposes write access to Salesforce CMS through MCP, so agents can create, edit, and manage enhanced CMS content, folders, workspaces, and channels. Use this server to: - Draft an article from source material - Publish approved content to a channel - Create a folder in an enhanced CMS workspace and update its sharing settings - Set up a new enhanced CMS workspace and channel for a campaign When agents need read-only access to Salesforce CMS, such as to search for, retrieve, and read content, see the [Content Read-Only MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/content-readonly.md). ## Prerequisites - **API version:** v68.0 and later - **External Client App** configured with the `mcp_api` scope - **Agentforce Vibes** set up and connected to your Salesforce org **note:** Currently, Agentforce Vibes is the only supported MCP client for this server. To use this MCP server, make sure that Digital Experiences is enabled in your org. Users must have access to Salesforce CMS in the org to be able to access CMS through the server. For example, to create content in a CMS workspace via the MCP server, the user must be a contributor for that workspace. See [Contributors and Roles](https://help.salesforce.com/s/articleView?id=xcloud.cms_access_control_overview.htm) in Salesforce Help for more information. For setup instructions, see [Set Up Your Org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/setup/setup-overview.md). ## Server URL Use these server URLs to access the production and sandbox versions of the `content-write` server. - **Production:** `https://api.salesforce.com/platform/mcp/v1/platform/content-write` - **Sandbox/Scratch:** `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/content-write` ## Activate the Server 1. From Setup, in the Quick Find box, enter `MCP Servers`, and then select **MCP Servers**. 2. Find **content-write** in the list of servers. 3. Click **Activate**. ## Example Prompts - "Create a news article in the Marketing workspace titled 'Q3 Product Launch' with this body copy." - "Publish this content item to the public site channel." - "Unpublish the outdated pricing document from all channels." - "Create a new enhanced CMS workspace called 'Partner Enablement' and set up a channel for it." - "Create a French variant of this content item by using the translated text that I provided." ## Available Tools The `content-write` server provides the following tools. ### `update_cms_workspace_channels` Updates the channel assignments for an enhanced CMS workspace. Controls which channels are associated with the workspace. Inputs and outputs mirror the [Connect REST API at `PATCH /connect/cms/spaces/{contentSpaceId}/channels`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/patchManagedContentSpaceChannels). **Inputs:** | Parameter | Type | Required | Description | | ---------------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `contentSpaceId` | string | Yes | The ID of the CMS workspace | | `spaceChannels` | array of objects | Yes | A list of CMS channels to add or remove from the workspace. Each item is an object with `channelId` (string) and `operation` (string; enum: `Add`, `Remove`). | **Outputs:** A list of updated channel assignments for the workspace. ### `create_cms_workspace` Creates a CMS workspace, also known as a managed content space. A workspace is a container for creating, managing, and publishing CMS content. Inputs and outputs mirror the [Connect REST API at `POST /connect/cms/spaces`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/postManagedContentSpaceCollection). **Inputs:** | Parameter | Type | Required | Description | | ---------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | string | Yes | The name of the CMS workspace | | `apiName` | string | No | The API name of the CMS workspace | | `description` | string | No | The description of the CMS workspace | | `defaultLanguage` | string | No | The default language of the CMS workspace | | `spaceType` | string | No | Specifies the space type of the managed content space. Enum: `App_Dev`, `Content`, `Enablement`, `Experience`, `ExperienceContainer`, `Fragment_Space`, `Gen_AI`, `Library`, `Marketing`, `SalesEngagement`, `Web_App`. | | `channelsList` | array of strings | No | A list of CMS channels to add to the CMS workspace | | `collaboratorsList` | array of objects | No | A list of contributors to add to the CMS workspace. Each item is an object with `memberId` (the ID of the user or group to assign the role) and `roleId` (the ID of the role to assign). | | `supportedLanguagesList` | array of strings | No | A list of languages supported by the CMS workspace | | `isFlowOrchestrationEnabled` | boolean | No | Indicates whether the orchestrator module is installed (`true`) for the CMS workspace or not (`false`) | | `isSpaceV2` | boolean | No | Indicates whether the workspace is an enhanced (2.0) workspace | | `isUndeletable` | boolean | No | Indicates whether the CMS workspace can't be deleted (`true`) or can be deleted (`false`) | **Outputs:** The new CMS workspace's ID, name, type, and default language. ### `update_cms_workspace` Updates the properties of an existing CMS workspace such as its name and description. Inputs and outputs mirror the [Connect REST API at `PATCH /connect/cms/spaces/{contentSpaceId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/patchManagedContentSpace). **Inputs:** | Parameter | Type | Required | Description | | ---------------------------- | ---------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `contentSpaceId` | string | Yes | The ID of the CMS workspace | | `name` | string | No | The name of the CMS workspace | | `apiName` | string | No | The API name of the CMS workspace | | `description` | string | No | The description of the CMS workspace | | `channelsList` | array of strings | No | A list of CMS channels to add to the CMS workspace | | `collaboratorsList` | array of objects | No | A list of contributors to add to the CMS workspace. Each item is an object with `memberId` (the ID of the user or group to assign the role) and `roleId` (the ID of the role to assign). | | `supportedLanguagesList` | array of strings | No | A list of languages supported by the CMS workspace | | `isFlowOrchestrationEnabled` | boolean | No | Indicates whether the orchestrator module is installed (`true`) for the CMS workspace or not (`false`) | | `isSpaceV2` | boolean | No | Indicates whether the space is an enhanced (2.0) workspace | **Outputs:** The updated details of the CMS workspace. ### `create_cms_content` Creates a CMS content item in an enhanced CMS workspace or folder. Inputs and outputs mirror the [Connect REST API at `POST /connect/cms/contents`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/postManagedContentDocumentCreate). **Inputs:** | Parameter | Type | Required | Description | | ------------------------ | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `contentType` | string | Yes | The fully qualified name of the content type to create, such as `sfdc_cms__news`, or `sfdc_cms__email` | | `title` | string | Yes | The title of the content item | | `contentBody` | string | Yes | The body of the content as a JSON object string. The content body must match the content type schema. | | `contentSpaceOrFolderId` | string | Yes | The ID of the CMS workspace or folder where the content is created | | `apiName` | string | No | The API name of the content item | | `contentKey` | string | No | The Content key to assign to the managed content. A content key is a universally unique identifier (UUID) such as MCA4CCV5QS2BAB5H7YRCRPTCWGZQ. | | `externalId` | string | No | The content's external ID | | `urlName` | string | No | The URL-friendly identifier within the org | **Outputs:** The created CMS content item, including its content key, managed content ID and version ID, variant ID, content FQN, content type, title, URL name, API name, language, workspace, folder, created/modified by and date, content body, content version, and external ID. Any details from optional fields are omitted if they weren't originally provided. ### `create_cms_content_variant` Creates a variant for an existing CMS content item. A variant represents a language-specific or channel-specific version of content. Inputs and outputs mirror the [Connect REST API at `POST /connect/cms/contents/variants`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/postManagedContentVariantCreate). **Inputs:** | Parameter | Type | Required | Description | | ----------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------- | | `managedContentKeyOrId` | string | Yes | The ID or content key of the CMS content item to create a variant for | | `variantTitle` | string | Yes | The title of the content variant | | `languageCode` | string | Yes | The language code of the variant, such as `en_US`, `fr`, or `de`. | | `contentBody` | string | Yes | The body of the content as a JSON object string. The content body must match the content type schema. | | `urlName` | string | No | A URL-friendly identifier of the variant | **Outputs:** The created CMS content variant, including its variant ID, content ID, content version ID, variant title, URL name, language code, and content body. ### `clone_cms_content` Creates a copy of a specified CMS content item within the same enhanced CMS workspace. Inputs and outputs mirror the [Connect REST API at `POST /connect/cms/contents/{contentId}/clone`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/postManagedContentDocumentClone). **Inputs:** | Parameter | Type | Required | Description | | ------------------------ | ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- | | `contentKeyOrId` | string | Yes | The content key or ID of the CMS content item to clone | | `apiName` | string | No | The API name of the cloned content | | `contentSpaceOrFolderId` | string | No | The ID of the target folder for the cloned content. If unspecified, defaults to the folder of the source content. | | `includeVariants` | boolean | No | Specifies whether to include variants (`true`) or not (`false`) when cloning the content. If unspecified, the default is `false`. | | `referencesToClone` | array of strings | No | A list of (internal-only) references to clone | | `title` | string | No | The title of the cloned content. If unspecified, "clone of" is appended to the source content's title. | **Outputs:** The newly cloned CMS content item. ### `update_cms_content_variant` Updates an existing CMS content variant. Use this tool to replace the entire body of the content variant or refine the content body with AI. Inputs and outputs mirror the [Connect REST API at `PUT /connect/cms/contents/{variantId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/putManagedContentVariant). **Inputs:** | Parameter | Type | Required | Description | | ------------------------- | ------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `variantId` | string | Yes | ID of the content variant to update | | `contentBody` or `prompt` | string | Yes (exactly one) | Specify exactly one of `contentBody` or `prompt`, not both `contentBody`: full content body as a JSON object string, replacing the variant body wholesale (partial bodies aren't supported). `prompt`: a natural-language instruction describing the changes to the content body. The content body is fetched, sent to an LLM along with the schema and the instruction, and the refined body is saved. | | `title` | string | No | Override for the variant title. If omitted in authored mode, the existing title is preserved. In prompt mode, the LLM-produced title is used unless overridden. | | `urlName` | string | No | Override for the variant URL name | | `apiName` | string | No | Override for the variant API name | **Outputs:** The updated content variant, including content key, managed content ID and version ID, variant ID, content FQN, content type, title, URL name, API name, language, workspace, folder, created/modified by and date, content body, and content version. Optional fields are omitted if not originally provided. ### `publish_cms_content` Publishes CMS content to one or more channels connected to the content's enhanced CMS workspace. This tool makes content publicly available through the delivery channels associated with the content's workspace. Inputs and outputs mirror the [Connect REST API at `POST /connect/cms/contents/publish`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/postManagedContentPublish). **Inputs:** | Parameter | Type | Required | Description | | -------------------------- | ---------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `contentIds` | array of strings | Yes, when variantIds isn't specified | IDs of the CMS content items to publish. When specified, all variants of the content are published. | | `variantIds` | array of strings | Yes, when contentIds isn't specified | IDs of the content variants to publish. All variants must be from the same CMS workspace. | | `contextContentSpaceId` | string | No | ID of the enhanced CMS workspace from where the content is published. If unspecified, the context workspace is derived from the content’s origin workspace, and all content items in the request must belong to the same origin workspace. If publishing CMS content that's shared to a workspace, this parameter is required. | | `includeContentReferences` | boolean | No | Specifies whether to include content references (`true`) or not (`false`). | | `description` | string | No | Description for publish action | **Outputs:** A success or error indicator for each content and channel pair. ### `unpublish_cms_content` Unpublishes CMS content from one or more CMS channels. This tool removes content from the delivery channels associated with the content's enhanced CMS workspace, making it unavailable to external viewers. The content reverts to draft status in the workspace. Inputs and outputs mirror the [Connect REST API at `POST /connect/cms/contents/unpublish`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/postManagedContentUnpublish). **Inputs:** | Parameter | Type | Required | Description | | ----------------------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `contentIds` | array of strings | Yes | The content items to unpublish. | | `variantIds` | array of strings | No | Reserved for internal use only | | `contextContentSpaceId` | string | No | ID of the enhanced CMS workspace from where the content is unpublished. Shared content is always unpublished from all channels that it's published to. | | `description` | string | No | Description for the unpublish action. | **Outputs:** A success or error indicator for each content or variant that was unpublished. ### `create_cms_folder` Creates a folder in an enhanced CMS workspace. Folders help organize content within a workspace. **Inputs:** | Parameter | Type | Required | Description | | ---------- | ------ | -------- | --------------------------- | | `name` | string | Yes | The name of the folder | | `parentId` | string | No | The ID of the parent folder | **Outputs:** The new folder's ID, name, creation date, and parent folder. ### `update_cms_folder` Updates the name of an existing CMS folder. **Inputs:** | Parameter | Type | Required | Description | | ---------------- | ------ | -------- | ------------------------------ | | `folderId` | string | Yes | The ID of the folder | | `name` | string | No | The updated name of the folder | | `parentFolderId` | string | No | The ID of the parent folder | **Outputs:** A success or error indicator noting that the folder was updated or not. ### `update_cms_folder_sharing_settings` Updates sharing settings for a folder in a CMS workspace. Use this tool to grant, modify, or revoke folder access for users, groups, or roles. Inputs and outputs mirror the [Connect REST API at `PATCH /connect/cms/folders/{folderId}/shares`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/patchMCSFolderShareCollection). **Inputs:** | Parameter | Type | Required | Description | | ------------- | ---------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `folderId` | string | Yes | The ID of the folder | | `shareWith` | array of objects | No | The list of targets to share the folder with. Each item is an object with a `targetId` field, which is the ID of the share target. | | `unshareWith` | array of strings | No | The list of targets to unshare the folder with. | **Outputs:** A success or error indicator indicating that the folder's sharing settings were updated or not. ### `create_cms_channel` Creates a CMS channel. A channel controls how and where CMS content is delivered. Inputs and outputs mirror the [Connect REST API at `POST /connect/cms/channels`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/postManagedContentChannels). **Inputs:** | Parameter | Type | Required | Description | | ------------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | string | Yes | The name of the CMS channel. | | `type` | string | Yes | The type of managed content channel. Enum: `CloudToCloud`, `Community`, `ConnectedApp`, `PublicUnauthenticated`, `UserPermission`, `WebApp`. | | `targetId` | string | No | The ID of the target associated with the CMS channel. | | `domain` | string | No | The ID or name of the domain assigned to the public channel. | | `isDomainLocked` | boolean | No | Specifies whether the domain is locked and can’t be changed (`true`) or not (`false`). | | `isEnhanced` | boolean | No | Specifies whether the channel is compatible with an enhanced workspace (`true`) or not (`false`). | | `isCrossApi` | boolean | No | Specifies whether the channel is able to support both 1.0 and 2.0 content (`true`) or not (`false`). | | `isSearchable` | boolean | No | Enables text search of the channel's content. | | `isHighScale` | boolean | No | Indicates if the channel is a high scale channel (`true`) or not (`false`). | | `isDedicatedContentDelivery` | boolean | No | Specifies whether the channel has off-core dedicated content delivery enabled (`true`) or not (`false`). Orgs hosted on Hyperforce use off-core dedicated content delivery to deliver content in public channels with high performance and low latency. | | `cacheControlMaxAge` | number | No | The Cache-Control max age value, in seconds | | `mediaCacheControlMaxAge` | number | No | The Media Cache-Control max age value, in seconds | | `managedContentOffCoreLocation` | object | No | The input representation for creating or updating an off-core location. Contains `bucketName` (string), `namedCredential` (string), and `offCoreLocationType` (string; enum: `Customer_External_S3_Location`). | **Outputs:** The new channel's ID, name, and type. ### `update_cms_channel` Updates the properties of an existing CMS channel, such as its name, domain, and cache settings. Inputs and outputs mirror the [Connect REST API at `PATCH /connect/cms/channels/{channelId}`](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources/operation/patchManagedContentChannel). **Inputs:** | Parameter | Type | Required | Description | | ------------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `channelId` | string | Yes | The ID of the CMS channel. | | `name` | string | No | The name of the CMS channel. | | `targetId` | string | No | The ID of the target associated with the CMS channel. | | `domain` | string | No | The ID or name of the domain assigned to the public channel. | | `isDomainLocked` | boolean | No | Specifies whether the domain is locked and can’t be changed (`true`) or not (`false`). | | `isEnhanced` | boolean | No | Specifies whether the channel is compatible with an enhanced workspace (`true`) or not (`false`). | | `isCrossApi` | boolean | No | Specifies whether the channel is able to support both 1.0 and 2.0 content (`true`) or not (`false`). | | `isSearchable` | boolean | No | Enables text search of the channel's content. | | `isHighScale` | boolean | No | Indicates if the channel is a high scale channel (`true`) or not (`false`). | | `isDedicatedContentDelivery` | boolean | No | Specifies whether the channel has off-core dedicated content delivery enabled (`true`) or not (`false`). Orgs hosted on Hyperforce use off-core dedicated content delivery to deliver content in public channels with high performance and low latency. | | `cacheControlMaxAge` | number | No | The Cache-Control max age value, in seconds | | `mediaCacheControlMaxAge` | number | No | The Media Cache-Control max age value, in seconds | | `managedContentOffCoreLocation` | object | No | The input representation for creating or updating an off-core location. Contains `bucketName` (string), `namedCredential` (string), and `offCoreLocationType` (string; enum: `Customer_External_S3_Location`). | **Outputs:** A success or error indicator indicating that the channel's properties were updated or not. ### `get_or_create_cms_workspace_and_web_app_channel` Gets or creates an enhanced CMS workspace and Web Apps (`WEB_APP`) channel for a UI Bundle, and makes sure that the channel is associated with the workspace. The CMS content of the UI Bundle is authored in the workspace, and when content gets published, it's served through the Web App channel. If the workspace or channel already exists, it gets reused instead of copied. **Inputs:** | Parameter | Type | Required | Description | | --------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------- | | `developerName` | string | Yes | The developer name of the UI Bundle whose CONTENT space and WEB_APP channel which are being created or retrieved. | | `masterLabel` | string | Yes | The human-readable name of the UI Bundle, used for the space when a new one is created. | **Outputs:** The ID of the found or created workspace (`spaceId`), the ID of the found or created channel (`channelId`), and the ID of the found or created `WEB_APP` channel associated with the workspace. ## Understand How Security Works Every Salesforce Hosted MCP transaction runs as the authenticated user, scoped through an External Client App with the `mcp_api` scope. Object permissions (CRUD), field-level security (FLS), sharing rules, profile permissions, and permission sets all apply. If you can't perform an action in Salesforce, your agent can't perform it through the MCP server. The audit trail attributes every action to you. The Content Write server follows the same practices that apply across all Salesforce Hosted MCP servers. For full guidance, see [Security Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/security-best-practices.md) and [General Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/general-best-practices.md). ## Related Resources - [Content Read-Only MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/content-readonly.md) - [Standard MCP Servers Reference](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/servers-reference.md) - [_Connect REST API Developer Guide_: Enhanced CMS Workspace Resources](https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms#tag/Enhanced-CMS-Workspaces-Resources) # Create an External Client App To integrate third-party applications with your Salesforce org via APIs and security controls, you must use an External Client App for registration and enablement. > **Note:** Use an External Client App to connect an MCP client to a Salesforce org. Connected Apps aren't supported. > **Note:** You can't create External Client Apps directly in scratch orgs using the Setup UI. To test in a scratch org, create the External Client App in a developer hub org, add it to a package, and install the package in the target scratch org. ## Steps to Create an External Client App 1. From Setup, in the Quick Find box, enter **external client**, and then select **External Client App Manager**. 2. Click **New External Client App**. 3. Fill out the **Basic Information** section. 4. Expand the section labeled **API (Enable OAuth Settings)** and click the **Enable OAuth** checkbox. 5. In **Callback URL**, enter the applicable URL based on your MCP client: - **Postman**: Enter `https://oauth.pstmn.io/v1/callback` to use Postman's MCP capability via HTTP (not STDIO). If you're using the web browser version of Postman, enter `https://oauth.pstmn.io/v1/browser-callback` instead. Consult Postman's documentation if you're unsure. - **Cursor**: Enter `http://localhost:8787/callback`. Some versions of Cursor also use `cursor://anysphere.cursor-mcp/oauth/callback`. If you can enter more than one callback URL, add both. - **Claude**: Enter `https://claude.ai/api/mcp/auth_callback` - **ChatGPT**: Copy the callback URL from ChatGPT's Advanced settings (see Configure ChatGPT for details) - **Other clients**: Consult the provider's documentation for the callback URL. > **Note:** Recent versions of Cursor use a local callback URL (`http://localhost:8787/callback`) for OAuth authentication, replacing the earlier `cursor://anysphere.cursor-mcp/oauth/callback` scheme. If authorization fails, make sure the callback URL your version of Cursor uses matches a value in your External Client App. 6. In **OAuth Scopes**, include the following: - Access MCP servers (`mcp_api`) - Perform requests at any time (`refresh_token`) 7. Under **Security**: - Select **Issue JSON Web Token (JWT)-based access tokens for named users**. - Deselect all other options that don't require contacting Salesforce customer support to change. 8. Click **Create**. > **Note:** The External Client App can take up to 30 minutes to become available and operational for use with your MCP client. (The delay is similar to registering a new domain with DNS.) 9. Click **Settings**, then click **Consumer Key and Secret** under OAuth Settings to get the consumer key. Store the consumer key for later use. ## Enhance Security for Production Before deploying your MCP integration to production, consider implementing these additional security measures. Each enhancement is independent and can be applied based on your organization's security requirements. ### Require Client Secrets (Web-Based Clients Only) For web-based MCP clients, requiring a client secret adds an additional layer of verification during authentication. The MCP client must present both the client ID and a secret to authenticate. **When to use:** Web-based MCP clients where the secret can be securely stored on the server side. **When to avoid:** Desktop applications, unless the vendor confirms secure secret storage. Embedded secrets in desktop applications can potentially be exposed through decompilation. **To enable:** 1. In your External Client App settings, expand the **Security** section. 2. Select **Require Secret for Web Server Flow**. 3. Generate and securely store the client secret. 4. Configure your MCP client with both the consumer key and client secret. ### Restrict Access to Specific Users By default, any user in your org can authenticate through the External Client App. You can limit access to specific users by requiring a custom Permission Set. **When to use:** When you need granular control over which users can access MCP servers through this client. **To enable:** 1. Create a custom Permission Set that includes the necessary permissions for MCP server access. 2. In your External Client App settings, navigate to **OAuth Policies**. 3. Configure the policy to require the Permission Set for pre-authorization. 4. Assign the Permission Set only to authorized users. ### Restrict Connections by IP Address If your MCP client connects from known IP address ranges, you can restrict the External Client App to accept connections from only those addresses. **When to use:** When your MCP client operates from predictable, stable IP ranges. **Important:** Some MCP clients operate from IP ranges that exceed Salesforce's allowlist capacity. Verify with your MCP client vendor before enabling IP restrictions. **To enable:** 1. In your External Client App settings, navigate to **OAuth Policies**. 2. Add the allowed IP address ranges. 3. Save your changes. ### Shorten Token Lifecycle By default, refresh tokens remain valid indefinitely. Shortening their validity period limits exposure if tokens are compromised. **Recommended settings:** - **Refresh Token Validity:** 30 days or less - **Refresh Token Rotation:** Enable to invalidate old tokens when new ones are issued **To enable:** 1. In your External Client App settings, navigate to **OAuth Policies**. 2. Set **Refresh Token Validity** to 30 days or your preferred timeframe. 3. Enable **Refresh Token Rotation**. 4. Save your changes. ### Enable Single Logout When single logout is enabled, revoking a Salesforce session terminates the corresponding MCP client session simultaneously. **When to use:** When you need immediate access revocation, such as when employees leave the organization. **To enable:** 1. In your External Client App settings, navigate to **Session Settings**. 2. Enable **Single Logout**. 3. Save your changes. ## Next Steps After creating your External Client App, proceed to [connect your MCP client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/client-connection/client-connection-overview.md). # CRM Analytics MCP Server (Beta) **important:** CRM Analytics MCP server is a pilot or beta service that is subject to the Beta Services Terms at [Agreements - Salesforce.com](https://www.salesforce.com/company/legal/) or a written Unified Pilot Agreement if executed by Customer, and applicable terms in the [Product Terms Directory](https://ptd.salesforce.com/). Use of this pilot or beta service is at the Customer's sole discretion. The `crma-beta` server gives AI agents direct, read-only access to CRM Analytics without any custom integration. With a single OAuth connection, agents like Claude, Cursor, ChatGPT, and Agentforce Vibes 2.0 can discover your analytics apps, inspect dataset schemas, run Salesforce Analytics Query Language (SAQL) queries, and read dashboard and lens metadata. When an agent queries through this server, it first inspects a dataset's schema through its extended metadata (XMD) to generate accurate SAQL queries with the correct syntax and field API names. Because the server handles schema resolution automatically, users get accurate results without needing to know SAQL syntax or field API names themselves. For details on how dataset structure and formatting are defined, see the [Salesforce Analytics Extended Metadata (XMD) Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_xmd.meta/bi_dev_guide_xmd/bi_xmd_reference.htm). ## Why Use CRM Analytics MCP Server? Using CRM Analytics MCP provides several key benefits: - **Natural-Language Data Access**: Business users can ask questions like "What were our top 10 accounts by revenue last quarter?" and get formatted results, without writing SAQL or knowing the underlying dataset schema. - **Automated Analytics Workflows**: Developers building internal reporting tools can pull dataset schemas and query results programmatically, without hard-coding SAQL or managing authentication themselves. - **Complete Asset Visibility for Admins**: Admins can inventory every app, dataset, and dashboard across the org in minutes, building a complete analytics catalog for governance and auditing. ## FAQs Common questions about CRM Analytics MCP server and the Model Context Protocol. ### What's MCP? The Model Context Protocol (MCP) is an open standard that enables AI models to securely access data, tools, and context from specialized systems. CRM Analytics MCP server uses the protocol to expose CRM Analytics datasets, folders, dashboards, and lenses to external AI agents. ### Is CRM Analytics MCP Server secure? Yes. Every request is enforced against the connecting user's own Salesforce permissions: field-level security, object-level security, row-level security, and sharing rules. Your agent can never see data or assets that you can't see in CRM Analytics directly. Authentication uses individual OAuth 2.0 and PKCE. Shared service account tokens aren't supported. ### How does CRM Analytics MCP Server generate SAQL queries? Your agent doesn't write SAQL blind. The typical workflow is: - `list_datasets` → `get_dataset` - to capture the dataset's `currentVersionId` - `get_xmd` - to get exact field API names, types, and labels - `execute_query` - to run the generated SAQL and return structured results Because the agent inspects the real schema before generating a query, it produces syntactically correct SAQL without you needing to know the dataset's field names in advance. ### Is CRM Analytics MCP Server available in production? Yes, the CRM Analytics MCP server is available in production, as well as on sandbox and scratch orgs. To use it, you also need a CRM Analytics license, System Admin permissions to create the external client app and enable the server, and a supported MCP Client. Supported clients include Agentforce Vibes 2.0, Claude (Desktop, Web, Code), Cursor, ChatGPT developer mode, or any client supporting OAuth 2.0 and PKCE. All CRM Analytics tools are currently read-only. ## Server URL Use these server URLs to access the production and sandbox versions of the MCP server. - Production: https://api.salesforce.com/platform/mcp/v1/analytics/crma-beta - Sandbox/Scratch: https://api.salesforce.com/platform/mcp/v1/sandbox/analytics/crma-beta ## Example Prompts - "What analytics apps do I have access to?" - "What CRM Analytics datasets do I have access to right now?" - "Give me the full metadata for the Executive Pipeline dataset." - "What are the exact fields, dimensions, and measures in the Opportunity dataset?" - "What were our top 10 accounts by revenue last fiscal year?" - "What was the total pipeline by region last quarter?" - "Show me rep performance versus quota this month." - "Show me all the dashboards in my Sales Application folder." - "List all the saved explorations I'm permitted to view." ## Available Tools The CRM Analytics MCP server provides a suite of read-only tools that allow external AI agents to interact with your CRM Analytics assets. After you complete the initial setup, you no longer need to manually select or configure these tools. Ask your preferred MCP-compliant AI client, such as ChatGPT, Claude, or Cursor, questions using natural language, and it automatically selects the right tools for the task. For example, when you ask, "What were our top 10 accounts by revenue last quarter?", the AI agent calls `list_datasets`, `get_dataset`, and `get_xmd` to understand the data structure, generates valid SAQL, and executes it via `execute_query`. The available tools are grouped by their functional role within an analytical workflow. ### Organization and Discovery Tools External MCP-compliant AI agents use these tools to navigate CRM Analytics folders before scoping deeper searches. Folders represent analytics apps. #### `list_folders` Returns all analytics apps that the connected user can access. Analytics apps or folders are containers for related dashboards, datasets, and lenses. Use the returned ID to scope other `list_` calls. **Inputs:** | Parameter | Type | Required | Description | | ---------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------- | | `q` | string | No | Search terms. Individual terms are separated by spaces. A wildcard is automatically appended to the last token. | | `scope` | enum | No | Filter by scope: `CreatedByMe`, `Mru`, `SharedWithMe`. | | `sort` | enum | No | Sort order: `Name`, `Mru`, `LastModified`, `LastModifiedBy`. | | `isPinned` | boolean | No | When `true`, returns only pinned folders. | | `pageSize` | integer | No | Number of results per page. Min: 1, Max: 200, Default: 25. | | `page` | string | No | Pagination token for the next page of results. | **Outputs:** A collection of folder objects, each with ID, label, description, template source, and permissions. #### `get_folder` Returns full metadata for a single analytics app by ID, including its label, description, template source, and permissions. **Inputs:** | Parameter | Type | Required | Description | | ---------- | ------ | -------- | ------------------------------------------------------------------------------ | | `folderId` | string | Yes | The ID of the folder to retrieve. Discovered automatically via `list_folders`. | **Outputs:** A folder object with full metadata including label, description, template source, and permissions. ### Data and Schema Tools External MCP-compliant AI agents use these tools to discover datasets and inspect their schemas before building queries. #### `list_datasets` Returns datasets available in a specific app or across the org, with names, IDs, and last-modified dates. **Inputs:** | Parameter | Type | Required | Description | | ----------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `q` | string | No | Search terms. Individual terms are separated by spaces. A wildcard is automatically appended to the last token. | | `folderId` | string | No | Filters results to datasets within a specific folder (app). | | `datasetTypes` | string | No | Filter by dataset type: `Default`, `Live`, `StagedData`, `Trended`. | | `scope` | enum | No | Filter by scope: `CreatedByMe`, `Mru`, `SharedWithMe`. | | `sort` | enum | No | Sort order: `Name`, `Mru`, `LastModified`, `TotalRows`, `CreatedDate`, `LastRefreshed`, `CreatedBy`, `LastQueried`, `ConnectionName`. | | `order` | enum | No | Sort direction: `Ascending`, `Descending`. | | `includeCurrentVersion` | boolean | No | When `true`, includes current version metadata in the response. | | `pageSize` | integer | No | Number of results per page. Min: 1, Max: 200, Default: 25. | | `page` | string | No | Pagination token for the next page of results. | **Outputs:** A collection of dataset objects with names, types, and last-modified dates. #### `get_dataset` Returns full metadata for a dataset, including field names, data types, and labels for dimensions and measures. Use this to capture the dataset's `currentVersionId`, which `get_xmd` and `execute_query` require. **Inputs:** | Parameter | Type | Required | Description | | -------------------- | ------ | -------- | ---------------------------------- | | `datasetIdOrApiName` | string | Yes | The ID or API name of the dataset. | **Outputs:** Full dataset metadata including field names, data types, dimension and measure labels, and current version information. #### `get_xmd` Returns the extended metadata (XMD) field schema for a dataset version, including exact field API names, data types, labels, and formatting. Use this after `get_dataset` to get the precise field names an agent needs to build valid SAQL. **Inputs:** | Parameter | Type | Required | Description | | -------------------- | ------ | -------- | ----------------------------------------------------------------- | | `datasetIdOrApiName` | string | Yes | The ID or API name of the dataset. | | `versionId` | string | Yes | 18-character version ID starting with `0Fc` (from `get_dataset`). | | `xmdType` | enum | No | `main` (default, query-ready), `system`, or `user`. | **Outputs:** Extended metadata for the dataset version, including field API names, data types, labels, and display formatting. ### Query and Analysis Tools External MCP-compliant AI agents use this tool to execute analytical queries once they understand the dataset schema. #### `execute_query` Executes a SAQL query against a CRM Analytics dataset and returns structured results. The AI agent generates SAQL automatically from the natural-language request, using the schema returned by `get_dataset` and `get_xmd`. **Inputs:** | Parameter | Type | Required | Description | | --------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------- | | `query` | string | Yes | SAQL pipeline; the load stage must use `"/"`; end with `q = limit q N;`. | | `queryLanguage` | enum | No | Locked to `Saql`. | | `timezone` | string | No | IANA timezone, for example `America/Los_Angeles`. | | `version` | number | No | SAQL version; omit for latest. | **Outputs:** Structured JSON query results containing rows, column metadata, and query execution details. ### Dashboard, Visualization, and Exploration Tools External MCP-compliant AI agents use these tools to discover and inspect prebuilt dashboards and saved explorations (lenses). #### `list_dashboards` Returns all CRM Analytics dashboards in a specified app or across the org, with names, IDs, and app context. **Inputs:** | Parameter | Type | Required | Description | | ----------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | string | No | Search terms. A wildcard is automatically appended to the last token. | | `folderId` | string | No | Filters results to dashboards within a specific folder (app). | | `type` | enum | No | Asset type filter. Defaults to `Dashboard`. Other values: `DashboardSnapshot`, `Component`. `Component` requires edit access and may return no results for view-only users. | | `templateApiName` | string | No | Filters results to dashboards created from a specific application template. | | `mobileOnly` | boolean | No | When `true`, returns only dashboards enabled for the Analytics mobile app. | | `ids` | string | No | Filters results to only the dashboards with the specified IDs. | | `scope` | enum | No | Filter by scope: `CreatedByMe`, `SharedWithMe`, `Mru`. | | `sort` | enum | No | Sort order: `Name`, `Mru`, `LastModified`, `LastModifiedBy`. | | `pageSize` | integer | No | Number of results per page. Min: 1, Max: 200, Default: 25. | | `page` | string | No | Pagination token for the next page of results. | **Outputs:** A collection of dashboard objects with names, IDs, types, and app context. #### `get_dashboard` Returns full metadata for a single dashboard, including widgets, steps, and filter configurations. **Inputs:** | Parameter | Type | Required | Description | | ---------------------- | ------ | -------- | ------------------------------------ | | `dashboardIdOrApiName` | string | Yes | The ID or API name of the dashboard. | **Outputs:** Full dashboard metadata including widgets, steps, filter configurations, and layout details. #### `list_lenses` Returns all saved explorations (lenses) that the connected user can access, with names, IDs, and the datasets they reference. **Inputs:** | Parameter | Type | Required | Description | | ---------- | ------- | -------- | --------------------------------------------------------------------- | | `q` | string | No | Search terms. A wildcard is automatically appended to the last token. | | `folderId` | string | No | Filters results to lenses within a specific folder (app). | | `scope` | enum | No | Filter by scope: `CreatedByMe`, `SharedWithMe`, `Mru`. | | `sort` | enum | No | Sort order: `Name`, `Mru`, `LastModified`, `LastModifiedBy`. | | `pageSize` | integer | No | Number of results per page. Min: 1, Max: 200, Default: 25. | | `page` | string | No | Pagination token for the next page of results. | **Outputs:** A collection of lens objects with names, IDs, and the datasets they reference. #### `get_lens` Returns full metadata for a single lens, including the query definition and dataset reference. **Inputs:** | Parameter | Type | Required | Description | | ----------------- | ------ | -------- | ------------------------------- | | `lensIdOrApiName` | string | Yes | The ID or API name of the lens. | **Outputs:** Full lens metadata including the query definition, visualization configuration, and dataset reference. ## Troubleshooting and Tips for Success Use these solutions to resolve common issues and optimize the performance of CRM Analytics MCP server across different AI clients. ### General Connectivity Issues **Server Connection Fails:** Verify you've created an external client app using OAuth 2.0 and PKCE, and that an administrator has enabled CRM Analytics MCP server in Setup (**MCP Servers** under **API Catalog**). Both steps are required before any client can connect. **Multitenant Conflicts:** Because the MCP specification doesn't support multitenant systems like Salesforce, log out of all other Salesforce orgs, log into the target org in your default browser, and keep that browser window open before connecting your client. The client opens a new tab in that same window during authentication. Most connection failures trace back to skipping this step. ### Optimization for AI Clients **Describe Your Goal, Not the Tool:** Say "Show me open opportunities by stage" rather than "call `list_datasets`." The AI agent handles tool selection. **Improve Query Accuracy with Field Descriptions:** Adding field labels and descriptions to your dataset XMD helps your AI agent generate more accurate SAQL queries. **Complex Queries Sometimes Need Refinement:** Nested groupings, multi-dataset joins, or advanced SAQL functions can require follow-up prompting to get the exact result you need. ### Data and Tool Access **Read-Only During the Beta Program:** Create, update, and delete operations aren't supported yet. If an agent suggests it modified a dataset or dashboard, it didn't. Treat any such claim as an error. **Missing or Unavailable Assets:** If the agent reports that a dataset, dashboard, or lens is unavailable, or a `list_` call returns fewer items than you expect, this means you lack permission to that specific asset, not that the server failed. Confirm the app or asset is shared with you and that your permission set grants CRM Analytics access. **Permissions and Governance:** MCP sessions use OAuth-authenticated users, meaning any permissions or restrictions that apply to your user profile also apply to your MCP session. Individual authentication is required. Shared service account tokens aren't supported. **Monitor API Usage:** MCP tool calls count against your org's Wave API limits. Check usage in **Setup** → **API Usage**, especially for high-volume workloads. # Custom MCP Servers Salesforce ships various standard MCP servers bundling out-of-box capabilities oriented around discrete product areas. To combine MCP tools from different servers to accomplish broader workflows, administrators can create and curate custom MCP servers. Combining the tools needed by a given persona into a single server URL also simplifies interactions with MCP clients, since MCP clients would only need a single URL representing all the tools across Salesforce. Additionally, custom servers provide a means to surface custom tools backed by your own Apex code, Flows, or APIs, since standard servers are immutable. For more information about the Model Context Protocol and how to build your own MCP servers from scratch, see the [Model Context Protocol documentation](https://modelcontextprotocol.io). ## Why Curating Matters MCP clients have practical limits on how many tools they can work with effectively. Beyond a few dozen tools, an AI client struggles to select the right one for a given task. You can't serve every dish from the buffet on a single plate — it doesn't fit, and it's not useful. Curating focused, persona-specific servers produces better agent behavior and aligns with how Salesforce already works: admins compose Lightning pages from multiple sources — tabs, components, contributed by different teams and ISVs — to give a sales rep or marketer the specific experience they need. Custom MCP servers work the same way for AI-assisted workflows. ## Analogy: Buffet and Plate Think of every available MCP tool across the Salesforce platform as a **buffet**. Salesforce product teams contribute standard tools to that buffet — SObject access, Data 360 queries, Tableau analytics, and more. Internal developers and ISVs add their own dishes: custom Apex Actions, Flows, and REST APIs. An **MCP Server** is the **plate** curated for a given persona. When an admin configures a custom server in Setup, they're choosing what to put on that plate — picking from everything available on the buffet and composing it into a focused set of tools for a specific team or agent workflow. One team might get a plate with read-only CRM tools and nothing else. Another gets write access plus a custom Flow for a more powerful workflow agent. Same buffet, different plates. This separation is what makes the model flexible: contributors (Salesforce, ISVs, internal developers) don't need to know how and when customers will use their tools, and customers don't need to build from scratch. They assemble from what's available. ## Standard Servers vs. Custom Servers Standard servers are pre-configured by Salesforce. They expose a fixed set of tools from a single product area — for example, the SObject servers expose platform record operations, and the Data 360 server exposes SQL queries. Standard servers are disabled by default and can be enabled by an admin, but their contents are not editable. Custom servers are admin-configured. They can: - **Combine tools from multiple standard servers** under a single URL — for example, pairing SObject read tools with a Tableau Next analytics tool for a reporting persona - **Include custom tools** backed by Apex Invocable Actions, `@AuraEnabled` methods, Apex REST endpoints, Flows, or API Catalog endpoints unique to your org - **Be scoped to a specific persona** — a sales rep server, a support agent server, a data hygiene server — each with a different mix of capabilities - **Be deployed via Metadata API** between sandboxes and production. The URL for a custom server is unique to that configuration, so different teams can be pointed at different servers with different tool sets — without requiring multiple OAuth apps or separate Salesforce orgs. ## Custom Tools Custom servers are the only way to surface tools that don't exist in any standard server. These tools are backed by logic you've already built in Salesforce: ### Flows Autolaunched Flows can be exposed as MCP tools. Reuse declarative automation you've already built in Flow Builder — multi-step processes, conditional branching, callouts to external systems — without writing integration code. See [Flows](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/flows.md) for configuration requirements. ### Apex Invocable Actions Apex classes annotated with `@InvocableMethod` become custom tools. Use these for business logic that goes beyond what Flows can express: complex calculations, custom integrations, or performance-sensitive operations. See [Invocable Actions](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/invocable-actions.md) for requirements. [Learn more about `@InvocableMethod`](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm). ### AuraEnabled Apex Methods Apex methods annotated with `@AuraEnabled` can be exposed as custom tools. If your org already uses these methods as Lightning component controllers, they can also serve as agent-accessible tools with no additional code. [Learn more about `@AuraEnabled`](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_AuraEnabled.htm). ### Apex REST Methods Custom Apex REST endpoints (classes annotated with `@RestResource`) can be mapped as custom tools. Use these when you have existing custom REST APIs on the platform that agents should be able to invoke. [Learn more about Apex REST](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_rest.htm). ### APIs from API Catalog REST API endpoints registered in the Salesforce API Catalog can be mapped to custom tools, including standard platform APIs and a growing subset of [product-specific Connect APIs](https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/connect_resources_overview.htm). Not all Connect API endpoints are in the catalog at GA — coverage is expanding over time. For more information, see [Manage Salesforce Hosted MCP Servers in API Catalog](https://help.salesforce.com/s/articleView?id=platform.api_catalog_manage_salesforce_hosted_mcp_servers.htm&type=5). ## Configuring a Custom Server Custom servers are configured in Salesforce Setup: **Integration → Salesforce MCP Servers**. No code is required to configure the server itself. For step-by-step instructions, refer to the section of Help & Training that covers custom server configuration through the API Catalog. The tool name and description you provide for each custom tool are as important as the backing implementation. Clear, specific descriptions help AI clients select the right tool at the right time. See [Best Practices](https://developer.salesforce.com/docs/platform/guides/best-practices/general-best-practices.md) for guidance on writing effective tool descriptions. ## Example Configurations **Sales rep server** — Combine SObject read/write tools with a custom Flow that logs meeting notes as Activities, and an Apex Action that enriches a Lead from an external data source. **Data hygiene server** — Combine SObject query tools (to identify duplicates) with delete tools (to remove them) and a Flow that runs deduplication logic. Point this server at a dedicated user profile that only data stewards can authenticate as. **Reporting server** — Combine `soqlQuery` from the SObject reads server with Tableau Next analytics tools and a Data 360 SQL tool. Give this plate to reporting personas who need broad read access but no write operations. ## Guidance for ISVs ISV managed packages cannot yet include MCP server configurations directly. However, ISVs can make their capabilities available for MCP by including Apex classes annotated with `@InvocableMethod`, `@AuraEnabled`, or `@RestResource`, or by including Autolaunched Flows in their package. Once installed, a subscriber administrator can configure a custom server in their org and add those packaged actions as tools. This means ISVs designing new capabilities should consider adding these Apex annotations to their code and ensuring Flows are Autolaunched — these patterns expose the capability to MCP without requiring any additional integration surface. # Data 360 Legacy MCP Server The `data/data-cloud-queries` server lets AI agents query and explore Data 360 objects using SQL. Use this server to build agents that analyze customer data, generate insights, or answer natural-language questions about unified profiles. This server provides two tools: - Data space object discovery - SQL query execution **Note:** This server provides query-only access to Data 360. For full Connect API access (segments, activations, data streams, transforms), use the [Data 360 MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/data360-mcp.md). ## Prerequisites - **Data 360 license** enabled in your org - **View Data 360 permission** for query access - **MCP client** installed and configured with OAuth authentication For setup instructions, see [Set Up Your Org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/setup/setup-overview.md). ## Server URL Use these server URLs to access the production, sandbox, and scratch versions of the `data-cloud-queries` server. - **Production:** `https://api.salesforce.com/platform/mcp/v1/data/data-cloud-queries` - **Sandbox/Scratch:** `https://api.salesforce.com/platform/mcp/v1/sandbox/data/data-cloud-queries` ## Example Prompts - "What data is available about Sarah Chen in Data 360?" - "Query the unified customer profile for contacts at Acme Corp — show engagement scores and last interaction dates." - "What are the top 20 accounts by product usage events in the last 30 days?" - "Show me all customers who received a marketing email last week but haven't opened it." - "Pull the behavioral data for customer ID cust_abc123 from Data 360." ## Available Tools The `data/data-cloud-queries` server provides the following tools. ### `get_dc_metadata` Lists all objects available in the Data 360 data space. Use this information to understand what data is available before you write a query. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | --------- | ---- | -------- | ---------------------- | | _(none)_ | — | — | No parameters required | **Outputs:** A list of available entities in the Data 360 data space, with metadata describing each entity's purpose and structure. ### `post_dc_query_sql` Executes a SQL query against the Data 360 data space and returns the first chunk of results with accompanying metadata. This function uses [Query SQL syntax](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/dc-sql-reference/data-cloud-sql-context.html). Useful for ad hoc analysis, data exploration, and pulling aggregated data. Because Data 360 stores large volumes of data, be specific in your WHERE clause and use LIMIT to control result size. The response includes the first chunk of data. Pagination metadata is included for large result sets. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | ----------------------------------------- | | `sql` | string | Yes | A valid SQL query using Query SQL syntax. | **Outputs:** Returns the first chunk of query results with metadata describing total result size and pagination details if the result set is larger than one chunk. ## Related Resources - [Query SQL Reference](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/dc-sql-reference/data-cloud-sql-context.html) - [Data 360 MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/data360-mcp.md) (for full Connect API access) # Data 360 MCP Server The `data360` server exposes Data 360's Connect API through MCP, so agents can query, transform, and activate customer data programmatically. Use this server to: - Query unified customer profiles, trigger segmentation, and manage identity resolution through MCP - Manage unified profiles and calculated insights at runtime via API - Ingest, transform, and activate data through API prompting - Configure data mappings, identity resolution, and developer environments The server exposes three **meta-tools** (tools that manage other tools): `search`, `payload_examples`, and `execute`. These tools discover the correct Connect API at runtime rather than loading all of them up front, which keeps token usage low regardless of how many Data 360 APIs exist. Use the Data 360 MCP server to create, list, update, and delete: - Data lake objects (DLO) - Data model objects (DMO) - Data streams - Transforms - Calculated insights - Segments - Activations and activation targets - Data actions and data action targets - Data spaces - Data kits - RAG retrievers and retriever configurations - Semantic search indexes - Semantic data models (SDM) and SDM entities (data objects, calculated dimensions/measurements, metrics, relationships) - DLO-to-DMO mappings (including field mappings) **Note:** This MCP server replaces the previous Data 360 server, which is now available as the [Data 360 Legacy MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/data-cloud-sql.md). The Data 360 MCP is available with API v66.0 and later. MCP server calls count as calls to the underlying Connect API endpoints for limits and Flex Credit usage. See [Data Cloud License Billing and Limits](https://help.salesforce.com/s/articleView?id=data.c360_a_d360_profile_billing_considerations.htm&type=5). ## Prerequisites - **Data 360 license** enabled in your org - **API v66.0 or later** - **Permissions:** - `Manage Data 360` for configuration operations - `View Data 360` for read-only operations - **MCP client** installed and configured with OAuth authentication For setup instructions, see [Set Up Your Org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/setup/setup-overview.md). ## Server URL Use these server URLs to access the production, sandbox, and scratch versions of the `data-360` server. - **Production:** `https://api.salesforce.com/platform/mcp/v1/data/data360` - **Sandbox/Scratch:** `https://api.salesforce.com/platform/mcp/v1/data/sandbox/data360` ## Example Prompts - "What data is available about {customer name} in Data 360?" - "Query the unified customer profile for contacts at Acme Corp — show engagement scores and last interaction dates." - "What are the top 20 accounts by product usage events in the last 30 days?" - "Show me all customers who received a marketing email last week but haven't opened it." - "Pull the behavioral data for customer ID cust_abc123 from Data 360." ## Available Tools The `data360` server provides the following tools. Use them in this order for the best result. - search: identifies the correct tool to use - payload_examples: provides payload examples - execute: executes tool with payload ### 1. `search` — discover tool families by intent Describe what you want to do in natural language. The server scores tool _families_ by intent and returns matching tool names. **Params:** `query` (natural-language intent) ```jsonc // request { "query": "create and manage a segment" } // response (trimmed to two families) { "query": "create and manage a segment", "results": [ { "family": "Segment", "summary": "Segment Connect API tools.", "tools": ["d360_segment_count", "d360_segment_create", "d360_segment_deactivate", "d360_segment_delete", "d360_segment_get", "d360_segment_get_by_id", "d360_segment_list", "d360_segment_member_list", "d360_segment_publish", "d360_segment_update"] }, { "family": "Activation", "summary": "Activation Connect API tools.", "tools": ["d360_activation_create", "d360_activation_get", "d360_activation_list", "d360_activation_update"] } ] } ``` ### 2. `payload_examples` — get the schema and example for a named tool Given a tool name, returns its input JSON Schema, an example payload, and a human-readable description. **Params:** `toolName` ```jsonc // request { "toolName": "d360_query_sql" } // response (trimmed) { "toolName": "d360_query_sql", "family": "Query", "description": "Submit Data Cloud SQL for execution and return query metadata plus the first chunk of rows. Use d360_query_sql_status to poll long-running queries and d360_query_sql_rows to fetch additional pages.", "example": { "input": { "sql": "SELECT FirstName__c, LastName__c FROM UnifiedIndividual__dlm LIMIT 10" } }, "inputSchema": { "type": "object", "required": ["input"], "properties": { "input": { "type": "object", "properties": { "sql": { "type": "string" }, "rowLimit": { "type": "integer" }, "adaptiveTimeout": { "type": "integer" }, "querySettings": { "type": "object" }, "sqlParameters": { "type": "object" } } }, "workloadName": { "type": "string" }, "dataspace": { "type": "string" } } } } ``` ### 3. `execute` — run a named tool Names a tool and passes its arguments as a JSON **string**. The server dispatches to the underlying Connect API and returns the result. **Params:** - `toolName` — the tool to invoke - `paramsJson` — parameters as a JSON string matching the tool's schema ```jsonc // request — list segments { "toolName": "d360_segment_list", "paramsJson": "{\"batchSize\": 3}" } // response (one segment shown; includeCriteria DBT/XML elided) { "result": { "batchSize": 3, "offset": 0, "orderByExpression": "[Name asc]", "totalSize": 1, "segments": [{ "apiName": "High_Value_Accounts", "displayName": "High Value Accounts", "description": "Top-spending accounts by total order revenue…", "segmentOnApiName": "ssot__Account__dlm", "segmentType": "DBT", "segmentStatus": "ACTIVE", "publishStatus": "SUCCESS", "publishInterval": "NO_REFRESH", "lastSegmentMemberCount": 1, "lookbackPeriod": "P90D", "dataSpace": "default", "marketSegmentId": "1sgVF000001PVhZYAW", "includeCriteria": "…SELECT DISTINCT … HAVING SUM(...TotalAmount__c) >= 1359.67…" }] } } ``` ```jsonc // request — run SQL (Query family) { "toolName": "d360_query_sql", "paramsJson": "{\"input\": {\"sql\": \"SELECT 1 AS test_col\"}}" } // response { "result": { "data": [[1]], "metadata": [{ "name": "test_col", "type": "Integer", "nullable": false }], "returnedRows": 1, "status": { "completionStatus": "ResultsProduced", "progress": 1.0, "rowCount": 1, "chunkCount": 1, "wallClockTime": 0.001728879, "queryId": "MTAuMjIuMTIxLjkxOjc0ODQ_1adb65f9-…" } } } ``` Long-running queries return a `queryId`. Poll `d360_query_sql_status` and page results with `d360_query_sql_rows`. --- ## Related Resources - [Legacy Data 360 Query Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/data-cloud-sql.md) (for query-only access) - [Data 360 Connect API Documentation](https://developer.salesforce.com/docs/data/connectapi/overview) - [Query SQL Reference](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/dc-sql-reference/data-cloud-sql-context.html) # Flows Lightning Flows can be exposed as custom MCP tools, giving AI agents access to declarative automation your team has already built. If you've implemented a business process in Flow Builder — routing a lead, sending an approval request, creating a set of related records from a template, triggering a notification sequence — that same flow can now be invoked by an agent through MCP without any code changes. Flows are a natural path for orgs that manage business processes declaratively. Rather than writing Apex just to give agents access to automation, admins can publish existing flows as tools directly through the Salesforce Setup UI. ## How It Works You configure Flow-backed tools through the custom server Setup UI — select a Flow as the backing type, choose an autolaunched flow with defined input and output variables, name the tool, provide a description, and publish. See [Custom MCP Servers](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/custom-servers.md) for the full configuration walkthrough. The MCP server generates a tool from the flow's input and output variable schema. When an agent invokes the tool, Salesforce launches the flow server-side with the provided inputs and returns the output variables. Because the flow runs in Salesforce, it has full access to platform capabilities: it can query and update records, call external services via Named Credentials, send emails, trigger subflows, and interact with approval processes — all with the authenticated user's permissions applied. ## When to Use This **Use Flows as MCP tools when:** - You have existing flows that implement the process you want to expose. Reuse is faster than rebuilding in Apex. - The business process is owned by admins who maintain it in Flow Builder. Keeping the automation in Flow means future changes don't require code deployments. - The operation involves sequential, multi-step logic that's easier to express declaratively (branching, looping, record lookups) than as a single API call. - The process needs to be auditable and modifiable by non-developers. Flows are visible and editable in Flow Builder without an IDE. **Use [Invocable Actions](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/invocable-actions.md) (Apex) instead when:** - The operation requires complex computation, external API calls with custom error handling, or logic that's difficult to express in Flow Builder. - Performance is critical — Apex generally executes faster than flows for compute-intensive operations. - You need fine-grained control over bulkification, transactions, or exception handling. ## Example Use Cases - **Lead routing**: An agent collects lead qualification information from a conversation and invokes a flow tool that assigns the lead to the right territory and rep, creates a follow-up task, and sends an intro email — all in one step. - **Onboarding provisioning**: An agent working through a customer onboarding checklist invokes a flow that creates the initial set of records (Account, Contact, Opportunity, related custom objects) from a template, eliminating manual data entry. - **Approval initiation**: An agent reviewing a contract identifies a discount that exceeds policy thresholds and invokes a flow tool that submits the record to the appropriate approval process and notifies the manager — without the agent needing to know the approval process configuration. ## Limitations - Only **autolaunched flows** (not screen flows or scheduled flows) can be exposed as MCP tools. The flow must have defined input and output variables. - Flow execution runs as the **authenticated user**, not as a system context. Flow logic that relies on permissions or sharing may behave differently depending on who invokes the tool. - Governor limits apply. Flows invoked via MCP consume Apex and DML limits the same as flows triggered from the UI or Apex. Bulk operations that would exceed limits should use Batch Apex or Bulk API patterns instead. - Tool descriptions are set at configuration time. If the flow's behavior changes significantly, update the tool description in Setup to keep agents informed. - There is no streaming or progress reporting for long-running flows. The agent waits for the flow to complete and receives the final output. For processes that take more than a few seconds, consider a flow that returns a job ID for later status checking. # General Best Practices Follow these best practices as you deploy Model Context Protocol (MCP)-based integrations in your enterprise architecture. ## Use the Hosted MCP Server, Not API Wrappers Salesforce provides a hosted MCP server that handles authentication, authorization, and observability on your behalf. Building a custom proxy layer around the Salesforce REST APIs instead of using the hosted server undermines those guarantees: it bypasses the platform's security controls, removes request-level telemetry, and creates a maintenance burden that grows as the API surface evolves. Use the hosted server as intended. ## Keep Humans in the Loop Per-user authentication means every MCP tool call runs with the same permissions as the user who authorized the connection—the same field-level security, object access, and sharing rules that apply in Lightning. This is a feature, not a constraint: it means that AI agents operate within your existing governance model without extra configuration. For detailed guidance on access control strategies, authentication requirements, and monitoring, see [Security Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/security-best-practices.md). ## Signal Tool Behavior with Annotations MCP tools support an `annotations` object with four boolean hints that tell clients how the tool behaves: `readOnlyHint`, `destructiveHint`, `idempotentHint`, and `openWorldHint`. Well-behaved clients use these to present appropriate UX—auto-executing read-only tools and requiring confirmation for destructive ones. Platform tools ship with accurate annotation values. Read operations like SOQL queries and schema lookups are marked `readOnlyHint: true`; delete operations are marked `destructiveHint: true`. Clients that respect these annotations can deliver a smoother experience without sacrificing safety. For custom tools backed by Flows, Apex, or REST endpoints, set annotations explicitly. The spec defaults are conservative—a tool with no annotations is assumed potentially destructive and open-world. This means a custom query tool that omits `readOnlyHint: true` will trigger unnecessary "are you sure?" prompts in clients that respect annotations. At a minimum, set `readOnlyHint: true` and `destructiveHint: false` on tools that only read data, and `destructiveHint: true` on tools that delete or irreversibly modify records. Annotations are hints, not enforcement. Not all clients read or respect them. They complement—but do not replace—the access control and human-in-the-loop strategies described above. ## Design Tools at the Correct Level of Grain Getting tool granularity right is one of the most consequential decisions when building a custom MCP server. There are two failure modes, and both are common. **Too granular (subatomic).** Many teams start by mapping their existing APIs directly to MCP tools. The problem is that internal APIs are often designed to be called in a specific sequence—each call returns a partial result that only makes sense in context of the calls around it. An AI client doesn't know this sequence. It sees a flat list of tools, tries to use them independently, and produces incorrect or incomplete results. If your tool surface requires an agent to call tools in a prescribed order to accomplish anything useful, it's too granular. **Too coarse (bundled workflows).** The opposite problem is tools that bundle too many steps into a single operation—a tool that, for example, creates a lead, scores it, and routes it to a rep in one call. This kind of tool reduces flexibility: the agent can't intervene between steps, adjust behavior based on intermediate results, or reuse any part of the workflow in a different context. Broadly, if a tool is encoding a multi-step process with its own decision logic, it's better represented as a Salesforce Flow that the agent can invoke as needed. **The Goldilocks zone.** The right level of grain sits between these extremes, and it isn't always a single atomic operation. A good tool returns something an AI client can reason about on its own, without needing to know what to call next. Sometimes that's a single operation—create a record, run a query. Sometimes it's a slightly more molecular unit—retrieve an opportunity with its related contacts and recent activity in one call, because that's the natural unit of information an agent needs to reason about a deal. The test is whether a tool call produces a self-contained, useful result. If the result is only meaningful after calling two more tools, reconsider the design. When in doubt, start with slightly coarser tools and split them if agents demonstrate they need finer control—rather than starting subatomic and trying to compose upward. # Headless 360 MCP Server (Beta) > **Beta:** The Headless 360 MCP Server is a Beta Service, available starting in July 2026. You can choose to try this Beta Service at your sole discretion. Any use of the Beta Service is subject to the applicable [Beta Services Terms](https://www.salesforce.com/company/legal/agreements/). The `platform/headless-360` server brings the full breadth of Salesforce to any MCP-aware agent through a single connection. Instead of exposing thousands of features as individual tools, the server provides four tools backed by a continuously growing library of Salesforce operations. Your agent's tool surface stays small and stable while the set of actions it can take scales independently. Use this server to let agents do tasks such as: - Query, create, and update Salesforce records - Manage users, including creating, deactivating, freezing, and assigning permission sets and permission set licenses - Read, write, and deploy Apex triggers - Build event-driven integrations with platform events, Change Data Capture, and event relays - Create named credentials, including authentication mechanisms, endpoints, and certificate handling - Manage Commerce Cloud Orders At beta launch, the server offers dozens of operations, with most focused on Setup tasks for admins. The library grows with each release to cover more of what admins, developers, and business users can do across Salesforce. Your agent discovers what's currently available at runtime through Discover. **Note:** The Headless 360 MCP Server isn't the same as the Data 360 MCP Server. The Data 360 server works only with Data 360 data. The Headless 360 server works across all of Salesforce. ## Prerequisites - **API version:** v67.0 and later - **External Client App** configured with the `mcp_api` scope - **MCP client** installed and configured with OAuth authentication For setup instructions, see [Set Up Your Org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/setup/setup-overview.md). ## Server URL Use these server URLs to access the production and sandbox versions of the `headless-360` server. - **Production:** `https://api.salesforce.com/platform/mcp/v1/platform/headless-360` - **Sandbox/Scratch:** `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/headless-360` ## Activate the Beta Server 1. From Setup, in the Quick Find box, enter `MCP Servers`, and then select **MCP Servers**. 2. Find **headless-360** in the list of servers. 3. Click **Activate**. ## Example Prompts - "Create a user for our new sales rep and assign the Sales permission set." - "Tell me about what opportunities I should focus on today." - "Log a call in Salesforce." - "Deactivate the user account for a departing employee." - "Build an integration that sends events to AWS when Account records change." - "Set up a named credential for our external inventory service." ## Available Tools The `platform/headless-360` server provides four tools that map to how an agent moves through a request. Use them in this order for the best result. - Discover: finds the actions your agent can take - Describe: returns the full specification for an action - Dispatch: runs the chosen action - Dispatch (Read-Only): runs read-only actions ### 1. Discover — find actions by intent Takes your agent's interpretation of a request and runs a semantic search across an index of available Salesforce operations. It returns a ranked set of candidate operations, so agents spend less time finding the right action. **Internal name:** `discover` Request Schema: ```json { "type": "object", "properties": { "query": { "type": "string", "description": "Natural language description of what you want to do (e.g., 'enable digital lending', 'create a permission set'). Hybrid semantic + keyword search across the API corpus." }, "limit": { "type": "integer", "description": "Maximum number of results to return.", "minimum": 1, "maximum": 50, "default": 10 }, "domain": { "type": "string", "description": "Optional AIP-103 domain filter (e.g., 'platform', 'commerce', 'service'). Leave unset to search all domains." }, "resultType": { "type": "string", "description": "Optional filter: 'endpoint' for individual API operations, 'sor' for multi-step Setup Operation Recipes. Leave unset to search both.", "enum": ["endpoint", "sor"] } }, "required": ["query"], "additionalProperties": false } ``` ### 2. Describe — get the specification for an action Returns the technical contract for an operation, including the APIs, parameters, dependencies, and ordered steps. Your agent uses this tool to verify that Discover returned the right result and to understand the steps needed to complete the action. **Internal name:** `describe` Request Schema: ```json { "type": "object", "properties": { "id": { "type": "string", "description": "The qualified operation ID (e.g., 'setup.platform.named-credentials.getNamedCredentials') or SOR ID (e.g., 'SlackSetupAssistant') to describe. Bare operation IDs are accepted as a fallback." } }, "required": ["id"], "additionalProperties": false } ``` ### 3. Dispatch — run an action Invokes the chosen operation. Dispatch routes the request to the correct endpoint and enforces the access guard before anything runs. **Internal name:** `dispatch` Request Schema: ```json { "type": "object", "properties": { "url": { "type": "string", "description": "The complete URL to call (e.g., https://api.example.com/v1/users)" }, "method": { "type": "string", "description": "HTTP method to use", "enum": ["GET", "POST", "PUT", "DELETE", "PATCH"] }, "headers": { "type": "object", "description": "Optional HTTP headers as key-value pairs", "additionalProperties": true }, "body": { "type": "object", "description": "Optional request body (for POST, PUT, PATCH methods)" }, "queryParams": { "type": "object", "description": "Optional query parameters as key-value pairs", "additionalProperties": true } }, "additionalProperties": false, "required": ["url", "method"] } ``` ### 4. Dispatch (Read-Only) — run read-only actions Invokes the chosen operation in read-only mode. This tool never changes data or configuration—it's for when your agent only needs to retrieve information. **Internal name:** `dispatch_readonly` Request Schema: ```json { "type": "object", "properties": { "url": { "type": "string", "description": "The complete URL to call (e.g., https://api.example.com/v1/users)" }, "method": { "type": "string", "description": "HTTP method to use (restricted to GET for read-only access)", "enum": ["GET"] }, "headers": { "type": "object", "description": "Optional HTTP headers as key-value pairs", "additionalProperties": true }, "queryParams": { "type": "object", "description": "Optional query parameters as key-value pairs", "additionalProperties": true } }, "additionalProperties": false, "required": ["url", "method"] } ``` ## Understand How Security Works Every Salesforce Hosted MCP transaction runs as the authenticated user, scoped through an External Client App with the `mcp_api` scope. Object permissions (CRUD), field-level security (FLS), sharing rules, profile permissions, and permission sets all apply. If you can't perform an action in Salesforce, your agent can't perform it through the MCP server. The audit trail attributes every action to you. The Headless 360 server follows the same practices that apply across all Salesforce Hosted MCP servers. For full guidance, see [Security Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/security-best-practices.md) and [General Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/general-best-practices.md). One practice deserves special attention with this server: be deliberate about the permissions you grant at the client level. Most MCP clients let you set tool-level restrictions, so configure your client to require your approval before it runs a tool that changes org configuration or alters or deletes data on your behalf. This step is especially important for admins and developers, who carry wide-ranging permissions. As a best practice, make configuration changes in a sandbox or Developer org before you apply them in production. ## Related Resources - [Data 360 MCP Server](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/data360-mcp.md) (for Data 360 customer data access) - [Standard MCP Servers Reference](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/servers-reference.md) - [Salesforce Hosted MCP Servers on GitHub](https://github.com/forcedotcom/mcp-hosted) # Hosted MCP Servers End-of-Life Salesforce is committed to continually innovating and applying our resources to areas that add the most value for customers. In order to mature, improve, and develop new technologies, servers and server versions may be retired if Salesforce determines that they deliver limited value to customers or provide value to a limited number of customers. While we understand that retirement may occasionally impact some customers more than others, we believe that we can best serve our overall customer and partner community by focusing on their collective highest priorities. In the event of retirement, advance notice will be given, and Salesforce will make an effort to limit disruption to the extent possible. Hosted MCP servers will also evolve and change from release to release. Tools, prompts, and resources may be upgraded or replaced to improve the user experience and keep pace with changes to Salesforce applications. # Log In to Your Org Your MCP client authenticates with your org by using OAuth in a web browser. The MCP specification doesn't support multitenant systems like Salesforce, so you must follow these additional steps: ## Pre-Authentication Steps 1. **Log out of all other Salesforce Orgs.** 2. **Using your default browser, log in to the Org that you want to access from your MCP client.** - Be sure to log in to the Org that contains the External Client App you created in the previous step. 3. **Keep the browser open**, since the MCP client will open a new tab in that browser window in a later step. ## Why This Matters These pre-authentication steps help prevent common authentication failures when connecting MCP clients. By ensuring you're logged into only the target Org before initiating the OAuth flow, you avoid multi-tenant confusion that can cause connection issues. ## Next Steps After completing these steps, proceed to [configure your MCP client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/client-connection/client-connection-overview.md). # Products Supporting MCP Many Salesforce products are available through pre-built integrations in Hosted MCP Servers. These integrations give AI agents secure access to your data, automation, and analytics without requiring custom integration work. ## Apex Invocable Actions Expose Apex classes annotated with `@InvocableMethod` as custom MCP tools. The right choice for business logic, data validation, and multi-step operations that go beyond basic record operations. [Learn more about `@InvocableMethod`](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm). ## AuraEnabled Apex Methods Expose Apex methods annotated with `@AuraEnabled` as custom MCP tools. If your org already has Lightning components backed by `@AuraEnabled` controller methods, those same methods can be surfaced to AI agents — no new code required. [Learn more about `@AuraEnabled`](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_AuraEnabled.htm). ## Apex REST Methods Custom Apex REST endpoints (classes annotated with `@RestResource`) can be exposed as MCP tools. Use these when you have existing custom REST APIs built on the Salesforce platform that agents should be able to call. [Learn more about Apex REST](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_rest.htm). ## APIs from API Catalog REST API endpoints registered in the Salesforce API Catalog can be mapped to custom tools. This includes standard platform APIs and a growing subset of product-specific [Connect APIs](https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/connect_resources_overview.htm). There are thousands of Connect API endpoints across Salesforce products, but not all are in the catalog. Connect APIs are authored by Salesforce — customers cannot create their own. ## CRM Analytics (Beta) [CRM Analytics](/docs/platform/hosted-mcp-servers/references/reference/crm-analytics-mcp.html) — Discover analytics apps, inspect dataset schemas, run SAQL queries, and read dashboard and lens metadata. Read-only and available on sandbox and scratch orgs only. ## Data 360 [Data 360](/docs/platform/hosted-mcp-servers/references/reference/data-cloud-sql.html) — Query unified customer data in Data 360 using SQL. ## Flows Lightning Flows exposed as custom MCP tools. Reuse declarative automation you've already built in Flow Builder without writing integration code. [Learn more about Flow Builder](https://help.salesforce.com/s/articleView?id=sf.flow.htm). ## Prompts from Prompt Builder Prompt templates created in Prompt Builder exposed as MCP prompts, surfacing your organization's curated, admin-approved templates directly in compatible MCP clients. Client support for MCP prompts varies — check your client before relying on this capability. See the Prompt Builder documentation for details. ## SObject Access Multiple pre-configured SObject servers are available to allow access to standard and custom objects in your org via the MCP protocol. Each provides administrators different levels of control over which operations they expose: - [SObject All](/docs/platform/hosted-mcp-servers/references/reference/sobject-all.html) (`platform/sobject-all`) — Full CRUD: create, read, update, delete, query, search - [SObject Reads](/docs/platform/hosted-mcp-servers/references/reference/sobject-reads.html) (`platform/sobject-reads`) — Read and query only (no mutations) - [SObject Mutations](/docs/platform/hosted-mcp-servers/references/reference/sobject-mutations.html) (`platform/sobject-mutations`) — Create and update (no delete) - [SObject Deletes](/docs/platform/hosted-mcp-servers/references/reference/sobject-deletes.html) (`platform/sobject-deletes`) — Delete operations only All SObject tools respect each user's field-level security, object permissions, and sharing rules. ## Tableau Next [Tableau Next](/docs/platform/hosted-mcp-servers/references/reference/tableau-next.html) (`analytics/tableau-next`) — Discover semantic models, retrieve dashboard and visualization metadata, query KPIs, and run natural-language analytical questions via the Analytics Agent. # Prompt Run Failures If you're having problems with server actions failing: ## Step 1: Check Salesforce permissions Make sure that you have the required permissions for the operation you’re trying to run. For example, running prompt templates requires specific permissions. ## Step 2: Confirm feature activation Make sure the feature that the tool or prompt is trying to access is enabled in your Salesforce org. ## Step 3: Verify the data exists and is accessible If the operation reads or updates records, confirm that the target data exists and your user can access it. ## Step 4: Validate parameters Review server documentation and confirm that your parameters are correct and complete. # Prompts from Prompt Builder Prompt templates created in Salesforce Prompt Builder can be exposed as **MCP prompts** — a primitive in the Model Context Protocol that lets clients surface reusable, parameterized prompt templates to users. When a user selects an MCP prompt in a compatible client, the client retrieves the template, fills in any Salesforce record data, and presents the resolved prompt ready to send. > **Client compatibility:** MCP prompt support varies across clients. Claude and Cursor support MCP prompts, but ChatGPT does not. Check your client's MCP documentation before building workflows that depend on this capability. ## How It Works You configure Prompt Builder templates as MCP prompts through the custom server Setup UI — select Prompt Builder as the backing type, choose a published Flex template, and publish. See [Custom MCP Servers](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/custom-servers.md) for the full configuration walkthrough. In a compatible MCP client, the prompt appears as a selectable template — typically surfaced through a slash command, a prompt picker, or a similar UI affordance depending on the client. When a user selects it, the client retrieves the template from Salesforce, merges any required record data using the authenticated user's access, and presents the resolved text. Unlike MCP tools (which agents invoke programmatically), MCP prompts are user-initiated. They're a way to put governed, data-enriched prompt templates directly in front of users at the moment they need them. Think of an MCP prompt as a recipe. Individual MCP tools are ingredients — useful on their own, but without instructions for how to combine them. A prompt template can specify a precise sequence: call this tool first, pass its output as input to the next tool, interpret the combined result this way. This is especially valuable when tools are granular primitives that don't carry enough business context on their own. Rather than hoping the client figures out the right sequence, the prompt template encodes that knowledge explicitly — written once by someone who understands the business process, reused every time the template is invoked. ## When to Use This **Use Prompt Builder MCP prompts when:** - Your org has established templates for common tasks (call summaries, email drafts, case response starters, meeting prep) that users should be able to invoke quickly from their AI client. - Consistency matters — a sales team that wants all customer emails to follow a specific structure benefits from a template that enforces that structure, even when drafting from an external client. - Compliance or legal review has approved specific prompt formulations for regulated use cases. Exposing these as MCP prompts ensures users start from approved language regardless of which client they're using. - You want to pull live Salesforce data into a prompt — for example, a meeting prep prompt that automatically includes the contact's recent activity, open cases, and account health score. - You want to select the model used for the agentic work. ## Example Use Cases - **Call summary**: A rep finishes a call and selects the "Summarize Call" prompt in Claude. The template pulls the Opportunity record and recent activity history from Salesforce, merging them into a structured prompt the rep sends to get a formatted summary. - **Meeting prep brief**: Before a customer meeting, a rep invokes a meeting prep prompt that pulls account health, open opportunities, and last interaction date — producing a briefing in seconds without leaving their AI client. - **Compliance-approved outreach**: In a regulated industry, all AI-assisted outbound communication must start from legal-reviewed templates. Publishing these as MCP prompts ensures users across the organization start from the approved language. ## Limitations - Only **Flex templates** are supported. Other Prompt Builder template types (Sales Emails, Field Generation, etc.) cannot be exposed as MCP prompts. - Only **published** templates are available for selection. Draft or inactive templates do not appear in the Setup UI. - **Client support is not universal.** MCP prompts are only surfaced in clients that implement the MCP Prompts primitive. Verify support in your target client before relying on this capability. - Template variable data is pulled using the **authenticated user's permissions**. If the template references a field the user cannot access, that field will be blank or the call will fail depending on the template's error handling configuration. - The use of Prompt Builder templates consumes credits at invocation time, the same as if the template were triggered from the Salesforce UI. # Reference Documentation This section contains technical reference documentation for Salesforce Hosted MCP Servers. **Available References:** - **[Servers and Tools](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/servers/servers-reference.md)** - Detailed documentation for each MCP server type, including SObject operations, custom servers, and product integrations. # Salesforce Hosted MCP Servers Salesforce Hosted MCP Servers give AI agents a secure, governed way to interact with Salesforce data and automation. Using the open [Model Context Protocol (MCP)](https://modelcontextprotocol.io) standard, any compatible AI client—Claude, ChatGPT, Cursor, or a custom agent—can connect to a Salesforce org and act on behalf of authorized users. Think of it as a universal connector: instead of building custom API integrations for each AI tool your team uses, you configure a server once in Salesforce, and any MCP-compatible client can connect to it by using standard OAuth-based authentication. ## What Is MCP? MCP (Model Context Protocol) is an open-source standard for connecting AI applications to external systems. Salesforce Hosted MCP Servers use this protocol to turn on secure agentic interoperability. External AI agents can securely connect with your Salesforce data, assets, and logic safely within the Salesforce security perimeter and governance policies. ## When to Use This Use Hosted MCP Servers when you have an AI client—a chatbot, coding assistant, or agent workflow—that must interact with Salesforce logic and assets. MCP is the right choice if: - Your AI client already supports MCP (most major LLM clients do) - You want per-user authentication so that agent actions respect each user's existing Salesforce permissions - You want an admin-configurable, auditable integration rather than a custom-coded API connection ## Key Capabilities - **SObject Operations**: Read, create, update, and delete Salesforce records with tools that respect field-level security and sharing rules - **Custom Tools**: Expose Apex Invocable Actions, @AuraEnabled methods, Apex REST methods, Flows, and Named Queries as MCP tools without writing connector code - **Product Integration**: Access Data 360 SQL queries, Tableau analytics, and more - **Prompt Templates**: Use Prompt Builder templates from your MCP client - **Secure Authentication**: Per-user OAuth 2.0 with PKCE ensures that agents operate with appropriate permissions ## Getting Started To begin using Hosted MCP Servers: 1. [Set up your Salesforce org](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/setup/create-external-client-app.md) to turn on the feature. 2. [Connect an MCP client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/client-connection/client-connection-overview.md) like Claude, ChatGPT, or Postman. 3. [Test your connection](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/testing/test-connection.md) to verify everything works. 4. Review [best practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/best-practices/best-practices-overview.md) for secure, effective deployment. ## Billing Considerations Salesforce Hosted MCP Servers are intended only for customers with Flex Credits and you may be billed for server usage. For details, see [Flex Credits usage](https://sfdc.co/usage_headless). To get Flex Credits, contact your account executive, or get started with [Salesforce Foundations](https://www.salesforce.com/ca/crm/foundations/). ## Learn More - To learn about which Salesforce products support MCP, see [Products Supporting MCP](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/products-supporting-mcp.md) - For detailed server documentation, see the [Servers Reference](/docs/platform/hosted-mcp-servers/references/reference/servers-reference.html) - For release information, see [Release Notes](#release-notes) ## Release Notes Changelog coming soon. # Security Best Practices Secure your deployment with proper authentication, permission controls, and monitoring. ## Understand the Core Security Model Every MCP tool call runs with the same permissions as the user who authorized the connection: - The agent has the same object-level access (CRUD permissions) as the user. - The agent respects field-level security restrictions. - The agent follows record sharing rules. - All actions are attributed to the named user in audit trails. This inheritance means that if a user cannot perform an action in the Lightning UI or over the REST API, they cannot perform it via MCP. The system uses OAuth authorization code flow exclusively, maintaining human accountability for all transactions. There are no service accounts, no machine-to-machine flows, and no autonomous operation outside of user context. ## Use Incremental Permission Strategies When deploying MCP servers, start with the most restrictive configuration that meets your use case, then expand access only as needed. Use these strategies to dial back agent capabilities: - **Read-only servers.** The `platform/sobject-reads` server exposes only read operations, eliminating modification risks entirely. Read operations are sufficient for answering questions, generating reports, and surfacing insights from Salesforce data without enabling data changes. - **Named Queries.** Administrators can define specific SOQL queries as reusable APIs, providing controlled data access without exposing the full query surface. Use this approach when you want an agent to query a specific slice of your data model. For more information, see the [Named Query API documentation](https://developer.salesforce.com/blogs/2025/06/named-query-api-simplifies-data-access-for-agents-and-apps). - **Custom tools with embedded logic.** Use Apex Invocable Actions, REST endpoints, or Flows to implement precise business logic and conditional access rules beyond what standard permissions can express. Custom tools give you full programmatic control over what the agent can see and do. - **External Client App restrictions.** Link External Client Apps to specific profiles and permission sets to control which users can access which MCP clients, adding an additional layer of access control at the OAuth application level. ## Require Strong Authentication Salesforce Hosted MCP Servers enforce authentication requirements that maintain security and auditability: - **Authorization code flow only.** The system requires browser-based authentication to ensure every transaction traces to a named user. This flow prevents automated or headless authentication that could bypass user context. - **PKCE required.** Proof Key for Code Exchange (PKCE) is mandatory for all OAuth flows. This standard prevents authorization code interception during the OAuth exchange. - **Explicit server enablement.** MCP servers are disabled by default and require explicit administrative action to enable. This secure-by-default approach prevents accidental exposure of Salesforce capabilities to external AI clients. - **Administrative control over client registration.** Dynamic client registration is not supported. Administrators must explicitly create and configure External Client Apps, maintaining centralized control over which applications can connect to the org. ## Monitor and Audit Agent Activity Because every MCP tool call runs in the authenticated user's context, agent actions appear in standard Salesforce API logs with full user attribution. You can identify MCP traffic by filtering for records where `API_CLIENT_CATEGORY` = `SALESFORCE_HOSTED_MCP`. API logs can be downloaded as CSV files on a daily basis or retrieved programmatically. These logs include: - Which operations agents performed on behalf of each user - Which data objects were accessed - Timestamps and access patterns Monitoring and alerting tools based on these API logs work seamlessly with MCP traffic now added to this log set. # Server Connection Failures To troubleshoot server connection issues: ## Step 1: Verify the server URL Use the URL format that matches your org type and server type: - For a Sandbox or scratch org with a standard server: `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-all` - For a Developer, Enterprise, other non-sandbox org with a standard server: `https://api.salesforce.com/platform/mcp/v1/platform/sobject-all` - For a Sandbox or scratch org with a custom server: `https://api.salesforce.com/platform/mcp/v1/sandbox/custom/myserver` - For a Developer, Enterprise, or other non-sandbox org with a custom server: `https://api.salesforce.com/platform/mcp/v1/custom/myserver` ## Step 2: Confirm that the server is activated Be sure to activate your Salesforce Hosted MCP servers in the Salesforce UI before use. ## Step 3: Test a known server Try connecting to `sobject-all`. - If `sobject-all` works, your original server name or configuration is likely incorrect. - If `sobject-all` also fails, continue to the next steps. ## Step 4: Check Org API eligibility Confirm that your Org edition supports API access (for example, Developer or Enterprise, or Professional with API access enabled). ## Step 5: Check for local or client issues - Confirm that you can log in to Salesforce UI from the same machine or network. - Test with Postman or MCP Inspector. If those tests succeed, the issue is likely specific to your MCP client settings. # Set Up Your Org Before AI clients can connect to your Salesforce org through MCP, you need to configure authentication and access. This setup process is a one-time configuration that enables any MCP-compatible client to connect securely using OAuth 2.0. ## What You'll Configure **External Client App** — Register your MCP client as an OAuth application in Salesforce. This provides the authentication credentials that clients use to connect to your org. **OAuth Scopes** — Grant the permissions needed for MCP servers to access Salesforce data and operations on behalf of authenticated users. **Security Settings** — Enable Proof Key for Code Exchange (PKCE) and JWT-based tokens to ensure secure, standards-based authentication. ## Before You Begin - You need System Administrator or equivalent permissions to create an External Client App in Setup. - Identify which MCP client you'll be connecting (Claude, ChatGPT, Cursor, Postman, or another MCP-compatible tool). You'll need to configure the callback URL specific to your client. ## Next Steps Start by [creating an External Client App](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/create-external-client-app.md) to register your MCP client with Salesforce. # SObject All The `platform/sobject-all` server is the full-capability SObject server. It exposes every standard and custom object in your Salesforce org through a complete set of tools covering create, read, update, delete, query, search, and relationship traversal. This is the right choice when you want AI agents to have full access to Salesforce data, matching the permissions of the human-in-the-loop and trusting them to prompt appropriately. This provides maximum productivity gains. Note that Salesforce's permission model still acts as a safety net: even with all tools available, every operation is constrained by the authenticated user's field-level security, object permissions, and sharing rules. An agent cannot update a field the user cannot edit in Lightning, and cannot delete a record the user cannot delete in the UI. If you want to limit what agents can do, choose a scoped server instead: [SObject Reads](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-reads.md) for query-only access, [SObject Mutations](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-mutations.md) to allow create and update but not delete, or [SObject Deletes](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-deletes.md) for delete-focused workflows. ## Server URL - Production: `https://api.salesforce.com/platform/mcp/v1/platform/sobject-all` - Sandbox/Scratch: `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-all` ## Example Prompts - "Show me all open opportunities in the Manufacturing industry over \$500K, grouped by owner." - "Create a follow-up task for every Account where the last activity date is more than 90 days ago." - "Update the Stage on opportunity {name} to Closed Won and set the Close Date to today." - "Find every Contact associated with Acme Corp and return their names, titles, and email addresses." ## Available Tools The following tools are available in the `sobject-all` server. ### `getObjectSchema` Returns Salesforce schema information optimized for LLM consumption. Call with no parameters first to get a compact index of all queryable business objects — significantly smaller than the raw Describe API. Then call with a specific object name to get field-level details when constructing queries or mutations. Includes admin-authored guidance about data quality and business definitions alongside the standard schema (e.g., "use `Calculated_ACV__c` instead of `Amount` for accurate forecasting"). **Two modes:** - **Index mode** (no parameters): Compact list of all business objects with descriptions and relationships - **Detail mode** (with object name): Full field schema plus any contextual admin guidance **Inputs:** | Parameter | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------------------------------- | | `object-name` | string | No | API name of the object. Omit to get the compact index of all objects. | **Outputs:** Index mode: compact list of queryable objects with descriptions. Detail mode: full field schema with types, required flags, picklist values, relationships, and any admin-authored guidance. ### `soqlQuery` Executes a SOQL query to retrieve Salesforce records. This is the primary way to read data when you know which object and fields you need. SOQL syntax: `SELECT fields FROM Object WHERE conditions ORDER BY field LIMIT n`. Supports relationship queries to traverse lookups (e.g., `Contact.Account.Name`) and subqueries for child records (e.g., `SELECT Id FROM Contacts`). Always include a WHERE clause to filter results and a LIMIT clause to control result size. For large objects, filter on indexed fields (Id, Name, foreign keys, External IDs) to avoid timeout errors. Maximum 50,000 total records per transaction across all queries. **Example:** `SELECT Id, Name, Industry FROM Account WHERE Industry = 'Technology' LIMIT 100` Use SOQL when you know which object contains your data and need precise filtering, sorting, aggregation, or relationship traversal. Use `find` instead when searching across multiple objects for a term that could appear anywhere. **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | `query` | string | Yes | A valid SOQL query string | **Outputs:** Array of matching records with the fields specified in the SELECT clause. ### `find` Executes a text search across multiple Salesforce objects simultaneously. Use this instead of `soql_query` when searching for a term that could exist in multiple object types, when you don't know which object contains the data, or when you need relevance-ranked text matching. Returns a maximum of 2,000 records total. Use search groups to narrow scope: `IN ALL FIELDS` (default), `IN NAME FIELDS`, `IN EMAIL FIELDS`, or `IN PHONE FIELDS`. **Example:** `FIND {Acme} IN NAME FIELDS RETURNING Account(Id, Name), Contact(Id, Name, Email)` Use `find` for "find me anything matching X" scenarios. It cannot traverse relationships or sort by field values — if you need related records after finding matches, follow up with a `soql_query` using the returned IDs. **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------------------------------- | | `search` | string | Yes | A valid SOSL search string (e.g., `FIND {Acme} IN NAME FIELDS RETURNING Account(Id, Name)`) | **Outputs:** Search result groups by object type, each containing matched records with the requested fields. ### `getUserInfo` Returns the currently authenticated user's identity and context — User ID, name, email, role, profile, manager, local time, and timezone. Call this when you need to personalize responses, filter queries to "my" records using the returned User ID, or apply the user's time and locale when interpreting date-based requests. **Inputs:** | Parameter | Type | Required | Description | | --------- | ---- | -------- | ---------------------- | | _(none)_ | — | — | No parameters required | **Outputs:** Identity object with user ID, full name, email, username, profile, role, manager, local time, and timezone. ### `listRecentSobjectRecords` Returns records of a specific type that the user recently viewed or modified. Use this as a starting point when the user refers to "my accounts," "recent cases," or "that opportunity I was looking at" without providing specific record IDs or names. Returns records ordered by last viewed date. **Inputs:** | Parameter | Type | Required | Description | | -------------- | ------ | -------- | --------------------------------------------------------------- | | `sobject-name` | string | Yes | API name of the object (e.g., `Account`, `Case`, `Opportunity`) | **Outputs:** Array of recently viewed records of the specified type, ordered by last viewed date. ### `getRelatedRecords` Retrieves child records related to a parent record by traversing relationships. Use this instead of a separate SOQL query when you already have a record ID and need its related records — for example, get all Contacts for an Account, or all Opportunity Line Items for an Opportunity. Supports multi-level traversal. More efficient than writing a subquery when navigating a known relationship. **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ------------------------------------------------------------ | | `sobject-name` | string | Yes | API name of the parent object | | `id` | string | Yes | Salesforce record ID of the parent record | | `relationship-path` | string | Yes | Relationship name (e.g., `Contacts`, `OpportunityLineItems`) | **Outputs:** Array of related records via the specified relationship. ### `createSobjectRecord` Creates a new Salesforce record. Call `getObjectSchema` first to understand required fields and valid values — the operation fails if required fields are missing or values violate validation rules. Returns the new record's ID on success. All operations respect the user's permissions and field-level security; attempts to set fields the user cannot edit are rejected. **Inputs:** | Parameter | Type | Required | Description | | -------------- | ------ | -------- | --------------------------------------------- | | `sobject-name` | string | Yes | API name of the object to create a record for | | `body` | object | Yes | Field-value pairs for the new record | **Outputs:** The new record's Salesforce ID and success indicator. ### `updateSobjectRecord` Updates an existing record by ID. Only include fields you want to change — omitted fields keep their current values. Call `getObjectSchema` to verify field names and valid picklist values if unsure. Fails if the record doesn't exist, the user lacks edit permission, or field validations fail. **Inputs:** | Parameter | Type | Required | Description | | -------------- | ------ | -------- | -------------------------------------------- | | `sobject-name` | string | Yes | API name of the object | | `id` | string | Yes | Salesforce record ID of the record to update | | `body` | object | Yes | Field-value pairs to update | **Outputs:** Success or error indicator. ### `updateRelatedRecord` Updates a parent record by traversing a child-to-parent relationship from a child record. Only child-to-parent relationships support updates, up to five levels deep — for example, from a Contact to its Account to that account's parent Account. Use this when you have a child record and need to update a record higher in the relationship hierarchy, such as updating the Account associated with a Contact. If you already know the parent record's ID, call `updateSobjectRecord` directly. **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ------------------------------------------------------------------------------------- | | `sobject-name` | string | Yes | API name of the child object you start from (for example, `Contact`) | | `id` | string | Yes | Salesforce record ID of the child record you start from | | `relationship-path` | string | Yes | Child-to-parent relationship field that points to the parent (for example, `Account`) | | `body` | object | Yes | Field-value pairs to update on the parent record | **Outputs:** Success or error indicator. ### `deleteSobjectRecord` Permanently deletes a record by ID. Confirm with the user before deleting. Deleted records go to the Recycle Bin and can be recovered in the Salesforce UI for up to 15 days (no undelete tool is available through MCP). Fails if the user lacks delete permission or deletion would violate relationship rules. **Inputs:** | Parameter | Type | Required | Description | | -------------- | ------ | -------- | -------------------------------------------- | | `sobject-name` | string | Yes | API name of the object | | `id` | string | Yes | Salesforce record ID of the record to delete | **Outputs:** Success or error indicator. ### `deleteRelatedRecord` Deletes a parent record by traversing a child-to-parent relationship from a child record. The same cautions as `deleteSobjectRecord` apply, with one addition: deleting a master record in a master-detail relationship also deletes all of its detail records, including the child record you started from. Confirm with the user before deleting. If you already know the parent record's ID, call `deleteSobjectRecord` directly. **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ----------------------------------------------------------------------------- | | `sobject-name` | string | Yes | API name of the child object you start from | | `id` | string | Yes | Salesforce record ID of the child record you start from | | `relationship-path` | string | Yes | Child-to-parent relationship field that points to the parent record to delete | **Outputs:** Success or error indicator. # SObject Deletes The `platform/sobject-deletes` server provides targeted access for agents that need to remove records from Salesforce. It combines delete operations with schema discovery and query tools — giving agents the ability to identify records and delete them — while excluding create and update. This is a narrowly scoped server for deletion-specific workflows. This server is appropriate for data hygiene use cases: deduplication cleanup, archival workflows, removing records that don't meet data quality standards, or bulk purging of records created in error. Because deletion is the highest-risk mutation, this server should be deployed with extra care — require human review before invoking delete tools wherever possible. Deleted records go to the Recycle Bin and can be recovered in the Salesforce UI. No undelete tool is available through MCP at this time. Deletion is constrained by the authenticated user's object permissions — an agent cannot delete a record the user cannot delete manually. For workflows that need the full range of mutations including deletion, use [SObject All](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-all.md). ## Server URL - Production: `https://api.salesforce.com/platform/mcp/v1/platform/sobject-deletes` - Sandbox/Scratch: `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-deletes` ## Example Prompts - "Find all duplicate lead records with the same email address and delete the older copies." - "Delete the test accounts created in the last 24 hours — they all have '[TEST]' in the name." - "Remove every Contact record that has no associated Account and has never had any activity." - "I have a list of opportunity IDs for closed-lost deals from 2020. Delete them from the system." - "Show me all Cases with status 'Invalid' before I approve deletion." ## Available Tools The `sobject-deletes` server provides the following tools. ### `getObjectSchema` Returns Salesforce schema information optimized for LLM consumption. Call with no parameters to get a compact index of all objects, then call with a specific object name to understand what fields are available when constructing queries to identify records for deletion — for example, finding the field that stores deduplication keys or record creation timestamps. **Two modes:** - **Index mode** (no parameters): Compact list of all business objects with descriptions and relationships - **Detail mode** (with object name): Full field schema plus any contextual admin guidance **Inputs:** | Parameter | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------------------------------- | | `object-name` | string | No | API name of the object. Omit to get the compact index of all objects. | **Outputs:** Index mode: compact list of queryable objects with descriptions. Detail mode: full field schema with types, required flags, picklist values, relationships, and any admin-authored guidance. ### `soqlQuery` Executes a SOQL query to retrieve records for review before deletion. Always query and confirm the target record set before invoking a delete — present results to the user for approval when possible. Supports complex filtering to precisely identify records meeting deletion criteria. **Example:** `SELECT Id, Name, CreatedDate FROM Lead WHERE Email = 'duplicate@example.com' ORDER BY CreatedDate ASC LIMIT 100` **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | `query` | string | Yes | A valid SOQL query string | **Outputs:** Array of matching records with the fields specified in the SELECT clause. ### `find` Executes a text search across multiple Salesforce objects. Use this to surface candidate records for deletion when the identifiers span multiple object types, or when searching by name or keyword rather than ID. **Example:** `FIND {[TEST]} IN NAME FIELDS RETURNING Account(Id, Name, CreatedDate), Contact(Id, Name, CreatedDate)` **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------- | | `search` | string | Yes | A valid SOSL search string | **Outputs:** Search result groups by object type, each containing matched records with the requested fields. ### `deleteSobjectRecord` Permanently deletes a record by ID. Confirm with the user before deleting. Deleted records go to the Recycle Bin and can be recovered in the Salesforce UI for up to 15 days — no undelete tool is available through MCP. Fails if the user lacks delete permission or deletion would violate relationship rules (e.g., deleting a parent with required child relationships). **Inputs:** | Parameter | Type | Required | Description | | -------------- | ------ | -------- | -------------------------------------------- | | `sobject-name` | string | Yes | API name of the object | | `id` | string | Yes | Salesforce record ID of the record to delete | **Outputs:** Success or error indicator. ### `deleteRelatedRecord` Deletes a parent record by traversing a child-to-parent relationship from a child record. The same cautions as `deleteSobjectRecord` apply, with one addition: deleting a master record in a master-detail relationship also deletes all of its detail records, including the child record you started from. Confirm with the user before deleting. If you already know the parent record's ID, call `deleteSobjectRecord` directly. **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ----------------------------------------------------------------------------- | | `sobject-name` | string | Yes | API name of the child object you start from | | `id` | string | Yes | Salesforce record ID of the child record you start from | | `relationship-path` | string | Yes | Child-to-parent relationship field that points to the parent record to delete | **Outputs:** Success or error indicator. # SObject Mutations The `platform/sobject-mutations` server allows AI agents to create and update Salesforce records, but not delete them. It gives agents write access to your data while excluding potential destructive operations. This is a natural middle ground for workflows where agents need to act on data (log a note, create a task, update a stage, add a contact) but where permanent deletion should require a separate, more deliberate process. Choose this server when your use case involves data entry or record enrichment: an agent that creates follow-up tasks from a meeting summary, fills in fields based on research, or updates opportunity stages based on criteria — without any risk of accidental deletion. Because records go to the Recycle Bin when deleted (not immediate permanent removal), admins who want to allow deletion but retain a recovery window may consider [SObject All](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-all.md) instead. All mutations are constrained by the authenticated user's field-level security and object permissions. An agent cannot create a record the user cannot create, and cannot set a field the user cannot edit. ## Server URL - Production: `https://api.salesforce.com/platform/mcp/v1/platform/sobject-mutations` - Sandbox/Scratch: `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-mutations` ## Example Prompts - "Create a new Lead for Sarah Chen at Brightpath Technologies — she's VP of Engineering and her email is sarah.chen@brightpath.com." - "Update the Stage on each open opportunity where Close Date is past due to 'Needs Review'." - "Add a note to the Acme Corp account summarizing today's meeting: they're interested in the Enterprise tier but need security review first." - "Create a follow-up task for every Contact I met with at the conference last week. I'll give you their names." - "Update the Annual Revenue field on these five accounts based on the figures I'm about to share." ## Available Tools The `sobject-mutations` server provides the following tools. ### `getObjectSchema` Returns Salesforce schema information optimized for LLM consumption. Call with no parameters to get a compact index of all objects, then call with a specific object name before creating or updating records to understand required fields, valid picklist values, and field data types. Includes admin-authored guidance alongside the standard schema. **Two modes:** - **Index mode** (no parameters): Compact list of all business objects with descriptions and relationships - **Detail mode** (with object name): Full field schema plus any contextual admin guidance **Inputs:** | Parameter | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------------------------------- | | `object-name` | string | No | API name of the object. Omit to get the compact index of all objects. | **Outputs:** Index mode: compact list of queryable objects with descriptions. Detail mode: full field schema with types, required flags, picklist values, relationships, and any admin-authored guidance. ### `soqlQuery` Executes a SOQL query to retrieve Salesforce records. Use this to look up existing records before creating or updating — for example, to find the Account ID to associate with a new Contact, or to identify which records need updating based on criteria. **Example:** `SELECT Id, Name, StageName FROM Opportunity WHERE CloseDate < TODAY AND StageName NOT IN ('Closed Won', 'Closed Lost') LIMIT 50` **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | `query` | string | Yes | A valid SOQL query string | **Outputs:** Array of matching records with the fields specified in the SELECT clause. ### `find` Executes a text search across multiple Salesforce objects simultaneously. Use this to look up records by name or search term when you don't know which object to query, or when the search term could appear across multiple objects. **Example:** `FIND {Sarah Chen} IN NAME FIELDS RETURNING Contact(Id, Name, AccountId), Lead(Id, Name, Company)` **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------- | | `search` | string | Yes | A valid SOSL search string | **Outputs:** Search result groups by object type, each containing matched records with the requested fields. ### `createSobjectRecord` Creates a new Salesforce record. Call `getObjectSchema` first to understand required fields and valid values — the operation fails if required fields are missing or values violate validation rules. Returns the new record's ID on success. All operations respect the user's permissions and field-level security. **Inputs:** | Parameter | Type | Required | Description | | -------------- | ------ | -------- | --------------------------------------------- | | `sobject-name` | string | Yes | API name of the object to create a record for | | `body` | object | Yes | Field-value pairs for the new record | **Outputs:** The new record's Salesforce ID and success indicator. ### `updateSobjectRecord` Updates an existing record by ID. Only include fields you want to change — omitted fields keep their current values. Call `getObjectSchema` to verify field names and valid picklist values if unsure. Fails if the record doesn't exist, the user lacks edit permission, or field validations fail. **Inputs:** | Parameter | Type | Required | Description | | -------------- | ------ | -------- | -------------------------------------------- | | `sobject-name` | string | Yes | API name of the object | | `id` | string | Yes | Salesforce record ID of the record to update | | `body` | object | Yes | Field-value pairs to update | **Outputs:** Success or error indicator. ### `updateRelatedRecord` Updates a parent record by traversing a child-to-parent relationship from a child record. Only child-to-parent relationships support updates, up to five levels deep — for example, from a Contact to its Account to that account's parent Account. Use this when you have a child record and need to update a record higher in the relationship hierarchy, such as updating the Account associated with a Contact. If you already know the parent record's ID, call `updateSobjectRecord` directly. **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ------------------------------------------------------------------------------------- | | `sobject-name` | string | Yes | API name of the child object you start from (for example, `Contact`) | | `id` | string | Yes | Salesforce record ID of the child record you start from | | `relationship-path` | string | Yes | Child-to-parent relationship field that points to the parent (for example, `Account`) | | `body` | object | Yes | Field-value pairs to update on the parent record | **Outputs:** Success or error indicator. # SObject Reads The `platform/sobject-reads` server provides read-only access to standard and custom objects in your Salesforce org. It is the safest of the SObject server family: agents can discover schema, query records, search across objects, and traverse relationships — but cannot create, update, or delete anything. No data changes are possible through this server. If you’re still evaluating how best to put AI to work in production, this is a great place to start. Read-only access is sufficient for answering questions, summarizing data, generating reports, preparing talking points before a meeting, and surfacing insights from Salesforce data. Limiting agents to read-only access also satisfies common enterprise requirements around human-in-the-loop review for any data modification. See [Best Practices](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guides/best-practices/general-best-practices.md) for guidance on access control and human-in-the-loop design. When you’re ready to give agents write access, the other SObject servers are available: [SObject Mutations](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-mutations.md) adds create and update, [SObject Deletes](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-deletes.md) adds delete, and [SObject All](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-all.md) provides the full range. ## Server URL - Production: `https://api.salesforce.com/platform/mcp/v1/platform/sobject-reads` - Sandbox/Scratch: `https://api.salesforce.com/platform/mcp/v1/sandbox/platform/sobject-reads` ## Example Prompts - "What are the top 10 opportunities by amount currently in the pipeline?" - "Give me a summary of all cases opened in the last 7 days for accounts in the Financial Services industry." - "Find everything related to Acme Corp — contacts, opportunities, and open cases." - "Who are the contacts at GlobalTech and what are their titles?" ## Available Tools The `sobject-reads` server provides the following tools. ### `getObjectSchema` Returns Salesforce schema information optimized for LLM consumption. Call with no parameters first to get a compact index of all queryable business objects. Then call with a specific object name to get field-level details before writing queries. Includes admin-authored guidance alongside the standard schema. **Two modes:** - **Index mode** (no parameters): Compact list of all business objects with descriptions and relationships - **Detail mode** (with object name): Full field schema plus any contextual admin guidance **Inputs:** | Parameter | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------------------------------- | | `object-name` | string | No | API name of the object. Omit to get the compact index of all objects. | **Outputs:** Index mode: compact list of queryable objects with descriptions. Detail mode: full field schema with types, required flags, picklist values, relationships, and any admin-authored guidance. ### `soqlQuery` Executes a SOQL query to retrieve Salesforce records. This is the primary way to read data when you know which object and fields you need. SOQL syntax: `SELECT fields FROM Object WHERE conditions ORDER BY field LIMIT n`. Supports relationship queries to traverse lookups and subqueries for child records. Always include a WHERE clause and a LIMIT clause. For large objects, filter on indexed fields to avoid timeout errors. **Example:** `SELECT Id, Name, StageName, Amount, CloseDate FROM Opportunity WHERE StageName != 'Closed Lost' ORDER BY Amount DESC LIMIT 10` **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | `query` | string | Yes | A valid SOQL query string | **Outputs:** Array of matching records with the fields specified in the SELECT clause. ### `find` Executes a text search across multiple Salesforce objects simultaneously. Use this instead of `soqlQuery` when searching for a term that could exist in multiple object types, or when you don't know which object contains the data. **Example:** `FIND {Acme} IN NAME FIELDS RETURNING Account(Id, Name), Contact(Id, Name, Email)` **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------- | | `search` | string | Yes | A valid SOSL search string | **Outputs:** Search result groups by object type, each containing matched records with the requested fields. ### `getUserInfo` Returns the currently authenticated user's identity and context — User ID, name, email, role, profile, manager, local time, and timezone. Call this when you need to personalize responses, filter queries to "my" records using the returned User ID, or apply the user's time and locale when interpreting date-based requests. **Inputs:** | Parameter | Type | Required | Description | | --------- | ---- | -------- | ---------------------- | | _(none)_ | — | — | No parameters required | **Outputs:** Identity object with user ID, full name, email, username, profile, role, manager, local time, and timezone. ### `listRecentSobjectRecords` Returns records of a specific type that the user recently viewed or modified. Use this as a starting point when the user refers to "my accounts," "recent cases," or "that opportunity I was looking at" without providing specific IDs or names. **Inputs:** | Parameter | Type | Required | Description | | -------------- | ------ | -------- | --------------------------------------------------------------- | | `sobject-name` | string | Yes | API name of the object (e.g., `Account`, `Case`, `Opportunity`) | **Outputs:** Array of recently viewed records of the specified type, ordered by last viewed date. ### `getRelatedRecords` Retrieves child records related to a parent record by traversing relationships. Use this instead of a separate SOQL query when you already have a record ID and need its related records — for example, all Contacts for an Account, or all Opportunity Line Items for an Opportunity. **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ------------------------------------------------------------ | | `sobject-name` | string | Yes | API name of the parent object | | `id` | string | Yes | Salesforce record ID of the parent record | | `relationship-path` | string | Yes | Relationship name (e.g., `Contacts`, `OpportunityLineItems`) | **Outputs:** Array of related records via the specified relationship. # Standard MCP Servers Reference Salesforce provides a set of standard MCP servers that expose built-in platform and product capabilities. These servers are pre-configured by Salesforce and provide a fixed set of tools. Standard servers are disabled by default and can be enabled by an administrator, but their tool sets cannot be modified. All servers enforce per-user authentication and respect Salesforce's standard security model: field-level security, object permissions, and sharing rules apply to every tool call. ## SObject Servers - **[SObject All](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-all.md)** - Full CRUD operations (create, read, update, delete) plus query and search across all Salesforce objects - **[SObject Reads](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-reads.md)** - Read and query only, no mutations - **[SObject Mutations](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-mutations.md)** - Create and update operations, no delete - **[SObject Deletes](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/sobject-deletes.md)** - Delete operations only ## Product-Specific Servers - **[Backup and Recover](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/backup-and-recover.md)** - Discover and inspect backups, manage backup policy, and drive the guided restore workflow - **[Content Read-Only](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/content-readonly.md)** and **[Content Write](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/content-write.md)** - Get read and write access to Salesforce CMS assets including workspaces, channels, content, and folders - **[Data 360](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/data360-mcp.md)** - Query unified customer data in Data 360 - **[Headless 360 (Beta)](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/headless-360-mcp.md)** - Access the full breadth of Salesforce Setup and platform capabilities through tools like Discover, Describe, and Dispatch. [Archive Connect](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/archive-connect.md) tools (search, unarchive, analysis, and compliance operations on archived records) are available through this server. - **[Tableau Next](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/tableau-next.md)** - Discover semantic models, query KPIs, and execute analytics - **[CRM Analytics (Beta)](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/crm-analytics-mcp.md)** - Discover analytics apps, inspect dataset schemas, run SAQL queries, and read dashboard and lens metadata # Tableau Next The `analytics/tableau-next` server exposes Tableau Next's semantic layer and analytics capabilities to AI agents. It provides tools to discover semantic models (SDMs), retrieve dashboard and visualization metadata, explore metrics and KPIs, and execute natural-language analytical questions via the Analytics Agent. This is the bridge between AI agent conversations and the structured analytical layer that Tableau Next maintains over your data. Tableau Next's semantic model is the key concept here. An SDM defines the business meaning of your data: how tables relate, what metrics mean, how KPIs are calculated, and what terminology maps to what fields. When an agent queries through this server, it operates at the level of business concepts ("revenue by region," "customer churn rate") rather than raw SQL or object fields. This makes the server particularly effective for analytics use cases where the right answer depends on how metrics are defined by your data team, not just what's in the database. ## Why Use Tableau Next MCP? Using Tableau Next MCP provides several key benefits: - **Interoperability Across Agentic Ecosystems**: Concierge: Analytics Q&A engine gives your AI agents secure, natural language access to governed data. This integration allows agents to generate answers directly from your Tableau Next models within your preferred AI tools. - **Grounded AI Responses**: Empower your AI agent responses with a ready-to-use semantic layer. - **Metadata-Rich Discovery**: Enable agents to understand dashboards, KPIs, and analytical assets directly from Tableau Next for better context and discovery. ## FAQs Common questions about Tableau Next MCP Server and the Model Context Protocol. ### What's MCP? The Model Context Protocol (MCP) is an open standard that enables AI models to securely access data, tools, and context from specialized systems. Tableau Next MCP Server uses the protocol to expose Tableau Next analytical capabilities to external AI agents. ### Is Tableau Next MCP secure? Tableau Next MCP uses the data privacy and security tools provided by the AI Platform in Salesforce. Each interaction is protected by the same enterprise-grade standards as your current Tableau Next environment. ### How does Tableau Next MCP Server use Concierge: Analytics Q&A? Concierge: Analytics Q&A is exposed as an Analytics Q&A tool, making its functionality available externally through any MCP client. In short: Concierge powers Tableau Next's own conversational experience, and Tableau Next MCP Server lets other AI systems call that same capability. When you use Tableau Next MCP, you're using Concierge through a different frontend interface. ## Server URL - Production: `https://api.salesforce.com/platform/mcp/v1/analytics/tableau-next` - Sandbox/Scratch: `https://api.salesforce.com/platform/mcp/v1/sandbox/analytics/tableau-next` ## Example Prompts - "What analytics models and dashboards are available?" - "What is our current win rate by region according to the Sales Performance semantic model?" - "Show me the revenue trend for the last 6 months from the Revenue semantic model." - "What KPIs are defined in the Customer Health model?" - "Find dashboards related to pipeline and show me the key metrics they track." - "Ask the Analytics Agent: what drove the spike in churn last quarter?" ## Available Tools The `analytics/tableau-next` server provides a suite of tools that allow external AI agents to interact with your analytical ecosystem. After you complete the initial setup, you no longer need to manually select or configure these tools. Ask your preferred MCP-compliant AI client (such as ChatGPT, Claude, or Cursor) questions using natural language, and it automatically selects the right tools for the task. For example, when you ask, "What are my best product sales in 2025?", the AI agent uses the Analytics Q&A tool `analyze_data` to query your governed data via Concierge. The integration returns accurate answers and visualizations directly within your chat interface. For documentation purposes, the available tools are grouped by their functional role within an analytical workflow. ### Analysis External MCP-compliant AI agents use these tools to query data and explore visual assets. #### `analyze_data` Executes a natural-language question via the Tableau Analytics Agent against a target semantic model. Use this when the user asks an open-ended analytical question and a semantic model exists that covers the relevant data. The Analytics Agent interprets the question, selects appropriate metrics and dimensions, executes the analysis, and returns results in a structured format. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | -------------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------- | | `utterance` | string | Yes | The natural-language question to analyze (e.g., "What drove the increase in churn last quarter?") | | `target_entity_type` | string | Yes | Must be `sdm` | | `target_entity_name_or_id` | string | Yes | API name or ID of the target semantic model | **Outputs:** Structured analytical response — the interpreted question, data used, computed results, and a narrative summary. #### `list_dashboards` Lists Tableau Next dashboards available to the current user — metadata only, for discovery and selection. Use this to find relevant dashboards before retrieving a specific one's details. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | --------- | ---- | -------- | ---------------------- | | _(none)_ | — | — | No parameters required | **Outputs:** Array of dashboard descriptors — ID, API name, display name, and description. #### `get_dashboard` Retrieves details for a single Tableau Next dashboard. Use this after identifying the relevant dashboard via `list_dashboards` to get its full metadata, including which visualizations it contains. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ---------------------- | ------ | -------- | ----------------------------------- | | `dashboardIdOrApiName` | string | Yes | The ID or API name of the dashboard | **Outputs:** Dashboard details — name, description, workspace, and contained visualization references. #### `list_visualizations` Lists all visualizations (worksheets) available across Tableau Next — metadata only. Use this to discover available charts and analyses, or to find a specific visualization to retrieve in detail. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | --------- | ---- | -------- | ---------------------- | | _(none)_ | — | — | No parameters required | **Outputs:** Array of visualization descriptors — ID, API name, display name, and description. #### `get_visualization` Retrieves details for a single Tableau Next visualization. Use this to understand what a specific chart or worksheet contains and how it's configured. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | -------------------------- | ------ | -------- | --------------------------------------- | | `visualisationIdOrApiName` | string | Yes | The ID or API name of the visualization | **Outputs:** Visualization details — name, type, data source, and configuration metadata. ### Semantic Model Structure Discovery External MCP-compliant AI agents use these tools to understand Tableau Next's schemas, relationships, and logical views. The agents use this data architecture to make sense of the tables and connections inside Tableau Next. #### `list_semantic_models` Lists all semantic data models (SDMs) available to the current user. Call this first to discover what analytical models exist before drilling into dimensions, measures, or metrics. An SDM represents a curated business view of data — start here to understand what analytical topics are available. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | --------- | ---- | -------- | ---------------------- | | _(none)_ | — | — | No parameters required | **Outputs:** Array of semantic model descriptors — ID, API name, display name, and description. #### `get_semantic_model` Retrieves the full profile of a single semantic model, including business preferences and configuration. Use this to understand the purpose and scope of a specific model before querying its dimensions, measures, or metrics. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ------------------ | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | **Outputs:** Semantic model profile — name, description, business preferences, and configuration metadata. #### `list_semantic_model_data_objects` Lists the data objects (entities/tables) defined within a semantic model. Call this to understand the data model structure — what entities the SDM contains — before querying for dimensions or measures on a specific object. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ------------------ | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | **Outputs:** Array of data objects in the model, each with ID, API name, and display name. #### `list_semantic_model_relationships` Lists relationships between data objects in a semantic model. Use this to understand how entities join — for example, how Orders relates to Customers, or how Products relates to Transactions. Helpful before constructing multi-entity analytical queries. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ------------------ | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | **Outputs:** Array of relationship descriptors — from object, to object, join type, and cardinality. #### `get_semantic_model_logical_view` Retrieves the structure of a single logical view within a semantic model. Logical views define how data is organized and exposed within an SDM — use this for deep inspection of a specific view's structure. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ------------------------ | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | | `logicalViewIdOrApiName` | string | Yes | The ID or API name of the logical view | **Outputs:** Logical view structure including fields, data sources, and configuration. ### Business Logic and Definitions External MCP-compliant AI agents use these tools to identify specific Tableau Next KPIs and calculation logic. #### `list_semantic_model_measures` Lists measures for a specific data object in a semantic model. Measures are numeric fields used for aggregation — for example, Revenue, Deal Count, or Customer Lifetime Value. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ----------------------- | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | | `dataObjectIdOrApiName` | string | Yes | The ID or API name of the data object | **Outputs:** Array of measure descriptors — name, aggregation type, description, and unit. #### `list_semantic_model_dimensions` Lists dimensions for a specific data object in a semantic model. Dimensions are categorical, date, or text fields used for grouping and slicing data — for example, Region, Product Category, or Time Period. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ----------------------- | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | | `dataObjectIdOrApiName` | string | Yes | The ID or API name of the data object | **Outputs:** Array of dimension descriptors — name, type, description, and usage guidance. #### `list_semantic_model_metrics` Lists business metrics and KPIs defined in a semantic model. Metrics are named, governed calculations — the official definition of how a business measure is computed, often corresponding to targets, OKRs, or executive dashboards. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ------------------ | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | **Outputs:** Array of metric descriptors — name, description, calculation definition, and target values if configured. #### `get_semantic_model_metric` Retrieves the full definition of a single metric or KPI — including how it is calculated, what data it draws from, and any thresholds or targets configured. Use this when you need to explain what a metric means or verify the calculation behind a number. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | | `metricIdOrApiName` | string | Yes | The ID or API name of the metric | **Outputs:** Full metric definition — name, description, formula, data source, and configured targets. #### `list_semantic_model_calculated_dimensions` Lists calculated dimensions in a semantic model — user-defined expressions that yield categorical, date, or text results. These are derived fields that don't exist in the raw data but are defined in the semantic layer for analytical consistency. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ------------------ | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | **Outputs:** Array of calculated dimension descriptors with their expressions and descriptions. #### `list_semantic_model_calculated_measures` Lists calculated measures in a semantic model — user-defined numeric expressions or aggregations. These are derived metrics defined in the semantic layer, such as "Win Rate" or "Average Deal Size." **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ------------------ | ------ | -------- | ---------------------------------------- | | `modelIdOrApiName` | string | Yes | The ID or API name of the semantic model | **Outputs:** Array of calculated measure descriptors with their formulas and descriptions. ### Workspace and General Asset Discovery External MCP-compliant AI agents use these tools to navigate Tableau Next's environment and search for relevant analytical assets. #### `list_workspaces` Lists Tableau Next workspaces available to the current user, or retrieves a specific workspace by ID. Workspaces are containers that organize related dashboards, visualizations, and data assets. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ---------------------- | ------ | -------- | --------------------------------------------------------------------------------------- | | `workspaceIdOrApiName` | string | No | If provided, returns the specified workspace; otherwise lists all accessible workspaces | **Outputs:** Array of workspace descriptors (or a single workspace) — ID, name, and description. #### `list_workspace_assets` Lists assets contained within a specific workspace — dashboards, visualizations, and other items. Use this after identifying a relevant workspace to see what analytics content it contains. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | ---------------------- | ------ | -------- | ----------------------------------- | | `workspaceIdOrApiName` | string | Yes | The ID or API name of the workspace | **Outputs:** Array of asset descriptors — type, ID, name, and description for each asset in the workspace. #### `search_assets` Searches for analytics assets (dashboards, visualizations, semantic models) using a keyword and optional type filter. Use this to quickly find relevant content by name or description without browsing the full catalog. **Annotations:** `readOnlyHint: true` · `openWorldHint: false` **Inputs:** | Parameter | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------------------------------------- | | `query` | string | Yes | Search keyword or phrase | | `type` | string | No | Optional asset type filter (e.g., `dashboard`, `visualization`, `semanticModel`) | **Outputs:** Array of matching assets across the Tableau Next catalog — type, ID, name, and relevance summary. ## Troubleshooting and Tips for Success Use these solutions to resolve common issues and optimize the performance of Tableau Next MCP Server across different AI clients. ### General Connectivity Issues **Server Connection Fails:** Verify that Node.js is installed on your environment. It's a mandatory requirement to run the initial command that connects AI clients like ChatGPT or Claude to Tableau Next MCP Server. **Claude Disconnections:** Updates to your configuration, or inactivity with Claude for a few hours, can cause the session managed by Tableau Next MCP Server to disconnect. To resolve this, exit and re-open Claude. If the issue persists, click "Search and tools," select "Manage connectors," and reconnect the Tableau Next MCP custom connector. ### Optimization for AI Clients (ChatGPT, Claude, Cursor) **Performance Expectations:** Note that AI clients like Claude desktop can vary in their response time depending on the specific AI client, the model being used, and their connection to the MCP server via HTTPS. For example, Claude Desktop might take about a minute to produce an answer, while native Agentforce is considerably faster, often 10-20 times quicker. **Context Retrieval:** If the agent needs to find named business metrics or KPIs rather than row fields, prompt it to use the `list_semantic_model_metrics` tool. **Stop Claude Tool Prompts:** If Claude keeps asking for your approval before running tools, navigate to the "Manage Connectors" setup page, edit the tab-next-mcp connector, and change the tool permissions to "Always allow". Ensure you don't turn off notifications for tools that require manual approval. ### Data and Tool Access **Missing Q&A Tools:** If you can't access the Analytics Q&A capabilities, verify that Concierge is enabled in your Salesforce Org. Users are only able to see and work with the tools they have permissions to use. **Permissions and Governance:** MCP sessions use OAuth-authenticated users, meaning any permissions or restrictions that apply to your user profile also apply to your MCP session. The MCP enforces your standard Tableau user permissions, semantic model definitions, and Trust Layer protections. **"Unavailable for you at the moment" Error:** If you receive a message stating an item is unavailable, this specifically indicates a lack of permissions for that asset. If this happens, review the MCP documentation for further details. # Test with Postman Once you've configured Postman with OAuth 2.0 authentication for Salesforce, you can test the MCP server by calling its tools. This page walks through basic testing scenarios to verify your connection is working correctly. ## Testing Tools Without Parameters Some MCP tools don't require any input parameters, making them ideal for initial testing. A simple example is `getUserInfo`, which returns information about the currently authenticated user. ### Steps to Test 1. In the **Message** tab, you'll see a list of available tools on the left side. 2. In the right pane, you'll see a JSON structure with `"method": "tools/call"` and a `"params"` section. 3. Click on a tool name (such as `getUserInfo`) in the left pane. Postman automatically populates the JSON in the right pane: ```json { "method": "tools/call", "params": { "name": "getUserInfo", "arguments": {} } } ``` 4. Click **Run** in the upper right corner. 5. View the results in the **Response** pane at the bottom of the window. ### Expected Results For `getUserInfo`, you'll see information about the current authenticated user — name, role, profile, timezone, and preferences. ## Testing Tools With Parameters Many MCP tools require input parameters. The `soqlQuery` tool is a good example that lets you execute SOQL queries against your Salesforce org. ### Steps to Test 1. Click on `soqlQuery` in the tools list on the left side. Postman populates the JSON structure in the right pane: ```json { "method": "tools/call", "params": { "name": "soqlQuery", "arguments": {} } } ``` 2. Add your SOQL query to the `arguments` object. For example, to query Account records: ```json { "method": "tools/call", "params": { "name": "soqlQuery", "arguments": { "query": "SELECT Id, Name, Type, Industry, Phone, Website, BillingStreet, BillingCity, BillingState, NumberOfEmployees, AnnualRevenue FROM Account WHERE Name = 'Abbott Insurance'" } } } ``` 3. Click **Run** in the upper right corner. 4. View the query results in the **Response** pane at the bottom. ### Expected Results The response shows the matching Account records with all requested fields. ## What to Try Next Once you've successfully tested these basic tools, you can explore other available tools: - **getObjectSchema** - Get schema information about Salesforce objects - **getRelatedRecords** - Retrieve related records for a given record - **listRecentSobjectRecords** - Get recently viewed records of a specific object type - **find** - Search across multiple objects using SOSL Each tool will have different required and optional parameters. Click on the tool name in Postman to see the parameter structure, then add your specific values in the `arguments` object before clicking **Run**. ## Important Note About MCP and LLMs The MCP server itself is completely deterministic and does not involve an LLM for tool calls. When you call a tool directly in Postman, you're making direct API calls to Salesforce and receiving structured responses—no language model is processing your requests or responses. Postman offers AI-powered developer tools that allow you to connect an LLM to the MCP server responses if you want to test agentic workflows. These AI features are separate capabilities within Postman and are not part of the MCP server itself. # Test Your MCP Client Once the MCP client has authenticated successfully against the target org, you can test the MCP-based interaction with your org. Each client is different, though most of them have a chatbot window or UI element in which you can enter a prompt and use the client to send it to the MCP server. ## Simple Test Prompt Here's a simple prompt that works with the SObject servers: ``` tell me some basic information about the {ACCOUNT NAME HERE} account ``` **Example:** ``` tell me some basic information about the abbott insurance account ``` ## Expected Response Here's how the chatbot might respond: > Here's some basic information about the Abbott Insurance account based on the Salesforce data available to you: > > 🔎 **Account Overview** > > - Name: Abbott Insurance > - Industry: Insurance > - Type: Customer - Direct > - Website: https://www.abbott-ins.com/ > - Phone: (847) 694-4800 > > If you'd like, I can also help you: > > - Pull related contacts or opportunities > - Summarize recent activities on the account > - Analyze whitespace / growth opportunities > - Draft outreach messaging tailored to Utilities prospects > > Just let me know what you'd like to do next! ## Advanced Testing For more detailed testing including direct tool calls and response inspection, see [Testing with Postman](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/postman-testing.md). # Transition from Beta If you integrated with the Salesforce hosted MCP server during the pilot or beta period, you'll need to complete a few steps to reconnect using the GA release. The changes are straightforward, and your underlying Salesforce configuration — permissions, sharing rules, data — is unchanged. ## What Changes at GA Three things change between the beta and GA release: **The server URL changes.** The beta service used a versioned URL path (`v1-beta.2`) that is specific to the pre-GA infrastructure. The GA release uses a new URL format. Any MCP client configuration that references the old URL will stop working once beta access is retired, so you'll need to update the server URL in each client that was connected during beta. **MCP servers must be enabled.** In the GA release, MCP servers are disabled in your org by default and must be explicitly enabled by an administrator. This is a deliberate security posture: org capabilities that expose data to external systems should require an intentional administrator action to turn on. If your servers aren't enabled, clients will not be able to connect, even with correct authentication. **OAuth scopes change.** The beta required a set of individual scopes (`api`, `sfap_api`, `refresh_token`, `einstein_gpt_api`). At GA, these are replaced by two scopes: `mcp_api` and `refresh_token`. You'll need to update the scope configuration in your External Client App and in each connected MCP client. ## What Stays the Same The fundamental connection model is unchanged. You'll still use an External Client App (ECA) for OAuth authentication, and the same per-user permission model governs what agents can access. Your existing ECA can be reused — you don't need to create a new one, though you will need to update its scope configuration as noted above. The tools available in each server, and the behavior of those tools, are also unchanged. Integrations and prompts built during beta should work without modification once clients are reconnected to the GA endpoints. ## Steps to Reconnect 1. **Enable MCP servers in Setup.** An administrator must navigate to **Setup → API Catalog → MCP Servers** and enable the servers your team uses. Servers are disabled by default at GA. 2. **Update OAuth scopes.** In your External Client App, remove the beta scopes (`api`, `sfap_api`, `refresh_token`, `einstein_gpt_api`) and replace them with `mcp_api` and `refresh_token`. Update the scope value in each MCP client configuration as well. 3. **Update server URLs in your MCP clients.** In each connected client, update the server URL to use the GA endpoint format. Refer to [Connecting an MCP Client](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/client-connection/client-connection-overview.md) for client-specific instructions. 4. **Reauthorize.** After updating the URL and scopes, each user will be prompted to authorize the connection again. This is expected — tokens issued during beta are not valid for the GA service. 5. **Verify.** Confirm the connection is working by running a simple tool call (for example, a simple SOQL query) and checking that it returns expected results. # Troubleshooting Use this guide when your MCP client isn't working with Salesforce Hosted MCP Servers. Choose the issue that matches your situation: 1. **[Server connection failures](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/connection-issues.md)** - Server URL, activation, API access 2. **[Authentication issues](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/authentication-issues.md)** - External client app, OAuth, callback URLs 3. **[Prompt run failures](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/execution-issues.md)** - Permissions, feature activation, parameters 4. **[Contact support](https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/contact-support.md)** - What to gather before contacting support # Use Prompt Templates Use your MCP client to access Salesforce prompt templates in your org that were created with Prompt Builder. Add inputs to bring specific data into the template to let the client create a customized response. To use prompt templates, enable Prompt Builder in your org. You also need to connect your client to your org. ## Available Templates Prompt templates incorporate your CRM data from merge fields that reference record fields, flows, related lists, Apex, and more. There are two prompt templates available to your MCP client when you use the `platform/sobject-all` hosted MCP server: - **Create Executive Briefing for Account Review Meeting** (`einstein_gpt__accountReviewBriefing`) generates an executive briefing for an account review meeting by summarizing recent opportunities, cases, and public information about the account. - **Revenue Reconciliation Analysis** (`einstein_gpt__revenueReconciliationAnalysis`) finds discrepancies between financial accounting records and closed deals. ## Example: Using a Prompt Template with Claude After you enable Prompt Builder on your org and connect your client to that org, you can access these templates from your client. This example shows how to use the `einstein_gpt__accountReviewBriefing` template with Claude: 1. Click the plus on the Claude chat, then select the connector to your Salesforce org from the menu. - For example, if your connector is called MyConnector, the menu item is "Add from MyConnector" 2. Select **Einstein gpt accountReviewBriefing**. 3. Enter the name of an account, then click **Add Prompt**. - To create the summary, this prompt template requires input in the form of an account name 4. To review the prompt before sending it, click the text file that appears in the Claude chat. 5. Send the prompt. - Claude responds with a briefing about the company named in the account