AgentExchange

Help & Support

Elevate Your Agents with AgentExchange Solutions
Easily enhance Agentforce with pre-built AI solutions from AgentExchange. Browse, install, and deploy agents, actions, and apps directly into your environment. Tell Me More

Have Questions?

Experience CMS Content Generate

Beta
undefinedFiles
  • SKILL.md

Creating CMS Content

Universal skill for creating Salesforce CMS content records — orchestrates type discovery, workspace resolution, and create_cms_content dispatch against an existing ContentTypeBundle.

Content generation is server-side, always. create_cms_content / update_cms_content_variant take the goal / edit instruction as prompt; the server generates + validates the body against the schema and returns the persisted record. Agent never walks the schema, assembles contentBody, pre-validates, or regenerates rejected fields (Principle 3).

Scope

Creates managed content records in Salesforce CMS — instances authored against an existing ContentTypeBundle.

Use when the user wants to: create a content record of any kind (single or bulk) from a free-text prompt against an existing CMS type; edit/refine session items; update/edit OR publish a record identified directly by managedContentVariantId / managedContentId — even if NOT created this session (Step 0 → UPDATE / PUBLISH entry); publish all or a subset; delete/remove a record — this skill OWNS the delete request and routes to a hard stop (Step 0-D); never surface the internal reason.

DO NOT use when the user wants to: define a new content type / schema (use experience-cms-content-type-generate); unpublish, clone, or version a record; manage workspaces / folders / channels; attach images / media; apply branding.

"Create image/media content" is NOT a pre-flight scope-out (only literal binary file attach/upload is the excluded "attach media" above). Creating an image/video content record (e.g. from a URL) enters the normal flow — resolve type + workspace, dispatch create_cms_content, never refuse up front or propose a REST / UI workaround. sfdc_cms__media is server-decided: let the tool return the error, then hard-stop per Principle 15 (references/error-recovery.md).

Before You Start

Follow steps in order — do not skip or reorder.

Every successful run MUST end by dispatching create_cms_content (≥1×), each carrying the goal via prompt.

Interaction-minimal — the only pre-dispatch question is Step 3 (workspace). Never ask for goal refinement, mode, or body details. Step 1 is silent. FQN in prompt → Step 2 fast-path; else Step 2a delegates with no intervening ask_user_tool. Bulk exception: Step 4 presents topic prompts for approval.

VERBATIM QUESTION CONTRACT — EVERY ask_user_tool, no exceptions. Full rule → references/ux-rules.md. Every question goes through ask_user_tool (never plain text); before ANY call, open assets/questions.md and copy BOTH the question string AND the answers array character-for-character, filling only <placeholders> — never reword/shorten the question, never add/drop/reorder answers, never put list content into an answer. No template covers it? STOP and re-read assets/questions.md — never compose one ad hoc.

Workflow Overview

- [ ] Step 1: Understand intent (silent — domain, count, FQN if present)
- [ ] Step 2: Resolve content type — fast-path (Buckets 1/2/3) or delegate → contentTypeFqn
- [ ] Step 3: Resolve workspace — UIBundle options or manual ID
- [ ] Step 4: Build payload — single or bulk (topic approval if bulk)
- [ ] Step 5: Dispatch create_cms_content (parallel for bulk)
- [ ] Step 6: Display content body + summary
- [ ] Step 7: Post-action loop — Edit / Publish / End
- [ ] Step 8: Edit — update_cms_content_variant
- [ ] Step 9: Publish — publish_content
- [ ] Step 10: Post-publish — Create more / Render (if UIBundle) / End

Step 0: Route the Intent (run FIRST, always)

Before Step 1, classify into exactly one intent and route. update/publish/delete are first-class entry points — NOT only tails of the create flow. Opening with one of those verbs → do NOT freelance (pick tools by intuition, run SOQL, guess a variant ID). Read the opening verb and route:

