Let us know so we can improve!
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.
Prerequisites
- API version: v68.0 and later
- External Client App configured with the
mcp_apiscope - MCP client installed and configured with OAuth authentication
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 in Salesforce Help for more information.
For setup instructions, see Set Up Your Org.
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
- From Setup, in the Quick Find box, enter
MCP Servers, and then select MCP Servers. - Find content-write in the list of servers.
- 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.
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.
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}.
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.
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.
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.
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}.
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.
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.
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.
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.
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}.
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 and General Best Practices.
Related Resources
- Content Read-Only MCP Server
- Standard MCP Servers Reference
- Connect REST API Developer Guide_: Enhanced CMS Workspace Resources
Let us know so we can improve!