User intent (opening verb) Route to
create, generate, write, draft, author, post, add, compose; "create N <things>" CREATE — continue to Step 1
update, edit, change, modify, revise an existing record UPDATE entry — Step 0-U
publish an existing record PUBLISH entry — Step 0-P
delete, remove, destroy a record DELETE — Step 0-D (hard stop)
ambiguous (can't tell create vs update vs publish) ask_user_tool disambiguation (Create new / Update existing / Publish existing / Cancel), route on the answer

No-drift STOP rule (every route). If the route's required content-write tool (create_cms_content/update_cms_content_variant/publish_content) is unavailable on this bridge, STOP, print the actionable user-facing message, end the turn. Never substitute SOQL, sf data, CLI, a sibling tool, or the contentBody channel — tool-unavailable and unsupported-operation are terminal, never a fallback trigger. Exact message + per-route slots + may/may-not-say → references/intent-routing.md § No-drift STOP rule.

Step 0-U (UPDATE) and Step 0-P (PUBLISH) — direct-entry paths

Full procedural detail → references/intent-routing.md. Direct-entry counterparts to in-session Step 8 (edit) / Step 9 (publish) — a record identified directly, possibly from a prior session or another user (editing/publishing is NOT session-only). Load-bearing invariants:

  • Hard identifier gate — BEFORE any tool call. Target managedContentVariantId comes ONLY from (a) the session registry or (b) a user-typed identifier (MC…/20Y…/9Ps). Name-only, no ID, not in registry → STOP and ask via ask_user_tool ("Which record should I work with?" question, copied EXACTLY, answers ["Cancel"]). You may NOT locate the record yourself — no search_content, discovery/listing tool, SOQL, or guessed ID.
  • Resolve by prefix + validate before actingreferences/identifier-resolution.md (9Psget_content_variant; MC…/20Y…get_content). Read fails → STOP; never edit/publish blindly.
  • 0-U → Step 8c (after MANDATORY full-body display + edit-instructions prompt), closes via Step 7 dialog. 0-P → Step 9b, closes with publish confirmation and ends the turn (no Step 10 — no session context). Neither runs Steps 1–5.

Step 0-D: DELETE (hard stop)

Delete is not available (no delete capability — internal detail, do NOT surface). Print exactly and only this message, nothing else:

Deleting content isn't supported here. To delete this content, open it in Salesforce CMS and use the Delete option there.

Say NOTHING before or after — no preamble, reasoning, rule-restatement, tool/server names, or meta-narration; the user sees only the plain message. End the turn. Do NOT offer unpublish_content, SOQL, or CLI as a substitute — the CMS UI is the only path to surface.

Step 1: Understand Intent

Silent step — NEVER ask anything here. Extract agent-internally, then go straight to Step 2. No "Let me clarify…" turn, no ask_user_tool, no content-type menu — even a vague prompt (generate new content for Q4 launch) has everything Step 2 needs. About to dispatch a question in Step 1 (clarify, content-type menu, "type in mind?", "how many?")? That IS the bug — move to Step 2. Parse the message for:

  • Content domain (article, blog, news, FAQ, …) — inferred as-is; no domain named is fine.
  • Quantity — explicit count → that number; "multiple"/"several"/"a few"/"some" → agent chooses 4–5; no indicator → single.
  • Content-type reference — capture any token that looks like a content type name (exact FQN, single-underscore near-miss, bare developer name, natural-language name) verbatim. Do NOT classify here — Step 2 assigns the bucket.

Do not strip or rewrite the message — the original is the creative direction for Step 4 topic prompts and what Step 2a passes to the sibling verbatim as intent.

Multi-type gate — the ONE question Step 1 may raise. If the prompt spans ≥2 distinct content TYPES (each its own ContentTypeBundle, e.g. grooming packages AND service area coverage), you MUST ask the user to pick ONE before Step 2 (one type per run; two corrupts the delegation contract). Dispatch the Step 1 multi-type prompt VERBATIM (answers = distinct domains in the user's words + Cancel), carry ONLY the chosen domain forward as intent. SOLE exception to "never ask" — fires only on ≥2-distinct-types, never goal/mode/quantity. Multiple topics of ONE type (5 blog posts) do NOT trigger it (bulk). Rule + examples → references/content-type-classification.md § Multi-type gate.

Step 2: Resolve the Content Type

Classify Step 1's captured content-type reference into one of four buckets — full detection rules, examples, routing → references/content-type-classification.md. Summary:

  • Bucket 1 — Exact FQN. Matches ^[a-zA-Z_][a-zA-Z0-9_]*__[A-Za-z][A-Za-z0-9_]*$ (c__BlogPost). Capture contentTypeFqn, Step 3. Silent.
  • Bucket 2 — Auto-correctable near-miss. Single-underscore between known namespace and name (c_newsc__news). Auto-correct, announce in chat (no ask_user_tool), Step 3.
  • Bucket 3 — Low-confidence FQN-ish. Bare name (BlogPost→propose c__BlogPost) or unknown-namespace single-underscore. Dispatch the Step 2 FQN-correction prompt, route on the answer.
  • Invalid-FQN gate. Token meant as FQN (has __) but malformed, not a Bucket 2 near-miss (c__, __Foo, c__Blog Post, c__123) → do NOT delegate as free text; dispatch the FQN-correction prompt (Let me provide a different FQN/Cancel), restart Step 2 on the new string.
  • Bucket 4 — Natural language or no token (blog post). Delegate — Step 2a.

Fast-path invariants (Buckets 1/2/3): once the FQN is captured, do NOT verify it in the org, delegate, scan contentTypes/, dispatch metadata-grounding, retrieve, or read schema.json. A bad FQN fails deterministically as INVALID_TYPE at Step 5. On the delegated path the sibling owns scan, grounding, pick question, create-new + deploy, FQN construction, retrieve-and-reconcile.

2a–2d. Delegate to the sibling (Bucket 4 only)

Full protocol → references/delegation-protocol.md. In short: 2a resolve workspace FIRST (Step 3 → contentSpaceOrFolderId), print banner Resolving the content type for your request…, invoke via mcp__skill_bridge__load_skill("experience-cms-content-type-generate") (NOT built-in Skill — returns Unknown skill), pass { intent: "<user message verbatim>", suppressCreateContentPrompt: true, <scope> } (<scope> = spaceId 0Zu OR folderId 9Pu, exactly one, never baseType); no pre-delegation question. 2b — while the sibling runs this skill is PAUSED (no Step 4+ call until a terminal outcome; interleaving corrupts its state machine). Consume { status, fqn, message } (ignore any schema), route strictly on status:

status Action for this skill
success (fqn present) Print the sibling's message verbatim (carries type + deploy line); if empty, print Using content type \`.` Then Step 2c.
not_deployed (fqn present) STOP. Print message verbatim. Do NOT continue to Step 3 — create_cms_content fails INVALID_TYPE against a local-only bundle.
cancelled STOP silently. Print Session ended. and exit. Do NOT loop back into the sibling.
error STOP. Print message verbatim (carries reason + recovery hint). Do NOT retry or work around.
load failed (bridge Unknown skill/error — sibling never ran) STOP per references/delegation-protocol.md § 2b (terminal, NOT a fallback — no local scan, grounding, or workspace call). Retry once via search_skillsload_skill first.

2c (only on success) — verify fqn matches the FQN regex; missing/malformed → surface re-run message + ask_user_tool (Retry with an explicit FQN/Cancel); then capture contentTypeFqn, Step 3. 2d — never call metadata-grounding, sf project retrieve, re-present/re-pick, or build FQNs from folder names (sibling owns all of that); five drift signals → hard-stop to the load failed row; never downgrade not_deployed to success. On a manual space the 2a call is the Layer-2 confirmation — invalid/not-found → HARD STOP, re-ask via the invalid-ID template.

Step 3: Resolve the Workspace — Question 1

When Step 3 runs depends on how Step 2 resolved the type: fast-path (Buckets 1/2/3) → run it here, after Step 2. Delegation path (Bucket 4) → runs EARLY, first action of Step 2a before the sibling is dispatched, so contentSpaceOrFolderId scopes the sibling's discovery; do NOT re-run or re-ask after the sibling returns. Same resolution steps both cases.

Silently scan the local project for UIBundle directories, then present a single ask_user_tool question with all options. Full discovery + routing + validation → references/workspace-resolution.md. In short:

  • Discovery (silent): scan uiBundles/ under each sfdx-project.json package path (fallback: recursive), read each <name>.uibundle-meta.xml <masterLabel>{ developerName, masterLabel }. Zero → "no local UIBundles" variant. Never invent a workspace, run SOQL, or read ui-bundle.json.
  • Ask (single question): dispatch the "Step 3 — Workspace resolution" template from assets/questions.md via ask_user_tool (never plain text); copy question + answers VERBATIM, reword/rename/drop nothing. No-UIBundle variant is fixed copy — question: "Which content space or folder should I create the content in? Provide the ID (Content Space IDs start with 0Zu; Folder IDs start with 9Pu).", answers: ["Cancel"]. UIBundle-found, manual-ID, and invalid-ID variants → assets/questions.md.
  • UIBundle pickget_or_create_cms_workspace_and_web_app_channel(developerName, masterLabel); returned spaceId = contentSpaceOrFolderId; record workspaceMethod=uibundle + channelId; persist channelId to uiBundles/<developerName>/public/content-metadata.json (merge). Tool failure → retry prompt.
  • Manual ID → record workspaceMethod=manual (no channelId → Step 10 render hidden); manual-ID prompt with "Go back". Validate (prefix+length necessary NOT sufficient): L1 0ZuspaceId / 9PufolderId, 15/18 alphanumeric. L2 on FIRST call touching the space (delegation: get_content_types_for_workspace; fast-path: create_cms_content) — invalid/not-found → STOP, surface verbatim, re-ask via invalid-ID template. No org picker.

Step 4: Build the Create-Content Payload

HARD ENTRY GATE — contentTypeFqn MUST come from Step 2 (Bucket 1/2/3 fast-path capture OR status: success sibling outcome). Not run Step 2 (and delegated on Bucket 4)? STOP, back to Step 2. Never invent, guess, or default a type — picking sfdc_cms__news or any base/standard type without Step 2 is a regression. No FQN → Bucket 4 → delegate FIRST. Front-loading the create tool via ToolSearch before Step 2 is the same bug.

Goal passes as prompt; server generates + validates the body. Agent only shapes the payload and generates a title. Inputs: contentType = Step 2 contentTypeFqn; contentSpaceOrFolderId = Step 3; prompt = [USER GOAL] (message verbatim for single, or Step 4.B.2-approved topic prompt for bulk). Title stays agent-side — concise, on-topic, customer-facing, reflecting [USER GOAL].

  • Single (quantity = 1): assets/payloads/create-content-single.json. Required: contentType, contentSpaceOrFolderId, title, prompt (verbatim). Optional (urlName, contentKey, externalId, apiName) only when the user named them. Never include contentBody — mutually exclusive with prompt.
  • Bulk (quantity > 1): generate N distinct topic prompts, present for approval (two-part: markdown list + ask_user_tool), then build N independent 1-element payloads (shared contentType/contentSpaceOrFolderId; per-item title + prompt). Never combine into one inputs array — one call per item. Flow → references/bulk-batching.md.

Full schema → references/content-write-tool.md; payload walkthrough → examples/create-content-call.md.

Step 5: Execute the Create Call

Dispatch create_cms_content with the Step 4 payload; the server generates + validates and returns the record. Complex types can be slower.

Bulk Content

5a. Pre-dispatch confirmation (blanket approval) — one confirmation for all items (prevents per-call prompts). Print chat Ready to create all **<N>** content items in your org. Proceed?, dispatch the Step 5a approval prompt. Yes, create all → 5b; Cancel → end session.

5b. Dispatch N parallel single-item calls per references/bulk-batching.md: exactly N create_cms_content calls, each a 1-element inputs array, all fanned out in one turn. Partial failure → register successes, surface failures (topic + error), dispatch retry prompt (retry re-dispatches failed items as fresh parallel calls). Total failure → apply "Bulk total-failure retry guards" in references/error-recovery.md first (bulk total-failure branch only).

Step 6: Display Content Body and Summary

On success, print the summary + content-body tables from assets/display-formats.md (real markdown, every field; same for create/edit). NEVER collapse to one-line title · status · id — summary table MUST carry Content Key + Managed Content ID (omit only fields the response lacks). On failure, use references/error-recovery.md; surface the error verbatim, ask via ask_user_tool: Retry / Refine goal and retry / CancelEXCEPT type-class-unsupported (sfdc_cms__media / image / video), a hard stop (Principle 15): print ONLY this fixed copy verbatim (no preamble/rewording), then end turn: Content generation isn't supported for content type \` (type class: ``). This skill can't author that type class. To create or edit this content, use the Salesforce CMS UI directly.` Server owns validation.

Step 7: Post-Action Loop

After displaying the content body (create or edit), dispatch the Step 7 prompt from assets/questions.md (single or bulk variant by quantity). Route:

  • Edit content → Step 8
  • Publish content / Publish all → Step 9 with all variant IDs
  • Publish subset → ask which items by number via the publish-subset template in assets/questions.md, then Step 9 with selected variant IDs
  • End session → print one line: Session ended. Content saved as draft. and exit.

Steps 8, 9, 10: Edit / Publish / Post-Publish

Full procedural detail → references/edit-publish-workflow.md. All three MCP-only — no SOQL, no CLI (read via content-readonly, write via content-write). Load-bearing summary:

  • Step 8 — Edit (update_cms_content_variant). 8a scope (single, or Step 8a prompt for bulk) → 8b edit-instructions prompt (verbatim, applies to all selected) → 8c payload (variantId from item's latest response OR the Step 0-U ID; prompt verbatim; re-emit title ONLY on rename) → 8d dispatch (bulk = N parallel) → 8e back to Step 6, display full updated body, every field (NOT a diff table; re-fetch via get_content_variant if the response lacks it), then Step 7. Failures → Retry / Refine edit instruction and retry / Cancel; bulk total-failure → error-recovery guards.
  • Step 9 — Publish (publish_content via variantIds). 9a scope (all / subset / default all) → 9b dispatch (in-session IDs, or the Step 0-P validated ID — direct-entry ends the turn after confirmation, no Step 10) → 9c on success flip each published item's registry publishStatus draft→published (hard — Step 10 filters on it), print the assets/display-formats.md publish confirmation VERBATIM (Content published successfully. + Title/Managed Content ID/Variant ID) — NOT reworded Content is live/deployment-id prose, then Step 10. Partial/total-failure → error-recovery guards + retry prompt.
  • Step 10 — Post-Publish. Dispatch the Step 10 prompt; options depend on workspaceMethod (uibundle includes render, manual hides it). In-session publish ALWAYS dispatches this for BOTH methods — skipping to Session ended. is a regression. Create more content → restart FULL flow at Step 1 (silent — no "what next?" ask, wait for user's next message) → Step 2 → Step 3; do NOT reuse this run's workspace. Render… → hand off to experience-cms-content-render with channelId, contentKeys (ONLY publishStatus=published), contentTypeFqn, uiBundleDeveloperName, uiBundleMasterLabel; zero published → print the "no published items" line + re-dispatch. End sessionSession ended.

Error Handling

references/error-recovery.md — full error-signal → response mapping: create_cms_content / update_cms_content_variant / publish_content server-side failures, bulk partial failures, sibling terminal states, out-of-scope requests.

Cross-Skill Integration

  • Discover / define a ContentTypeBundle (Step 2 delegation path only, not fast-path) → experience-cms-content-type-generate (payload + status routing in Step 2a–2d).
  • Render published content to a UIBundle (Step 10) → experience-cms-content-render (handoff params + workspaceMethod=uibundle gate in Step 10).

Key Principles

Full text of all 15 → references/principles.md (canonical index; each is ALSO enforced inline in its Step body above): (1) workflow in order, (2) dispatch is the work, (3) server-side generation only, (4) user goal verbatim, (5) sibling owns type on delegation, (6) workspace from user/UIBundle — never infer/SOQL, (7) cancel terminates, (8) consistent display, (9) session registry + stable variant ID, (10) post-action loop, (11) bulk = one call per item parallel, (12) publish defaults to all, (13) route intent FIRST + identifier gate, (14) no-drift STOP, (15) type-class-unsupported hard stop. Identifiers → references/identifier-resolution.md.

Related Skills

  • SkillSkill
    Salesforce
    Experience CMS Content Type Generate

    Salesforce

    Salesforce CMS ContentTypeBundle creation skill. Use this skill ANY TIME a user request involves creating a ContentTypeBundle, and activate FIRST when CMS ContentTypeBundle creation is mentioned. Discovers existing types via metadata-grounding and produce