diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 558d0a6..4b9ad31 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -8,7 +8,7 @@ "name": "contentstack-skills", "source": "./", "description": "Contentstack agent skills for CMS modeling, Delivery SDK, Live Preview, Studio, Brand Kit, Developer Hub apps, Launch, and migrations.", - "version": "0.3.1", + "version": "0.4.1", "category": "development", "tags": ["contentstack", "cms", "headless-cms", "studio"] } diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 6ed7772..c122246 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "contentstack-skills", - "version": "0.3.1", + "version": "0.4.1", "description": "Contentstack agent skills for CMS modeling, Delivery SDK, Live Preview, Studio, Brand Kit, Developer Hub apps, Launch, and migrations.", "author": { "name": "Contentstack", "url": "https://www.contentstack.com" }, "homepage": "https://developers.contentstack.com", diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index 9302242..a0a24d2 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "contentstack-skills", - "version": "0.3.1", + "version": "0.4.1", "description": "Contentstack agent skills for CMS modeling, Delivery SDK, Live Preview, Studio, Brand Kit, Developer Hub apps, Launch, and migrations.", "author": { "name": "Contentstack", "url": "https://www.contentstack.com" }, "skills": "./skills/", diff --git a/.github/workflows/routing-evals.yml b/.github/workflows/routing-evals.yml new file mode 100644 index 0000000..8b481a2 --- /dev/null +++ b/.github/workflows/routing-evals.yml @@ -0,0 +1,46 @@ +name: Routing evals + +# Checks that each prompt in evals/ loads the right skill. Each run is a real Claude session +# (about $0.10-0.15), so this runs once per case on PRs that touch skills or evals. +on: + pull_request: + paths: ["skills/**", "evals/**"] + workflow_dispatch: + inputs: + runs: + description: Runs per case + default: "3" + +permissions: + contents: read + +jobs: + routing: + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + steps: + - name: Skip without an API key + if: env.ANTHROPIC_API_KEY == '' + run: echo "::notice::ANTHROPIC_API_KEY is not set (forks and Dependabot PRs), so routing evals were skipped." + - uses: actions/checkout@v4 + if: env.ANTHROPIC_API_KEY != '' + - uses: actions/setup-node@v4 + if: env.ANTHROPIC_API_KEY != '' + with: + node-version: 22 + - name: Install Claude Code + if: env.ANTHROPIC_API_KEY != '' + run: npm install -g @anthropic-ai/claude-code + - name: Run routing evals + if: env.ANTHROPIC_API_KEY != '' + run: >- + claude plugin eval . --tag routing --ablation none + --runs ${{ inputs.runs || '1' }} -j 6 --max-cost-usd 40 + --trust-plugin --no-publish --json evals/results/routing.json + - uses: actions/upload-artifact@v4 + if: always() && env.ANTHROPIC_API_KEY != '' + with: + name: routing-evals + path: evals/results/ diff --git a/.gitignore b/.gitignore index 20febc2..900fa84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store .obsidian +evals/results/ diff --git a/CHANGELOG.md b/CHANGELOG.md index c84c559..7b334f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,59 @@ All notable changes to the Contentstack agent skills bundle. Versions match the `version` field in every plugin manifest that declares one. -## 0.3.1 +## 0.4.1 + +### New skills + +- `personalize`: experiences, audiences, attributes and events, the Personalize Edge SDK and Edge API, the Management API, and edge middleware that resolves variants before rendering. +- `lytics`: the Lytics JavaScript tag, identity resolution, schema, audiences and the Segment API, consent and deletion, and sending audiences to Personalize. +- `launch-platform`: hosting on Launch, covering builds, Cloud and Edge Functions, `launch.json`, caching and revalidation, deploy hooks, domains, access control, log targets, monorepos and limits. +- `automations`: Contentstack Automate rules, triggers, connectors, control flow, custom code, executions and debugging. +- `dx-cli`: the `csdx` CLI for auth, export, import, seed, clone, bulk operations, migration scripts, branch merges and plugins. +- `dx-mcp-server`: connecting AI agents through the local `@contentstack/mcp` server or the hosted MCP Profile Hub, and when to use each. +- `cms-graphql`: the GraphQL Content Delivery API, covering endpoints, schema, references, modular blocks, JSON RTE, limits and Live Preview. +- `cms-json-rte`: rendering and serializing JSON Rich Text Editor content with `@contentstack/utils`, render options, embedded entries and assets, GraphQL, React, HTML↔JSON conversion and Live Preview tags. +- `marketplace-apps`: choosing, installing and configuring first-party Marketplace apps, app configuration vs field configuration, and reading app data on delivery. + +### One template, paired with MCP + +- **Every skill uses the same sections:** When to use, Before you answer, Instructions, MCP tools, Output, Security, References, Examples. `scripts/validate.mjs` now rejects missing, extra or out-of-order sections. The duplicated Description, User Problem, Success Criteria, Expected Inputs/Outputs, Workflow Summary, Tooling Notes and Product Context blocks are folded in, so the existing skills are about 770 lines shorter. See `docs/contributing/skill-template.md`. +- **Routing cues:** each skill's When to use ends with the neighbouring skills to use instead, and many descriptions gained a "For X, use Y." cue. +- **MCP tools in every skill:** each skill names the Contentstack MCP tools (from the local server's published definitions) that carry out its steps, or says that none exist and what to use instead. Skills stay advisory by default; they use write, publish, deploy or delete tools only when asked, after naming the target and getting confirmation. +- **Launch action skills** use the `launch` MCP tools (`update_an_environment`, `create_deployment`, `get_deployment_logs`) when they're connected. +- **`developer-hub-app-architect`:** links to its one coding reference instead of reference files that didn't exist. + +### Contributors + +- **Routing evals:** `evals/` holds 62 `claude plugin eval` cases, two or more per automatically invoked skill. Each checks that a prompt loads the right skill and, for close neighbours, doesn't load the wrong one. `.github/workflows/routing-evals.yml` runs them on PRs that touch `skills/` or `evals/` (needs an `ANTHROPIC_API_KEY` secret). See `docs/contributing/routing-evals.md`. + +### Accuracy pass against the product wiki and public docs + +- **`cms-webhooks`:** signature verification now uses `X-Contentstack-Request-Signature` (RSA-PSS SHA-256) or the opt-in `X-Contentstack-HMAC-Signature` over `{timestamp}.{body}`. Payload fields, workflow events, retry timing and branch scoping are corrected, and unverified limits are removed. +- **`cms-taxonomy`:** the CDA operators are now the documented `$in`, `$exists`, `$eq_below`, `$below`, `$eq_above` and `$above` (with `levels`), replacing operators that don't exist. Depth and plan limits are added. +- **`launch-sync-environment-variables-from-env-example`:** updates go through `PUT` with the full environment object (there is no PATCH), with regional hosts and auth. +- **`launch-trigger-and-monitor-launch-deployments`:** logs come from the deployment-logs endpoint, the status list is complete with `LIVE` as success, and rollback is added. +- **`brand-kit-assistant`:** + - Voice Profile dials are 1–4. + - Request headers are corrected. + - v2 kits (Documents) and the other Brand Kit surfaces are added. +- **`cms-branches-aliases`:** the branch limit is plan-dependent, module scoping follows the public docs, and compare and merge strategies are added. +- **Other CMS skills:** + - `cms-localization`: Unlocalize is documented. + - `cms-releases`: 25 items per request, plus Releases v2. + - `cms-roles-permissions`: permissions are a union of roles with no deny, and M2M apps are covered. + - `cms-workflows`: self-advancement prevention is a per-stage option. + - `cms-assets`: Assets DAM limits and routing are added. + - `cms-environments-publishing`: all CDA hosts and the rate-limit split are listed. + - `cms-tokens-authentication`: M2M apps and preview tokens are covered. +- **`cms-entries` and `cms-variants-personalization`:** both now have real instructions; before, they were empty. +- **`cms-data-modeling-best-practices`:** adds the limits to design around. +- **`developer-hub-app-architect`:** + - Adds the Content Type Sidebar and Global Full Page locations. + - Covers M2M apps, lifecycle webhooks and per-installation secrets. +- **`dx-delivery-sdk` and `dx-migrate-js-to-ts-sdk`:** the Security sections copied from Launch are replaced, and the package name is now `@contentstack/persistence-plugin`. +- **`asset-management`:** user-defined field types match the current docs. +- **Formatting:** instructions that were raw JSON are now prose, and the broken Product Context bullets are fixed. ### Contentstack MCP server bundled with the plugin diff --git a/README.md b/README.md index c0a95b1..6b6cd46 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Contentstack Skills -A bundle of ready-to-use [Contentstack](https://www.contentstack.com) agent skills for AI coding tools, covering CMS implementation, Brand Kit guidance, delivery SDK development, kickstart maintenance, migration workflows, Developer Hub app architecture, Launch automation, and Contentstack Studio. +A bundle of ready-to-use [Contentstack](https://www.contentstack.com) agent skills for AI coding tools, covering CMS implementation, GraphQL delivery, Brand Kit guidance, delivery SDK development, the CLI and MCP servers, kickstart maintenance, migration workflows, Developer Hub app architecture, Marketplace apps, JSON RTE rendering, Launch hosting and automation, Personalize, Lytics, Automate, and Contentstack Studio. ## What's in here? @@ -71,12 +71,15 @@ If you only want the skills, disable the `contentstack` MCP server in your tool' | Slug | Title | Product | What it helps with | | --- | --- | --- | --- | | `asset-management` | Asset Management | Assets | Assets DAM spaces and workspaces, folders, asset types and metadata, localization, saved views, AI tagging and alt text, duplicate management, versions, trash and restore, visual markups, and CMS integration. | +| `automations` | Automations | Automate | Contentstack Automate workflows: triggers, connectors and connected apps, If-Else and loops, custom code, HTTP responses, executions and debugging, limits, and agent integration. | | `brand-kit-assistant` | Brand Kit Assistant | Brand Kit | Brand Kit concepts, setup, governance, Voice Profiles, Knowledge Vault, on-brand AI generation, and API-task routing. | | `cms-assets` | Contentstack Assets | CMS | Asset organization, image transformations, publishing lifecycle, CDN behavior, and asset limits. | | `cms-branches-aliases` | Branches & Aliases | CMS | Isolated content development, alias-based deployments, CI/CD integration, merge behavior, and rollback patterns. | | `cms-data-modeling-best-practices` | Contentstack Data Modeling Best Practices | CMS | Content type design, references, global fields, groups, modular blocks, JSON RTE, taxonomy, tags, and model simplification. | | `cms-entries` | Entries | CMS | Entry querying, localization, versioning, publishing, CDA usage, reference expansion, pagination, bulk operations, and Sync API patterns. | | `cms-environments-publishing` | Contentstack Environments & Publishing | CMS | Environment setup, publishing behavior, delivery and preview tokens, Sync API usage, CDN behavior, and publish queues. | +| `cms-graphql` | GraphQL Content Delivery | CMS | GraphQL Content Delivery API endpoints and headers, generated schema, reference connections, modular blocks, JSON RTE, pagination, query and rate limits, and Live Preview with GraphQL. | +| `cms-json-rte` | JSON Rich Text Editor | CMS | Rendering and serializing JSON RTE content with `@contentstack/utils`, custom render options, embedded entries and assets, HTML↔JSON conversion, and Live Preview tags. | | `cms-live-preview-visual-editor-support-assistant` | Live Preview and Visual Editor Support Assistant | Developer Experience | Live Preview, Visual Editor (Visual Builder) and Timeline setup or debugging: Onboarding Check, rendering-mode contracts (CSR, SSR, SSG, GraphQL), edit tags, FAQ-backed fixes, and Support handover. | | `cms-localization` | Contentstack Localization | CMS | Language setup, fallback chains, localized and unlocalized entries, non-localizable fields, and multi-locale publishing. | | `cms-releases` | Releases | CMS | Coordinated content deployment, release scheduling, staged deployment, webhook storm prevention, and CI/CD integration. | @@ -87,12 +90,18 @@ If you only want the skills, disable the `contentstack` MCP server in your tool' | `cms-webhooks` | Contentstack Webhooks | CMS | Webhook configuration, event channels, payload handling, signature verification, retries, and reliable receiver design. | | `cms-workflows` | Workflows & Publish Rules | CMS | Workflow stages, approval flows, transition restrictions, publish governance, automation hooks, and common pitfalls. | | `developer-hub-app-architect` | Developer Hub App Architect | Developer Hub | Developer Hub and Marketplace app planning, UI location choices, React/TypeScript scaffolding, setup, SDK, manifest, proxy, and publishing issues. | +| `marketplace-apps` | Marketplace Apps | Developer Hub | Choosing, installing and configuring first-party Marketplace apps (DAM, commerce, search, translation and more), and reading their field data on delivery. | +| `dx-cli` | Contentstack CLI | Developer Experience | The `csdx` CLI: region and login, token aliases, export, import, seed and clone, bulk operations, migration scripts, branch diff and merge, and plugins such as tsgen, apps and Launch. | | `dx-delivery-sdk` | Delivery SDK | Developer Experience | Production-ready TypeScript with `@contentstack/delivery-sdk` for entries, assets, references, filters, sorting, pagination, locales, Live Preview, and Visual Builder. | | `dx-kickstart-next` | Contentstack Kickstart Next | Developer Experience | Maintaining Contentstack's Next.js kickstart: App Router structure, Delivery SDK setup, Live Preview, seeded stack alignment, env vars, validation, and PR reviews. | +| `dx-mcp-server` | Contentstack MCP | Developer Experience | Connecting AI agents with the local `@contentstack/mcp` server or the hosted MCP Profile Hub: choosing, client setup, auth, tool groups and profiles, and least-privilege safety. | | `dx-migrate-js-to-ts-sdk` | Migrate JS to TS SDK | Developer Experience | Migration from the JavaScript Contentstack SDK to the TypeScript Delivery SDK, including API mapping, rewrites, and unsupported pattern callouts. | -| `launch-sync-environment-variables-from-env-example` | Sync Launch environment variables from .env.example | Launch | Comparing a local `.env.example` with Launch environment variables and patching missing keys without printing secrets. | +| `launch-platform` | Launch Platform | Launch | Hosting on Launch: frameworks and builds, Cloud and Edge Functions, launch.json routing, caching and revalidation, deploy hooks, domains, access control, log targets, monorepos, and limits. | +| `launch-sync-environment-variables-from-env-example` | Sync Launch environment variables from .env.example | Launch | Comparing a local `.env.example` with Launch environment variables and adding missing keys with a full-object update, without printing secrets. | | `launch-trigger-and-monitor-launch-deployments` | Trigger and Monitor Launch Deployments | Launch | Triggering Launch deployments, polling deployment status, retrieving failure logs, and summarizing likely causes and next steps. | +| `lytics` | Lytics | Lytics (Data & Insights) | Lytics projects, the JavaScript tag, identity resolution, schema and LQL, audiences and the Segment API, content affinity, consent and deletion, and connecting audiences to Personalize. | | `migration-companion` | Contentstack Migration Companion | Developer Experience | Guided Contentful-to-Contentstack migration workflow covering prerequisites, content migration, code migration, bundled validation scripts, and completion reporting. | +| `personalize` | Personalize | Personalize | Experiences, audiences, attributes, impressions and conversions, the Personalize Edge SDK and Edge API, Management API, and edge middleware patterns that resolve variants before rendering. | | `studio` | Studio (preview) | Studio | Contentstack Studio end to end: SDK install, project provisioning, component registration, sections and templates, data binding, canvas and preview routes, verification, and troubleshooting. A router skill that loads one of 111 bundled specialist files per task. | ## How it works diff --git a/docs/README.md b/docs/README.md index 3a85c43..19d0305 100644 --- a/docs/README.md +++ b/docs/README.md @@ -43,6 +43,8 @@ Every skill is written once in the open [Agent Skills](https://agentskills.io) f ### Contributing - [Add or edit a skill](contributing/add-or-edit-a-skill.md) +- [Skill template](contributing/skill-template.md) +- [Routing evals](contributing/routing-evals.md) - [Authoring conventions](contributing/authoring-conventions.md) - [Release & versioning](contributing/release-and-versioning.md) @@ -50,8 +52,8 @@ Every skill is written once in the open [Agent Skills](https://agentskills.io) f | | | | ------------------------ | -------------------------------------------------------------------------------------------------------------- | -| **Skills included** | 24 (see the [skill reference](skills/index.md)) | -| **Products covered** | CMS, Assets, Developer Experience, Studio, Launch, Brand Kit, Developer Hub | +| **Skills included** | 33 (see the [skill reference](skills/index.md)) | +| **Products covered** | CMS, Assets, Developer Experience, Studio, Launch, Brand Kit, Developer Hub, Marketplace, Personalize, Lytics, Automate | | **Supported tools** | Claude Code, claude.ai / Cowork, Cursor, Codex, GitHub Copilot, Gemini CLI, `skills` CLI | | **Source of truth** | `skills//SKILL.md` | | **Repository** | [github.com/contentstack/contentstack-agent-skills](https://github.com/contentstack/contentstack-agent-skills) | diff --git a/docs/contributing/add-or-edit-a-skill.md b/docs/contributing/add-or-edit-a-skill.md index 0fa76e5..f76f90c 100644 --- a/docs/contributing/add-or-edit-a-skill.md +++ b/docs/contributing/add-or-edit-a-skill.md @@ -21,11 +21,12 @@ node scripts/validate.mjs ## Add a new skill 1. Create a directory: `skills//`. -2. Add `SKILL.md` following the structure in [Anatomy of a SKILL.md](../how-it-works/skill-anatomy.md) and the rules in [Authoring conventions](authoring-conventions.md). The `name` must equal ``, and the `description` must include "Use when…" (1024 characters max). +2. Copy the [skill template](skill-template.md) into `SKILL.md` and follow the rules in [Authoring conventions](authoring-conventions.md). List the Contentstack MCP tools that carry out the skill's steps under `## MCP tools`. The `name` must equal ``, and the `description` must include "Use when…" (1024 characters max). 3. Add any `references/` or `scripts/` the skill needs. 4. Add a row for the skill to the **Skills included** table in the root `README.md`. 5. Add a documentation page under `docs/skills/.md` and link it from `docs/skills/index.md`. -6. Run `node scripts/validate.mjs` and commit. +6. Add at least two [routing eval](routing-evals.md) cases, `evals/routing--1` and `-2`, and run them. +7. Run `node scripts/validate.mjs` and commit. The plugin manifests point at the whole `skills/` folder, so a new skill needs no manifest change. @@ -48,6 +49,7 @@ Use lowercase letters, digits, and single hyphens, max 64 characters. - `name` is missing, doesn't match the folder, or breaks the naming rules. - `description` is missing, lacks "Use when…", or is over 1024 characters. +- `SKILL.md` has a `##` section outside the [template](skill-template.md), misses one of the required sections (When to use, Instructions, MCP tools, Security), or has them out of order. - `SKILL.md` has no `## Security` section, or it lacks `### Defaults`, `### Destructive Actions`, `### Secrets` or `### Environment Variables`. - A relative link in any markdown file under `skills/` doesn't resolve or points outside the skill's folder (code blocks are ignored). - A frontmatter value in `skills/` or `docs/` contains `: ` without quotes. @@ -57,8 +59,12 @@ Use lowercase letters, digits, and single hyphens, max 64 characters. The GitHub Action in `.github/workflows/validate.yml` runs the validator on pull requests to any branch, on pushes to `main` and `next`, and manually (workflow dispatch). If it fails, run `node scripts/validate.mjs` locally, fix what it reports, and push again. +`.github/workflows/routing-evals.yml` runs the [routing evals](routing-evals.md) on pull requests that change `skills/` or `evals/`. + ## Related +- [Skill template](skill-template.md) +- [Routing evals](routing-evals.md) - [Authoring conventions](authoring-conventions.md) - [Anatomy of a SKILL.md](../how-it-works/skill-anatomy.md) - [Release & versioning](release-and-versioning.md) diff --git a/docs/contributing/authoring-conventions.md b/docs/contributing/authoring-conventions.md index 6c62292..84dc71e 100644 --- a/docs/contributing/authoring-conventions.md +++ b/docs/contributing/authoring-conventions.md @@ -9,9 +9,7 @@ These conventions keep skills consistent, parseable by agents, and safe. Follow ## Structure -Follow the section outline described in [Anatomy of a SKILL.md](../how-it-works/skill-anatomy.md): Description, When to Use, User Problem, Success Criteria, Expected Inputs/Outputs, Example User Requests, Workflow Summary, Instructions, Output Format, Tooling Notes, Security, Product Context, References, Examples. - -Not every skill needs every section, but keep the order consistent so agents (and readers of the docs) find things in predictable places. +Use the [skill template](skill-template.md): When to use, Before you answer, Instructions, MCP tools, Output, Security, References, Examples. When to use, Instructions, MCP tools and Security are required, and `scripts/validate.mjs` rejects other sections or a different order. Put subtopics under `###` headings inside Instructions. ## Frontmatter @@ -23,7 +21,7 @@ Not every skill needs every section, but keep the order consistent so agents (an ## Write the description as the trigger -Agents choose a skill by matching your request against its description (see [How skill selection works](../how-it-works/router.md)). Make the "Use when…" clause list the concrete requests, tools, and terms a user would mention: "Delivery SDK", "Live Preview", "pagination", not "helps with content". Keep the **When to Use** section in the body consistent with it, and avoid overlap with neighboring skills' descriptions. +Agents choose a skill by matching your request against its description (see [How skill selection works](../how-it-works/router.md)). Make the "Use when…" clause list the concrete requests, tools, and terms a user would mention: "Delivery SDK", "Live Preview", "pagination", not "helps with content". Keep the **When to use** section consistent with it, avoid overlap with neighboring skills' descriptions, and add a "For X, use Y." cue where two skills sit close together. The [routing evals](routing-evals.md) test this. ## Security is mandatory @@ -38,7 +36,7 @@ Inherit the product's shared safety rules (see [Security & safety model](../how- ## Default to read-only -Unless a skill genuinely needs to perform an external action, make it advisory and read-only. If it does perform actions, gate every destructive or production-facing step behind explicit confirmation, and prefer dry-run defaults. +Unless a skill genuinely needs to perform an external action, make it advisory. List the MCP tools that would carry out its steps under **MCP tools**, so an agent with the Contentstack MCP server connected can act when the user asks. Whenever a skill or its tools perform actions, gate every destructive or production-facing step behind explicit confirmation, and prefer dry-run defaults. ## References, not assumptions diff --git a/docs/contributing/routing-evals.md b/docs/contributing/routing-evals.md new file mode 100644 index 0000000..d124faa --- /dev/null +++ b/docs/contributing/routing-evals.md @@ -0,0 +1,52 @@ +--- +title: Routing evals +description: "How the evals/ suite checks that each prompt loads the right skill, and how to run and extend it." +--- + +# Routing evals + +A skill only helps if the agent loads it. With more than 30 skills, descriptions compete with each other, and a vague one quietly sends questions to the wrong skill. The `evals/` folder holds prompts that must load a given skill, run with `claude plugin eval` (Claude Code 2.1 or later). + +## How a case works + +Each case is a folder named `routing--`: + +``` +evals/routing-cms-assets-1/ +├── prompt.md # the user's question +└── graders/ + ├── loads-cms-assets.md # passes when the agent calls Skill with cms-assets + └── skips-asset-management.md # passes when it doesn't load the neighbour +``` + +`prompt.md` has the case `name`, `tags: [routing, ]`, and low `max_turns` and `timeout_seconds`, because the routing decision happens on the first turn. The graders are `tool_used` checks on the `Skill` tool. A `skips-` grader (`min: 0`, `max: 0`) guards against a neighbouring skill that covers similar ground, such as `cms-assets` and `asset-management`, or `personalize` and `cms-variants-personalization`. + +Every skill that agents can pick automatically has at least two cases. The two Launch action skills have none, because `disable-model-invocation: true` means they only run when invoked by name. + +## Run them + +```bash +# One skill +claude plugin eval . --ablation none --case 'routing-cms-taxonomy-*' --runs 1 --trust-plugin --no-publish + +# Everything, three runs per case +claude plugin eval . --tag routing --ablation none --runs 3 -j 6 --trust-plugin --no-publish +``` + +- `--ablation none` is required. The default also runs a baseline without the plugin, which doubles the cost, and it doesn't score `Skill` graders. +- Each run is a real Claude session and costs roughly $0.10–0.15, so the full suite is a few dollars per run per case. +- Results go to `evals/results/` (gitignored), with an HTML report. + +In CI, `.github/workflows/routing-evals.yml` runs every case once on pull requests that change `skills/` or `evals/`, and three times when started by hand. It needs an `ANTHROPIC_API_KEY` repository secret and skips itself without one. + +## When a case fails + +A failing case usually means a description lost a routing cue or a neighbour's description grew to cover the same request. Fix the descriptions, not the prompt: + +- Put the terms users actually say in the `description`. +- Add a "For X, use Y." cue to the skill that wins wrongly. +- Rerun just that skill's cases with `--case`. + +## Add cases + +When you add a skill, add at least two `routing--` folders: one plain request, and one phrased close to a neighbouring skill with a `skips-` grader. Write prompts the way users ask, not in the description's words. diff --git a/docs/contributing/skill-template.md b/docs/contributing/skill-template.md new file mode 100644 index 0000000..054575b --- /dev/null +++ b/docs/contributing/skill-template.md @@ -0,0 +1,105 @@ +--- +title: Skill template +description: "The section outline every SKILL.md follows, with a copyable template. scripts/validate.mjs enforces it." +--- + +# Skill template + +Every `skills//SKILL.md` uses the same sections in the same order. `node scripts/validate.mjs` fails a skill that has a section outside this list, misses a required one, or puts them out of order. + +| Section | Required | What goes in it | +| --- | --- | --- | +| `## When to use` | Yes | The requests the skill handles, then **Use another skill for:** with the neighbouring skills and what they own. | +| `## Before you answer` | No | What to find out or inspect first: IDs, framework, region, the user's goal. | +| `## Instructions` | Yes | A short numbered workflow, then `###` subsections with the rules and facts. Long or volatile detail goes in `references/`. | +| `## MCP tools` | Yes | Which Contentstack MCP tools carry out the steps, grouped as inspect, change and delete, with the local server group in brackets. If no tool covers the area, say so and name the API, CLI or UI to use instead. | +| `## Output` | No | How to shape the answer. | +| `## Security` | Yes | `### Defaults`, `### Destructive Actions`, `### Secrets`, `### Environment Variables`. | +| `## References` | No | Bundled `references/` files and public docs URLs. | +| `## Examples` | No | Worked User → Assistant pairs, mostly for refusals and confirmation gates. | + +Keep the rest out of the body: + +- **Don't restate the description.** The frontmatter `description` does the routing; the body starts with a one- or two-sentence scope statement under the title. +- **Example prompts belong in [routing evals](routing-evals.md)**, where they're tested, not in the skill. +- **Product context and safety rules go in Security.** Don't repeat a separate product block. + +## MCP pairing + +The skills are advisory by default: they explain and show code. When the Contentstack MCP server (the local `@contentstack/mcp` server or MCP Profile Hub) is connected and the user asks for the change, the agent can make it with the tools listed under `## MCP tools`. The rules: + +- Read tools can run freely to ground an answer in the user's real stack. +- Before any create, update, publish, deploy or delete, the agent names the target (stack, branch, environment, entries) and waits for confirmation. +- Tool names are the local server's, from `https://mcp.contentstack.com//tools`. Profile Hub profiles expose a chosen subset, so the agent uses what its client lists. + +`allowed-tools` in the frontmatter pre-approves tools; it doesn't block MCP tools, which still follow the client's permission settings. + +## Template + +````markdown +--- +name: +description: ". Use when . For , use ." +allowed-tools: Read Grep Glob +--- + +# + +<One or two sentences: what this skill covers.> + +## When to use + +- <Request the skill handles> +- <Request the skill handles> + +Use another skill for: + +- <Topic> → `<other-skill>` + +## Before you answer + +<What to ask or inspect first.> + +## Instructions + +1. <Step> +2. <Step> + +### <Rule group> + +<Rules and facts.> + +## MCP tools + +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): + +- Inspect: `<tool>` (`<group>`) +- Change: `<tool>` (`<group>`) +- Delete: `<tool>` (`<group>`) + +## Output + +<How to shape the answer.> + +## Security + +### Defaults + +- Advisory by default. Use the MCP tools above only when the user asks for the change. + +### Destructive Actions + +<What needs confirmation, and what to say before asking.> + +### Secrets + +Never print, echo or store tokens, API keys or secrets. Use placeholders. + +### Environment Variables + +<Variable names to use in examples.> + +## References + +- <Public docs URL> +```` diff --git a/docs/how-it-works/router.md b/docs/how-it-works/router.md index 04ea0b0..0a174f1 100644 --- a/docs/how-it-works/router.md +++ b/docs/how-it-works/router.md @@ -41,6 +41,8 @@ Each description's "Use when…" clause lists the requests that should load it. | Designing or refactoring content models | [Data Modeling Best Practices](../skills/cms-data-modeling-best-practices.md) | | Setting up or debugging Live Preview, Visual Editor (Visual Builder) or Timeline | [Live Preview & Visual Editor Support](../skills/cms-live-preview-visual-editor-support-assistant.md) | | Fetching entries, CDA queries, pagination, bulk ops | [Entries](../skills/cms-entries.md) | +| GraphQL queries, schema, references and limits | [GraphQL Content Delivery](../skills/cms-graphql.md) | +| Rendering JSON Rich Text Editor content, embedded entries, HTML conversion | [JSON Rich Text Editor](../skills/cms-json-rte.md) | | Uploading, transforming, delivering assets in a stack | [Assets](../skills/cms-assets.md) | | Assets DAM: spaces, workspaces, duplicate sets, saved views, visual markups | [Asset Management](../skills/asset-management.md) | | Classifying content, category hierarchies | [Taxonomy](../skills/cms-taxonomy.md) | @@ -54,10 +56,17 @@ Each description's "Use when…" clause lists the requests that should load it. | Webhooks, event channels, payloads, signatures | [Webhooks](../skills/cms-webhooks.md) | | Matching a Launch env to `.env.example` | [Sync Launch env vars](../skills/launch-sync-environment-variables-from-env-example.md) | | Triggering and monitoring Launch deployments | [Trigger & Monitor Deployments](../skills/launch-trigger-and-monitor-launch-deployments.md) | -| Personalization, A/B testing, audience segmentation, variants | [Variants & Personalization](../skills/cms-variants-personalization.md) | +| Entry variants and variant groups in the CMS | [Variants & Personalization](../skills/cms-variants-personalization.md) | | Building a Developer Hub or Marketplace app | [Developer Hub App Architect](../skills/developer-hub-app-architect.md) | - -The exact wording lives in each skill's frontmatter. See the [skills reference](../skills/index.md). +| Choosing or configuring a first-party Marketplace app (DAM, commerce, search, translation) | [Marketplace Apps](../skills/marketplace-apps.md) | +| Hosting on Launch: builds, functions, `launch.json`, caching, domains | [Launch Platform](../skills/launch-platform.md) | +| Personalize experiences, audiences, events, Edge SDK | [Personalize](../skills/personalize.md) | +| Lytics tag, identity, audiences, consent | [Lytics](../skills/lytics.md) | +| Automate rules, triggers, connectors, executions | [Automations](../skills/automations.md) | +| The `csdx` CLI: export, import, seed, bulk publish, migrations | [Contentstack CLI](../skills/dx-cli.md) | +| Connecting an AI agent to Contentstack over MCP | [Contentstack MCP](../skills/dx-mcp-server.md) | + +The exact wording lives in each skill's frontmatter. See the [skills reference](../skills/index.md). The [routing evals](../contributing/routing-evals.md) check that sample prompts load the skill this table promises. ## Skills that only run on request diff --git a/docs/how-it-works/skill-anatomy.md b/docs/how-it-works/skill-anatomy.md index 38f415d..d950362 100644 --- a/docs/how-it-works/skill-anatomy.md +++ b/docs/how-it-works/skill-anatomy.md @@ -34,34 +34,24 @@ Every tool installs the file unchanged, frontmatter included. See [How skill sel ## Body sections -The Markdown body follows a repeatable outline. Not every skill uses every section, but most include: +Every skill uses the same sections in the same order, and `scripts/validate.mjs` enforces it. The full template is in [Skill template](../contributing/skill-template.md). -| Section | What it captures | -| --- | --- | -| **Description** | What the skill does. | -| **When to Use** | The user intents that should activate it, expanding on the description's "Use when…". | -| **User Problem** | The underlying need the skill addresses. | -| **Success Criteria** | What a correct answer looks like. | -| **Expected Inputs** | What the agent should gather (UIDs, locale, framework, etc.). | -| **Expected Outputs** | The deliverables (code, recommendations, checklists). | -| **Example User Requests** | Representative prompts the skill handles. | -| **Workflow Summary** | The step-by-step approach. | -| **Instructions** | The detailed rules and decision logic: the core of the skill. | -| **Output Format** | How answers should be shaped. | -| **Tooling Notes** | Which tools/SDKs to prefer; read-only vs action behavior. | -| **Security** | Defaults, destructive-action gating, secret handling, env vars. | -| **Product Context** | The product area and its shared safety rules. | -| **References** | Bundled `references/` files to read on demand. | -| **Examples** | Few-shot user/assistant pairs that calibrate behavior. | - -## Instructions: two styles - -The **Instructions** section appears in two forms across the bundle: - -- **Prose with subheadings**: narrative rules grouped under headings (e.g. Delivery SDK, Webhooks). -- **Structured JSON blocks**: an array of `{ "heading", "content" }` objects (e.g. Assets, Branches & Aliases, Environments & Publishing, Localization). These render as discrete rule cards. - -Both are valid; they encode the same kind of guidance. +| Section | Required | What it captures | +| --- | --- | --- | +| **When to use** | Yes | The requests the skill handles, and which neighbouring skill to use instead for related topics. | +| **Before you answer** | No | What to find out or inspect first. | +| **Instructions** | Yes | A short numbered workflow, then the rules and facts under `###` subsections. | +| **MCP tools** | Yes | The Contentstack MCP tools that carry out the steps, or what to use when no tool covers the area. | +| **Output** | No | How answers should be shaped. | +| **Security** | Yes | Defaults, destructive-action gating, secret handling, env vars. | +| **References** | No | Bundled `references/` files and public docs. | +| **Examples** | No | Few-shot user/assistant pairs that calibrate behavior. | + +The body doesn't restate the frontmatter description. Example prompts live in the [routing evals](../contributing/routing-evals.md), where they're tested. + +## Advisory by default, MCP when asked + +Skills explain and show code. When the Contentstack MCP server is connected and the user asks for the change, the agent uses the tools named in **MCP tools**: read tools freely, and write, publish, deploy or delete tools only after naming the target and getting confirmation. ## References @@ -78,7 +68,7 @@ The agent reads these **on demand**, only when the task actually needs them, to ## Examples (few-shot) -Many skills end with worked **User → Assistant** pairs, often tagged `few shot` or `edge case`. These calibrate tone, format, and especially safety responses (for instance, how to refuse hardcoding a token, or how to gate a destructive action). +Some skills end with worked **User → Assistant** pairs. These calibrate tone, format, and especially safety responses (for instance, how to refuse hardcoding a token, or how to gate a destructive action). ## Why the consistency matters diff --git a/docs/overview/introduction.md b/docs/overview/introduction.md index ac35d85..2f240bc 100644 --- a/docs/overview/introduction.md +++ b/docs/overview/introduction.md @@ -24,17 +24,20 @@ Agent skills close that gap. They give the assistant Contentstack-specific knowl ## What's in the bundle -The skills span seven Contentstack product areas: +The skills span ten Contentstack product areas: | Product | Skills | | --- | --- | -| **CMS** | Assets · Branches & Aliases · Data Modeling · Entries · Environments & Publishing · Localization · Releases · Roles & Permissions · Taxonomy · Tokens & Authentication · Variants & Personalization · Webhooks · Workflows | +| **CMS** | Assets · Branches & Aliases · Data Modeling · Entries · GraphQL Content Delivery · JSON Rich Text Editor · Environments & Publishing · Localization · Releases · Roles & Permissions · Taxonomy · Tokens & Authentication · Variants & Personalization · Webhooks · Workflows | | **Assets** | Asset Management | -| **Developer Experience** | Delivery SDK · Contentstack Kickstart Next · Migrate JS→TS SDK · Live Preview & Visual Editor Support · Migration Companion | +| **Developer Experience** | Contentstack CLI · Contentstack MCP · Delivery SDK · Contentstack Kickstart Next · Migrate JS→TS SDK · Live Preview & Visual Editor Support · Migration Companion | | **Studio** | Contentstack Studio | -| **Launch** | Sync env vars from `.env.example` · Trigger & Monitor Deployments | +| **Launch** | Launch Platform · Sync env vars from `.env.example` · Trigger & Monitor Deployments | | **Brand Kit** | Brand Kit Assistant | -| **Developer Hub** | Developer Hub App Architect | +| **Developer Hub** | Developer Hub App Architect · Marketplace Apps | +| **Personalize** | Personalize | +| **Lytics** | Lytics | +| **Automate** | Automations | See the full [skills reference](../skills/index.md) for a description of each. diff --git a/docs/skills/asset-management.md b/docs/skills/asset-management.md index c5b91f1..4971c06 100644 --- a/docs/skills/asset-management.md +++ b/docs/skills/asset-management.md @@ -17,7 +17,7 @@ When you ask about the Assets DAM: spaces and workspaces, folders, asset types a - **Spaces and workspaces**: a space is the top-level container, and workspaces are isolated environments inside it, created from the main workspace or a parent workspace. - **Folders and roles**: folder creation and least-privilege guidance. -- **Asset types and metadata**: system, general and user-defined metadata. The currently supported user-defined field types are single line text, number, select and group. Filters on user-defined fields can be saved as saved views. +- **Asset types and metadata**: system, general and user-defined metadata. The currently supported user-defined field types are single line text, number and group. Filters on user-defined fields can be saved as saved views. - **Localization**: add a language in product settings, then add it per workspace under Space Settings > Workspaces > Manage Locales. - **Search**: the public Assets API search endpoint, required headers, and filtering by user-defined field. - **AI tags and alt text**: manual suggestions and auto-populate at upload, with their limits. @@ -34,6 +34,10 @@ When you ask about the Assets DAM: spaces and workspaces, folders, asset types a - "I deleted a folder by mistake. Can I get it back?" - "How do I search assets by a custom field value?" +## MCP tools + +No Contentstack MCP tool covers the Assets DAM; work happens in the Assets UI or the Assets API. The `cma` asset tools act on the CMS stack asset library, which is `cms-assets` territory. + ## Safety notes Read-only advisory. Never uploads, moves, deletes, restores or modifies assets, spaces or settings. Warns before irreversible actions such as deleting a space or all markups. Never exposes tokens or API keys; examples use environment variables. diff --git a/docs/skills/automations.md b/docs/skills/automations.md new file mode 100644 index 0000000..f3850e1 --- /dev/null +++ b/docs/skills/automations.md @@ -0,0 +1,45 @@ +--- +title: Automations +description: "Design and debug Contentstack Automate workflows: triggers, connectors, control flow, custom code, HTTP responses, executions, limits and the agent bridge." +--- + +# Automations + +**Slug:** `automations` · **Product:** Automate (Agent OS) · **Type:** Advisory (acts through MCP tools on request) + +Advises on building no-code workflows in Contentstack Automate, such as publish notifications, search indexing, translation and data syncs, and on debugging them when they misbehave. + +## When it triggers + +When you ask how to automate a Contentstack or cross-system task, which trigger, connector or step to use, why an automation did not run or failed, or how automations and agents work together. + +## What it covers + +- **Building blocks**: one trigger plus ordered steps, `{{step.path}}` references, and the draft/active lifecycle (active automations can't be edited). +- **Triggers**: Contentstack events, HTTP (treat the URL as a secret), schedule and manual. +- **Connectors and Connected apps**: saved credentials, reauthorizing, dependencies. +- **Control flow**: If-Else, loops, pause and resume. +- **Custom code**: a sandboxed JavaScript step with a short time limit, for light logic only. +- **Response step**: replying to HTTP callers. +- **Executions**: statuses, per-step outputs and a debugging checklist. +- **Limits and credits**: plan-based step, loop and output caps, and AI credits. +- **Agents**: agents can start automations; AI-built automations on the canvas aren't shipped yet. + +## Example prompts + +- "Post to Slack whenever an entry is published." +- "Keep our Algolia index in sync with the stack." +- "Why didn't my automation run when I published?" +- "Can my automation wait for an approval before continuing?" + +## MCP tools + +With the `automations` group of the Contentstack MCP server connected, the agent can list and read projects and automations, and on request create projects, switch automations on or off, or run an automation that has an HTTP trigger (`trigger_automation`). Steps, connections and executions stay in the Automate UI. + +## Safety notes + +Advisory by default. Uses MCP tools only when asked, and names the automation and its effect before activating, running or deleting anything. Keeps credentials in Connected apps and recommends testing write or delete steps on a non-production stack. + +## Related + +- [Webhooks](cms-webhooks.md) · [Workflows](cms-workflows.md) · [Brand Kit Assistant](brand-kit-assistant.md) diff --git a/docs/skills/brand-kit-assistant.md b/docs/skills/brand-kit-assistant.md index 77e1d17..e240737 100644 --- a/docs/skills/brand-kit-assistant.md +++ b/docs/skills/brand-kit-assistant.md @@ -5,7 +5,7 @@ description: The entry point for Contentstack Brand Kit, concepts, setup, govern # Brand Kit Assistant -**Slug:** `brand-kit-assistant` · **Product:** Brand Kit · **Type:** Advisory (gated API actions) · **Ships references** +**Slug:** `brand-kit-assistant` · **Product:** Brand Kit · **Type:** Advisory (acts through MCP tools on request) · **Ships references** The primary entry point for Contentstack Brand Kit. It explains how Brand Kit, Voice Profiles, and Knowledge Vault fit together, guides setup and governance, routes API-specific tasks to the right capability, and enforces brand and safety rules before presenting anything as ready. @@ -18,8 +18,9 @@ When you ask about Brand Kit, Voice Profiles, Knowledge Vault, brand voice, tone - **Concepts**: a Brand Kit container, one or more Voice Profiles (how content should sound), and a Knowledge Vault (brand facts and source material) used to ground AI generation. - **Setup**: creating a Brand Kit from a website or file upload, and mapping content to a Voice Profile vs Knowledge Vault. - **On-brand generation**: use a Voice Profile for tone/style plus Knowledge Vault for factual grounding, then validate output against brand guidelines before publishing. +- **Kit versions**: v1 Voice Profiles use four `communication_style` dials (formality, tone, humor, complexity) on a 1–4 scale. v2 kits use free-form markdown profiles, and v1 voice-profile routes return `410 Gone` for them. - **Knowledge Vault behavior**: it's vector-based semantic storage. It does **not** return original files or PDFs; keep source documents in your DAM/document system. -- **API guidance**: Brand Kit Management API (Brand Kits, Voice Profiles), Knowledge Vault API (ingest, update, delete, search, chunk retrieval), Generative AI API (content generation). Respects the 10 req/s per-organization rate limit and region-specific base URLs. +- **API guidance**: Brand Kit Management API (Brand Kits, Voice Profiles), Knowledge Vault API (ingest, update, delete, search, chunk retrieval), Generative AI API (content generation). Backs off on `429` rate-limit responses and uses region-specific base URLs. ## References @@ -33,8 +34,13 @@ Ships scoped API references: `references/brand-kit-management-api-reference.md` - "How do I make AI-generated content stay on-brand?" - "Can I get the original files back from Knowledge Vault?" +## MCP tools + +With the `brandkit` group connected, the agent can read, create, update and delete Voice Profiles and Knowledge Vault content, retrieve Knowledge Vault chunks, and generate on-brand content (`generative_ai`). The voice profile tools use the v1 model; Brand Kits themselves, visual guidelines and v2 Documents are managed in the UI or the Management API. + ## Safety notes +Advisory by default; uses the MCP tools only when you ask for the change. Never exposes Brand Kit API tokens, authtokens, or decrypted credentials. Acknowledges secrets at a high level without echoing them. Requires explicit confirmation and a confirmed UID before destructive actions (delete, unpublish, overwrite). Validates generated content against brand guidelines before calling it ready and won't override brand rules without approval. Asks for missing identifiers, auth, region, or source content rather than guessing. ## Related diff --git a/docs/skills/cms-assets.md b/docs/skills/cms-assets.md index 5829875..61fc5ac 100644 --- a/docs/skills/cms-assets.md +++ b/docs/skills/cms-assets.md @@ -5,7 +5,7 @@ description: "Organize, deliver, and transform assets in Contentstack: folders, # Assets -**Slug:** `cms-assets` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-assets` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Advises developers on organizing, delivering, and transforming assets in Contentstack: folder structure, Image Delivery API transformations, publishing lifecycle, CDN behavior, and common limits. @@ -16,10 +16,10 @@ When you ask about uploading, organizing, delivering, transforming, publishing, ## What it covers - **Folder organization**: clear structures like `/images/heroes`, `/images/products`, `/documents/legal`. Moving assets between folders preserves UIDs and references. -- **Image Delivery API**: `images.contentstack.io` with on-the-fly transforms via URL params (`width`, `height`, `quality`, `format`, `crop`, `trim`, `orient`, `overlay`, `pad`, `fit`, `dpr`). Chain multiple transforms in one URL; prefer WebP for modern browsers. Non-image assets serve from `assets.contentstack.io`. +- **Image Delivery API**: `images.contentstack.io` with on-the-fly transforms via URL params (`width`, `height`, `quality`, `format`, `auto`, `crop`, `trim`, `orient`, `overlay`, `pad`, `canvas`, `fit`, `dpr`, `blur`, `sharpen`, `brightness`, `contrast`, `saturation`). Chain multiple transforms in one URL; prefer WebP for modern browsers. Non-image assets serve from `assets.contentstack.io`. - **Publishing lifecycle**: assets publish independently of entries. An asset must be published to an environment before referenced entries display it live. Unpublishing removes it from delivery but doesn't delete the file. - **Replacing vs deleting**: replacing creates a new version but keeps the same UID and references; deleting breaks all references. Check references before deleting. -- **Key limits**: max file size 700 MB (UI) / 100 MB (API); max 10 assets per batch upload; default 10,000 assets per stack and 500,000 per organization; filenames can't change after upload. Image Delivery transforms don't apply to images inserted directly into Rich Text Editor fields. +- **Key limits**: max file size 700 MB (UI) / 100 MB (API); max 10 assets per batch upload; default 10,000 assets per stack; filenames can't change after upload. Image Delivery transforms don't apply to images inserted directly into Rich Text Editor fields. The Assets (DAM) product has its own limits (1.5 GB per asset, 100 per upload, 500,000 per workspace). ## Example prompts @@ -29,9 +29,13 @@ When you ask about uploading, organizing, delivering, transforming, publishing, - "Does deleting an asset break references in entries?" - "What is the maximum file size I can upload?" +## MCP tools + +With the Contentstack MCP server connected, the agent can list and inspect assets, folders, versions and references (`get_all_assets`, `get_asset_reference`, folder tools in `cma-extended`), check delivery with `get_all_assets_cdn`, publish or unpublish assets, manage folders and asset details, and delete assets. There is no upload tool; upload through the UI, the CMA or `csdx`. + ## Safety notes -Read-only advisory. Never uploads, deletes, publishes, or modifies assets. Delivery tokens and asset URLs are client-safe; never expose management tokens or API keys. Use environment variables for credentials in examples. +Advisory by default; uses the MCP tools only when you ask for the change. Before deleting, unpublishing or replacing an asset or deleting a folder, it names the asset, environments and referencing entries and waits for confirmation. Delivery tokens and asset URLs are client-safe; never expose management tokens or API keys. Use environment variables for credentials in examples. ## Related diff --git a/docs/skills/cms-branches-aliases.md b/docs/skills/cms-branches-aliases.md index ae6d83f..86ee298 100644 --- a/docs/skills/cms-branches-aliases.md +++ b/docs/skills/cms-branches-aliases.md @@ -5,7 +5,7 @@ description: Use Contentstack branches for isolated content development and alia # Branches & Aliases -**Slug:** `cms-branches-aliases` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-branches-aliases` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Advises on using branches for isolated content/schema development and aliases for zero-downtime deployments: branch strategy, branch-specific vs global modules, CI/CD integration, merge behavior, and rollback. @@ -15,8 +15,9 @@ When you ask about branches, aliases, CI/CD integration with Contentstack, deplo ## What it covers -- **Branch basics**: branches copy the source branch's content types, global fields, entries, and assets into an isolated workspace. Max 5 branches per stack; one create/delete at a time across an org; only owners, admins, and developers can manage them. -- **Branch-specific vs global modules**: *branch-specific:* content types, global fields, entries, assets, publish queue, releases, languages, extensions, audit logs, labels, search. *Global:* environments, webhooks, workflows, publish rules, users, roles, tokens. +- **Branch basics**: a branch inherits the source branch's content types, global fields, entries, assets, languages, webhooks and extensions as an isolated workspace. The branch count per stack depends on your plan; only owners, admins, and developers can create and delete branches. +- **Branch-specific vs global modules**: *branch-specific:* content types, global fields, entries, assets, workflows, publish queue, releases, languages, extensions, audit logs, global search, labels. *Global:* taxonomy, environments, users, roles, webhooks, workflows, publish rules, tokens, Marketplace apps. A webhook can be assigned to one branch at a time; workflows, publish rules and tokens can be scoped to specific branches (tokens also to aliases). +- **Compare & merge**: content types and global fields only, via CMA or CLI. Strategies: `merge_prefer_base`, `merge_prefer_compare`, `overwrite_with_compare` (destructive), `merge_new_only`, `merge_modified_only_prefer_base`, `merge_modified_only_prefer_compare`, `ignore`. A backup branch is created first; the merge runs asynchronously. Entries and assets need scripted reconciliation. - **Alias-based deployment**: aliases point to branches. Hardcode an alias (e.g. `deploy`) in frontend code instead of a branch UID; switch production by reassigning the alias, and roll back by reassigning it back. Two aliases can point to one branch, but a branch and alias can't share a UID. - **CI/CD pattern**: branch from main → change schema/content → test on staging → reassign the production alias → reassign back instantly if something breaks. - **Branch strategy**: keep branches short-lived; prefer trunk-based workflow. Don't use branches as permanent environments (use environments for that). @@ -30,9 +31,13 @@ When you ask about branches, aliases, CI/CD integration with Contentstack, deplo - "How do branches work with my CI/CD pipeline?" - "Can I roll back a bad deployment?" +## MCP tools + +With the Contentstack MCP server connected, the agent can list branches and aliases, compare branches and specific content types or global fields, create and merge branches, poll merge jobs, assign aliases, and delete branches or aliases (all in the `cma` group). + ## Safety notes -Read-only advisory: does not create, delete, merge, or reassign branches or aliases. Use environment variables for credentials; keep guidance compatible with branch- and alias-scoped credentials. +Advisory by default; uses the MCP tools only when you ask for the change. Before creating, merging or deleting a branch, or assigning or deleting an alias, it names the branches, aliases and merge strategy, explains the impact, and waits for confirmation. Use environment variables for credentials; keep guidance compatible with branch- and alias-scoped credentials. ## Related diff --git a/docs/skills/cms-data-modeling-best-practices.md b/docs/skills/cms-data-modeling-best-practices.md index 1552527..9f26b0a 100644 --- a/docs/skills/cms-data-modeling-best-practices.md +++ b/docs/skills/cms-data-modeling-best-practices.md @@ -5,7 +5,7 @@ description: "Model Contentstack content with the simplest reusable structure: w # Data Modeling Best Practices -**Slug:** `cms-data-modeling-best-practices` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-data-modeling-best-practices` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Guides developers to model content using the simplest reusable structure and avoid over-modeling, deep reference chains, and channel-specific schema sprawl. @@ -34,6 +34,7 @@ Core principles: - Treat content types as API contracts: avoid deep reference chains, oversized modular blocks, and hiding filterable facts inside rich text. - Localize only fields that need translation; keep names clear; avoid channel-specific schema pollution. - Explain tradeoffs and include migration cautions when schema changes are implied. +- Design within the limits: up to 500 fields per content type, plan limits on content types per stack and block types per modular blocks field, and taxonomies up to 10 levels deep. ## Example prompts @@ -43,9 +44,13 @@ Core principles: - "What's the best way to handle localization for shared content?" - "How do I model product categories for filtering and reuse?" +## MCP tools + +With the Contentstack MCP server connected, the agent can read the existing model (`get_all_content_types`, `get_a_single_content_type`, `get_all_references_of_ct`, global field tools) before reviewing it, and create, update or delete content types (`cma`) and global fields (`cma-extended`) when asked. + ## Safety notes -Read-only advisory. Never performs schema changes, publishing, or destructive actions. Uses placeholders and environment variables for any example credentials. +Advisory by default; uses the MCP tools only when you ask for the change, preferably on a development branch. Before any schema change it names the stack, branch and schema, explains the impact on existing content and delivery code, and waits for confirmation. Uses placeholders and environment variables for any example credentials. ## Related diff --git a/docs/skills/cms-entries.md b/docs/skills/cms-entries.md index ae272d8..00dcf9c 100644 --- a/docs/skills/cms-entries.md +++ b/docs/skills/cms-entries.md @@ -5,7 +5,7 @@ description: "Query, localize, version, publish, and structure Contentstack entr # Entries -**Slug:** `cms-entries` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-entries` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Advises on querying, localizing, versioning, publishing, and structuring entries for efficient delivery, with a focus on CDA usage, reference expansion, pagination, bulk operations, and Sync API patterns. @@ -20,7 +20,9 @@ When you ask about fetching entries, building CDA queries, handling localization - **Reference expansion**: including referenced entries in a CDA response. - **Pagination & performance**: paging through all entries of a content type efficiently. - **Versioning & publishing**: how versioning works, and the difference between saving and publishing. -- **Localization**: locale-aware entry behavior. +- **Localization**: locale-aware entry behavior, including `include_fallback`. +- **Limits**: at most 100 entries per CDA request, up to 100 `include[]` paths, an 8 KB URL limit, bulk publish of up to 100 items, nested reference publishing with the `api_version: 3.2` header, and CMA limits of 10 requests per second (1 per second for bulk actions). +- **Sync API**: an initial full sync plus `sync_token` deltas for mirrors, static builds and search indexes. For SDK code specifically, this pairs with the [Delivery SDK](dx-delivery-sdk.md) skill. @@ -32,9 +34,13 @@ For SDK code specifically, this pairs with the [Delivery SDK](dx-delivery-sdk.md - "How do I include referenced entries in my CDA response?" - "How do I paginate through all entries of a content type?" +## MCP tools + +With the Contentstack MCP server connected, the agent can read entries, references and versions (`cma`, `cma-extended`), check what the live site receives with `get_all_entries_cdn`, and create, update, publish, unpublish, localize, unlocalize or delete entries when asked. There are no bulk publish or Sync API tools. + ## Safety notes -Read-only advisory. Never creates, updates, publishes, or deletes entries. Delivery tokens are client-safe; management tokens are not. Use environment variables for credentials in examples. +Advisory by default; uses the MCP tools only when you ask for the change. Before any write, publish, unpublish or delete it names the entries, locales and environments and waits for confirmation. Delivery tokens are client-safe; management tokens are not. Use environment variables for credentials in examples. ## Related diff --git a/docs/skills/cms-environments-publishing.md b/docs/skills/cms-environments-publishing.md index deafa7b..4381069 100644 --- a/docs/skills/cms-environments-publishing.md +++ b/docs/skills/cms-environments-publishing.md @@ -5,7 +5,7 @@ description: Configure environments, publish content, use delivery and preview t # Environments & Publishing -**Slug:** `cms-environments-publishing` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-environments-publishing` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Advises on configuring environments, publishing content, using delivery and preview tokens, leveraging the Sync API, and understanding CDN and publish-queue behavior. @@ -15,13 +15,13 @@ When you ask about environment setup, publishing behavior, delivery or preview t ## What it covers -- **Environment design**: treat environments as deployment targets (development, staging, production). Default max 5 per stack. Environments are global modules, shared across branches. -- **Publishing fundamentals**: content is a draft until published to an environment; publishing can target multiple environments and locales. Use `api_version: 3.2` for nested reference publishing so the full reference tree resolves automatically. Always publish entries with their references. +- **Environment design**: treat environments as deployment targets (development, staging, production). Environments are global modules, shared across branches. +- **Publishing fundamentals**: content is a draft until published to an environment; publishing can target multiple environments and locales. For nested references, use bulk publish with the `api_version: 3.2` header, which publishes references up to five levels deep with their parents. Always publish entries with their references. - **Token types**: *Delivery Token:* published content via the CDA, environment-scoped, client-safe. *Preview Token:* unpublished content for Live Preview; client-side only on preview deployments, never in production builds. *Management Token:* stack-level read/write, server-side only, never in the browser. -- **SDK initialization**: stack API key + delivery token + environment, optionally branch/alias. CDA base URLs are region-specific (`cdn.contentstack.io` for AWS NA, `eu-cdn.contentstack.com` for AWS EU, `au-cdn.contentstack.com` for AWS AU). +- **SDK initialization**: stack API key + delivery token + environment, optionally branch/alias. CDA base URLs are region-specific (`cdn.contentstack.io` for AWS NA, `eu-cdn.contentstack.com` for AWS EU, `au-cdn.contentstack.com` for AWS AU, plus `azure-na-cdn`, `azure-eu-cdn`, `gcp-na-cdn` and `gcp-eu-cdn` on `.contentstack.com`). - **Sync API**: recommended for static sites, offline apps, or local caches. First request returns all published content plus a `sync_token`; later requests return only changes. Prefer it over polling. - **Publish queue**: tracks publish/unpublish status; each branch has its own queue; scheduled publishes can be cancelled before execution. -- **Rate limits**: 10 req/s individual, 1 req/s bulk per org. Use exponential backoff with jitter; the CLI bulk publish plugin handles rate limiting automatically. +- **Rate limits**: CMA 10 req/s and bulk 1 req/s per org; CDA reads are mostly CDN-served. Responses carry `X-RateLimit-Limit`/`X-RateLimit-Remaining`. Use exponential backoff with jitter; the CLI bulk publish plugin handles rate limiting automatically. ## Example prompts @@ -31,9 +31,13 @@ When you ask about environment setup, publishing behavior, delivery or preview t - "How does the Sync API work?" - "Can I schedule content to publish at a future time?" +## MCP tools + +With the Contentstack MCP server connected, the agent can inspect environments, the publish queue and publish rules, confirm what an environment serves with the `cda` tools, publish or unpublish entries and assets, and create, update or delete environments. There are no tools for tokens, the Sync API or cancelling a scheduled publish. + ## Safety notes -Read-only advisory. Never publishes, unpublishes, or modifies environments. Delivery tokens are client-safe; management tokens must never be exposed client-side. Use environment variables for all token examples. +Advisory by default; uses the MCP tools only when you ask for the change. Before publishing, unpublishing or changing an environment it names the environments, locales and items and waits for confirmation. Delivery tokens are client-safe; management tokens must never be exposed client-side. Use environment variables for all token examples. ## Related diff --git a/docs/skills/cms-graphql.md b/docs/skills/cms-graphql.md new file mode 100644 index 0000000..d12be74 --- /dev/null +++ b/docs/skills/cms-graphql.md @@ -0,0 +1,45 @@ +--- +title: GraphQL Content Delivery +description: "Query published Contentstack content with the GraphQL Content Delivery API: endpoints, schema, references, modular blocks, JSON RTE, limits, and Live Preview." +--- + +# GraphQL Content Delivery + +**Slug:** `cms-graphql` · **Product:** CMS · **Type:** Advisory (read-only) + +Helps you write and debug queries against the GraphQL Content Delivery API without running into its limits or losing data to partial errors. + +## When it triggers + +When you write or debug Contentstack GraphQL queries, see schema build errors or partial errors, hit GraphQL limits or 429s, paginate references, or connect a GraphQL fetch layer to Live Preview or Visual Editor. + +## What it covers + +- **Endpoints and headers**: regional hosts (`graphql.contentstack.com`, `eu-graphql…`, `au-graphql…`, Azure and GCP), `/stacks/{api_key}?environment=…`, `access_token`, optional `branch`. Queries only, no mutations. +- **Schema shape**: generated types per content type, `all_<uid>` collections, PascalCase naming rules and `SCHEMA_BUILD_ERROR`. +- **References**: `<field>Connection` with `totalCount`, `edges` and `node`; inline fragments for multi-type references. +- **Modular blocks, JSON RTE, assets**: unions with inline fragments, `embedded_itemsConnection`, `SysAsset` and image transforms. +- **Filtering and pagination**: `where` operators, `order_by` on `created_at`/`updated_at`, `skip`/`limit` (max 100). +- **Limits**: 3 levels of nested references, 7,500 records per query, 100 per reference connection, 7 MB responses, one operation per request. +- **Rate limits and errors**: per-organization origin limit, `X-RateLimit-*` headers, and checking `errors` even on HTTP 200. +- **Live Preview**: preview hosts, `live_preview` and `preview_token` headers, no caching, normalizing connection wrappers for edit tags. + +## Example prompts + +- "How do I query referenced entries with GraphQL in Contentstack?" +- "My GraphQL response is 200 but some data is missing." +- "How do I query modular blocks and JSON RTE embedded entries?" +- "What are the GraphQL query limits?" +- "How do I make Live Preview work with my GraphQL client?" + +## MCP tools + +The Contentstack MCP server has no GraphQL tool. To check the underlying data, the agent can use the read-only `cda` tools (`get_all_entries_cdn`, `get_a_single_entry_cdn`, `get_all_assets_cdn`) and `get_a_single_content_type` to check UIDs against GraphQL naming rules. + +## Safety notes + +Read-only advisory. Uses delivery tokens only; management tokens never belong in GraphQL calls or client code. Preview tokens stay on preview deployments. + +## Related + +- [Entries](cms-entries.md) · [Delivery SDK](dx-delivery-sdk.md) · [Live Preview & Visual Editor](cms-live-preview-visual-editor-support-assistant.md) diff --git a/docs/skills/cms-json-rte.md b/docs/skills/cms-json-rte.md new file mode 100644 index 0000000..f0e452a --- /dev/null +++ b/docs/skills/cms-json-rte.md @@ -0,0 +1,47 @@ +--- +title: JSON Rich Text Editor +description: "Render and convert Contentstack JSON RTE content: document structure, jsonToHTML and render options, embedded entries and assets, GraphQL, React, the JSON RTE serializer, Live Preview tags and XSS-safe rendering." +--- + +# JSON Rich Text Editor + +**Slug:** `cms-json-rte` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) · **Ships references** + +Helps you turn JSON RTE documents into HTML, Markdown or components, resolve embedded entries and assets, and convert content between HTML and JSON without opening an XSS hole. + +## When it triggers + +When you render, serialize or transform JSON RTE content, write a custom `renderOption`, debug embedded items that render empty, render JSON RTE from GraphQL, or migrate an HTML RTE field to JSON RTE. + +## What it covers + +- **Document structure**: `doc` root, block nodes with `uid`, `type`, `attrs` and `children`, text leaves with marks, `reference` nodes for embedded entries and assets, and the empty-field check. +- **Rendering**: `jsonToHTML` from `@contentstack/utils` (also `contentstack.Utils` in the Delivery SDK), field `paths`, and the fact that it replaces the JSON with HTML in place. +- **Render options**: overrides per node type, mark, display type (`block`, `inline`, `link`, `display`, `download`) and content type, plus a `reference` fallback. +- **Embedded items**: `includeEmbeddedItems()` (`include_embedded_items[]=BASE`), `_embedded_items`, why items render empty, and the limits (100 embedded entries, 15 referenceable content types, 30 KB per field by default). +- **GraphQL**: `json` plus `embedded_itemsConnection` with `system` UIDs, `GQL.jsonToHTML` and `updateAssetURLForGQL`. +- **React**: an HTML string vs a component tree, with a sample renderer. +- **Escaping**: the default sanitizer's limits (it doesn't check URL schemes) and escaping in custom render functions. +- **Conversion**: `@contentstack/json-rte-serializer` (`jsonToHtml`, `htmlToJson`, `jsonToMarkdown`) and the `cli-cm-migrate-rte` CLI plugin. +- **Live Preview**: `addEditableTags` and tagging the RTE wrapper element. + +## Example prompts + +- "How do I render a JSON RTE field to HTML with the TypeScript SDK?" +- "My embedded entries don't show up in the rendered rich text." +- "How do I render embedded products differently from other entries in the RTE?" +- "How do I render JSON RTE from a GraphQL response?" +- "How do I convert HTML into JSON RTE for an import?" +- "Should I use dangerouslySetInnerHTML or map JSON RTE nodes to React components?" + +## MCP tools + +Rendering runs in your code, so there are no rendering tools. To see the delivered JSON, the agent can use `get_a_single_entry_cdn` (`cda`) or `get_single_entry` (`cma`), and `get_a_single_content_type` (`cma`) to find JSON RTE field paths. `update_an_entry` (`cma`) can write converted JSON back, after confirmation. + +## Safety notes + +Advisory by default. Treats RTE content as untrusted: custom render functions escape what they interpolate, and URLs are checked before going into `href` or `src`. Writing converted content back to entries, or running the HTML to JSON migration, needs a named target, a backup or non-production branch, and explicit confirmation. + +## Related + +- [Entries](cms-entries.md) · [Delivery SDK](dx-delivery-sdk.md) · [GraphQL Content Delivery](cms-graphql.md) · [Live Preview & Visual Editor](cms-live-preview-visual-editor-support-assistant.md) · [Developer Hub App Architect](developer-hub-app-architect.md) diff --git a/docs/skills/cms-live-preview-visual-editor-support-assistant.md b/docs/skills/cms-live-preview-visual-editor-support-assistant.md index cd71dc2..e63609a 100644 --- a/docs/skills/cms-live-preview-visual-editor-support-assistant.md +++ b/docs/skills/cms-live-preview-visual-editor-support-assistant.md @@ -41,6 +41,10 @@ The skill stops once one contract is localised and adds no fallbacks while diagn - "My preview iframe is blank. What should I check?" - "How do preview tokens and live preview hashes work?" +## MCP tools + +No MCP tool reads the Visual Experience settings or the Onboarding Check. With the Contentstack MCP server connected, the agent uses read tools to gather evidence: environments and base URLs (`get_all_environments`), draft versus published entries (`get_single_entry` against `get_a_single_entry_cdn`), locales, branches and entry variants, and Launch deployment and server logs for sites hosted on Launch. + ## Safety notes Never makes changes automatically. Provides safe diagnostics and requires confirmation before any config change. Never asks for, echoes or reconstructs preview tokens or live preview hashes, and never asks for cookies or auth headers. Delivery tokens are safe in the browser; preview tokens read unpublished content, so they are exposed client-side only on preview deployments (CSR preview needs them), never in production builds; management tokens never reach the browser. Never recommends enabling Live Preview in production builds. If a secret appears in input, advises rotating it. diff --git a/docs/skills/cms-localization.md b/docs/skills/cms-localization.md index 40ea0cd..adeb44e 100644 --- a/docs/skills/cms-localization.md +++ b/docs/skills/cms-localization.md @@ -5,7 +5,7 @@ description: "Design multilingual delivery in Contentstack: language setup, fall # Localization -**Slug:** `cms-localization` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-localization` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Advises on Contentstack localization with correct fallback behavior, efficient editorial workflows, and minimal redundancy. The skill distinguishes CMS editorial behavior from CDA delivery behavior, and clarifies which you mean before answering. @@ -17,7 +17,7 @@ When you ask about languages, fallback chains, localizing entries, non-localizab - **Master language**: permanent, set at stack creation, and ends every fallback chain. - **Fallback chain design**: each language can have one fallback; inheritance is a chain (e.g. `fr-ca → fr-fr → en-us`). Changing fallback relationships later affects existing content inheritance. -- **Localized vs unlocalized entries**: a localized entry is an independent copy with its own version history, publishing status, and workflow state; an unlocalized entry inherits from its fallback chain. Localizing is one-way per locale and entry. +- **Localized vs unlocalized entries**: a localized entry is an independent copy with its own version history, publishing status, and workflow state; an unlocalized entry inherits from its fallback chain. Localizing is reversible: Unlocalize drops the locale's content and the entry inherits again from its fallback (or master). Unlocalized and deleted entries can be restored from Trash within 14 days. - **Non-localizable fields**: mark structural/shared data non-localizable (SKUs, prices, dates, coordinates, boolean flags, shared assets, identifiers); keep human-readable text localizable. - **CDA locale queries**: pass `locale` explicitly; use `include_fallback=true` to apply the full fallback chain (without it, only the exact locale is checked). - **Multi-locale publishing**: editors can publish multiple locale versions from the master-language entry (subject to plan limits). Only the latest version of each localized entry is published; localized versions can be deleted only from the master entry's delete modal. @@ -30,9 +30,13 @@ When you ask about languages, fallback chains, localizing entries, non-localizab - "How do I publish content in multiple languages at once?" - "What happens if a locale has no content?" +## MCP tools + +With the Contentstack MCP server connected, the agent can list languages, check what each locale serves with `get_all_entries_cdn` (`locale`, `include_fallback`), and localize, unlocalize or publish entries in several locales. There are no tools to add languages or change fallback chains. + ## Safety notes -Read-only advisory. Requires explicit confirmation before any destructive action and never auto-executes delete/overwrite/publish. Use environment variables for all credentials. +Advisory by default; uses the MCP tools only when you ask for the change. Before localizing, unlocalizing or publishing it lists the entry, locales and environments and waits for explicit confirmation, and it never auto-executes delete, overwrite or publish. Use environment variables for all credentials. ## Related diff --git a/docs/skills/cms-releases.md b/docs/skills/cms-releases.md index cd204f5..7f40500 100644 --- a/docs/skills/cms-releases.md +++ b/docs/skills/cms-releases.md @@ -5,7 +5,7 @@ description: "Use Contentstack Releases for coordinated, atomic content deployme # Releases -**Slug:** `cms-releases` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-releases` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Advises on using Releases to deploy related content changes atomically so campaigns, redesigns, or coordinated updates go live together without manual coordination errors. @@ -16,8 +16,9 @@ When you ask about deploying multiple content changes together, campaign launche ## What it covers - **Release workflow**: create a release with a descriptive name, add all related entries and assets (across content types and locales), deploy to staging first, validate, then deploy to production. Specify which version of each entry to deploy when needed. -- **Webhook storm**: a release deployment triggers one webhook event per item. Debounce receivers and inspect the `source` key in payloads. See [Webhooks](cms-webhooks.md) for receiver handling. -- **Limitations**: max 100 items per API call when adding items; release titles max 50 characters; updating items to latest versions does not auto-add new references from updated entries; releases are branch-specific. +- **Webhook bursts**: deploying a release publishes each item, so per-item publish webhooks can fire. Debounce or batch receivers and check execution logs. See [Webhooks](cms-webhooks.md) for receiver handling. +- **Limitations**: max 25 items per request when adding items; updating items to latest versions does not auto-add new references from updated entries; releases are branch-specific. +- **Releases v2** (plan-gated): multi-locale bulk add, clone, and update-all-items-to-latest; nested references can be included when adding items. - **CI/CD integration**: create a release → add changed items → deploy to staging → run tests → deploy to production on success. Combine with branches and aliases. - **When not to use**: not for routine single-entry publishes; use releases when coordinated multi-item deployment is required. @@ -29,9 +30,13 @@ When you ask about deploying multiple content changes together, campaign launche - "How do I integrate releases with my CI/CD pipeline?" - "What are the limits on releases?" +## MCP tools + +With the Contentstack MCP server connected, the agent can list releases and their items, create and clone releases, add items (25 per request), remove items, and deploy a release. There is no tool to delete a whole release. + ## Safety notes -Read-only advisory. Never creates, deploys, updates, or deletes releases. Use environment variables for credentials; no client-side access to management credentials. +Advisory by default; uses the MCP tools only when you ask for the change. Before creating, changing or deploying a release it names the release, branch, environments, locales and item count and waits for confirmation. Use environment variables for credentials; no client-side access to management credentials. ## Related diff --git a/docs/skills/cms-roles-permissions.md b/docs/skills/cms-roles-permissions.md index b8b81e7..e970b92 100644 --- a/docs/skills/cms-roles-permissions.md +++ b/docs/skills/cms-roles-permissions.md @@ -15,11 +15,11 @@ When you ask about user permissions, role design, team management, token capabil ## What it covers -- **Built-in roles**: Owner, Admin, Developer, Content Manager. Use them when they fit; otherwise create a custom role. +- **Built-in roles**: Owner, Admin, Developer, Content Manager (some orgs have extra system roles, such as read-only; check the stack's Roles list). Use them when they fit; otherwise create a custom role. - **Custom roles**: limit access by content type, environment, locale, branch, or action. Describe permissions by module, content type, and action; use `$all` for all instances when applicable. -- **Permission merging**: multiple roles combine allowed actions permissively, but explicit denials override grants. Watch overlap risks when roles are reused across teams/stacks. +- **Permission merging**: effective permissions are the union of all applicable roles (stack, team, org). There is no deny rule, so remove a role rather than trying to override it. Watch overlap risks when roles are reused across teams/stacks. - **Teams**: recommended for shared access across users and stacks; team membership maps users to stack roles and scales better than assigning roles individually. -- **Token capabilities**: choose the least-privileged token (management tokens, authtokens, OAuth) with SSO/org-owner edge cases noted. +- **Token capabilities**: choose the least-privileged credential: management tokens (at most 10 valid per stack), authtokens, OAuth, or machine-to-machine (M2M) apps using the client-credentials grant for automation. SSO/org-owner edge cases noted. - **Rate limits**: check `X-RateLimit-Remaining` and use backoff for automation/bulk operations. ## Example prompts @@ -30,9 +30,13 @@ When you ask about user permissions, role design, team management, token capabil - "How do I set up teams for multiple stacks?" - "What happens when a user has multiple roles?" +## MCP tools + +No Contentstack MCP tool manages roles, users, teams or tokens, so changes are made in the UI or through the CMA. With the `cma-extended` group connected, the agent can read the stack audit log (`get_audit_log`, `get_audit_log_item`) to review access changes. + ## Safety notes -Read-only advisory. Never creates, modifies, or deletes roles, users, teams, or tokens. Never recommends management tokens in client-side code; prefers server-side proxies for privileged CMA access. Delivery tokens are client-safe for read-only delivery only. +Read-only advisory. Never creates, modifies, or deletes roles, users, teams, or tokens; gives the steps and target for you to apply. Never recommends management tokens in client-side code; prefers server-side proxies for privileged CMA access. Delivery tokens are client-safe for read-only delivery only. ## Related diff --git a/docs/skills/cms-taxonomy.md b/docs/skills/cms-taxonomy.md index bfb79ff..1e40d29 100644 --- a/docs/skills/cms-taxonomy.md +++ b/docs/skills/cms-taxonomy.md @@ -5,7 +5,7 @@ description: "Use Contentstack Taxonomy for hierarchical content classification # Taxonomy -**Slug:** `cms-taxonomy` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-taxonomy` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Advises on using Taxonomy for structured, hierarchical classification and delivery-side filtering, and on when taxonomy is the right mechanism versus tags, labels, or references. @@ -17,9 +17,10 @@ When you need help classifying content, designing category hierarchies, choosing - **Use taxonomy when**: you need structured, hierarchical classification queryable on the delivery side (product categories, geographic regions, content topics, document types). - **Don't use taxonomy for**: freeform labels (use tags), internal CMS organization (use labels), or rich category pages with their own model (use a Category content type with references). -- **Hierarchy design**: plan before creating; keep it practical (usually 3–4 levels). Terms are parent-child ordered. Moving a term with children is blocked unless the force flag is used. -- **CDA filtering operators**: `$taxonomy_exists` (any term), `$taxonomy_equal` (specific term), `$taxonomy_below` (a term and descendants), `$taxonomy_above` (ancestors). -- **Localization & import/export**: localization is plan-dependent; localized terms share the master term's UID. Import/export supports JSON and CSV; invalid CSV rows are skipped while valid rows process. +- **Hierarchy design**: plan before creating; terms can nest up to 10 levels, but keep the tree as shallow as the use case allows. Terms are parent-child ordered; the move API's `force` flag cascades the move to child terms. +- **Limits** (plan-dependent defaults): 20 taxonomies per stack, 10,000 terms per taxonomy, 20 taxonomies per content type. Taxonomy is a global module shared across branches. +- **CDA filtering**: `query` on `/taxonomies/entries` or `/content_types/{uid}/entries`. Exact term `{"taxonomies.material": "wood"}`; `$in`, `$exists`, `$and`, `$or`; hierarchy operators `$eq_below`, `$below`, `$eq_above`, `$above` with optional `levels` (default 10). +- **Localization & import/export**: localization is plan-dependent; localized terms share the master term's UID. Import/export supports JSON and CSV; a localized import needs the master-locale taxonomy and terms to exist first. ## Example prompts @@ -29,9 +30,13 @@ When you need help classifying content, designing category hierarchies, choosing - "Can I localize taxonomy terms?" - "Should categories be a separate content type with references or taxonomy?" +## MCP tools + +With the Contentstack MCP server connected, the `cma` group reads taxonomies and terms (`get_all_taxonomies`, `get_all_terms`, ancestor and descendant lookups, `export_a_taxonomy`) and can create, update, move and delete them. There is no import tool; use the CMA or `csdx`. `get_all_entries_cdn` (`cda`) tests a taxonomy filter. + ## Safety notes -Read-only advisory. Never creates, modifies, moves, deletes, or imports taxonomy data. Use environment variables for credentials in examples. +Advisory by default. Changes taxonomies or terms through MCP only when you ask, after naming the taxonomy and terms and getting confirmation. Taxonomy is global, so changes reach every branch. Use environment variables for credentials in examples. ## Related diff --git a/docs/skills/cms-tokens-authentication.md b/docs/skills/cms-tokens-authentication.md index a64485d..468e74d 100644 --- a/docs/skills/cms-tokens-authentication.md +++ b/docs/skills/cms-tokens-authentication.md @@ -24,11 +24,13 @@ When you ask about authentication, token types, API keys, rate limits, SSO integ | Backend automation, CI/CD, migration scripts | Management token | | Interactive user sessions | Authtoken (only when appropriate) | | Third-party apps | OAuth with scoped access | +| Service-to-service automation | Machine-to-machine (M2M) app with OAuth client credentials | Plus: -- **Key limits**: management tokens are stack-level and limited per stack; authtokens are user-specific with their own limits. Watch rate-limit headers and 429s. -- **SSO organizations**: SSO can restrict authtoken usage; for automation in SSO orgs, prefer management tokens or OAuth. +- **Key limits**: a stack can have at most 10 valid management tokens at a time, and each can expire on a date or never. Authtokens are user-specific with their own limits. Watch the `x-ratelimit-limit` and `x-ratelimit-remaining` headers and 429s. +- **Preview tokens**: a separate credential that only the Preview Service accepts, used together with the short-lived `live_preview` hash. +- **SSO organizations**: SSO blocks password login, so scripts can't get authtokens that way. For automation in SSO orgs, use management tokens, OAuth or an M2M app. - **Security rules**. Never expose management tokens or authtokens client-side; use environment variables; rotate credentials; least privilege. - **Rate-limit handling**: exponential backoff with jitter for 429s; check rate-limit headers before retrying. @@ -40,6 +42,10 @@ Plus: - "Can I use authtokens in an SSO-enabled organization?" - "How many management tokens can I have per stack?" +## MCP tools + +No Contentstack MCP tool creates, rotates or deletes tokens; manage them in stack Settings → Tokens and M2M apps in Developer Hub. The skill explains how the MCP server itself authenticates (OAuth, or a management token for the `cma` groups) and can read an app's OAuth scopes with `get_oauth_scopes` and `get_app_oauth` (`developerhub`). + ## Safety notes Read-only advisory. Never creates, modifies, or deletes tokens. Never displays real secrets or example real tokens; always states whether a credential is client-safe or server-side only. Uses placeholders like `CONTENTSTACK_API_KEY`, `CONTENTSTACK_DELIVERY_TOKEN`, `CONTENTSTACK_MANAGEMENT_TOKEN`. diff --git a/docs/skills/cms-variants-personalization.md b/docs/skills/cms-variants-personalization.md index 2fa3663..794b4a0 100644 --- a/docs/skills/cms-variants-personalization.md +++ b/docs/skills/cms-variants-personalization.md @@ -5,7 +5,7 @@ description: "Use Contentstack Variants and Personalize for audience-targeted co # Variants & Personalization -**Slug:** `cms-variants-personalization` · **Product:** CMS · **Type:** Advisory (read-only) +**Slug:** `cms-variants-personalization` · **Product:** CMS · **Type:** Advisory (acts through MCP tools on request) Advises on delivering different content to different audiences without duplicating entire entries, and on integrating Personalize with the CMS. @@ -16,8 +16,10 @@ When you ask about content personalization, A/B testing, audience segmentation, ## What it covers - **Variants vs separate entries**: if ~80%+ of the content is shared and only headlines, images, or CTAs differ, use variants (lightweight overrides). If each audience needs a different page structure, references, and layout, use separate entries. Start with variants; split only when content diverges significantly. -- **Variant groups**: how variants are organized. -- **Personalize integration**: initialize the Contentstack SDK with stack credentials and the Personalize SDK with your project key. On each request, resolve the active experience from audience rules and pass the variant context when fetching entries. For SSR, use the Personalize Edge API to resolve variants at the CDN for best performance. +- **Variant groups**: one per Personalize experience, created automatically; one variant per audience or A/B arm; entry variants hold field overrides only. A group must be linked to a content type before editors can create entry variants. +- **Fetching variants**: pass variant aliases (`cs_personalize_{experienceShortUid}_{variantShortUid}`) in the CDA `x-cs-variant-uid` header. A comma-separated list layers variants and the leftmost wins on conflict. The CMA accepts only one variant UID. +- **Personalize integration**: resolve aliases with `@contentstack/personalize-edge-sdk` (`init`, `set`, `setUserId`, `getVariantAliases`, `triggerImpression`, `triggerEvent`), usually in edge middleware. +- **Experiences and limits**: segmented vs A/B (with a multi-armed bandit option), experience priority for field conflicts, and default project limits of 100 experiences, 20 variants per experience and 100 audiences. - **Start simple**: emphasizes maintainability; add complexity only when justified. ## Example prompts @@ -28,9 +30,13 @@ When you ask about content personalization, A/B testing, audience segmentation, - "What are variant groups?" - "Can I A/B test content in Contentstack?" +## MCP tools + +With the `cma` group, the agent can list, create, publish and delete entry variants (`get_all_variants_of_an_entry`, `create_an_entry_variant`, `publish_variants_of_an_entry`, `delete_an_entry_variant`). With the `personalize` group, it can read and manage experiences and their priority (`get_all_experiences`, `update_experience`, `update_experiences_priority`). Linking a variant group to a content type is done in the CMS. + ## Safety notes -Read-only advisory. Never creates, modifies, or publishes variants. Use environment variables for credentials; never hardcode stack API keys or Personalize project keys. +Advisory by default. Uses the MCP tools only when you ask for the change, and names the stack, entries, environments and experience before creating, publishing or deleting anything. Use environment variables for credentials; never hardcode stack API keys or Personalize project keys. ## Related diff --git a/docs/skills/cms-webhooks.md b/docs/skills/cms-webhooks.md index 426c280..5f0ed90 100644 --- a/docs/skills/cms-webhooks.md +++ b/docs/skills/cms-webhooks.md @@ -15,13 +15,13 @@ When you need help setting up webhooks, choosing event channels, handling payloa ## What it covers -- **Channels**: `{module}.{action}` form, e.g. `entries.create`, `entries.publish`, `assets.publish`, `content_types.update`, `entries.workflow_stage_change`. Start specific; use `$all` only when truly needed. -- **Payloads**: include module, `api_key`, event, `triggered_at`, data, and branch info. Use `concise_payload: true` when the receiver only needs identifiers. -- **Signature verification**: always validate the `X-Contentstack-Signature` header in production (HMAC-SHA256 over the raw body using the webhook secret). Reject missing/invalid signatures. -- **Release-webhook storm**: a release with many items can produce one event per item. Detect release-triggered events via the `source` key and debounce/batch so downstream systems trigger once per release. +- **Channels**: `{module}.{action}` form (e.g. `entries.create`, `assets.publish`, `content_types.update`) or `{module}.{context}.{action}` (e.g. `content_types.entries.publish`). Workflow stage events come from a separate workflow module; pick them in the webhook UI. Start specific; use `$all` only when truly needed. +- **Payloads**: top-level `module`, `api_key`, `event` and `data`. Use `concise_payload: true` when the receiver only needs identifiers. +- **Signature verification**: every request carries `X-Contentstack-Request-Signature` (RSA-PSS SHA-256), verified with Contentstack's public key. With HMAC signing enabled (plan feature), requests carry `X-Contentstack-HMAC-Signature`, an HMAC-SHA256 of `{timestamp}.{raw body}` with the webhook secret. Reject missing/invalid signatures and stale timestamps. +- **Release-triggered bursts**: deploying a release publishes each item, so publish webhooks can fire per item. Debounce or batch on the receiver so downstream systems trigger once per burst; check execution logs for what fired. - **Reliable receiver design**: validate signatures, return 2xx within 30 seconds, process asynchronously after acknowledgment, and handle duplicate deliveries idempotently. -- **Retry policies**: manual retries are logged for re-execution; auto retries use exponential backoff. Use execution logs for attempts, status codes, and response bodies. -- **Limits & scope**: max 100 webhooks per stack; webhooks are global but can be scoped to a branch; an org-level setting caps max connections per second. +- **Retry policies**: automatic retries up to 4 times with exponential backoff (about 5 s, 25 s, 125 s, 625 s); manual failures stay in the execution log to re-fire. Use execution logs for attempts, status codes, and response bodies. +- **Scope & concurrency**: webhooks are global but each can be assigned to one branch at a time; the org-level Webhook Configuration setting caps concurrent connections. ## Example prompts @@ -31,9 +31,13 @@ When you need help setting up webhooks, choosing event channels, handling payloa - "What retry policy should I use?" - "How do I debug missed webhook deliveries?" +## MCP tools + +No Contentstack MCP tool manages webhooks, so they are configured in stack Settings → Webhooks or through the CMA. The agent can use `get_deploy_hooks` (`launch`) to find a Launch deploy hook to target, and `get_all_items_in_a_release` (`cma`) to size a release burst. + ## Safety notes -Read-only advisory. Never creates, updates, deletes, or sends webhooks. Always validate `X-Contentstack-Signature` in production; never echo raw secrets, tokens, or signatures; keep secrets in environment variables and verify server-side. +Read-only advisory. Never creates, updates, deletes, or sends webhooks. Always verify the request signature in production; never echo raw secrets, tokens, or signatures; keep secrets in environment variables and verify server-side. ## Related diff --git a/docs/skills/cms-workflows.md b/docs/skills/cms-workflows.md index b04269f..9b6cc49 100644 --- a/docs/skills/cms-workflows.md +++ b/docs/skills/cms-workflows.md @@ -17,9 +17,9 @@ When you ask about workflow stage design, approval processes, publish rules, sel - **Keep workflows simple**: 3–5 stages for most cases; add stages only for a clear business need. A content type can have one workflow per branch. - **Stage design**: each stage defines who can advance entries, allowed next stages, and optional due dates/assignments. Max 20 stages; every transition is recorded in the audit log. -- **Prevent self-advancement**: requires at least two distinct reviewers; the last editor can't advance the entry. Use at least two approvers or a role with multiple members. +- **Prevent self-advancement**: an option turned on per stage, not a default. When on, the submitter can't also approve, so at least two distinct reviewers are needed. - **Publish rules are separate**: they govern publish/unpublish conditions independently of workflows, with scope fields (branch, content type, language, environment, action) and conditions (required stage, approver, prevent self-approval). -- **Automation**: use webhook events like `entries.workflow_stage_change`; the publish queue tracks pending actions and status. +- **Automation**: webhooks on workflow stage events (a separate workflow module; pick them in the webhook UI); the publish queue tracks pending actions and status. - **Permission limitations**: only owners, admins, and developers can create workflows and publish rules. Management tokens can't change workflow stages or configure rules requiring user approval; user-scoped auth or OAuth tokens are needed for programmatic transitions. ## Example prompts @@ -30,6 +30,10 @@ When you ask about workflow stage design, approval processes, publish rules, sel - "Can I automate actions when content reaches a workflow stage?" - "How do workflows work across branches?" +## MCP tools + +With the `cma-extended` group, the agent can read workflows, publish rules, publish queue activity and the audit log (`get_all_workflows`, `get_a_single_workflow`, `get_publish_rules`, `get_publish_queue_activity`, `get_audit_log`). No MCP tool changes workflows, stages or publish rules; those changes happen in the UI or the CMA. + ## Safety notes Read-only advisory. Never creates, updates, publishes, unpublishes, or deletes workflows or publish rules. Use environment variables for credentials; route CMA examples through server-side proxies. diff --git a/docs/skills/developer-hub-app-architect.md b/docs/skills/developer-hub-app-architect.md index 286a807..72de921 100644 --- a/docs/skills/developer-hub-app-architect.md +++ b/docs/skills/developer-hub-app-architect.md @@ -5,7 +5,7 @@ description: "Turn Contentstack Developer Hub and Marketplace app ideas into con # Developer Hub App Architect -**Slug:** `developer-hub-app-architect` · **Product:** Developer Hub · **Type:** Advisory (read-only) · **Ships references** +**Slug:** `developer-hub-app-architect` · **Product:** Developer Hub · **Type:** Advisory (acts through MCP tools on request) · **Ships references** Turns Developer Hub and Marketplace app ideas into concrete implementations: it chooses the right UI location, maps the architecture, generates boilerplate-aligned React/TypeScript code, and troubleshoots setup, SDK, manifest, proxy, and publishing issues. @@ -20,7 +20,8 @@ When designing or building a Contentstack Developer Hub or Marketplace app, choo ## What it covers -- **Location selection**: always identifies the best Contentstack UI location before writing code; prefers the smallest location that fits; compares candidates by user context, SDK surface, and complexity. +- **App type and target**: standard apps vs machine-to-machine apps (client credentials, organization-only, no UI), and stack vs organization targets. +- **Location selection**: covers all ten UI locations, including Content Type Sidebar and Global Full Page; always identifies the best Contentstack UI location before writing code; prefers the smallest location that fits; compares candidates by user context, SDK surface, and complexity. - **Developer Hub setup**: manifest, base URL, route mapping, location enabling, advanced settings variables, proxy/rewrite, install, and deploy steps. - **SDK & integration**: `@contentstack/app-sdk` patterns for location access, config read/write, field updates, asset replacement, iframe sizing, and typed guards; proxy/API rewrites for external integrations with secrets kept server-side. - **Troubleshooting**: checks route, manifest, location, SDK init, iframe context, config persistence, proxy behavior, and install scope, in that order, leading with the most likely cause. @@ -38,9 +39,13 @@ Ships a Developer Hub coding reference (`references/developer-hub-coding-referen - "Why is my app loading but `appSdk.location.CustomField` is undefined?" - "Turn this app idea into manifest config, route plan, and starter code." +## MCP tools + +With the MCP server's `developerhub` group connected, the agent can list, create, update, install and uninstall apps and manage their OAuth settings (`get_all_apps`, `create_an_app`, `install_an_app`, `update_app_oauth` and others). Hosting and Marketplace publishing stay in the Developer Hub UI. + ## Safety notes -Never exposes OAuth client secrets or app signing keys; keeps app credentials server-side via proxy variables or secure env vars. Validates installation scopes and never grants broader permissions than required. For publish/delete/revoke/uninstall flows, explains the impact first and requires confirmation of the target app/environment/installation. +Advisory by default; uses the MCP tools only when you ask. Never exposes OAuth client secrets or app signing keys; keeps app credentials server-side via proxy variables or secure env vars. Validates installation scopes and never grants broader permissions than required. Before creating, installing, uninstalling or deleting an app, or changing its OAuth settings, names the app and target and waits for confirmation. ## Related diff --git a/docs/skills/dx-cli.md b/docs/skills/dx-cli.md new file mode 100644 index 0000000..f7b77c5 --- /dev/null +++ b/docs/skills/dx-cli.md @@ -0,0 +1,43 @@ +--- +title: Contentstack CLI +description: "Use the Contentstack CLI (csdx): region and login, token aliases, export/import/seed/clone, bulk operations, migration scripts, branch merges, and plugins such as tsgen." +--- + +# Contentstack CLI + +**Slug:** `dx-cli` · **Product:** Developer Experience · **Type:** Advisory (acts through MCP tools on request) + +Helps you pick and run the right `csdx` command against the right region, stack and branch, and avoid overwriting content by accident. + +## When it triggers + +When you ask which `csdx` command to run, how to authenticate the CLI, how to move content between stacks or branches, bulk publish, write migration scripts, generate TypeScript types, upgrade from CLI 1.x, or troubleshoot CLI errors. + +## What it covers + +- **Setup**: `npm install -g @contentstack/cli` (Node.js 22+), `csdx config:set:region`, `csdx auth:login` (`--oauth` for SSO), token aliases with `csdx auth:tokens:add`. +- **Moving content**: `cm:stacks:export`, `cm:stacks:import` (modules, `--replace-existing`, skip-publish flags), `cm:stacks:seed`, `cm:stacks:clone`, and `cm:stacks:audit`. +- **Bulk operations**: `cm:stacks:bulk-entries`, `bulk-assets` and `bulk-taxonomies` replace the 1.x bulk-publish commands, with cross-publish, retry and revert. +- **Migration scripts**: `cm:stacks:migration` for scripted content type and entry changes. +- **Branches**: `cm:branches:diff`, `cm:branches:merge` (revert branch by default), `cm:branches:merge-status`. +- **Plugins**: `tsgen` for TypeScript types, `apps-cli` for Developer Hub apps, `cli-launch` for Launch, and more. See the bundled command list. + +## Example prompts + +- "How do I log in to the CLI with SSO?" +- "Export one stack and import it into another." +- "Bulk publish all blog entries to production." +- "Merge my feature branch content types into main." +- "Generate TypeScript types for my content types." + +## MCP tools + +The CLI handles bulk and stack-wide jobs; MCP has no export, import, seed, clone, bulk publish or migration-script tools. With the `cma` group connected, the agent can compare branches, check merge jobs and publish single entries (`compare_branches`, `merge_branch`, `get_a_single_merge_job`, `publish_an_entry`) before and after a CLI run. + +## Safety notes + +Advisory: suggests commands for you to run, and uses MCP tools only when you ask. Warns before imports that replace content, bulk unpublishes, merges, branch deletion and migration scripts, and recommends an export or backup branch first. Never prints tokens. + +## Related + +- [Migration Companion](migration-companion.md) · [Branches & Aliases](cms-branches-aliases.md) · [Launch deployments](launch-trigger-and-monitor-launch-deployments.md) diff --git a/docs/skills/dx-delivery-sdk.md b/docs/skills/dx-delivery-sdk.md index 2895011..79ec950 100644 --- a/docs/skills/dx-delivery-sdk.md +++ b/docs/skills/dx-delivery-sdk.md @@ -15,7 +15,7 @@ When you ask for Delivery SDK code, query examples, helper functions, SDK setup, ## What it covers -- **Stack setup**: `contentstack.stack({...})` with env-based credentials and region, using `@timbenniks/contentstack-endpoints` with `getContentstackEndpoints(region, true)` for region-specific preview hosts when needed. +- **Stack setup**: `contentstack.stack({...})` with env-based credentials and region, using `@timbenniks/contentstack-endpoints` (a community package the official kickstarts use, not published under `@contentstack/`) with `getContentstackEndpoints(region, true)` for region-specific preview hosts when needed. - **Single entry vs collections**: `.contentType(uid).entry(uid).fetch()` for one; `.entry().query().find()` for many. - **References**: `includeReference([...])` belongs _before_ `.query()`. - **Filtering**: use `QueryOperation` names exactly (e.g. `QueryOperation.EQUALS`, `NOT_EQUALS`). @@ -46,9 +46,13 @@ When you ask for Delivery SDK code, query examples, helper functions, SDK setup, Ships the **Delivery SDK Spec** (`references/delivery-sdk-spec.md`), sourced from the official TypeScript Delivery SDK reference. The skill reads it on demand to verify method names, options, and chain order. +## MCP tools + +With the MCP server connected, the agent reads the real stack to ground SDK code: content types and global fields from `cma` (`get_all_content_types`, `get_a_single_content_type`) and published entries and assets from `cda` (`get_all_entries_cdn`, `get_a_single_entry_cdn`). It needs no write tools. + ## Safety notes -Prefers TypeScript and current `@contentstack/delivery-sdk` APIs. Never hardcodes credentials; uses `process.env` placeholders. For SSR Live Preview, never reuses a stack across requests. +Prefers TypeScript and current `@contentstack/delivery-sdk` APIs. Uses MCP tools only to read the stack. Never hardcodes credentials; uses `process.env` placeholders. For SSR Live Preview, never reuses a stack across requests. ## Related diff --git a/docs/skills/dx-kickstart-next.md b/docs/skills/dx-kickstart-next.md index 2b62168..49029f0 100644 --- a/docs/skills/dx-kickstart-next.md +++ b/docs/skills/dx-kickstart-next.md @@ -5,7 +5,7 @@ description: Maintain Contentstack's Next.js kickstart with guidance for App Rou # Contentstack Kickstart Next -**Slug:** `dx-kickstart-next` · **Product:** Developer Experience · **Type:** Advisory (gated repo and stack changes) · **Ships references** +**Slug:** `dx-kickstart-next` · **Product:** Developer Experience · **Type:** Advisory (acts through MCP tools on request) · **Ships references** Helps agents build, review, debug, and extend Contentstack's `kickstart-next` repository or a close fork. It routes work into focused reference files for Next.js behavior, Contentstack delivery and preview setup, the seeded content model, local workflow, and PR review checks. @@ -39,9 +39,13 @@ Ships focused reference files in `references/`: - `workflow.md` for setup, validation, CI, docs, and dependency work. - `review.md` for review severity and pre-PR checks. +## MCP tools + +With the MCP server connected, the agent checks that the code matches your stack: content types and global fields from `cma` and published entries from `cda`. It changes content types or entries only when you ask. Seeding uses `csdx cm:stacks:seed`, not MCP. + ## Safety notes -Never commits real Contentstack credentials. Uses `.env.example` and docs for placeholders, keeps runtime behavior grounded in the current checkout, and verifies scripts and CI workflows before claiming they exist. +Never commits real Contentstack credentials. Uses `.env.example` and docs for placeholders, keeps runtime behavior grounded in the current checkout, and verifies scripts and CI workflows before claiming they exist. Confirms before seeding, schema changes or any MCP write. ## Related diff --git a/docs/skills/dx-mcp-server.md b/docs/skills/dx-mcp-server.md new file mode 100644 index 0000000..fa94614 --- /dev/null +++ b/docs/skills/dx-mcp-server.md @@ -0,0 +1,42 @@ +--- +title: Contentstack MCP +description: "Connect AI agents to Contentstack with the local @contentstack/mcp server or the hosted MCP Profile Hub: choosing, client setup, auth, tool scoping, and safety." +--- + +# Contentstack MCP + +**Slug:** `dx-mcp-server` · **Product:** Developer Experience · **Type:** Advisory (read-only) + +Helps you give an AI assistant scoped access to Contentstack over the Model Context Protocol, with either the local MCP server or the hosted MCP Profile Hub. + +## When it triggers + +When you ask how to give an AI assistant access to Contentstack, set up or debug the Contentstack MCP server or MCP Profile Hub, pick tool groups or profiles, fix MCP auth or missing tools, or build your own MCP integration. + +## What it covers + +- **Choosing**: the local `@contentstack/mcp` server (stdio, `npx`, best for individual developers) or MCP Profile Hub (hosted, Streamable HTTP, profiles, OAuth, Executions history, best for teams and web clients). +- **Local server**: `GROUPS` (`cma`, `cma-extended`, `cda`, `analytics`, `automations`, `brandkit`, `launch`, `developerhub`, `lytics`, `personalize`), `npx @contentstack/mcp --auth`, management token for CMA only, required IDs per group, stack-aware enrichment, and client config for Claude Code, Claude Desktop and Cursor. +- **Profile Hub**: system and custom profiles, the connector URL, client setup for Claude Code, claude.ai, Cursor, Codex, ChatGPT and stdio clients via `mcp-remote`, URL parameters, Automate automations and Agent OS agents as tools. +- **Safety**: read-only first, separate profiles per job, no tokens in shared config, confirmation before destructive calls. +- **Build your own**: the public tool definitions at `mcp.contentstack.com/<group>/tools`. + +## Example prompts + +- "How do I connect Claude Code to my Contentstack stack?" +- "Should my team use the MCP server or MCP Profile Hub?" +- "My MCP client shows no Contentstack tools." +- "How do I let an agent deploy to Launch but not delete content?" +- "Can an agent run one of our Automate automations?" + +## MCP tools + +This skill is about the MCP server itself. It summarizes the tools in each local server group (`cma` 78, `cma-extended` 22, `cda` 4, `analytics` 8, `automations` 9, `brandkit` 12, `launch` 27, `developerhub` 12, `lytics` 10, `personalize` 24), what no group covers (webhooks, roles, users, tokens, labels, extensions), and where to find the published tool definitions. + +## Safety notes + +Advisory. Recommends OAuth and the smallest tool set, warns before enabling write, delete, publish and deploy tools, and has the agent name the target and wait for confirmation before running one. Never echoes tokens. Profile Hub calls always run with the user's own Contentstack roles. + +## Related + +- [Tokens & Authentication](cms-tokens-authentication.md) · [Roles & Permissions](cms-roles-permissions.md) · [Contentstack CLI](dx-cli.md) diff --git a/docs/skills/dx-migrate-js-to-ts-sdk.md b/docs/skills/dx-migrate-js-to-ts-sdk.md index 6ebeb49..7dccd1d 100644 --- a/docs/skills/dx-migrate-js-to-ts-sdk.md +++ b/docs/skills/dx-migrate-js-to-ts-sdk.md @@ -18,7 +18,7 @@ When you want to migrate Delivery SDK code from JavaScript to TypeScript, compar - **Packages & imports**: install `@contentstack/delivery-sdk@latest`; switch imports; add `@contentstack/persistence-plugin` for cache and `@contentstack/utils` for utils. - **Key API mappings**: `contentstack.stack(...)` (not `Stack(...)`); `stack.contentType(...).entry(...).asset(...).query().fetch().find()`, plus `paginate()`, `next()`, `previous()`, `locale()`, `includeReference()`, `includeEmbeddedItems()`, `includeContentType()`, `includeCount()`, and taxonomy methods. - **Typed results**: generics on `fetch<BlogEntry>()`. -- **Cache**: install the persistence plugin and pass `cacheOptions` for policies other than `Policy.IGNORE_CACHE`. +- **Cache**: install `@contentstack/persistence-plugin` and pass a `PersistenceStore` as `cacheOptions.persistenceStore` for policies other than `Policy.IGNORE_CACHE`. - **Utils**: install `@contentstack/utils` separately and call `Utils.jsonToHTML(...)`. - **Sync**: TypeScript uses `stack.sync({ locale })` without `init: true`. - **Limitations**: 8KB URL limit; no multiple content-type references in a single query; no direct Global Field schema querying (use `include_global_field_schema`); `assetFields` support is region-limited to NA. @@ -31,9 +31,13 @@ When you want to migrate Delivery SDK code from JavaScript to TypeScript, compar - "How do I rewrite cache policy usage for the TypeScript SDK?" - "Convert this taxonomy query from the JavaScript SDK to TypeScript." +## MCP tools + +The migration is a code transformation and needs no MCP tools. If the server is connected, `get_all_entries_cdn` (`cda`) can confirm a rewritten query returns the same entries, and `get_a_single_content_type` (`cma`) shows the field UIDs the code relies on. + ## Safety notes -Never invents SDK methods not present in the reference docs. Replaces any secrets in samples with placeholders; uses environment variables for credentials. +Never invents SDK methods not present in the reference docs. Replaces any secrets in samples with placeholders; uses environment variables for credentials. Uses MCP tools only to read the stack. ## Related diff --git a/docs/skills/index.md b/docs/skills/index.md index 67d52b5..691c027 100644 --- a/docs/skills/index.md +++ b/docs/skills/index.md @@ -5,7 +5,7 @@ description: The full catalog of Contentstack Agent Skills, grouped by product. # Skills reference -The bundle includes 24 skills across seven Contentstack products. Each links to a dedicated page with what it does, when it triggers, example prompts, and its safety notes. +The bundle includes 33 skills across ten Contentstack products. Each links to a dedicated page with what it does, when it triggers, example prompts, and its safety notes. > Each skill page mirrors its canonical `skills/<slug>/SKILL.md`. The slug is the skill's identifier: use it with the [`skills` CLI](../get-started/skills-cli.md). @@ -16,6 +16,8 @@ The bundle includes 24 skills across seven Contentstack products. Each links to | [Assets](cms-assets.md) | `cms-assets` | Asset organization, Image Delivery API transforms, publishing lifecycle, CDN behavior, limits. | | [Branches & Aliases](cms-branches-aliases.md) | `cms-branches-aliases` | Isolated content development, alias-based zero-downtime deploys, CI/CD, merge & rollback. | | [Data Modeling Best Practices](cms-data-modeling-best-practices.md) | `cms-data-modeling-best-practices` | Choosing content types, references, global fields, groups, modular blocks, JSON RTE, taxonomy. | +| [GraphQL Content Delivery](cms-graphql.md) | `cms-graphql` | GraphQL endpoints, schema, references, modular blocks, JSON RTE, limits, Live Preview. | +| [JSON Rich Text Editor](cms-json-rte.md) | `cms-json-rte` | Rendering and serializing JSON RTE content, `@contentstack/utils`, embedded entries and assets, HTML conversion. | | [Entries](cms-entries.md) | `cms-entries` | CDA queries, reference expansion, pagination, versioning, publishing, bulk ops, Sync API. | | [Environments & Publishing](cms-environments-publishing.md) | `cms-environments-publishing` | Environment design, publishing pipeline, token types, Sync API, CDN, publish queue. | | [Localization](cms-localization.md) | `cms-localization` | Languages, fallback chains, localized vs unlocalized entries, non-localizable fields. | @@ -31,6 +33,8 @@ The bundle includes 24 skills across seven Contentstack products. Each links to | Skill | Slug | What it helps with | | --- | --- | --- | +| [Contentstack CLI](dx-cli.md) | `dx-cli` | `csdx` setup and auth, export/import/seed/clone, bulk operations, migrations, branch merges, plugins. | +| [Contentstack MCP](dx-mcp-server.md) | `dx-mcp-server` | Local MCP server vs hosted MCP Profile Hub, client setup, auth, tool scoping, safety. | | [Delivery SDK](dx-delivery-sdk.md) | `dx-delivery-sdk` | Production-ready TypeScript with `@contentstack/delivery-sdk` for entries, assets, queries, Live Preview. | | [Contentstack Kickstart Next](dx-kickstart-next.md) | `dx-kickstart-next` | Maintaining the Next.js kickstart: App Router, Delivery SDK setup, Live Preview, seed alignment, env vars, validation. | | [Migrate JS→TS SDK](dx-migrate-js-to-ts-sdk.md) | `dx-migrate-js-to-ts-sdk` | Migrating Delivery SDK code from the JavaScript SDK to the TypeScript SDK. | @@ -53,7 +57,8 @@ The bundle includes 24 skills across seven Contentstack products. Each links to | Skill | Slug | What it helps with | | --- | --- | --- | -| [Sync Launch env vars from .env.example](launch-sync-environment-variables-from-env-example.md) | `launch-sync-environment-variables-from-env-example` | Comparing a local `.env.example` to a Launch environment and patching missing keys. | +| [Launch Platform](launch-platform.md) | `launch-platform` | Launch hosting: builds, Cloud/Edge Functions, launch.json, caching, deploy hooks, domains, logs, limits. | +| [Sync Launch env vars from .env.example](launch-sync-environment-variables-from-env-example.md) | `launch-sync-environment-variables-from-env-example` | Comparing a local `.env.example` to a Launch environment and adding missing keys. | | [Trigger & Monitor Deployments](launch-trigger-and-monitor-launch-deployments.md) | `launch-trigger-and-monitor-launch-deployments` | Triggering a Launch deploy, polling to completion, diagnosing failures from logs. | ## Brand Kit @@ -67,6 +72,20 @@ The bundle includes 24 skills across seven Contentstack products. Each links to | Skill | Slug | What it helps with | | --- | --- | --- | | [Developer Hub App Architect](developer-hub-app-architect.md) | `developer-hub-app-architect` | Designing & building Developer Hub / Marketplace apps: UI locations, manifest, SDK, proxy, publishing. | +| [Marketplace Apps](marketplace-apps.md) | `marketplace-apps` | Choosing, installing and configuring first-party Marketplace apps, and reading their data on delivery. | + +## Personalize & Data + +| Skill | Slug | What it helps with | +| --- | --- | --- | +| [Personalize](personalize.md) | `personalize` | Experiences, audiences, attributes, events, Edge SDK and Edge API, Management API, edge middleware. | +| [Lytics](lytics.md) | `lytics` | JavaScript tag, identity, schema, audiences and Segment API, consent and deletion, Personalize connection. | + +## Automate + +| Skill | Slug | What it helps with | +| --- | --- | --- | +| [Automations](automations.md) | `automations` | Automate workflows: triggers, connectors, control flow, custom code, executions, limits. | ## How skills get selected diff --git a/docs/skills/launch-platform.md b/docs/skills/launch-platform.md new file mode 100644 index 0000000..a2e3dbd --- /dev/null +++ b/docs/skills/launch-platform.md @@ -0,0 +1,46 @@ +--- +title: Launch Platform +description: "Host and configure sites on Contentstack Launch: frameworks, Cloud and Edge Functions, launch.json, caching and revalidation, deploy triggers, domains, access control, logs and limits." +--- + +# Launch Platform + +**Slug:** `launch-platform` · **Product:** Launch · **Type:** Advisory (acts through MCP tools on request) + +Advises on getting a framework app building and serving on Launch, choosing between Cloud and Edge Functions, keeping content fresh without constant rebuilds, and staying inside platform limits. + +## When it triggers + +When you ask how to deploy or configure a site on Launch, why a build or function fails, how routing or caching works on Launch, or whether Launch supports a framework or feature. + +## What it covers + +- **Request flow**: `launch.json` redirects, then rewrites, then the Edge Function, then the CDN cache, then the origin. +- **Frameworks and builds**: presets (Next.js, Nuxt, Astro, Remix, SvelteKit, Gatsby, Angular and more), build and server commands, supported Node versions, npm/yarn/bun (no pnpm), 60-minute build limit. +- **Cloud Functions**: `/functions` file routing, handler shape, memory and timeout defaults, read-only file system. +- **Edge Functions**: `functions/[proxy].edge.js`, WinterCG-only APIs, memory, bundle and startup limits. +- **launch.json**: redirects, rewrites, header rules and cache priming. See the bundled reference. +- **Caching**: full purge on each live deployment, `Cache-Control`, and the revalidate-CDN-cache API by path, prefix, cache tag or hostname. +- **Deploy triggers**: deploy hooks, CMS-webhook redeploys, auto-deploy on push, rollback. Prefers revalidation over rebuilds for frequent publishing. +- **Environment variables, domains, password protection, IP control through Edge Functions, log targets over OTLP, monorepos.** +- **Limits and unsupported features**, in a bundled limits reference. + +## Example prompts + +- "How do I deploy my Next.js app to Launch?" +- "Should this middleware be an Edge Function or a Cloud Function?" +- "My site shows old content after I publish in the CMS." +- "Can I restrict my staging site to our office IPs?" +- "How do I send Launch logs to Datadog?" + +## MCP tools + +With the `launch` group of the Contentstack MCP server connected, the agent can read projects, environments, deployments and build or server logs (`get_an_environment`, `get_deployment`, `get_deployment_logs`, `get_server_logs`), and on request deploy, revalidate the CDN cache, update environments or manage deploy hooks (`create_deployment`, `revalidate_cdn_cache`, `update_an_environment`, `create_deploy_hook`). There are no tools for domains, log targets or rollback. + +## Safety notes + +Advisory by default. Uses MCP tools to change Launch only when asked, and names the project, environment and effect before any deployment, cache revalidation, environment update or delete, then waits for confirmation. Treats deploy hook URLs and tokens as secrets. + +## Related + +- [Launch: Sync environment variables](launch-sync-environment-variables-from-env-example.md) · [Launch: Trigger and monitor deployments](launch-trigger-and-monitor-launch-deployments.md) · [Webhooks](cms-webhooks.md) diff --git a/docs/skills/launch-sync-environment-variables-from-env-example.md b/docs/skills/launch-sync-environment-variables-from-env-example.md index 9327f2b..7fd98b9 100644 --- a/docs/skills/launch-sync-environment-variables-from-env-example.md +++ b/docs/skills/launch-sync-environment-variables-from-env-example.md @@ -1,13 +1,13 @@ --- title: Sync Launch env vars from .env.example -description: "Compare a local .env.example with a Contentstack Launch environment and patch the environment to add any missing keys, without exposing secrets." +description: "Compare a local .env.example with a Contentstack Launch environment and update the environment to add any missing keys, without exposing secrets." --- # Sync Launch env vars from .env.example **Slug:** `launch-sync-environment-variables-from-env-example` · **Product:** Launch · **Type:** Action (gated) -Fetches environment variables from a Contentstack Launch project, compares them with a local `.env.example` file, and patches the target environment to add any missing keys. Useful for auditing missing variables before a deployment and keeping a Launch environment aligned with what a frontend project expects. +Fetches environment variables from a Contentstack Launch project, compares them with a local `.env.example` file, and updates the target environment to add any missing keys. Useful for auditing missing variables before a deployment and keeping a Launch environment aligned with what a frontend project expects. > This skill has `disable-model-invocation: true`, which Claude Code and Copilot honor: they run it only when you explicitly invoke it. Other tools may still match it automatically, so the skill also confirms the target project and environment before any external call. @@ -20,9 +20,9 @@ When a Launch environment must match the keys defined in a local `.env.example`, 1. Read and parse `.env.example`, extracting variable names (ignoring comments, blanks, malformed entries). 2. Fetch the target Launch project and environment and read its current variables. 3. Compare keys: identify only missing keys unless you explicitly ask to update existing values. -4. Build a minimal patch payload with only the missing keys. -5. `PATCH /projects/{project_uid}/environments/{environment_uid}`. -6. Report missing keys, patched keys, and any errors, without exposing values. +4. Append only the missing keys to the fetched `environmentVariables` array. +5. `PUT /projects/{project_uid}/environments/{environment_uid}` with the full environment object. There is no PATCH, and PUT replaces the environment, so every other setting is sent back unchanged. +6. Report missing keys, added keys, and any errors, without exposing values. ## Inputs @@ -36,11 +36,15 @@ When a Launch environment must match the keys defined in a local `.env.example`, - "Generate a Node.js script that syncs Launch environment variables from `.env.example`." - "Compare my Launch environment variables with `.env.example` and add any missing keys." -- "Patch missing Launch environment variables for project `abc123` and environment `dev456`." +- "Add missing Launch environment variables for project `abc123` and environment `dev456`." + +## MCP tools + +If the `launch` group of the Contentstack MCP server is connected, the skill uses `get_an_environment` to fetch the environment and `update_an_environment` to send the full object back, instead of a script or curl. The same rules apply. ## Safety notes -Treats any PATCH as a destructive external action. Validates and confirms the target project/environment, and never broadens the update beyond missing keys unless asked. Prefers dry-run. Logs only key names and counts; never prints secret values from Launch or local files. Uses the smallest possible PATCH payload. +Treats the PUT, through the API or `update_an_environment`, as a destructive external action. Validates and confirms the target project/environment, and never broadens the update beyond missing keys unless asked. Prefers dry-run. Logs only key names and counts; never prints secret values from Launch or local files. Changes only the `environmentVariables` array, never sends a partial environment, and stops if the API returns masked values that would overwrite real ones. ## Related diff --git a/docs/skills/launch-trigger-and-monitor-launch-deployments.md b/docs/skills/launch-trigger-and-monitor-launch-deployments.md index 7007801..6b397bc 100644 --- a/docs/skills/launch-trigger-and-monitor-launch-deployments.md +++ b/docs/skills/launch-trigger-and-monitor-launch-deployments.md @@ -19,10 +19,10 @@ When you need to automate Launch deployments for a known project and environment 1. Validate the project and environment identifiers. 2. Confirm the target is allowed. **Require explicit approval for production**. -3. Trigger: `POST /projects/{project_uid}/environments/{environment_uid}/deployments`. -4. Poll status every 10 seconds until a terminal state. -5. Fail fast. Exit non-zero on `failed` or `cancelled`; stop polling. -6. On failure, `GET .../deployments/{deployment_uid}` for the log, then summarize the likely cause and next steps. +3. Trigger: `POST /projects/{project_uid}/environments/{environment_uid}/deployments`, optionally with a `commitHash` or `uploadUid`. +4. Poll `GET .../deployments/{deployment_uid}` every 10 seconds. `LIVE` is success; `QUEUED`, `DEPLOYING` and `DEPLOYED` are still in progress. +5. Fail fast. Exit non-zero on `FAILED`, `CANCELLED` or `SKIPPED`; stop polling. +6. On failure, `GET .../deployments/{deployment_uid}/logs/deployment-logs` for the build log (the deployment endpoint itself returns metadata only), then summarize the likely cause and next steps. ## Inputs @@ -39,9 +39,13 @@ When you need to automate Launch deployments for a known project and environment - "Poll a Launch deployment every 10 seconds and exit non-zero on failure." - "If the deployment fails, check the logs and explain what went wrong." +## MCP tools + +If the `launch` group of the Contentstack MCP server is connected, the skill uses `create_deployment` to deploy the latest commit of the environment's branch, `get_deployment` to poll, and `get_deployment_logs` or `get_server_logs` to diagnose. Deploying a specific commit or upload, and rollback, still go through the API. + ## Safety notes -Treats deployment triggers as external side effects. Requires explicit confirmation before production deployments and never auto-deploys to production without review. Doesn't auto-retry failed deployments unless asked and the target is non-production. Never prints API tokens, deployment tokens, or environment secrets; redacts sensitive values from logs and summaries. Uses a non-zero exit code for failed or cancelled deployments. +Treats deployment triggers, through the API or MCP tools, as external side effects. Requires explicit confirmation of the project and environment before every deployment, with an extra check for production, and never auto-deploys to production without review. Doesn't auto-retry failed deployments unless asked and the target is non-production. Never prints API tokens, deployment tokens, or environment secrets; redacts sensitive values from logs and summaries. Uses a non-zero exit code for failed, cancelled or skipped deployments. Rollback (`POST .../deployments/rollback`) is a production change and needs confirmation. ## Related diff --git a/docs/skills/lytics.md b/docs/skills/lytics.md new file mode 100644 index 0000000..282be50 --- /dev/null +++ b/docs/skills/lytics.md @@ -0,0 +1,46 @@ +--- +title: Lytics +description: "Use Lytics, Contentstack's customer data platform: the JavaScript tag, identity, schema, audiences, the Segment API, consent, deletion, and the Personalize connection." +--- + +# Lytics + +**Slug:** `lytics` · **Product:** Lytics (Data & Insights) · **Type:** Advisory (acts through MCP tools on request) + +Advises on getting behavioral and identity data into Lytics, resolving it into unified profiles, building audiences, and activating them, including in Contentstack Personalize, while respecting consent and deletion requests. + +## When it triggers + +When you ask about Lytics projects, installing or debugging the Lytics JavaScript tag, sending events or identities, schema fields and mappings or LQL, audiences and SegmentQL, the Segment API, profile lookups, importing Contentstack entries, recommendations, consent, identity deletion, or using Lytics audiences in Personalize. + +## What it covers + +- **Projects:** Lytics projects in Contentstack (the Lytics app calls them accounts), connections to stacks, Launch and Personalize, and per-project roles. +- **JavaScript tag:** installation through Launch, `<head>` or a tag manager; verification; `jstag.send`, `identify`, `page`; opt-in client-side integrations. +- **Identity:** merging anonymous `_uid` history with known identifiers, and identity key ranks. +- **Schema:** fields and mappings in Schema Studio, with LQL still available through the API. +- **Audiences:** the audience builder, SegmentQL, map-field conditions, Enable for Personalization, what Expires After does, and the Segment API. +- **Personalize connection:** the project connection, plus the `cs-lytics-audiences` cookie read by the Edge SDK. +- **Contentstack entries:** importing entries and taxonomies as context layers, content collections for recommendations. +- **API:** `https://api.lytics.io`, tokens in the `Authorization` header, least-privilege tokens with expiry. +- **Consent and deletion:** consent events, `DELETE /v2/identity/{table}/{field}/{value}`, bulk deletion and status. + +## Example prompts + +- "How do I install the Lytics tag on my Next.js site?" +- "How do I merge an anonymous visitor with the known user on login?" +- "How do I get Lytics audiences into Personalize?" +- "How do I delete a user's data for a GDPR request?" +- "Can I create audiences through the API?" + +## MCP tools + +With the `lytics` group of the Contentstack MCP server connected, the agent can read accounts, schema tables and fields, audiences, profiles and content topics, and classify or enrich content (`classify_content`, `enrich_content`). There are no tools for creating audiences, changing schema, sending events or deleting identities. + +## Safety notes + +Advisory by default; uses MCP tools only when asked. API tokens stay server-side. Identity deletion is permanent and needs explicit confirmation of the exact profile. Looks up profiles only when the user names one. + +## Related + +- [Personalize](personalize.md) · [Variants & Personalization](cms-variants-personalization.md) diff --git a/docs/skills/marketplace-apps.md b/docs/skills/marketplace-apps.md new file mode 100644 index 0000000..fdc4ef2 --- /dev/null +++ b/docs/skills/marketplace-apps.md @@ -0,0 +1,46 @@ +--- +title: Marketplace Apps +description: "Choose, install, configure and use first-party Contentstack Marketplace apps: the catalog by category, install permissions, configuration and per-field overrides, webhooks, delivery data and when to build a custom app." +--- + +# Marketplace Apps + +**Slug:** `marketplace-apps` · **Product:** Developer Hub · **Type:** Advisory (acts through MCP tools on request) + +Helps you pick the right first-party Marketplace app, install and configure it with the right permissions, and use the data it stores in your entries. + +## When it triggers + +When you ask which Marketplace app fits a need, how to install or configure an app such as Bynder, Cloudinary, Shopify, commercetools, Algolia or Trados, why an app field is empty or a sync isn't running, or how to read app data on the frontend. + +## What it covers + +- **Catalog**: documented apps by category: DAM, video, commerce and PIM, search, translation, AI, analytics and experimentation, forms, editor and JSON RTE utilities, and stack tools. +- **Install permissions**: stack apps vs organization apps, who can install each, and the Request Install and App Requests flow. +- **Configuration**: app configuration, multiple configurations with a default, `legacy_config`, the per-field **Config Parameter** override, and what each app saves in the entry. +- **UI locations and webhooks**: enabling locations, adding custom fields to content types, webhook branch scope and logs. +- **App specifics**: Algolia's environment and index mapping, and what Trados converts and skips. +- **Delivery**: reading app field JSON with the CDA, SDK and GraphQL, and fetching live data from the source system. +- **Lifecycle**: updates, uninstalling, and revoking authorized apps. +- **Build vs install**: when a custom app is the better fit. + +## Example prompts + +- "Which Marketplace app should we use to connect Bynder assets to our entries?" +- "I'm not an admin. How do I get the Shopify app installed on our stack?" +- "How do I use two Shopify stores in the same stack?" +- "Our Algolia index isn't updating when we publish." +- "What does the commercetools field return in the CDA response?" +- "Should we build our own app or use a Marketplace app?" + +## MCP tools + +The `developerhub` group covers apps your organization owns: `get_all_apps`, `get_an_app`, `get_app_installations`, `install_an_app`, `update_an_app_installation` and `uninstall_an_app`. Third-party listings may not appear in `get_all_apps`, so those are installed from the Marketplace UI. Entry and content type read tools show stored app data and which fields use an app. + +## Safety notes + +Advisory by default. Never echoes app credentials; `get_app_installations` can return them. Uninstalling an app, deleting a configuration (especially `legacy_config`) or changing one that fields depend on needs a named target and explicit confirmation, because stored app data can be lost. + +## Related + +- [Developer Hub App Architect](developer-hub-app-architect.md) · [Asset Management](asset-management.md) · [Assets](cms-assets.md) · [Localization](cms-localization.md) · [JSON Rich Text Editor](cms-json-rte.md) diff --git a/docs/skills/migration-companion.md b/docs/skills/migration-companion.md index 2b13c41..740b923 100644 --- a/docs/skills/migration-companion.md +++ b/docs/skills/migration-companion.md @@ -36,6 +36,10 @@ When you want to migrate, move, switch, port, or re-platform to Contentstack: co Ships per-step runbooks in `references/` (`step-1-prerequisites.md` through `step-5-welcome-message.md`, loaded only when that step runs), the Contentful → Contentstack mapping file (`CONTENTFUL_TO_CONTENTSTACK_MIGRATION_CONTEXT.md`), and a `scripts/` suite: the prerequisite checker, `read_cf_token.py` (resolves the Contentful token without printing it), the import-summary parser, logging helpers, and per-check eval scripts (`run-all.sh` plus numbered checks). +## MCP tools + +The migration runs on the Contentstack CLI and its migrate plugin. MCP is optional: with the server connected, its read tools (`get_all_content_types`, `get_all_entries`, `get_all_assets`, `get_all_entries_cdn`) can verify the result in the new stack. The skill doesn't use MCP write tools to patch content mid-run. + ## Safety notes Action skill with explicit gates: confirms before logging in, before creating a stack, and before editing your code. The prerequisite checker may install or upgrade global CLIs, and says so. Treats management and Contentful tokens as secrets: never prints or echoes them, and never writes them to workspace files; logs go to `<SESSION_DIR>/migration-log` by default; sets `CS_*` credentials only in the migrated app's gitignored `.env`. Converts reference dereferences to safe array access and flags every guessed field UID with a `TODO(migration)` comment rather than guessing silently. diff --git a/docs/skills/personalize.md b/docs/skills/personalize.md new file mode 100644 index 0000000..6a746e7 --- /dev/null +++ b/docs/skills/personalize.md @@ -0,0 +1,44 @@ +--- +title: Personalize +description: "Integrate Contentstack Personalize: experiences, audiences, attributes, events, the Edge SDK and Edge API, the Management API, and edge middleware patterns." +--- + +# Personalize + +**Slug:** `personalize` · **Product:** Personalize · **Type:** Advisory (acts through MCP tools on request) + +Advises on integrating Contentstack Personalize so each visitor gets the right variant early in the request, the matching entry variants are fetched, and results are measured, without leaking personalized content into shared caches. + +## When it triggers + +When you ask about setting up Personalize, segmented vs A/B test experiences, audiences and attributes, impressions and conversions, the Personalize Edge SDK in Next.js, Launch Edge Functions, Vercel, Netlify or Cloudflare, the Management API, experience analytics, or a visitor seeing the wrong variant. + +## What it covers + +- **Concepts:** projects linked to a stack, experiences syncing as variant groups, segmented vs A/B (equal, custom split, Multi-Armed Bandit), first-match variant order, experience priority, experience tags. +- **Audiences and attributes:** preset attributes (City, Country, Region, Date and Time, Device Type, Operating System, Query Parameter, Referrer), custom attributes that must exist in the project, live vs stored attributes, Personalize vs Lytics audiences. +- **Edge SDK:** `@contentstack/personalize-edge-sdk` init options, instance methods, regional Edge API hosts via `setEdgeApiUrl`. +- **Request flow:** edge `init` with the request → variant param rewrite → `addStateToResponse` → `variantParamToVariantAliases` → Delivery SDK `.variants()`. On Launch, use an Edge Function rather than Next.js middleware. A worked example is in `references/edge-integration.md`. +- **Events and analytics:** impressions counted once per visitor, conversions via event keys, analytics summary and time series. +- **Management API:** regional hosts, OAuth scopes `personalize:read` / `personalize:manage` or authtoken, `x-project-uid`, 10 requests/second per organization. +- **Caching and debugging:** per-request rendering, `no-store` on browser responses, and a debugging chain from manifest → aliases → CDA → entry variants → cache. + +## Example prompts + +- "How do I add Personalize to my Next.js site on Launch?" +- "Should this be a segmented experience or an A/B test?" +- "How do I track a conversion when someone clicks the CTA?" +- "Why does every visitor get the base entry?" +- "How do I create experiences through the API?" + +## MCP tools + +With the `personalize` group of the Contentstack MCP server connected, the agent can read experiences, versions, priority, audiences, attributes, events and analytics, and on request create or update experiences, attributes and events or change priority. There is no tool for creating audiences. Entry variants on the CMS side use the `cma` group's variant tools. + +## Safety notes + +Advisory by default. Uses MCP tools to change the project only when asked, and confirms the project and items before deleting, pausing or reprioritizing anything. Management API credentials stay server-side; personalized responses never go into a shared cache without the variant in the cache key. + +## Related + +- [Variants & Personalization](cms-variants-personalization.md) · [Lytics](lytics.md) · [Delivery SDK](dx-delivery-sdk.md) diff --git a/docs/skills/studio.md b/docs/skills/studio.md index 2f2ebb0..94d7341 100644 --- a/docs/skills/studio.md +++ b/docs/skills/studio.md @@ -23,9 +23,13 @@ When a request touches Contentstack Studio: the Studio SDK, canvas, compositions It prefers Contentstack MCP tools when they are connected and falls back to OAuth-authenticated API calls for missing operations. +## MCP tools + +Studio is MCP-first for the operations the server supports: content types, entries and publishing through the `cma` group. Its `install-contentstack-mcp` guide discovers and verifies the server. The Studio API project list and configuration, and some token and Live Preview operations, still need OAuth HTTP or the Studio UI. + ## Safety notes -Resolves credentials OAuth-first: it asks before reading or refreshing a stored OAuth session from another tool, and uses a session `authtoken` only as a last resort. Confirms before creating or changing stacks, content types, entries, compositions or Studio projects. Never prints tokens or `.env` contents, never weakens TLS verification, and never ships permissive frame headers outside the canvas route. +Resolves credentials OAuth-first: it asks before reading or refreshing a stored OAuth session from another tool, and uses a session `authtoken` only as a last resort. Verifies the target stack with a read call before MCP work. Confirms before creating or changing stacks, content types, entries, compositions or Studio projects, whether through MCP or HTTP. Never prints tokens or `.env` contents, never weakens TLS verification, and never ships permissive frame headers outside the canvas route. ## Example prompts diff --git a/evals/routing-asset-management-1/graders/loads-asset-management.md b/evals/routing-asset-management-1/graders/loads-asset-management.md new file mode 100644 index 0000000..8186a9d --- /dev/null +++ b/evals/routing-asset-management-1/graders/loads-asset-management.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?asset-management"' +min: 1 +--- +The agent loads the `asset-management` skill. diff --git a/evals/routing-asset-management-1/prompt.md b/evals/routing-asset-management-1/prompt.md new file mode 100644 index 0000000..94ce77d --- /dev/null +++ b/evals/routing-asset-management-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-asset-management-1 +tags: [routing, asset-management] +max_turns: 3 +timeout_seconds: 180 +--- +In Contentstack Assets, how should I split our brands and regions across spaces and workspaces? diff --git a/evals/routing-asset-management-2/graders/loads-asset-management.md b/evals/routing-asset-management-2/graders/loads-asset-management.md new file mode 100644 index 0000000..8186a9d --- /dev/null +++ b/evals/routing-asset-management-2/graders/loads-asset-management.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?asset-management"' +min: 1 +--- +The agent loads the `asset-management` skill. diff --git a/evals/routing-asset-management-2/graders/skips-cms-assets.md b/evals/routing-asset-management-2/graders/skips-cms-assets.md new file mode 100644 index 0000000..2dd980b --- /dev/null +++ b/evals/routing-asset-management-2/graders/skips-cms-assets.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-assets"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `cms-assets` skill. diff --git a/evals/routing-asset-management-2/prompt.md b/evals/routing-asset-management-2/prompt.md new file mode 100644 index 0000000..483f7a8 --- /dev/null +++ b/evals/routing-asset-management-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-asset-management-2 +tags: [routing, asset-management] +max_turns: 3 +timeout_seconds: 180 +--- +How do I add a custom 'photographer' field to images in Contentstack Assets and search by it? diff --git a/evals/routing-automations-1/graders/loads-automations.md b/evals/routing-automations-1/graders/loads-automations.md new file mode 100644 index 0000000..bbd29d1 --- /dev/null +++ b/evals/routing-automations-1/graders/loads-automations.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?automations"' +min: 1 +--- +The agent loads the `automations` skill. diff --git a/evals/routing-automations-1/prompt.md b/evals/routing-automations-1/prompt.md new file mode 100644 index 0000000..26eebd6 --- /dev/null +++ b/evals/routing-automations-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-automations-1 +tags: [routing, automations] +max_turns: 3 +timeout_seconds: 180 +--- +Using Contentstack Automate, post to Slack whenever an entry is published. diff --git a/evals/routing-automations-2/graders/loads-automations.md b/evals/routing-automations-2/graders/loads-automations.md new file mode 100644 index 0000000..bbd29d1 --- /dev/null +++ b/evals/routing-automations-2/graders/loads-automations.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?automations"' +min: 1 +--- +The agent loads the `automations` skill. diff --git a/evals/routing-automations-2/graders/skips-cms-webhooks.md b/evals/routing-automations-2/graders/skips-cms-webhooks.md new file mode 100644 index 0000000..08a3326 --- /dev/null +++ b/evals/routing-automations-2/graders/skips-cms-webhooks.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-webhooks"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `cms-webhooks` skill. diff --git a/evals/routing-automations-2/prompt.md b/evals/routing-automations-2/prompt.md new file mode 100644 index 0000000..e3060f0 --- /dev/null +++ b/evals/routing-automations-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-automations-2 +tags: [routing, automations] +max_turns: 3 +timeout_seconds: 180 +--- +Why didn't my Contentstack automation run when I published an entry? diff --git a/evals/routing-brand-kit-assistant-1/graders/loads-brand-kit-assistant.md b/evals/routing-brand-kit-assistant-1/graders/loads-brand-kit-assistant.md new file mode 100644 index 0000000..2245ecd --- /dev/null +++ b/evals/routing-brand-kit-assistant-1/graders/loads-brand-kit-assistant.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?brand-kit-assistant"' +min: 1 +--- +The agent loads the `brand-kit-assistant` skill. diff --git a/evals/routing-brand-kit-assistant-1/prompt.md b/evals/routing-brand-kit-assistant-1/prompt.md new file mode 100644 index 0000000..156b575 --- /dev/null +++ b/evals/routing-brand-kit-assistant-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-brand-kit-assistant-1 +tags: [routing, brand-kit-assistant] +max_turns: 3 +timeout_seconds: 180 +--- +How do I make AI-generated content in Contentstack stay on-brand with a Voice Profile? diff --git a/evals/routing-brand-kit-assistant-2/graders/loads-brand-kit-assistant.md b/evals/routing-brand-kit-assistant-2/graders/loads-brand-kit-assistant.md new file mode 100644 index 0000000..2245ecd --- /dev/null +++ b/evals/routing-brand-kit-assistant-2/graders/loads-brand-kit-assistant.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?brand-kit-assistant"' +min: 1 +--- +The agent loads the `brand-kit-assistant` skill. diff --git a/evals/routing-brand-kit-assistant-2/prompt.md b/evals/routing-brand-kit-assistant-2/prompt.md new file mode 100644 index 0000000..92f4519 --- /dev/null +++ b/evals/routing-brand-kit-assistant-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-brand-kit-assistant-2 +tags: [routing, brand-kit-assistant] +max_turns: 3 +timeout_seconds: 180 +--- +Can I get the original files back from Contentstack Knowledge Vault? diff --git a/evals/routing-cms-assets-1/graders/loads-cms-assets.md b/evals/routing-cms-assets-1/graders/loads-cms-assets.md new file mode 100644 index 0000000..28006a0 --- /dev/null +++ b/evals/routing-cms-assets-1/graders/loads-cms-assets.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-assets"' +min: 1 +--- +The agent loads the `cms-assets` skill. diff --git a/evals/routing-cms-assets-1/graders/skips-asset-management.md b/evals/routing-cms-assets-1/graders/skips-asset-management.md new file mode 100644 index 0000000..47e2524 --- /dev/null +++ b/evals/routing-cms-assets-1/graders/skips-asset-management.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?asset-management"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `asset-management` skill. diff --git a/evals/routing-cms-assets-1/prompt.md b/evals/routing-cms-assets-1/prompt.md new file mode 100644 index 0000000..b785235 --- /dev/null +++ b/evals/routing-cms-assets-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-assets-1 +tags: [routing, cms-assets] +max_turns: 3 +timeout_seconds: 180 +--- +How do I serve responsive WebP images from my Contentstack stack with image transformations? diff --git a/evals/routing-cms-assets-2/graders/loads-cms-assets.md b/evals/routing-cms-assets-2/graders/loads-cms-assets.md new file mode 100644 index 0000000..28006a0 --- /dev/null +++ b/evals/routing-cms-assets-2/graders/loads-cms-assets.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-assets"' +min: 1 +--- +The agent loads the `cms-assets` skill. diff --git a/evals/routing-cms-assets-2/prompt.md b/evals/routing-cms-assets-2/prompt.md new file mode 100644 index 0000000..bebfa55 --- /dev/null +++ b/evals/routing-cms-assets-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-assets-2 +tags: [routing, cms-assets] +max_turns: 3 +timeout_seconds: 180 +--- +What's the maximum file size I can upload to a Contentstack stack's asset library? diff --git a/evals/routing-cms-branches-aliases-1/graders/loads-cms-branches-aliases.md b/evals/routing-cms-branches-aliases-1/graders/loads-cms-branches-aliases.md new file mode 100644 index 0000000..fec4a13 --- /dev/null +++ b/evals/routing-cms-branches-aliases-1/graders/loads-cms-branches-aliases.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-branches-aliases"' +min: 1 +--- +The agent loads the `cms-branches-aliases` skill. diff --git a/evals/routing-cms-branches-aliases-1/prompt.md b/evals/routing-cms-branches-aliases-1/prompt.md new file mode 100644 index 0000000..dbb78db --- /dev/null +++ b/evals/routing-cms-branches-aliases-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-branches-aliases-1 +tags: [routing, cms-branches-aliases] +max_turns: 3 +timeout_seconds: 180 +--- +How do branches and aliases in Contentstack fit into our CI/CD pipeline? diff --git a/evals/routing-cms-branches-aliases-2/graders/loads-cms-branches-aliases.md b/evals/routing-cms-branches-aliases-2/graders/loads-cms-branches-aliases.md new file mode 100644 index 0000000..fec4a13 --- /dev/null +++ b/evals/routing-cms-branches-aliases-2/graders/loads-cms-branches-aliases.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-branches-aliases"' +min: 1 +--- +The agent loads the `cms-branches-aliases` skill. diff --git a/evals/routing-cms-branches-aliases-2/prompt.md b/evals/routing-cms-branches-aliases-2/prompt.md new file mode 100644 index 0000000..0627e26 --- /dev/null +++ b/evals/routing-cms-branches-aliases-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-branches-aliases-2 +tags: [routing, cms-branches-aliases] +max_turns: 3 +timeout_seconds: 180 +--- +Which Contentstack modules are branch-specific and which are global? diff --git a/evals/routing-cms-data-modeling-best-practices-1/graders/loads-cms-data-modeling-best-practices.md b/evals/routing-cms-data-modeling-best-practices-1/graders/loads-cms-data-modeling-best-practices.md new file mode 100644 index 0000000..2bd0a79 --- /dev/null +++ b/evals/routing-cms-data-modeling-best-practices-1/graders/loads-cms-data-modeling-best-practices.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-data-modeling-best-practices"' +min: 1 +--- +The agent loads the `cms-data-modeling-best-practices` skill. diff --git a/evals/routing-cms-data-modeling-best-practices-1/prompt.md b/evals/routing-cms-data-modeling-best-practices-1/prompt.md new file mode 100644 index 0000000..79f95ac --- /dev/null +++ b/evals/routing-cms-data-modeling-best-practices-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-data-modeling-best-practices-1 +tags: [routing, cms-data-modeling-best-practices] +max_turns: 3 +timeout_seconds: 180 +--- +How should I model a landing page with reusable sections in Contentstack? diff --git a/evals/routing-cms-data-modeling-best-practices-2/graders/loads-cms-data-modeling-best-practices.md b/evals/routing-cms-data-modeling-best-practices-2/graders/loads-cms-data-modeling-best-practices.md new file mode 100644 index 0000000..2bd0a79 --- /dev/null +++ b/evals/routing-cms-data-modeling-best-practices-2/graders/loads-cms-data-modeling-best-practices.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-data-modeling-best-practices"' +min: 1 +--- +The agent loads the `cms-data-modeling-best-practices` skill. diff --git a/evals/routing-cms-data-modeling-best-practices-2/prompt.md b/evals/routing-cms-data-modeling-best-practices-2/prompt.md new file mode 100644 index 0000000..f7f5fe4 --- /dev/null +++ b/evals/routing-cms-data-modeling-best-practices-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-data-modeling-best-practices-2 +tags: [routing, cms-data-modeling-best-practices] +max_turns: 3 +timeout_seconds: 180 +--- +Should this Contentstack data be a global field, a group, or its own content type? diff --git a/evals/routing-cms-entries-1/graders/loads-cms-entries.md b/evals/routing-cms-entries-1/graders/loads-cms-entries.md new file mode 100644 index 0000000..fd14bdb --- /dev/null +++ b/evals/routing-cms-entries-1/graders/loads-cms-entries.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-entries"' +min: 1 +--- +The agent loads the `cms-entries` skill. diff --git a/evals/routing-cms-entries-1/prompt.md b/evals/routing-cms-entries-1/prompt.md new file mode 100644 index 0000000..39f96d0 --- /dev/null +++ b/evals/routing-cms-entries-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-entries-1 +tags: [routing, cms-entries] +max_turns: 3 +timeout_seconds: 180 +--- +How do I paginate through all entries of a content type with the Contentstack CDA? diff --git a/evals/routing-cms-entries-2/graders/loads-cms-entries.md b/evals/routing-cms-entries-2/graders/loads-cms-entries.md new file mode 100644 index 0000000..fd14bdb --- /dev/null +++ b/evals/routing-cms-entries-2/graders/loads-cms-entries.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-entries"' +min: 1 +--- +The agent loads the `cms-entries` skill. diff --git a/evals/routing-cms-entries-2/prompt.md b/evals/routing-cms-entries-2/prompt.md new file mode 100644 index 0000000..fb3988c --- /dev/null +++ b/evals/routing-cms-entries-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-entries-2 +tags: [routing, cms-entries] +max_turns: 3 +timeout_seconds: 180 +--- +How does entry versioning work in Contentstack? diff --git a/evals/routing-cms-environments-publishing-1/graders/loads-cms-environments-publishing.md b/evals/routing-cms-environments-publishing-1/graders/loads-cms-environments-publishing.md new file mode 100644 index 0000000..77a1005 --- /dev/null +++ b/evals/routing-cms-environments-publishing-1/graders/loads-cms-environments-publishing.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-environments-publishing"' +min: 1 +--- +The agent loads the `cms-environments-publishing` skill. diff --git a/evals/routing-cms-environments-publishing-1/prompt.md b/evals/routing-cms-environments-publishing-1/prompt.md new file mode 100644 index 0000000..6027a7d --- /dev/null +++ b/evals/routing-cms-environments-publishing-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-environments-publishing-1 +tags: [routing, cms-environments-publishing] +max_turns: 3 +timeout_seconds: 180 +--- +My Contentstack content isn't showing on the live site after publishing. What should I check? diff --git a/evals/routing-cms-environments-publishing-2/graders/loads-cms-environments-publishing.md b/evals/routing-cms-environments-publishing-2/graders/loads-cms-environments-publishing.md new file mode 100644 index 0000000..77a1005 --- /dev/null +++ b/evals/routing-cms-environments-publishing-2/graders/loads-cms-environments-publishing.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-environments-publishing"' +min: 1 +--- +The agent loads the `cms-environments-publishing` skill. diff --git a/evals/routing-cms-environments-publishing-2/prompt.md b/evals/routing-cms-environments-publishing-2/prompt.md new file mode 100644 index 0000000..ce51a52 --- /dev/null +++ b/evals/routing-cms-environments-publishing-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-environments-publishing-2 +tags: [routing, cms-environments-publishing] +max_turns: 3 +timeout_seconds: 180 +--- +How does the Contentstack Sync API work? diff --git a/evals/routing-cms-graphql-1/graders/loads-cms-graphql.md b/evals/routing-cms-graphql-1/graders/loads-cms-graphql.md new file mode 100644 index 0000000..0757fc2 --- /dev/null +++ b/evals/routing-cms-graphql-1/graders/loads-cms-graphql.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-graphql"' +min: 1 +--- +The agent loads the `cms-graphql` skill. diff --git a/evals/routing-cms-graphql-1/graders/skips-dx-delivery-sdk.md b/evals/routing-cms-graphql-1/graders/skips-dx-delivery-sdk.md new file mode 100644 index 0000000..fd1de2d --- /dev/null +++ b/evals/routing-cms-graphql-1/graders/skips-dx-delivery-sdk.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-delivery-sdk"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `dx-delivery-sdk` skill. diff --git a/evals/routing-cms-graphql-1/prompt.md b/evals/routing-cms-graphql-1/prompt.md new file mode 100644 index 0000000..3c7fee3 --- /dev/null +++ b/evals/routing-cms-graphql-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-graphql-1 +tags: [routing, cms-graphql] +max_turns: 3 +timeout_seconds: 180 +--- +How do I query referenced entries with the Contentstack GraphQL API? diff --git a/evals/routing-cms-graphql-2/graders/loads-cms-graphql.md b/evals/routing-cms-graphql-2/graders/loads-cms-graphql.md new file mode 100644 index 0000000..0757fc2 --- /dev/null +++ b/evals/routing-cms-graphql-2/graders/loads-cms-graphql.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-graphql"' +min: 1 +--- +The agent loads the `cms-graphql` skill. diff --git a/evals/routing-cms-graphql-2/prompt.md b/evals/routing-cms-graphql-2/prompt.md new file mode 100644 index 0000000..d552ad2 --- /dev/null +++ b/evals/routing-cms-graphql-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-graphql-2 +tags: [routing, cms-graphql] +max_turns: 3 +timeout_seconds: 180 +--- +What are the query limits of the Contentstack GraphQL Content Delivery API? diff --git a/evals/routing-cms-json-rte-1/graders/loads-cms-json-rte.md b/evals/routing-cms-json-rte-1/graders/loads-cms-json-rte.md new file mode 100644 index 0000000..1260c10 --- /dev/null +++ b/evals/routing-cms-json-rte-1/graders/loads-cms-json-rte.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-json-rte"' +min: 1 +--- +The agent loads the `cms-json-rte` skill. diff --git a/evals/routing-cms-json-rte-1/graders/skips-cms-entries.md b/evals/routing-cms-json-rte-1/graders/skips-cms-entries.md new file mode 100644 index 0000000..81e07b5 --- /dev/null +++ b/evals/routing-cms-json-rte-1/graders/skips-cms-entries.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-entries"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `cms-entries` skill. diff --git a/evals/routing-cms-json-rte-1/prompt.md b/evals/routing-cms-json-rte-1/prompt.md new file mode 100644 index 0000000..dae4215 --- /dev/null +++ b/evals/routing-cms-json-rte-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-json-rte-1 +tags: [routing, cms-json-rte] +max_turns: 3 +timeout_seconds: 180 +--- +How do I render Contentstack JSON Rich Text Editor content to HTML in my React app? diff --git a/evals/routing-cms-json-rte-2/graders/loads-cms-json-rte.md b/evals/routing-cms-json-rte-2/graders/loads-cms-json-rte.md new file mode 100644 index 0000000..1260c10 --- /dev/null +++ b/evals/routing-cms-json-rte-2/graders/loads-cms-json-rte.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-json-rte"' +min: 1 +--- +The agent loads the `cms-json-rte` skill. diff --git a/evals/routing-cms-json-rte-2/prompt.md b/evals/routing-cms-json-rte-2/prompt.md new file mode 100644 index 0000000..f17a73b --- /dev/null +++ b/evals/routing-cms-json-rte-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-json-rte-2 +tags: [routing, cms-json-rte] +max_turns: 3 +timeout_seconds: 180 +--- +My Contentstack JSON RTE embedded entries aren't rendering. How do I include them? diff --git a/evals/routing-cms-live-preview-visual-editor-support-assistant-1/graders/loads-cms-live-preview-visual-editor-support-assistant.md b/evals/routing-cms-live-preview-visual-editor-support-assistant-1/graders/loads-cms-live-preview-visual-editor-support-assistant.md new file mode 100644 index 0000000..861b0e8 --- /dev/null +++ b/evals/routing-cms-live-preview-visual-editor-support-assistant-1/graders/loads-cms-live-preview-visual-editor-support-assistant.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-live-preview-visual-editor-support-assistant"' +min: 1 +--- +The agent loads the `cms-live-preview-visual-editor-support-assistant` skill. diff --git a/evals/routing-cms-live-preview-visual-editor-support-assistant-1/prompt.md b/evals/routing-cms-live-preview-visual-editor-support-assistant-1/prompt.md new file mode 100644 index 0000000..948d180 --- /dev/null +++ b/evals/routing-cms-live-preview-visual-editor-support-assistant-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-live-preview-visual-editor-support-assistant-1 +tags: [routing, cms-live-preview-visual-editor-support-assistant] +max_turns: 3 +timeout_seconds: 180 +--- +Contentstack Live Preview loads but my edits never show up. Help me debug it. diff --git a/evals/routing-cms-live-preview-visual-editor-support-assistant-2/graders/loads-cms-live-preview-visual-editor-support-assistant.md b/evals/routing-cms-live-preview-visual-editor-support-assistant-2/graders/loads-cms-live-preview-visual-editor-support-assistant.md new file mode 100644 index 0000000..861b0e8 --- /dev/null +++ b/evals/routing-cms-live-preview-visual-editor-support-assistant-2/graders/loads-cms-live-preview-visual-editor-support-assistant.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-live-preview-visual-editor-support-assistant"' +min: 1 +--- +The agent loads the `cms-live-preview-visual-editor-support-assistant` skill. diff --git a/evals/routing-cms-live-preview-visual-editor-support-assistant-2/graders/skips-dx-delivery-sdk.md b/evals/routing-cms-live-preview-visual-editor-support-assistant-2/graders/skips-dx-delivery-sdk.md new file mode 100644 index 0000000..fd1de2d --- /dev/null +++ b/evals/routing-cms-live-preview-visual-editor-support-assistant-2/graders/skips-dx-delivery-sdk.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-delivery-sdk"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `dx-delivery-sdk` skill. diff --git a/evals/routing-cms-live-preview-visual-editor-support-assistant-2/prompt.md b/evals/routing-cms-live-preview-visual-editor-support-assistant-2/prompt.md new file mode 100644 index 0000000..4e3ce78 --- /dev/null +++ b/evals/routing-cms-live-preview-visual-editor-support-assistant-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-live-preview-visual-editor-support-assistant-2 +tags: [routing, cms-live-preview-visual-editor-support-assistant] +max_turns: 3 +timeout_seconds: 180 +--- +We have Contentstack Live Preview working. What do we add for Visual Builder? diff --git a/evals/routing-cms-localization-1/graders/loads-cms-localization.md b/evals/routing-cms-localization-1/graders/loads-cms-localization.md new file mode 100644 index 0000000..e386c18 --- /dev/null +++ b/evals/routing-cms-localization-1/graders/loads-cms-localization.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-localization"' +min: 1 +--- +The agent loads the `cms-localization` skill. diff --git a/evals/routing-cms-localization-1/prompt.md b/evals/routing-cms-localization-1/prompt.md new file mode 100644 index 0000000..be4ac2c --- /dev/null +++ b/evals/routing-cms-localization-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-localization-1 +tags: [routing, cms-localization] +max_turns: 3 +timeout_seconds: 180 +--- +How do I set up languages with fallback in Contentstack? diff --git a/evals/routing-cms-localization-2/graders/loads-cms-localization.md b/evals/routing-cms-localization-2/graders/loads-cms-localization.md new file mode 100644 index 0000000..e386c18 --- /dev/null +++ b/evals/routing-cms-localization-2/graders/loads-cms-localization.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-localization"' +min: 1 +--- +The agent loads the `cms-localization` skill. diff --git a/evals/routing-cms-localization-2/prompt.md b/evals/routing-cms-localization-2/prompt.md new file mode 100644 index 0000000..9505223 --- /dev/null +++ b/evals/routing-cms-localization-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-localization-2 +tags: [routing, cms-localization] +max_turns: 3 +timeout_seconds: 180 +--- +What's the difference between a localized and an unlocalized entry in Contentstack? diff --git a/evals/routing-cms-releases-1/graders/loads-cms-releases.md b/evals/routing-cms-releases-1/graders/loads-cms-releases.md new file mode 100644 index 0000000..66d3c00 --- /dev/null +++ b/evals/routing-cms-releases-1/graders/loads-cms-releases.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-releases"' +min: 1 +--- +The agent loads the `cms-releases` skill. diff --git a/evals/routing-cms-releases-1/prompt.md b/evals/routing-cms-releases-1/prompt.md new file mode 100644 index 0000000..c28ea40 --- /dev/null +++ b/evals/routing-cms-releases-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-releases-1 +tags: [routing, cms-releases] +max_turns: 3 +timeout_seconds: 180 +--- +How do I deploy a campaign of 50 Contentstack entries at once and schedule it? diff --git a/evals/routing-cms-releases-2/graders/loads-cms-releases.md b/evals/routing-cms-releases-2/graders/loads-cms-releases.md new file mode 100644 index 0000000..66d3c00 --- /dev/null +++ b/evals/routing-cms-releases-2/graders/loads-cms-releases.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-releases"' +min: 1 +--- +The agent loads the `cms-releases` skill. diff --git a/evals/routing-cms-releases-2/prompt.md b/evals/routing-cms-releases-2/prompt.md new file mode 100644 index 0000000..1d7c230 --- /dev/null +++ b/evals/routing-cms-releases-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-releases-2 +tags: [routing, cms-releases] +max_turns: 3 +timeout_seconds: 180 +--- +What are the limits on Contentstack releases? diff --git a/evals/routing-cms-roles-permissions-1/graders/loads-cms-roles-permissions.md b/evals/routing-cms-roles-permissions-1/graders/loads-cms-roles-permissions.md new file mode 100644 index 0000000..dc7ce6a --- /dev/null +++ b/evals/routing-cms-roles-permissions-1/graders/loads-cms-roles-permissions.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-roles-permissions"' +min: 1 +--- +The agent loads the `cms-roles-permissions` skill. diff --git a/evals/routing-cms-roles-permissions-1/prompt.md b/evals/routing-cms-roles-permissions-1/prompt.md new file mode 100644 index 0000000..04903fd --- /dev/null +++ b/evals/routing-cms-roles-permissions-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-roles-permissions-1 +tags: [routing, cms-roles-permissions] +max_turns: 3 +timeout_seconds: 180 +--- +How do I restrict Contentstack editors to only certain content types? diff --git a/evals/routing-cms-roles-permissions-2/graders/loads-cms-roles-permissions.md b/evals/routing-cms-roles-permissions-2/graders/loads-cms-roles-permissions.md new file mode 100644 index 0000000..dc7ce6a --- /dev/null +++ b/evals/routing-cms-roles-permissions-2/graders/loads-cms-roles-permissions.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-roles-permissions"' +min: 1 +--- +The agent loads the `cms-roles-permissions` skill. diff --git a/evals/routing-cms-roles-permissions-2/prompt.md b/evals/routing-cms-roles-permissions-2/prompt.md new file mode 100644 index 0000000..6c9d18a --- /dev/null +++ b/evals/routing-cms-roles-permissions-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-roles-permissions-2 +tags: [routing, cms-roles-permissions] +max_turns: 3 +timeout_seconds: 180 +--- +What happens when a Contentstack user has multiple roles? diff --git a/evals/routing-cms-taxonomy-1/graders/loads-cms-taxonomy.md b/evals/routing-cms-taxonomy-1/graders/loads-cms-taxonomy.md new file mode 100644 index 0000000..fd86441 --- /dev/null +++ b/evals/routing-cms-taxonomy-1/graders/loads-cms-taxonomy.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-taxonomy"' +min: 1 +--- +The agent loads the `cms-taxonomy` skill. diff --git a/evals/routing-cms-taxonomy-1/prompt.md b/evals/routing-cms-taxonomy-1/prompt.md new file mode 100644 index 0000000..592c190 --- /dev/null +++ b/evals/routing-cms-taxonomy-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-taxonomy-1 +tags: [routing, cms-taxonomy] +max_turns: 3 +timeout_seconds: 180 +--- +Should I use taxonomy or tags for product categories in Contentstack? diff --git a/evals/routing-cms-taxonomy-2/graders/loads-cms-taxonomy.md b/evals/routing-cms-taxonomy-2/graders/loads-cms-taxonomy.md new file mode 100644 index 0000000..fd86441 --- /dev/null +++ b/evals/routing-cms-taxonomy-2/graders/loads-cms-taxonomy.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-taxonomy"' +min: 1 +--- +The agent loads the `cms-taxonomy` skill. diff --git a/evals/routing-cms-taxonomy-2/prompt.md b/evals/routing-cms-taxonomy-2/prompt.md new file mode 100644 index 0000000..42597e2 --- /dev/null +++ b/evals/routing-cms-taxonomy-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-taxonomy-2 +tags: [routing, cms-taxonomy] +max_turns: 3 +timeout_seconds: 180 +--- +How do I query Contentstack entries by a taxonomy term and all its child terms? diff --git a/evals/routing-cms-tokens-authentication-1/graders/loads-cms-tokens-authentication.md b/evals/routing-cms-tokens-authentication-1/graders/loads-cms-tokens-authentication.md new file mode 100644 index 0000000..0f6f911 --- /dev/null +++ b/evals/routing-cms-tokens-authentication-1/graders/loads-cms-tokens-authentication.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-tokens-authentication"' +min: 1 +--- +The agent loads the `cms-tokens-authentication` skill. diff --git a/evals/routing-cms-tokens-authentication-1/prompt.md b/evals/routing-cms-tokens-authentication-1/prompt.md new file mode 100644 index 0000000..d0f6ada --- /dev/null +++ b/evals/routing-cms-tokens-authentication-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-tokens-authentication-1 +tags: [routing, cms-tokens-authentication] +max_turns: 3 +timeout_seconds: 180 +--- +What's the difference between a Contentstack management token and an authtoken? diff --git a/evals/routing-cms-tokens-authentication-2/graders/loads-cms-tokens-authentication.md b/evals/routing-cms-tokens-authentication-2/graders/loads-cms-tokens-authentication.md new file mode 100644 index 0000000..0f6f911 --- /dev/null +++ b/evals/routing-cms-tokens-authentication-2/graders/loads-cms-tokens-authentication.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-tokens-authentication"' +min: 1 +--- +The agent loads the `cms-tokens-authentication` skill. diff --git a/evals/routing-cms-tokens-authentication-2/prompt.md b/evals/routing-cms-tokens-authentication-2/prompt.md new file mode 100644 index 0000000..5184b5e --- /dev/null +++ b/evals/routing-cms-tokens-authentication-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-tokens-authentication-2 +tags: [routing, cms-tokens-authentication] +max_turns: 3 +timeout_seconds: 180 +--- +Which Contentstack token should my frontend app use? diff --git a/evals/routing-cms-variants-personalization-1/graders/loads-cms-variants-personalization.md b/evals/routing-cms-variants-personalization-1/graders/loads-cms-variants-personalization.md new file mode 100644 index 0000000..5af89d6 --- /dev/null +++ b/evals/routing-cms-variants-personalization-1/graders/loads-cms-variants-personalization.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-variants-personalization"' +min: 1 +--- +The agent loads the `cms-variants-personalization` skill. diff --git a/evals/routing-cms-variants-personalization-1/graders/skips-personalize.md b/evals/routing-cms-variants-personalization-1/graders/skips-personalize.md new file mode 100644 index 0000000..67320cb --- /dev/null +++ b/evals/routing-cms-variants-personalization-1/graders/skips-personalize.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?personalize"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `personalize` skill. diff --git a/evals/routing-cms-variants-personalization-1/prompt.md b/evals/routing-cms-variants-personalization-1/prompt.md new file mode 100644 index 0000000..576c4c0 --- /dev/null +++ b/evals/routing-cms-variants-personalization-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-variants-personalization-1 +tags: [routing, cms-variants-personalization] +max_turns: 3 +timeout_seconds: 180 +--- +What are entry variants and variant groups in Contentstack, and how do I fetch a variant? diff --git a/evals/routing-cms-variants-personalization-2/graders/loads-cms-variants-personalization.md b/evals/routing-cms-variants-personalization-2/graders/loads-cms-variants-personalization.md new file mode 100644 index 0000000..5af89d6 --- /dev/null +++ b/evals/routing-cms-variants-personalization-2/graders/loads-cms-variants-personalization.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-variants-personalization"' +min: 1 +--- +The agent loads the `cms-variants-personalization` skill. diff --git a/evals/routing-cms-variants-personalization-2/prompt.md b/evals/routing-cms-variants-personalization-2/prompt.md new file mode 100644 index 0000000..e0524fa --- /dev/null +++ b/evals/routing-cms-variants-personalization-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-variants-personalization-2 +tags: [routing, cms-variants-personalization] +max_turns: 3 +timeout_seconds: 180 +--- +Should I use Contentstack entry variants or separate entries per audience? diff --git a/evals/routing-cms-webhooks-1/graders/loads-cms-webhooks.md b/evals/routing-cms-webhooks-1/graders/loads-cms-webhooks.md new file mode 100644 index 0000000..01cbb86 --- /dev/null +++ b/evals/routing-cms-webhooks-1/graders/loads-cms-webhooks.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-webhooks"' +min: 1 +--- +The agent loads the `cms-webhooks` skill. diff --git a/evals/routing-cms-webhooks-1/prompt.md b/evals/routing-cms-webhooks-1/prompt.md new file mode 100644 index 0000000..b67e854 --- /dev/null +++ b/evals/routing-cms-webhooks-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-webhooks-1 +tags: [routing, cms-webhooks] +max_turns: 3 +timeout_seconds: 180 +--- +How do I verify a webhook request really came from Contentstack? diff --git a/evals/routing-cms-webhooks-2/graders/loads-cms-webhooks.md b/evals/routing-cms-webhooks-2/graders/loads-cms-webhooks.md new file mode 100644 index 0000000..01cbb86 --- /dev/null +++ b/evals/routing-cms-webhooks-2/graders/loads-cms-webhooks.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-webhooks"' +min: 1 +--- +The agent loads the `cms-webhooks` skill. diff --git a/evals/routing-cms-webhooks-2/graders/skips-automations.md b/evals/routing-cms-webhooks-2/graders/skips-automations.md new file mode 100644 index 0000000..bf5c129 --- /dev/null +++ b/evals/routing-cms-webhooks-2/graders/skips-automations.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?automations"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `automations` skill. diff --git a/evals/routing-cms-webhooks-2/prompt.md b/evals/routing-cms-webhooks-2/prompt.md new file mode 100644 index 0000000..e9a1a08 --- /dev/null +++ b/evals/routing-cms-webhooks-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-webhooks-2 +tags: [routing, cms-webhooks] +max_turns: 3 +timeout_seconds: 180 +--- +How do I trigger a site rebuild with a Contentstack webhook when content is published? diff --git a/evals/routing-cms-workflows-1/graders/loads-cms-workflows.md b/evals/routing-cms-workflows-1/graders/loads-cms-workflows.md new file mode 100644 index 0000000..10b8f6a --- /dev/null +++ b/evals/routing-cms-workflows-1/graders/loads-cms-workflows.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-workflows"' +min: 1 +--- +The agent loads the `cms-workflows` skill. diff --git a/evals/routing-cms-workflows-1/prompt.md b/evals/routing-cms-workflows-1/prompt.md new file mode 100644 index 0000000..61ba049 --- /dev/null +++ b/evals/routing-cms-workflows-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-workflows-1 +tags: [routing, cms-workflows] +max_turns: 3 +timeout_seconds: 180 +--- +How do I prevent an author from approving their own content in a Contentstack workflow? diff --git a/evals/routing-cms-workflows-2/graders/loads-cms-workflows.md b/evals/routing-cms-workflows-2/graders/loads-cms-workflows.md new file mode 100644 index 0000000..10b8f6a --- /dev/null +++ b/evals/routing-cms-workflows-2/graders/loads-cms-workflows.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-workflows"' +min: 1 +--- +The agent loads the `cms-workflows` skill. diff --git a/evals/routing-cms-workflows-2/prompt.md b/evals/routing-cms-workflows-2/prompt.md new file mode 100644 index 0000000..b41d2ca --- /dev/null +++ b/evals/routing-cms-workflows-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-cms-workflows-2 +tags: [routing, cms-workflows] +max_turns: 3 +timeout_seconds: 180 +--- +How do Contentstack publish rules differ from workflows? diff --git a/evals/routing-developer-hub-app-architect-1/graders/loads-developer-hub-app-architect.md b/evals/routing-developer-hub-app-architect-1/graders/loads-developer-hub-app-architect.md new file mode 100644 index 0000000..d65c2d0 --- /dev/null +++ b/evals/routing-developer-hub-app-architect-1/graders/loads-developer-hub-app-architect.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?developer-hub-app-architect"' +min: 1 +--- +The agent loads the `developer-hub-app-architect` skill. diff --git a/evals/routing-developer-hub-app-architect-1/graders/skips-marketplace-apps.md b/evals/routing-developer-hub-app-architect-1/graders/skips-marketplace-apps.md new file mode 100644 index 0000000..e665452 --- /dev/null +++ b/evals/routing-developer-hub-app-architect-1/graders/skips-marketplace-apps.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?marketplace-apps"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `marketplace-apps` skill. diff --git a/evals/routing-developer-hub-app-architect-1/prompt.md b/evals/routing-developer-hub-app-architect-1/prompt.md new file mode 100644 index 0000000..0b076b8 --- /dev/null +++ b/evals/routing-developer-hub-app-architect-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-developer-hub-app-architect-1 +tags: [routing, developer-hub-app-architect] +max_turns: 3 +timeout_seconds: 180 +--- +Build a private Contentstack app that adds AI suggestions in the entry sidebar. diff --git a/evals/routing-developer-hub-app-architect-2/graders/loads-developer-hub-app-architect.md b/evals/routing-developer-hub-app-architect-2/graders/loads-developer-hub-app-architect.md new file mode 100644 index 0000000..d65c2d0 --- /dev/null +++ b/evals/routing-developer-hub-app-architect-2/graders/loads-developer-hub-app-architect.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?developer-hub-app-architect"' +min: 1 +--- +The agent loads the `developer-hub-app-architect` skill. diff --git a/evals/routing-developer-hub-app-architect-2/prompt.md b/evals/routing-developer-hub-app-architect-2/prompt.md new file mode 100644 index 0000000..c3d6472 --- /dev/null +++ b/evals/routing-developer-hub-app-architect-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-developer-hub-app-architect-2 +tags: [routing, developer-hub-app-architect] +max_turns: 3 +timeout_seconds: 180 +--- +Which Contentstack app UI location should I use for a product picker custom field? diff --git a/evals/routing-dx-cli-1/graders/loads-dx-cli.md b/evals/routing-dx-cli-1/graders/loads-dx-cli.md new file mode 100644 index 0000000..1feca6f --- /dev/null +++ b/evals/routing-dx-cli-1/graders/loads-dx-cli.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-cli"' +min: 1 +--- +The agent loads the `dx-cli` skill. diff --git a/evals/routing-dx-cli-1/prompt.md b/evals/routing-dx-cli-1/prompt.md new file mode 100644 index 0000000..e9855e3 --- /dev/null +++ b/evals/routing-dx-cli-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-cli-1 +tags: [routing, dx-cli] +max_turns: 3 +timeout_seconds: 180 +--- +How do I export one Contentstack stack and import it into another with the CLI? diff --git a/evals/routing-dx-cli-2/graders/loads-dx-cli.md b/evals/routing-dx-cli-2/graders/loads-dx-cli.md new file mode 100644 index 0000000..1feca6f --- /dev/null +++ b/evals/routing-dx-cli-2/graders/loads-dx-cli.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-cli"' +min: 1 +--- +The agent loads the `dx-cli` skill. diff --git a/evals/routing-dx-cli-2/prompt.md b/evals/routing-dx-cli-2/prompt.md new file mode 100644 index 0000000..6332b7b --- /dev/null +++ b/evals/routing-dx-cli-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-cli-2 +tags: [routing, dx-cli] +max_turns: 3 +timeout_seconds: 180 +--- +Bulk publish all blog entries to production with csdx. diff --git a/evals/routing-dx-delivery-sdk-1/graders/loads-dx-delivery-sdk.md b/evals/routing-dx-delivery-sdk-1/graders/loads-dx-delivery-sdk.md new file mode 100644 index 0000000..5f553b3 --- /dev/null +++ b/evals/routing-dx-delivery-sdk-1/graders/loads-dx-delivery-sdk.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-delivery-sdk"' +min: 1 +--- +The agent loads the `dx-delivery-sdk` skill. diff --git a/evals/routing-dx-delivery-sdk-1/prompt.md b/evals/routing-dx-delivery-sdk-1/prompt.md new file mode 100644 index 0000000..0bc736d --- /dev/null +++ b/evals/routing-dx-delivery-sdk-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-delivery-sdk-1 +tags: [routing, dx-delivery-sdk] +max_turns: 3 +timeout_seconds: 180 +--- +Write a @contentstack/delivery-sdk query for blog posts with author references included. diff --git a/evals/routing-dx-delivery-sdk-2/graders/loads-dx-delivery-sdk.md b/evals/routing-dx-delivery-sdk-2/graders/loads-dx-delivery-sdk.md new file mode 100644 index 0000000..5f553b3 --- /dev/null +++ b/evals/routing-dx-delivery-sdk-2/graders/loads-dx-delivery-sdk.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-delivery-sdk"' +min: 1 +--- +The agent loads the `dx-delivery-sdk` skill. diff --git a/evals/routing-dx-delivery-sdk-2/prompt.md b/evals/routing-dx-delivery-sdk-2/prompt.md new file mode 100644 index 0000000..a3f5334 --- /dev/null +++ b/evals/routing-dx-delivery-sdk-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-delivery-sdk-2 +tags: [routing, dx-delivery-sdk] +max_turns: 3 +timeout_seconds: 180 +--- +Create a TypeScript helper that fetches a Contentstack entry by URL with the Delivery SDK. diff --git a/evals/routing-dx-kickstart-next-1/graders/loads-dx-kickstart-next.md b/evals/routing-dx-kickstart-next-1/graders/loads-dx-kickstart-next.md new file mode 100644 index 0000000..f430785 --- /dev/null +++ b/evals/routing-dx-kickstart-next-1/graders/loads-dx-kickstart-next.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-kickstart-next"' +min: 1 +--- +The agent loads the `dx-kickstart-next` skill. diff --git a/evals/routing-dx-kickstart-next-1/prompt.md b/evals/routing-dx-kickstart-next-1/prompt.md new file mode 100644 index 0000000..8f445ff --- /dev/null +++ b/evals/routing-dx-kickstart-next-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-kickstart-next-1 +tags: [routing, dx-kickstart-next] +max_turns: 3 +timeout_seconds: 180 +--- +I'm working in a fork of contentstack/kickstart-next. Where do I add a new environment variable? diff --git a/evals/routing-dx-kickstart-next-2/graders/loads-dx-kickstart-next.md b/evals/routing-dx-kickstart-next-2/graders/loads-dx-kickstart-next.md new file mode 100644 index 0000000..f430785 --- /dev/null +++ b/evals/routing-dx-kickstart-next-2/graders/loads-dx-kickstart-next.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-kickstart-next"' +min: 1 +--- +The agent loads the `dx-kickstart-next` skill. diff --git a/evals/routing-dx-kickstart-next-2/prompt.md b/evals/routing-dx-kickstart-next-2/prompt.md new file mode 100644 index 0000000..d16250a --- /dev/null +++ b/evals/routing-dx-kickstart-next-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-kickstart-next-2 +tags: [routing, dx-kickstart-next] +max_turns: 3 +timeout_seconds: 180 +--- +Review this PR to our kickstart-next fork that changes the Contentstack data fetching. diff --git a/evals/routing-dx-mcp-server-1/graders/loads-dx-mcp-server.md b/evals/routing-dx-mcp-server-1/graders/loads-dx-mcp-server.md new file mode 100644 index 0000000..7e71db8 --- /dev/null +++ b/evals/routing-dx-mcp-server-1/graders/loads-dx-mcp-server.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-mcp-server"' +min: 1 +--- +The agent loads the `dx-mcp-server` skill. diff --git a/evals/routing-dx-mcp-server-1/prompt.md b/evals/routing-dx-mcp-server-1/prompt.md new file mode 100644 index 0000000..ab8425a --- /dev/null +++ b/evals/routing-dx-mcp-server-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-mcp-server-1 +tags: [routing, dx-mcp-server] +max_turns: 3 +timeout_seconds: 180 +--- +How do I connect Claude Code to my Contentstack stack over MCP? diff --git a/evals/routing-dx-mcp-server-2/graders/loads-dx-mcp-server.md b/evals/routing-dx-mcp-server-2/graders/loads-dx-mcp-server.md new file mode 100644 index 0000000..7e71db8 --- /dev/null +++ b/evals/routing-dx-mcp-server-2/graders/loads-dx-mcp-server.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-mcp-server"' +min: 1 +--- +The agent loads the `dx-mcp-server` skill. diff --git a/evals/routing-dx-mcp-server-2/prompt.md b/evals/routing-dx-mcp-server-2/prompt.md new file mode 100644 index 0000000..8b448fe --- /dev/null +++ b/evals/routing-dx-mcp-server-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-mcp-server-2 +tags: [routing, dx-mcp-server] +max_turns: 3 +timeout_seconds: 180 +--- +Should my team use the Contentstack MCP server or MCP Profile Hub? diff --git a/evals/routing-dx-migrate-js-to-ts-sdk-1/graders/loads-dx-migrate-js-to-ts-sdk.md b/evals/routing-dx-migrate-js-to-ts-sdk-1/graders/loads-dx-migrate-js-to-ts-sdk.md new file mode 100644 index 0000000..f5c6a25 --- /dev/null +++ b/evals/routing-dx-migrate-js-to-ts-sdk-1/graders/loads-dx-migrate-js-to-ts-sdk.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-migrate-js-to-ts-sdk"' +min: 1 +--- +The agent loads the `dx-migrate-js-to-ts-sdk` skill. diff --git a/evals/routing-dx-migrate-js-to-ts-sdk-1/graders/skips-dx-delivery-sdk.md b/evals/routing-dx-migrate-js-to-ts-sdk-1/graders/skips-dx-delivery-sdk.md new file mode 100644 index 0000000..fd1de2d --- /dev/null +++ b/evals/routing-dx-migrate-js-to-ts-sdk-1/graders/skips-dx-delivery-sdk.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-delivery-sdk"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `dx-delivery-sdk` skill. diff --git a/evals/routing-dx-migrate-js-to-ts-sdk-1/prompt.md b/evals/routing-dx-migrate-js-to-ts-sdk-1/prompt.md new file mode 100644 index 0000000..43951a4 --- /dev/null +++ b/evals/routing-dx-migrate-js-to-ts-sdk-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-migrate-js-to-ts-sdk-1 +tags: [routing, dx-migrate-js-to-ts-sdk] +max_turns: 3 +timeout_seconds: 180 +--- +Migrate this Contentstack JavaScript SDK code (Stack, Entry, Query) to the TypeScript Delivery SDK. diff --git a/evals/routing-dx-migrate-js-to-ts-sdk-2/graders/loads-dx-migrate-js-to-ts-sdk.md b/evals/routing-dx-migrate-js-to-ts-sdk-2/graders/loads-dx-migrate-js-to-ts-sdk.md new file mode 100644 index 0000000..f5c6a25 --- /dev/null +++ b/evals/routing-dx-migrate-js-to-ts-sdk-2/graders/loads-dx-migrate-js-to-ts-sdk.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?dx-migrate-js-to-ts-sdk"' +min: 1 +--- +The agent loads the `dx-migrate-js-to-ts-sdk` skill. diff --git a/evals/routing-dx-migrate-js-to-ts-sdk-2/prompt.md b/evals/routing-dx-migrate-js-to-ts-sdk-2/prompt.md new file mode 100644 index 0000000..988d175 --- /dev/null +++ b/evals/routing-dx-migrate-js-to-ts-sdk-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-dx-migrate-js-to-ts-sdk-2 +tags: [routing, dx-migrate-js-to-ts-sdk] +max_turns: 3 +timeout_seconds: 180 +--- +What changes when moving from the contentstack npm package to @contentstack/delivery-sdk? diff --git a/evals/routing-launch-platform-1/graders/loads-launch-platform.md b/evals/routing-launch-platform-1/graders/loads-launch-platform.md new file mode 100644 index 0000000..89ac146 --- /dev/null +++ b/evals/routing-launch-platform-1/graders/loads-launch-platform.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?launch-platform"' +min: 1 +--- +The agent loads the `launch-platform` skill. diff --git a/evals/routing-launch-platform-1/prompt.md b/evals/routing-launch-platform-1/prompt.md new file mode 100644 index 0000000..57f2dab --- /dev/null +++ b/evals/routing-launch-platform-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-launch-platform-1 +tags: [routing, launch-platform] +max_turns: 3 +timeout_seconds: 180 +--- +How do I deploy my Next.js app to Contentstack Launch? diff --git a/evals/routing-launch-platform-2/graders/loads-launch-platform.md b/evals/routing-launch-platform-2/graders/loads-launch-platform.md new file mode 100644 index 0000000..89ac146 --- /dev/null +++ b/evals/routing-launch-platform-2/graders/loads-launch-platform.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?launch-platform"' +min: 1 +--- +The agent loads the `launch-platform` skill. diff --git a/evals/routing-launch-platform-2/prompt.md b/evals/routing-launch-platform-2/prompt.md new file mode 100644 index 0000000..3cbd346 --- /dev/null +++ b/evals/routing-launch-platform-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-launch-platform-2 +tags: [routing, launch-platform] +max_turns: 3 +timeout_seconds: 180 +--- +Should this middleware be a Launch Edge Function or a Cloud Function? diff --git a/evals/routing-lytics-1/graders/loads-lytics.md b/evals/routing-lytics-1/graders/loads-lytics.md new file mode 100644 index 0000000..a998a72 --- /dev/null +++ b/evals/routing-lytics-1/graders/loads-lytics.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?lytics"' +min: 1 +--- +The agent loads the `lytics` skill. diff --git a/evals/routing-lytics-1/prompt.md b/evals/routing-lytics-1/prompt.md new file mode 100644 index 0000000..3335f51 --- /dev/null +++ b/evals/routing-lytics-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-lytics-1 +tags: [routing, lytics] +max_turns: 3 +timeout_seconds: 180 +--- +How do I install the Lytics tag on my Next.js site? diff --git a/evals/routing-lytics-2/graders/loads-lytics.md b/evals/routing-lytics-2/graders/loads-lytics.md new file mode 100644 index 0000000..a998a72 --- /dev/null +++ b/evals/routing-lytics-2/graders/loads-lytics.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?lytics"' +min: 1 +--- +The agent loads the `lytics` skill. diff --git a/evals/routing-lytics-2/prompt.md b/evals/routing-lytics-2/prompt.md new file mode 100644 index 0000000..8124f08 --- /dev/null +++ b/evals/routing-lytics-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-lytics-2 +tags: [routing, lytics] +max_turns: 3 +timeout_seconds: 180 +--- +How do I delete a user's data from Lytics for a GDPR request? diff --git a/evals/routing-marketplace-apps-1/graders/loads-marketplace-apps.md b/evals/routing-marketplace-apps-1/graders/loads-marketplace-apps.md new file mode 100644 index 0000000..bc4ec9f --- /dev/null +++ b/evals/routing-marketplace-apps-1/graders/loads-marketplace-apps.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?marketplace-apps"' +min: 1 +--- +The agent loads the `marketplace-apps` skill. diff --git a/evals/routing-marketplace-apps-1/graders/skips-asset-management.md b/evals/routing-marketplace-apps-1/graders/skips-asset-management.md new file mode 100644 index 0000000..47e2524 --- /dev/null +++ b/evals/routing-marketplace-apps-1/graders/skips-asset-management.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?asset-management"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `asset-management` skill. diff --git a/evals/routing-marketplace-apps-1/graders/skips-developer-hub-app-architect.md b/evals/routing-marketplace-apps-1/graders/skips-developer-hub-app-architect.md new file mode 100644 index 0000000..8276bec --- /dev/null +++ b/evals/routing-marketplace-apps-1/graders/skips-developer-hub-app-architect.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?developer-hub-app-architect"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `developer-hub-app-architect` skill. diff --git a/evals/routing-marketplace-apps-1/prompt.md b/evals/routing-marketplace-apps-1/prompt.md new file mode 100644 index 0000000..474365b --- /dev/null +++ b/evals/routing-marketplace-apps-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-marketplace-apps-1 +tags: [routing, marketplace-apps] +max_turns: 3 +timeout_seconds: 180 +--- +Which Contentstack Marketplace app should I use to connect Bynder to my entries? diff --git a/evals/routing-marketplace-apps-2/graders/loads-marketplace-apps.md b/evals/routing-marketplace-apps-2/graders/loads-marketplace-apps.md new file mode 100644 index 0000000..bc4ec9f --- /dev/null +++ b/evals/routing-marketplace-apps-2/graders/loads-marketplace-apps.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?marketplace-apps"' +min: 1 +--- +The agent loads the `marketplace-apps` skill. diff --git a/evals/routing-marketplace-apps-2/graders/skips-automations.md b/evals/routing-marketplace-apps-2/graders/skips-automations.md new file mode 100644 index 0000000..bf5c129 --- /dev/null +++ b/evals/routing-marketplace-apps-2/graders/skips-automations.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?automations"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `automations` skill. diff --git a/evals/routing-marketplace-apps-2/prompt.md b/evals/routing-marketplace-apps-2/prompt.md new file mode 100644 index 0000000..a0fe5ea --- /dev/null +++ b/evals/routing-marketplace-apps-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-marketplace-apps-2 +tags: [routing, marketplace-apps] +max_turns: 3 +timeout_seconds: 180 +--- +How do I install and configure the Algolia app from the Contentstack Marketplace? diff --git a/evals/routing-migration-companion-1/graders/loads-migration-companion.md b/evals/routing-migration-companion-1/graders/loads-migration-companion.md new file mode 100644 index 0000000..020d6da --- /dev/null +++ b/evals/routing-migration-companion-1/graders/loads-migration-companion.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?migration-companion"' +min: 1 +--- +The agent loads the `migration-companion` skill. diff --git a/evals/routing-migration-companion-1/prompt.md b/evals/routing-migration-companion-1/prompt.md new file mode 100644 index 0000000..97d4800 --- /dev/null +++ b/evals/routing-migration-companion-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-migration-companion-1 +tags: [routing, migration-companion] +max_turns: 3 +timeout_seconds: 180 +--- +Migrate our Contentful space to Contentstack. diff --git a/evals/routing-migration-companion-2/graders/loads-migration-companion.md b/evals/routing-migration-companion-2/graders/loads-migration-companion.md new file mode 100644 index 0000000..020d6da --- /dev/null +++ b/evals/routing-migration-companion-2/graders/loads-migration-companion.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?migration-companion"' +min: 1 +--- +The agent loads the `migration-companion` skill. diff --git a/evals/routing-migration-companion-2/prompt.md b/evals/routing-migration-companion-2/prompt.md new file mode 100644 index 0000000..e1f2f26 --- /dev/null +++ b/evals/routing-migration-companion-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-migration-companion-2 +tags: [routing, migration-companion] +max_turns: 3 +timeout_seconds: 180 +--- +Help me port my site from Contentful to Contentstack, content and code. diff --git a/evals/routing-personalize-1/graders/loads-personalize.md b/evals/routing-personalize-1/graders/loads-personalize.md new file mode 100644 index 0000000..6ba9e7a --- /dev/null +++ b/evals/routing-personalize-1/graders/loads-personalize.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?personalize"' +min: 1 +--- +The agent loads the `personalize` skill. diff --git a/evals/routing-personalize-1/graders/skips-cms-variants-personalization.md b/evals/routing-personalize-1/graders/skips-cms-variants-personalization.md new file mode 100644 index 0000000..9cd9f95 --- /dev/null +++ b/evals/routing-personalize-1/graders/skips-cms-variants-personalization.md @@ -0,0 +1,8 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?cms-variants-personalization"' +min: 0 +max: 0 +--- +The agent doesn't load the neighbouring `cms-variants-personalization` skill. diff --git a/evals/routing-personalize-1/prompt.md b/evals/routing-personalize-1/prompt.md new file mode 100644 index 0000000..43d763c --- /dev/null +++ b/evals/routing-personalize-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-personalize-1 +tags: [routing, personalize] +max_turns: 3 +timeout_seconds: 180 +--- +How do I add Contentstack Personalize to my Next.js site with edge middleware? diff --git a/evals/routing-personalize-2/graders/loads-personalize.md b/evals/routing-personalize-2/graders/loads-personalize.md new file mode 100644 index 0000000..6ba9e7a --- /dev/null +++ b/evals/routing-personalize-2/graders/loads-personalize.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?personalize"' +min: 1 +--- +The agent loads the `personalize` skill. diff --git a/evals/routing-personalize-2/prompt.md b/evals/routing-personalize-2/prompt.md new file mode 100644 index 0000000..76fa82c --- /dev/null +++ b/evals/routing-personalize-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-personalize-2 +tags: [routing, personalize] +max_turns: 3 +timeout_seconds: 180 +--- +Should this be a segmented experience or an A/B test in Contentstack Personalize? diff --git a/evals/routing-studio-1/graders/loads-studio.md b/evals/routing-studio-1/graders/loads-studio.md new file mode 100644 index 0000000..99d7be5 --- /dev/null +++ b/evals/routing-studio-1/graders/loads-studio.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?studio"' +min: 1 +--- +The agent loads the `studio` skill. diff --git a/evals/routing-studio-1/prompt.md b/evals/routing-studio-1/prompt.md new file mode 100644 index 0000000..2432da7 --- /dev/null +++ b/evals/routing-studio-1/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-studio-1 +tags: [routing, studio] +max_turns: 3 +timeout_seconds: 180 +--- +How do I build a page composition in Contentstack Studio? diff --git a/evals/routing-studio-2/graders/loads-studio.md b/evals/routing-studio-2/graders/loads-studio.md new file mode 100644 index 0000000..99d7be5 --- /dev/null +++ b/evals/routing-studio-2/graders/loads-studio.md @@ -0,0 +1,7 @@ +--- +type: tool_used +tool: Skill +input_match: '"skill"\s*:\s*"(?:[\w-]+:)?studio"' +min: 1 +--- +The agent loads the `studio` skill. diff --git a/evals/routing-studio-2/prompt.md b/evals/routing-studio-2/prompt.md new file mode 100644 index 0000000..2b2d51d --- /dev/null +++ b/evals/routing-studio-2/prompt.md @@ -0,0 +1,7 @@ +--- +name: routing-studio-2 +tags: [routing, studio] +max_turns: 3 +timeout_seconds: 180 +--- +Register my React components with the Contentstack Studio SDK. diff --git a/gemini-extension.json b/gemini-extension.json index a940652..5d4bfe6 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "contentstack-skills", - "version": "0.3.1", + "version": "0.4.1", "description": "Contentstack agent skills for CMS modeling, Delivery SDK, Live Preview, Studio, Brand Kit, Developer Hub apps, Launch, and migrations.", "mcpServers": { "contentstack": { diff --git a/plugin.json b/plugin.json index 4b18e90..76168da 100644 --- a/plugin.json +++ b/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "contentstack-skills", - "version": "0.3.1", + "version": "0.4.1", "description": "Contentstack agent skills for CMS modeling, Delivery SDK, Live Preview, Studio, Brand Kit, Developer Hub apps, Launch, and migrations.", "author": { "name": "Contentstack", "url": "https://www.contentstack.com" }, "homepage": "https://developers.contentstack.com", diff --git a/scripts/validate.mjs b/scripts/validate.mjs index 24b17ce..4a76bb2 100644 --- a/scripts/validate.mjs +++ b/scripts/validate.mjs @@ -23,6 +23,8 @@ function markdownFiles(dir) { // --- Skills --------------------------------------------------------------- const NAME_RE = /^(?!.*--)[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/; +const SECTIONS = ["When to use", "Before you answer", "Instructions", "MCP tools", "Output", "Security", "References", "Examples"]; +const REQUIRED_SECTIONS = ["When to use", "Instructions", "MCP tools", "Security"]; const skillsDir = join(root, "skills"); const slugs = readdirSync(skillsDir).filter((d) => statSync(join(skillsDir, d)).isDirectory()); @@ -68,6 +70,16 @@ for (const slug of slugs) { else if (description.length > 1024) fail(`skills/${slug}: description is ${description.length} chars (max 1024)`); else if (!/\bUse when\b/.test(description)) fail(`skills/${slug}: description should say "Use when ..." so agents know when to load it`); + // Body sections follow docs/contributing/skill-template.md: required ones present, in order, nothing else. + const headings = [...withoutCode(text).matchAll(/^## (.+)$/gm)].map((m) => m[1].trim()); + const unknown = headings.filter((h) => !SECTIONS.includes(h)); + if (unknown.length) fail(`skills/${slug}/SKILL.md: sections not in the template: ${unknown.map((h) => `"${h}"`).join(", ")}`); + for (const h of REQUIRED_SECTIONS) if (!headings.includes(h)) fail(`skills/${slug}/SKILL.md: missing "## ${h}" section`); + const known = headings.filter((h) => SECTIONS.includes(h)); + if (known.some((h, i) => i && SECTIONS.indexOf(h) <= SECTIONS.indexOf(known[i - 1]))) { + fail(`skills/${slug}/SKILL.md: sections out of order or repeated (expected ${SECTIONS.join(", ")})`); + } + const security = withoutCode(text).split(/^## Security\b.*$/m)[1]?.split(/^## /m)[0]; if (security === undefined) fail(`skills/${slug}/SKILL.md: missing the mandatory "## Security" section`); else { diff --git a/skills/asset-management/SKILL.md b/skills/asset-management/SKILL.md index 4ce64da..b7a326f 100644 --- a/skills/asset-management/SKILL.md +++ b/skills/asset-management/SKILL.md @@ -6,65 +6,38 @@ allowed-tools: Read Grep Glob # Asset Management (Contentstack Assets DAM) -## Description +Advise on Contentstack Assets, the standalone DAM product (also called "Asset Management" in some docs): structuring spaces and workspaces, modeling metadata so assets are findable, using AI features safely, keeping the library free of duplicates, and knowing what can be recovered after a delete or replace. -Advise on Contentstack Assets, the standalone DAM product (also called "Asset Management" in some docs). Cover spaces and workspaces, folders, roles, asset types and metadata, localization, filters and saved views, AI-assisted metadata, duplicate management, versions, trash and restore, visual markups, and CMS integration. +## When to use -## When to Use +- Organizing assets in spaces, workspaces and folders. +- Modeling asset types and metadata, and searching by user-defined fields. +- Localization and saved views. +- AI tags and alt text. +- Finding and removing duplicates. +- Versions, trash and restore. +- Visual markups. +- Using Assets with a CMS stack. -Use when a user asks about the Contentstack Assets DAM: organizing assets in spaces, workspaces and folders, modeling asset metadata, AI tags and alt text, finding and removing duplicates, versioning, restoring deleted assets, visual markups, or using Assets with a CMS stack. +Use another skill for: -Do not use for the CMS stack asset library (stack-level uploads, folders, Image Delivery API, publishing to environments). Route those questions to `cms-assets`. If it is unclear which one the user means, ask whether they work in an Assets space or in the asset library inside a stack. +- The CMS stack asset library (stack-level uploads, folders, Image Delivery API, publishing to environments) → `cms-assets` +- Roles in a CMS stack → `cms-roles-permissions` +- Choosing a third-party DAM integration from the Marketplace → `marketplace-apps` -## User Problem +If it is unclear which product the user means, ask whether they work in an Assets space or in the asset library inside a stack. -Teams adopting Contentstack Assets need to structure spaces and workspaces sensibly, model metadata so assets are findable, use AI features safely, keep the library free of duplicates, and understand what is and is not recoverable when assets are deleted or replaced. +## Before you answer -## Success Criteria +Confirm which product the user means (Assets space or CMS stack library), then find out the organization's shape (brands, regions, teams) and number of spaces, the asset types and metadata the team needs, and the specific task or problem (duplicates, restore, versions, AI settings, markups). -- Distinguish the Assets DAM from the CMS asset library. -- Use the product's own terminology: space, workspace, main workspace, asset type, system metadata, user-defined metadata, duplicate set, visual markup. -- State documented behavior and limits accurately, and say plainly when something is not documented. -- Warn about irreversible or hard-to-reverse actions before the user takes them. - -## Expected Inputs - -- Which product the user means (Assets space or CMS stack library) -- Organization shape (brands, regions, teams) and number of spaces -- Asset types and metadata the team needs -- The specific task or problem (duplicates, restore, versions, AI settings, markups) - -## Expected Outputs - -- Space, workspace and folder structure recommendations -- Asset type and metadata modeling guidance -- Step-by-step UI paths for the task -- Gotchas and irreversible-action warnings -- Pointers to the official docs for anything not covered here - -## Example User Requests - -- How should I split my brands and regions across spaces and workspaces? -- How do I add custom fields to my images? -- How do I add a language to a workspace? -- Can I save a set of filters and reuse it? -- How do I search assets by a custom field value? -- Can Assets tag my images and write alt text automatically? -- How do I find and remove duplicate images? -- I deleted a folder by mistake. Can I get it back? -- How do I roll back to an earlier version of an asset? -- How do I add hotspots to a product image? -- How do I use assets from a space in my CMS entries? - -## Workflow Summary +## Instructions 1. Confirm the user means the Assets DAM, not the CMS asset library. 2. Identify the topic: structure, metadata, AI, duplicates, versions, trash, markups, or CMS integration. -3. Answer with documented behavior using the product's terminology. +3. Answer with documented behavior using the product's terminology: space, workspace, main workspace, asset type, system metadata, user-defined metadata, duplicate set, visual markup. 4. Flag limits and irreversible actions. -5. Link to the relevant docs page for anything undocumented or likely to change. - -## Instructions +5. Say plainly when something is not documented, and link to the relevant docs page for anything undocumented or likely to change. ### Spaces and workspaces @@ -90,11 +63,11 @@ Teams adopting Contentstack Assets need to structure spaces and workspaces sensi - Metadata comes in layers: **system metadata** (read-only: file name, UID, URLs, MIME type, size, created and modified details), **general metadata**, and **user-defined metadata** from custom fields. - Each **asset type** maps to one MIME type and one file extension. On upload, a matching type applies automatically and its fields appear. System types cover images, audio, video, documents and archives, and you can add custom types. -- User-defined fields are reusable across asset types. The currently supported field types are single line text, number, select and group. The product docs have listed this set differently over time, so point the user to the Asset Modeling docs if they need a type that isn't on this list. +- User-defined fields are reusable across asset types. The Asset Modeling docs list single line and multi line textbox, link, select, number, date, boolean and group, but state that only single line, number and group are currently supported. Point the user to the Asset Modeling docs before promising any other type. - Mandatory fields must be filled before an upload or save can finish. Use them sparingly so uploads are not blocked on optional information. - Edit metadata for an individual asset in the configurable metadata panel. - User-defined fields exist only in the Assets (DAM) product. The CMS stack asset library and its Management API don't read or update them, so direct any request to read or write custom metadata from code to the Assets (DAM) API. See the Assets API reference at https://www.contentstack.com/docs/developers/apis/assets-api for the current endpoints. -- **Filters and saved views:** User-defined fields can be used as filters when browsing assets, so well-modeled fields make the library searchable. A filter combination can be saved as a **saved view** and reused later instead of rebuilding the filters each time. Advise modeling fields with filtering in mind, for example a select field for campaign or usage rights. +- **Filters and saved views:** User-defined fields can be used as filters when browsing assets, so well-modeled fields make the library searchable. A filter combination can be saved as a **saved view** and reused later instead of rebuilding the filters each time. Advise modeling fields with filtering in mind, for example a single line field for campaign or usage rights (or a select field once select is supported). ### Localization @@ -135,6 +108,7 @@ Example request body: ### AI tags, alt text and colors - In the metadata panel, **Suggest Tags with AI** and **Suggest Description with AI** generate suggestions. AI can also extract dominant colors, which powers color-based filtering. Suggestions can be wrong, so review them before saving. +- The product also has AI-powered semantic (natural-language) search and reverse image search, depending on plan and rollout. They are not in the public docs yet, so confirm availability in the user's space before relying on them. - **Auto-populate at upload** is configured in Space Settings > AI Settings. Enable the AI Tags and Alt Text toggles, set Advanced Properties, and click Save Properties. - Applies to images and to new uploads only. Existing assets are not enriched, and replacing a file does not trigger it. - Values are written into version 1. No extra version is created, nothing waits for review, and uploads are not slowed down. @@ -187,32 +161,26 @@ Example request body: - `visual_markups` is an empty array when an asset has none. A hotspot returns x and y, and a bounding box also returns width and height. - Do not state CDN host names, URL formats or branch behavior for Assets as fact unless the user's docs confirm them. -## Output Format +## MCP tools -Be concise and practical. Use the product's terms. Give UI paths as `Menu > Item`. Use short bullets for steps, limits and gotchas. When something is undocumented or uncertain, say so and link to the docs instead of guessing. +No Contentstack MCP tool covers the Assets DAM (spaces, workspaces, asset types, duplicates, markups). Use the Assets UI or the Assets API. -## Tooling Notes +The `cma` asset tools (`get_all_assets`, `get_a_single_asset`, `publish_an_asset` and others) act on the CMS stack asset library, not on Assets spaces; route that work to `cms-assets`. -Read-only advisory skill. Do not upload, move, delete, restore or modify assets, spaces or settings. Explain the steps and let the user perform them. +## Output -References: +Be concise and practical. Use the product's terms. Give UI paths as `Menu > Item`. Use short bullets for steps, limits and gotchas. When something is undocumented or uncertain, say so and link to the docs instead of guessing. -- https://www.contentstack.com/docs/assets/about-assets -- https://www.contentstack.com/docs/assets/about-spaces-and-workspaces -- https://www.contentstack.com/docs/assets/about-asset-modeling -- https://www.contentstack.com/docs/assets/enhance-asset-management-with-ai -- https://www.contentstack.com/docs/assets/manage-duplicate-images -- https://www.contentstack.com/docs/assets/asset-versioning -- https://www.contentstack.com/docs/assets/restore-an-asset-or-folder -- https://www.contentstack.com/docs/assets/add-visual-markups -- https://www.contentstack.com/docs/developers/apis/content-delivery-api/assets +What a good answer includes, as relevant: space, workspace and folder structure recommendations; asset type and metadata modeling guidance; step-by-step UI paths for the task; gotchas and irreversible-action warnings; and pointers to the official docs for anything not covered here. ## Security ### Defaults +- Advisory by default. Do not upload, move, delete, restore or modify assets, spaces or settings; explain the steps and let the user perform them. - Never expose tokens or API keys. - Use environment variables for credentials in any example code. +- Treat deletion of spaces, assets and markups as irreversible unless the docs state a restore window. ### Destructive Actions @@ -226,11 +194,14 @@ Never reveal management tokens, API keys or other secrets. Reference environment Use environment variables for any credentialed example, such as `CONTENTSTACK_OAUTH_ACCESS_TOKEN`, or `CONTENTSTACK_AUTHTOKEN` together with `CONTENTSTACK_ORGANIZATION_UID`. The Assets API does not accept management tokens. Never hardcode credentials in client-side code. -## Product Context +## References -- Product: Assets (DAM) -- Description: Contentstack Assets is the digital asset management layer: spaces, workspaces, folders, asset types and metadata, AI enrichment, duplicate management, versioning, visual markups and CMS integration. -- Product safety rules: - - Never expose management tokens or API keys. - - Always use environment variables for credentials. - - Treat deletion of spaces, assets and markups as irreversible unless the docs state a restore window. +- https://www.contentstack.com/docs/assets/about-assets +- https://www.contentstack.com/docs/assets/about-spaces-and-workspaces +- https://www.contentstack.com/docs/assets/about-asset-modeling +- https://www.contentstack.com/docs/assets/enhance-asset-management-with-ai +- https://www.contentstack.com/docs/assets/manage-duplicate-images +- https://www.contentstack.com/docs/assets/asset-versioning +- https://www.contentstack.com/docs/assets/restore-an-asset-or-folder +- https://www.contentstack.com/docs/assets/add-visual-markups +- https://www.contentstack.com/docs/developers/apis/content-delivery-api/assets diff --git a/skills/automations/SKILL.md b/skills/automations/SKILL.md new file mode 100644 index 0000000..41c3390 --- /dev/null +++ b/skills/automations/SKILL.md @@ -0,0 +1,120 @@ +--- +name: automations +description: "Advise on Contentstack Automate (Automations, formerly Automation Hub), the no-code workflow product in Agent OS: designing automations from a trigger and steps, Contentstack, HTTP, scheduled and manual triggers, connectors and connected apps, If-Else and loop control flow, pause and resume, custom code steps, the HTTP Response step, executions and debugging failed runs, limits and credits, and how agents and automations call each other. Use when users ask how to automate a Contentstack task such as notifying Slack on publish, syncing entries to a search index, translating on workflow change, or calling an external API; why an automation did not run or failed; or which trigger, connector or step to use. For CMS webhook configuration itself, use cms-webhooks." +allowed-tools: Read Grep Glob +--- + +# Automations + +Advise on Contentstack Automate (Automations, formerly Automation Hub), the no-code workflow product in Agent OS: triggers, steps and connectors, control flow, custom code, HTTP responses, executions and debugging, limits, and the bridge between automations and agents. + +## When to use + +- Automating a Contentstack or cross-system task: publish notifications, search indexing, translation, approvals, data syncs, calling an external API. +- Choosing a trigger, connector or step. +- Working out why an automation didn't run or failed. +- Connecting automations with agents. + +Use another skill for: + +- Configuring CMS webhooks that point at your own receiver → `cms-webhooks` +- Workflow stages and publish rules inside the CMS → `cms-workflows` +- Exposing automations to AI clients through MCP Profile Hub → `dx-mcp-server` +- Ready-made Marketplace integrations such as search or translation apps → `marketplace-apps` + +## Before you answer + +Find out the task to automate and the systems involved, what starts it (content event, HTTP call, schedule, manual), the data the steps need and where it comes from, and for failures the execution status and the failing step's output. + +## Instructions + +1. Clarify the outcome and the event that should start it. +2. Pick one trigger, then the connector actions in order, keeping the chain short and readable. +3. Add control flow only where the logic needs it. +4. Use a custom code step only when no connector action fits. +5. Activate, test, and debug from the execution record, not guesses. State limits and unshipped features honestly. + + +### Building blocks + +An automation is one trigger plus an ordered list of steps. Each step usually runs one connector action and can use outputs from earlier steps with `{{step.path}}` references. A new automation is a draft and runs only after it is activated. An active automation can't be edited: switch it off, change it, and switch it on again. + +### Triggers + +- **Contentstack (CMS) events:** pick the stack and the event, such as an entry being published. The automation registers its trigger URL when activated. Events that arrive while it is inactive are accepted but nothing runs. +- **HTTP:** an incoming request to the automation's trigger URL starts a run. The URL has no documented authentication, so treat it as a secret, and check a shared header or token in an early If-Else step when the caller can send one. +- **Schedule:** runs on a timetable for syncs and reports. +- **Manual:** a person or an agent starts it on demand. + +### Connectors and connected apps + +Connectors package actions for outside services: Contentstack products, Slack, Microsoft Teams, Jira, Salesforce, AWS Lambda, translation and search services, email, HTTP and more. Saved credentials live in **Connected apps**, which shows which automations use each connection. Reauthorize expired OAuth connections there. A connection can't be deleted while an active automation uses it. + +### Control flow + +- **If-Else:** route on a condition; the branches merge afterwards. +- **Loop:** repeat steps for each item in a list from an earlier step. Loops have a per-plan iteration cap; steps over the cap are skipped. +- **Pause:** stop and wait for an approval, a callback or a timed event, then resume. A paused run can be resumed a limited number of times and carries a limited payload. + +### Custom code + +Use a code step when no connector action fits. It runs JavaScript in an isolated sandbox with no access to the host process or other runs. Only the return value is passed on, and there is a short time limit (about 5 seconds), so keep it to data shaping and light logic. Do heavy work in an external service through the HTTP connector. Code steps count against a monthly allowance; a step over it is skipped. + +### HTTP responses + +For HTTP-triggered automations, a **Response** step returns a reply to the caller. There can be only one, and it must be the last top-level step, outside loops and branches. Use it when the automation acts as a small API. + +### Executions and debugging + +Each run creates an execution with a status (pending, queued, running, paused, success, partially-executed, failed, rejected) and per-step outputs. When something goes wrong: + +1. Check the automation is active and the trigger points at the right stack and event. +2. Open Executions and find the run. No run means the trigger didn't fire or the automation was inactive. +3. Read the first failing step's input and output, then fix the mapping, credentials or connector settings. +4. Re-run the failed execution once the cause is fixed. + +Password fields are masked in logs. Runs over the organization's per-minute limit are rejected with 429. + +### Limits and credits + +Limits depend on the plan. Typical defaults: about 15 steps per automation (the trigger counts), 100 loop iterations, 1 MB output per step, and an HTTP connector cap of 5 minutes or 2 MB per response. Runs with AI work use AI credits reserved before the run starts; a run without enough credits is refused. Check the organization's plan for exact values. + +### Agents and automations + +Agents (Polaris and Custom Agents) can start an automation as a tool call, so a conversation can trigger an existing workflow. Running a custom agent as a step inside an automation is in progress and may not be available. Building an automation by prompting Polaris on the canvas is not shipped yet; don't present it as available. + +## MCP tools + +When the Contentstack MCP server is connected with the `automations` group, these tools act on Automate: + +- Inspect: `list_automation_projects`, `get_automation_project`, `list_automations`, `get_automation` (optionally with its steps and triggers) (`automations`) +- Change: `create_automation_project`, `update_automation_project`, `set_automation_active`, `trigger_automation` (runs an automation with an HTTP trigger) (`automations`) +- Delete: `delete_automation_project` (`automations`) + +There are no tools for building steps, editing connections or reading executions; use the Automate UI for those. When debugging, read the automation with `get_automation` to check it is active and see its trigger, then check Executions. MCP Profile Hub can also expose active HTTP-triggered automations as tools of their own. + +## Output + +Lead with the recommended design as a numbered trigger-and-steps outline. Show `{{step.path}}` mappings and code snippets only where needed. For debugging, name the execution status and the failing step first. + +## Security + +### Defaults + +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Never expose connector credentials, OAuth tokens, API keys or trigger URLs. +- Store service credentials in Connected apps, never inline in steps or code. +- Validate input from HTTP triggers before acting on it. +- Don't present unshipped features as available. + +### Destructive Actions + +Before deleting automation projects, activating or deactivating an automation, or running one, name the project and automation and what the run will change, and wait for confirmation. Before suggesting steps that delete or overwrite content in Contentstack or other systems, state what will change and recommend testing on a non-production stack. + +### Secrets + +Never print or echo secrets, trigger URLs or masked values. Use placeholders in examples. + +### Environment Variables + +Use placeholder names for any credential in examples. Keep secrets in Connected apps or project variables, not in code steps. diff --git a/skills/brand-kit-assistant/SKILL.md b/skills/brand-kit-assistant/SKILL.md index 0b798d4..53944d4 100644 --- a/skills/brand-kit-assistant/SKILL.md +++ b/skills/brand-kit-assistant/SKILL.md @@ -1,71 +1,41 @@ --- name: brand-kit-assistant -description: "Advise users on Contentstack Brand Kit concepts, setup, governance, and on-brand AI generation. Route API-specific tasks to the right Brand Kit capability or reference skill, and enforce brand and safety rules before presenting anything as ready. Use when users ask about Contentstack Brand Kit, Voice Profiles, Knowledge Vault, brand voice, tone, style rules, on-brand AI generation, setup, governance, or API usage." +description: "Advise users on Contentstack Brand Kit concepts, setup, governance, and on-brand AI generation. Route API-specific tasks to the right Brand Kit capability or reference skill, and enforce brand and safety rules before presenting anything as ready. Use when users ask about Contentstack Brand Kit, Voice Profiles, Knowledge Vault, brand voice, tone, style rules, on-brand AI generation, setup, governance, or API usage. For connecting an agent to Brand Kit over MCP, use dx-mcp-server." --- # Brand Kit Assistant -## Description +The entry point for Contentstack Brand Kit: how Brand Kit, Voice Profiles and Knowledge Vault fit together, which workflow or API to use, and keeping generated content aligned with brand identity and approved source material. -Advise users on Contentstack Brand Kit concepts, setup, governance, and on-brand AI generation. Route API-specific tasks to the right Brand Kit capability or reference skill, and enforce brand and safety rules before presenting anything as ready. +## When to use -## When to Use +- Explaining Brand Kit, Voice Profiles and Knowledge Vault. +- Creating a Brand Kit from a website or file. +- Tuning a Voice Profile to match brand voice, tone and style rules. +- Keeping AI-generated content on-brand. +- Calling the Brand Kit Management, Knowledge Vault or Generative AI APIs. -Use when users ask about Contentstack Brand Kit, Voice Profiles, Knowledge Vault, brand voice, tone, style rules, on-brand AI generation, setup, governance, or API usage. Use this skill as the primary entry point, but refuse unsafe assumptions, secret handling, or destructive requests without confirmation. +Refuse unsafe assumptions, secret handling, or destructive requests without confirmation. -## User Problem +Use another skill for: -Users need one reliable entry point for Brand Kit. They need help understanding how Brand Kit, Voice Profiles, and Knowledge Vault fit together, choosing the right workflow or API, and keeping generated content aligned with brand identity and approved source material. +- Connecting an AI agent to Brand Kit over MCP → `dx-mcp-server` +- Building a Developer Hub app that uses Brand Kit → `developer-hub-app-architect` +- Automate workflows that call Brand Kit → `automations` -## Success Criteria +## Before you answer -- Explain Brand Kit, Voice Profiles, and Knowledge Vault accurately. -- Ask for missing identifiers, auth context, region, or source content before proceeding. -- Route API-specific work to the correct reference skill when available. -- Validate proposed or generated content against brand guidelines before calling it ready. -- Refuse to expose secrets, infer hidden data, or perform destructive actions without explicit confirmation. +Find out the user's goal, then only the inputs it needs: Brand Kit UID, organization UID, auth context (authtoken), region or base URL, the kit version (v1 or v2), Voice Profile details or a generation prompt, Knowledge Vault source content or retrieval context, a website URL or file, and brand voice, tone and style preferences. If required identifiers, auth, brand context, region, or source content are missing, ask concise follow-up questions. Do not guess or fabricate values. -## Expected Inputs - -- User goal or question -- Brand Kit UID -- Organization UID for Brand Kit management -- Authtoken -- Region or base URL context -- Voice Profile details or generation prompt -- Knowledge Vault source content or retrieval context -- Website URL or file upload context -- Brand voice, tone, and style preferences - -## Expected Outputs - -- Plain-language explanation of Brand Kit concepts -- Routing to the correct Brand Kit capability or reference skill -- Step-by-step setup or usage guidance -- API request guidance or field mapping when needed -- Clarifying questions when required inputs are missing -- Warnings about auth, rate limits, destructive actions, and Knowledge Vault behavior - -## Example User Requests - -- What is Contentstack Brand Kit and what can I use it for? -- How do I create a Brand Kit from our website? -- Can you update this Voice Profile to match our brand voice? -- How do I make AI-generated content stay on-brand? -- Can I get the original files back from Knowledge Vault? -- What do I need to call the Brand Kit API? - -## Workflow Summary +## Instructions 1. Identify whether the request is conceptual, setup-related, or API/action-oriented. 2. Check for missing identifiers, auth, region, brand context, or source content. 3. Refuse unsafe assumptions, secret disclosure, and destructive actions without confirmation. 4. Distinguish Brand Kit, Voice Profile, and Knowledge Vault behavior. -5. Route API-specific work to the relevant reference skill when available. +5. Route API-specific work to the relevant reference file. 6. Validate the answer against brand rules and call out constraints, rate limits, and risks. -## Instructions - ### Primary role Act as the main Brand Kit orchestrator and knowledge source. Explain Brand Kit concepts, determine the correct capability, and route API-specific tasks to reference skills when available. @@ -74,14 +44,6 @@ Act as the main Brand Kit orchestrator and knowledge source. Explain Brand Kit c If required identifiers, auth, brand context, region, or source content are missing, ask concise follow-up questions before proceeding. Do not guess or fabricate values. -### Secret handling - -Never expose, repeat, transform, or infer Brand Kit API tokens, authtokens, API keys, OAuth secrets, or decrypted credentials. If the user provides secrets, acknowledge receipt at a high level and do not echo them back. - -### Destructive actions - -Do not delete, unpublish, overwrite, or make irreversible updates without explicit user confirmation and clear identification of the target resource. Confirm the Brand Kit UID, Voice Profile UID, or Knowledge Vault content UID before proceeding. - ### Brand governance Validate generated or proposed content against brand guidelines before presenting it as ready. Do not override brand rules without explicit approval. If the request conflicts with brand guidance, say so and offer the closest compliant alternative. @@ -90,33 +52,49 @@ Validate generated or proposed content against brand guidelines before presentin Treat Knowledge Vault as vector-based semantic storage. Do not imply original files, binary assets, or exact source documents can be retrieved from it. If the user asks for originals, explain the limitation directly. +Knowledge Vault ingests PDF and TXT files, crawled websites and Contentstack entries, chunks and embeds them, and serves semantic or hybrid (embedding plus keyword) search. Items can sit in folders, and retrieval can be scoped to a folder. Set an `external_uid` on items you sync from another system so re-ingesting upserts instead of duplicating. + +### Brand Kit versions and surfaces + +- **v1 kits** use Voice Profiles with four `communication_style` dials, each on a 1–4 scale: formality, tone, humor and complexity. Profiles also carry `insights` and `sample_content`. +- **v2 kits** replace the dials with free-form markdown profiles ("Documents"), optionally started from a profile template. The API version is sent as a request header, not a path prefix, and v1 voice-profile routes return `410 Gone` for a v2 kit. Ask which version the kit uses before mapping a request. +- Other surfaces you may be asked about: visual guidelines (logos, palettes, fonts, icons), image profiles, translation profiles, LLM configs (Contentstack-managed or customer-managed credentials), brand consistency scoring of an entry, a Playground for trying a profile, and Quick Start onboarding that drafts profiles from a URL or file for review. +- Brand Kit supplies context to other AI surfaces, such as the AI Assistant app, Polaris and the Contentstack MCP server. It is not a generator on its own. + ### Safety and constraints -Call out rate limits, region-specific base URLs, and API constraints when relevant. If a request is ambiguous, unsafe, or incomplete, pause and ask for the minimum additional information needed. +Call out rate limits, region-specific base URLs, and API constraints when relevant. The APIs are rate limited: on a `429`, back off and retry after a delay instead of retrying immediately. If a request is ambiguous, unsafe, or incomplete, pause and ask for the minimum additional information needed. + +### APIs + +Use Brand Kit Management API for Brand Kits and Voice Profiles. Use Knowledge Vault API for ingest, update, delete, search, and chunk retrieval. Use Generative AI API for content generation. Prefer reference skills for specific API collections when they exist. Respect rate limits (back off on `429`) and region-specific base URLs. Brand Kit and Voice Profile endpoints take `authtoken` and `organization_uid`, with the Brand Kit UID in the path for Voice Profile calls. Knowledge Vault endpoints take `organization_uid` and `brand_kit_uid` headers; confirm the auth header in the current API docs. Never surface tokens in examples, logs, or summaries. + +## MCP tools + +When the Contentstack MCP server is connected with the `brandkit` group (it needs `CONTENTSTACK_BRAND_KIT_ID`), these tools act on the Brand Kit: -## Output Format +- Inspect: `get_all_voice_profiles`, `get_a_single_voice_profile`, `get_all_contents_in_knowledge_vault`, `get_a_single_content_in_knowledge_vault`, `get_data_chunks_from_knowledge_vault` (`brandkit`) +- Generate: `generative_ai` (`brandkit`) +- Change: `create_a_voice_profile`, `update_a_voice_profile`, `create_an_content_in_knowledge_vault`, `update_a_content_in_knowledge_vault` (`brandkit`) +- Delete: `delete_a_voice_profile`, `delete_a_content_from_knowledge_vault` (`brandkit`) -Be concise and practical. -State the relevant Brand Kit concept, workflow, or API scope up front. -Ask only for the missing inputs needed to proceed. -Use bullets or short steps for setup and API guidance. -Do not include secrets, speculative values, or unsupported claims. -Warn clearly about destructive actions, rate limits, and Knowledge Vault limitations. +The voice profile tools call the v1 Voice Profile routes, which return `410 Gone` for a v2 kit. No tool manages Brand Kits themselves, visual guidelines or v2 Documents; use the Brand Kit UI or the Management API. -## Tooling Notes +## Output -Use Brand Kit Management API for Brand Kits and Voice Profiles. Use Knowledge Vault API for ingest, update, delete, search, and chunk retrieval. Use Generative AI API for content generation. Prefer reference skills for specific API collections when they exist. Respect the 10 requests/second per organization rate limit and region-specific base URLs. Never surface tokens in examples, logs, or summaries. +Be concise and practical. State the relevant Brand Kit concept, workflow, or API scope up front, and ask only for the missing inputs needed to proceed. Use bullets or short steps for setup and API guidance. Do not include secrets, speculative values, or unsupported claims. Warn clearly about destructive actions, rate limits, and Knowledge Vault limitations. ## Security ### Defaults -Never expose Brand Kit API tokens. -Validate generated content against brand guidelines before publishing. -Do not override brand rules without explicit approval. -Treat Knowledge Vault content as brand-governed source material, not a public data source. -If auth, region, or identifiers are missing, ask for them instead of guessing. -If a request is ambiguous, incomplete, or unsafe, stop and clarify before acting. +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Never expose Brand Kit API tokens. +- Validate generated content against brand guidelines before publishing. +- Do not override brand rules without explicit approval. +- Treat Knowledge Vault content as brand-governed source material, not a public data source. +- If auth, region, or identifiers are missing, ask for them instead of guessing. +- If a request is ambiguous, incomplete, or unsafe, stop and clarify before acting. ### Destructive Actions diff --git a/skills/brand-kit-assistant/references/brand-kit-management-api-reference.md b/skills/brand-kit-assistant/references/brand-kit-management-api-reference.md index 0270709..8a8f000 100644 --- a/skills/brand-kit-assistant/references/brand-kit-management-api-reference.md +++ b/skills/brand-kit-assistant/references/brand-kit-management-api-reference.md @@ -13,17 +13,18 @@ Operate Contentstack Brand Kit and Voice Profile APIs with correct headers, payl - Target resource: Brand Kit or Voice Profile - Region / base URL - organization_uid and authtoken -- brand_kit_uid for Voice Profile operations +- brand_kit_uid (path parameter) for Voice Profile operations - brand_kit_uid or voice_profile_uid for targeted get/update/delete operations - Name, description, linked stack API keys, communication_style, insights, and sample content as needed ## Behavior - Select the correct regional base URL. - Include authtoken and organization_uid for Brand Kit endpoints. -- Include authtoken and brand_kit_uid for Voice Profile endpoints. +- Include authtoken and organization_uid for Voice Profile endpoints too, with brand_kit_uid in the path (`brand-kits/{brand_kit_uid}/voice-profiles`). +- Check whether the kit is v1 or v2. The API version is a request header. v2 kits use markdown profiles ("Documents"), and v1 voice-profile routes return `410 Gone` for them. - Validate required IDs and payload fields before calling the API. - For create/update, support brand_kit.name, optional brand_kit.description, and optional brand_kit.api_keys. -- For Voice Profiles, validate communication_style values are integers from 1 to 5 and include insights and sample_content when available. +- For v1 Voice Profiles, validate the four communication_style dials (formality, tone, humor, complexity) are integers from 1 to 4, and include insights and sample_content when available. - If deleting a Voice Profile, ask for explicit confirmation before proceeding. - If the API returns 429, report rate-limit status and recommend retrying after a short delay. diff --git a/skills/brand-kit-assistant/references/knowledge-vault-api-reference-skill.md b/skills/brand-kit-assistant/references/knowledge-vault-api-reference-skill.md index 4e988d9..6c25a78 100644 --- a/skills/brand-kit-assistant/references/knowledge-vault-api-reference-skill.md +++ b/skills/brand-kit-assistant/references/knowledge-vault-api-reference-skill.md @@ -18,9 +18,11 @@ Operate Contentstack Knowledge Vault through the API and mapped MCP tools with r ## Behavior - Select the correct regional base URL. -- Include authtoken and brand_kit_uid headers. +- Include organization_uid and brand_kit_uid headers, plus the auth header the current API docs require. - Validate required IDs and payload fields before calling the API. - Accept text intended for semantic storage and include useful metadata when available. +- Use `external_uid` as an upsert key when syncing from another system, so re-ingesting updates instead of duplicating. +- Supported sources include PDF and TXT files, crawled websites and Contentstack entries. Items can be organized in folders, and search can be semantic or hybrid. - For delete, request explicit confirmation and verify brand_kit_uid and content_uid before proceeding. - If the API returns 429, report rate-limit status and recommend retrying after a short delay. - Support mapped MCP operations where available. diff --git a/skills/cms-assets/SKILL.md b/skills/cms-assets/SKILL.md index 37b1985..6363cff 100644 --- a/skills/cms-assets/SKILL.md +++ b/skills/cms-assets/SKILL.md @@ -6,82 +6,82 @@ allowed-tools: Read Grep Glob # Contentstack Assets -## Description +Advise on organizing, delivering, transforming and publishing files in a stack's asset library, and on the limits and reference risks that come with them. -Advise developers on organizing, delivering, and transforming assets in Contentstack. Cover folder structure, Image Delivery API transformations, publishing lifecycle, CDN behavior, and common limits. +## When to use -## When to Use +- Organizing assets into folders and naming them. +- Serving responsive or optimized images with the Image Delivery API. +- Publishing, unpublishing, replacing or deleting assets, and what that does to references. +- Upload limits and other asset library gotchas. -Use when developers ask about uploading, organizing, delivering, transforming, publishing, or troubleshooting images and other media files in a stack's asset library. +Use another skill for: -For the standalone Assets DAM product (spaces, workspaces, duplicate sets, saved views, visual markups), use the `asset-management` skill instead. +- The standalone Assets DAM (spaces, workspaces, duplicate sets, saved views, visual markups) and any reading or updating of user-defined fields → `asset-management` +- Images embedded in JSON Rich Text Editor content → `cms-json-rte` +- Fetching assets in code with the Delivery SDK → `dx-delivery-sdk` +- Asset fields in a GraphQL query → `cms-graphql` +- Environments and the publishing model in general → `cms-environments-publishing` +- Third-party DAM connectors such as Bynder or Cloudinary → `marketplace-apps` -This skill does not cover reading or updating user-defined fields (custom metadata). The stack asset library doesn't support them. Route those requests to the `asset-management` skill, which points to the Assets (DAM) API. +## Before you answer -## User Problem +Find out the asset type and use case, any image optimization requirements, how assets are organized today, and whether the question is about publishing or CDN delivery. -Developers need to organize assets effectively, serve optimized images, and understand how asset publishing and CDN delivery work. They also need to avoid broken references and common asset-management mistakes. +## Instructions -## Success Criteria +1. Identify the asset type and use case. +2. Recommend a folder organization if needed. +3. For images, explain the Image Delivery API transforms. +4. Describe publishing and CDN behavior. +5. Flag limits, gotchas and reference risks. -Recommend clear folder structures and naming patterns. -Explain Image Delivery API transformations and responsive image delivery. -Describe asset publishing, unpublishing, and replacement behavior correctly. -Call out relevant limits, gotchas, and reference-breaking actions. +### Folder organization -## Expected Inputs +Recommend a clear folder structure early in the project, such as `/images/heroes`, `/images/products` and `/documents/legal`. Moving assets between folders preserves UIDs and references. -- Asset type and use case -- Image optimization requirements -- Folder organization needs -- Publishing or CDN questions +### Image Delivery API -## Expected Outputs +Use `images.contentstack.io` for image delivery, with on-the-fly transforms through URL parameters such as `width`, `height`, `quality`, `format`, `auto`, `crop`, `trim`, `orient`, `overlay`, `pad`, `canvas`, `fit`, `dpr`, `blur`, `sharpen`, `brightness`, `contrast` and `saturation`. Recommend responsive delivery with width/height and dpr, WebP for modern browsers, and quality tuning for file size. Chain multiple transforms in one URL. Non-image assets serve from `assets.contentstack.io`. -- Folder structure recommendations -- Image Delivery API transformation guidance -- Publishing lifecycle explanations -- Performance optimization tips +### Publishing lifecycle -## Example User Requests +Assets have their own publishing lifecycle, independent of entries. An asset must be published to an environment before referenced entries display it on the live site. Unpublishing removes it from delivery for that environment but does not delete the file. -- How do I serve responsive images from Contentstack? -- What image transformations does Contentstack support? -- How should I organize my assets into folders? -- Does deleting an asset break references in entries? -- What is the maximum file size I can upload? +### Replacing vs deleting -## Workflow Summary +Replacing an asset creates a new version while keeping the same UID and references intact. Deleting an asset breaks all references to it in entries. Advise checking references before deletion. -Identify the asset type and use case. -Recommend folder organization if needed. -Explain Image Delivery API transforms for images. -Describe publishing and CDN behavior. -Flag limits, gotchas, and reference risks. +### Key limits -## Instructions +State the main stack asset library limits clearly: max file size is 700 MB via the UI and 100 MB via the API, max 10 assets per batch upload, 10,000 assets per stack by default, and filenames cannot be changed after upload. Image Delivery API transforms do not apply to images inserted directly into Rich Text Editor fields. The standalone Assets (DAM) product has different limits (up to 1.5 GB per asset, 100 assets per upload, 500,000 assets per workspace); route those questions to `asset-management`. -[{"heading":"Folder organization","content":"Recommend a clear folder structure early in the project, such as /images/heroes, /images/products, and /documents/legal. Moving assets between folders preserves UIDs and references."},{"heading":"Image Delivery API","content":"Use images.contentstack.io for image delivery and support on-the-fly transforms with URL parameters such as width, height, quality, format, crop, trim, orient, overlay, pad, fit, and dpr. Recommend responsive delivery with width/height and dpr, WebP for modern browsers, and quality tuning for file size. Chain multiple transforms in one URL. Non-image assets serve from assets.contentstack.io."},{"heading":"Publishing lifecycle","content":"Explain that assets have their own publishing lifecycle independent of entries. An asset must be published to an environment before referenced entries display it on the live site. Unpublishing removes it from delivery for that environment but does not delete the file."},{"heading":"Replacing vs deleting","content":"Explain that replacing an asset creates a new version while keeping the same UID and references intact. Deleting an asset breaks all references to it in entries. Advise checking references before deletion."},{"heading":"Key limits","content":"State the main limits clearly: max file size is 700 MB via UI and 100 MB via API, max 10 assets per batch upload, default 10,000 assets per stack and 500,000 per organization, and filenames cannot be changed after upload. Note that Image Delivery API transforms do not apply to images inserted directly into Rich Text Editor fields."}], +## MCP tools -## Output Format +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): -Be concise and practical. Show Image Delivery API parameters inline when helpful. Prefer direct answers with short bullets when listing options or limits. +- Inspect: `get_all_assets`, `get_a_single_asset`, `get_asset_reference` (`cma`); `get_assets_of_a_specific_folder`, `get_assets_and_subfolders_of_a_parent_folder`, `get_all_versions_of_an_asset` (`cma-extended`); `get_all_assets_cdn`, `get_a_single_asset_cdn` (`cda`) +- Change: `publish_an_asset`, `unpublish_an_asset` (`cma`); `update_asset_details`, `create_asset_folder`, `update_asset_folder`, `set_asset_version_name` (`cma-extended`) +- Delete: `delete_an_asset` (`cma`); `delete_asset_folder`, `delete_asset_version_name` (`cma-extended`) -## Tooling Notes +There is no upload tool; upload through the UI, the CMA or `csdx`. Run `get_asset_reference` before deleting an asset to see which entries use it. -Read-only advisory skill. Do not upload, delete, publish, or modify assets. Use only read-oriented guidance. +## Output + +Be concise and practical. Show Image Delivery API parameters inline when helpful. Prefer direct answers with short bullets when listing options or limits. ## Security ### Defaults +- Advisory by default. Use the MCP tools above only when the user asks for the change. - Never expose tokens or API keys. - Delivery tokens and asset URLs are safe for client-side code. -- Use environment variables for credentials in example code. +- Use environment variables for credentials in example code, and route CMA calls through a server-side proxy in browser apps. ### Destructive Actions -Do not perform destructive asset actions. If the user asks to delete, unpublish, or replace assets, explain the implications and recommend safe checks, but do not execute changes. +Before deleting, unpublishing or replacing an asset, or deleting a folder, name the asset, the environments and the entries that reference it, explain the impact (a deleted asset breaks every reference to it), and wait for confirmation. ### Secrets @@ -90,14 +90,3 @@ Never reveal management tokens, API keys, or other secrets. If code examples nee ### Environment Variables Use environment variables for any credentialed examples. Never hardcode stack API keys, management tokens, or delivery tokens in client-side code. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-branches-aliases/SKILL.md b/skills/cms-branches-aliases/SKILL.md index 44202ba..cd8e9d2 100644 --- a/skills/cms-branches-aliases/SKILL.md +++ b/skills/cms-branches-aliases/SKILL.md @@ -1,85 +1,93 @@ --- name: cms-branches-aliases -description: "Advise developers on using Contentstack branches for isolated content development and aliases for zero-downtime content deployments. Cover branch strategy, branch-specific vs global modules, CI/CD integration, merge behavior, and rollback patterns. Use when developers ask about branches, aliases, CI/CD integration with Contentstack, deployment strategies, or branch-specific vs global module behavior." +description: "Advise developers on using Contentstack branches for isolated content development and aliases for zero-downtime content deployments. Cover branch strategy, branch-specific vs global modules, CI/CD integration, merge behavior, and rollback patterns. Use when developers ask about branches, aliases, CI/CD integration with Contentstack, deployment strategies, or branch-specific vs global module behavior. For running csdx branch commands, use dx-cli." --- # Branches & Aliases -## Description +Advise on branches for isolated schema and content work, and aliases for zero-downtime deployment and rollback. -Advise developers on using Contentstack branches for isolated content development and aliases for zero-downtime content deployments. Cover branch strategy, branch-specific vs global modules, CI/CD integration, merge behavior, and rollback patterns. +## When to use -## When to Use +- Choosing a branch strategy for schema and content development. +- Which modules are branch-specific and which are global. +- Comparing and merging branches. +- Alias-based deployment, rollback and CI/CD pipelines. -Use when developers ask about branches, aliases, CI/CD integration with Contentstack, deployment strategies, or branch-specific vs global module behavior. +Use another skill for: -## User Problem +- Running `csdx` branch, export and import commands → `dx-cli` +- Deploying a set of entries together → `cms-releases` +- Environments, publishing and token scoping → `cms-environments-publishing` +- Designing the content types you change on a branch → `cms-data-modeling-best-practices` -Developers need to make schema and content changes safely without affecting the live site, then deploy changes with zero downtime and easy rollback. +## Before you answer -## Success Criteria +Find out the development workflow or CI/CD pipeline, the deployment and rollback requirements, and how the team collaborates. -Recommends an appropriate branch strategy. -Explains branch-specific vs global modules accurately. -Gives practical alias-based deployment patterns. -Provides safe CI/CD integration guidance. -Includes clear merge and rollback advice. +## Instructions -## Expected Inputs +1. Understand the development and deployment workflow. +2. Recommend a branch strategy. +3. Explain branch-specific vs global modules. +4. Guide alias-based deployment. +5. Cover merge, rollback and CI/CD integration. -- Development workflow or CI/CD pipeline -- Deployment strategy requirements -- Team structure and collaboration needs -- Rollback requirements +### Branch basics -## Expected Outputs +A new branch inherits the source branch's content types, global fields, entries, assets, languages, webhooks and extensions as an isolated workspace. The number of branches per stack depends on the plan. Only owners, admins and developers can create and delete branches. -- Branch strategy recommendations -- Global vs branch-specific module explanations -- Alias-based deployment patterns -- CI/CD integration guidance -- Merge and rollback advice +### Branch-specific vs global modules -## Example User Requests +Branch-specific: content types, global fields, entries, assets, workflows, publish queue, releases, languages, extensions, audit logs, global search and labels. Global: taxonomy, environments, users, roles, webhooks, workflows, publish rules, tokens and Marketplace apps. Some global modules can be scoped: a webhook can be assigned to one branch at a time, workflows and publish rules can apply to all branches or specific ones, and delivery and management tokens can be limited to specific branches or aliases. A content type on a development branch does not exist on main until merged. -- How do I use branches for content schema development? -- What is the difference between branch-specific and global modules? -- How do I deploy content changes with zero downtime? -- How do branches work with my CI/CD pipeline? -- Can I roll back a bad deployment? +### Compare and merge -## Workflow Summary +Compare and merge covers only content types and global fields, and runs through the CMA or the CLI. Merge strategies are `merge_prefer_base`, `merge_prefer_compare`, `overwrite_with_compare`, `merge_new_only`, `merge_modified_only_prefer_base`, `merge_modified_only_prefer_compare` and `ignore` (per item). Warn that `overwrite_with_compare` replaces the base and loses anything that exists only there. A backup branch is created before the merge runs, and the merge is asynchronous, so poll the merge queue for its status. Entries, assets and other modules have no merge tool; reconcile them with scripts. -Understand the development and deployment workflow. -Recommend a branch strategy. -Explain branch-specific vs global modules. -Guide alias-based deployment. -Cover merge, rollback, and CI/CD integration. +### Alias-based deployment -## Instructions +Aliases point to branches. Hardcode an alias such as `deploy` in frontend code instead of a branch UID. To switch production to a new branch, reassign the alias. Frontend code does not change. For rollback, reassign the alias back. Two aliases can point to the same branch, but a branch and alias cannot share the same UID. -[{"heading":"Branch basics","content":"Branches copy the source branch's content types, global fields, entries, and assets into an isolated workspace. Max 5 branches per stack. Only one branch can be created or deleted at a time across an organization. Only owners, admins, and developers can manage branches."},{"heading":"Branch-specific vs global modules","content":"Branch-specific: content types, global fields, entries, assets, publish queue, releases, languages, extensions, audit logs, labels, search. Global: environments, webhooks, workflows, publish rules, users, roles, tokens. A webhook created on main is visible everywhere but can be scoped to a specific branch. A content type on a development branch does not exist on main until merged."},{"heading":"Alias-based deployment","content":"Aliases point to branches. Hardcode an alias such as deploy in frontend code instead of a branch UID. To switch production to a new branch, reassign the alias. Frontend code does not change. For rollback, reassign the alias back. Two aliases can point to the same branch, but a branch and alias cannot share the same UID."},{"heading":"CI/CD pattern","content":"Create a branch from main, make schema and content changes, test on staging, reassign the production alias to the new branch, and reassign back immediately if something goes wrong."},{"heading":"Branch strategy","content":"Keep branch lifetimes short. Long-lived branches drift and create merge conflicts. Prefer trunk-based workflow with short-lived feature branches merged back to main quickly. Do not use branches as permanent environments; use environments for that."},{"heading":"SDK initialization","content":"Pass the branch or alias ID explicitly, for example branch: 'deploy'. If no branch header is passed, main is used by default. Always pass the branch header explicitly in scripts, even when targeting main."}], +### CI/CD pattern -## Output Format +Create a branch from main, make schema and content changes, test on staging, reassign the production alias to the new branch, and reassign back immediately if something goes wrong. -Provide concise branch and deployment guidance. Favor practical CI/CD patterns over abstract explanations. +### Branch strategy + +Keep branch lifetimes short. Long-lived branches drift and create merge conflicts. Prefer a trunk-based workflow with short-lived feature branches merged back to main quickly. Do not use branches as permanent environments; use environments for that. + +### SDK initialization + +Pass the branch or alias ID explicitly, for example `branch: 'deploy'`. If no branch header is passed, main is used by default. Always pass the branch header explicitly in scripts, even when targeting main. + +## MCP tools -## Tooling Notes +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): -Read-only advisory. Do not create, delete, or merge branches. +- Inspect: `get_all_branches`, `get_a_single_branch`, `get_all_branch_aliases`, `get_a_single_branch_alias`, `compare_branches`, `compare_content_types_between_branches`, `compare_global_fields_between_branches`, `compare_specific_ct_between_branches`, `compare_specific_gf_between_branches`, `get_all_merge_jobs`, `get_a_single_merge_job` (`cma`) +- Change: `create_a_branch`, `merge_branch`, `assign_a_branch_alias` (`cma`) +- Delete: `delete_a_branch`, `delete_a_branch_alias` (`cma`) + +Run a compare before `merge_branch`, and poll `get_a_single_merge_job` until the merge finishes. Set `CONTENTSTACK_BRANCH` (or the Profile Hub `branch` URL parameter) so other tools act on the intended branch. + +## Output + +Provide concise branch and deployment guidance. Favor practical CI/CD patterns over abstract explanations. ## Security ### Defaults +- Advisory by default. Use the MCP tools above only when the user asks for the change. - Never expose tokens or API keys. -- Use environment variables for credentials in example code. +- Use environment variables for credentials in example code, and route CMA calls through a server-side proxy in browser apps. - Do not recommend hardcoding secrets in client-side code. - Keep guidance compatible with branch- and alias-scoped credentials. ### Destructive Actions -Do not create, delete, merge, or reassign branches or aliases. Provide guidance only. +Before creating, merging or deleting a branch, or assigning or deleting an alias, name the stack, the branches and aliases involved and the merge strategy, explain the impact (reassigning a production alias switches the live site; `overwrite_with_compare` loses base-only items; deleting a branch deletes its content), and wait for confirmation. ### Secrets @@ -88,14 +96,3 @@ Never expose management tokens, delivery tokens, API keys, or other credentials. ### Environment Variables Use environment variables for all credentials and secret values. Never hardcode stack API keys, tokens, or branch-scoped credentials in examples. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-data-modeling-best-practices/SKILL.md b/skills/cms-data-modeling-best-practices/SKILL.md index 791d763..bb7641a 100644 --- a/skills/cms-data-modeling-best-practices/SKILL.md +++ b/skills/cms-data-modeling-best-practices/SKILL.md @@ -1,57 +1,34 @@ --- name: cms-data-modeling-best-practices -description: "Guide developers to model content in Contentstack using the simplest reusable structure. The skill explains when to use content types, references, global fields, groups, modular blocks, JSON RTE, taxonomy, and tags, and helps avoid over-modeling, deep reference chains, and channel-specific schema sprawl. Use when designing, reviewing, or refactoring Contentstack content models before creating or changing schemas." +description: "Guide developers to model content in Contentstack using the simplest reusable structure. The skill explains when to use content types, references, global fields, groups, modular blocks, JSON RTE, taxonomy, and tags, and helps avoid over-modeling, deep reference chains, and channel-specific schema sprawl. Use when designing, reviewing, or refactoring Contentstack content models before creating or changing schemas. For taxonomy hierarchies and CDA taxonomy filters, use cms-taxonomy." allowed-tools: Read Grep Glob --- # Contentstack Data Modeling Best Practices -## Description +Help pick the simplest Contentstack construct that fits, so editors work efficiently, delivery code stays simple, and schemas stay reusable, governed and easy to query. -Guide developers to model content in Contentstack using the simplest reusable structure. The skill explains when to use content types, references, global fields, groups, modular blocks, JSON RTE, taxonomy, and tags, and helps avoid over-modeling, deep reference chains, and channel-specific schema sprawl. +## When to use -## When to Use +- Designing a new content model, or reviewing and simplifying an existing one. +- Choosing between a content type, reference, global field, group, modular block, JSON RTE, taxonomy, tag or plain field. +- Planning localization and governance at the schema level. +- Checking a model against query impact and stack limits. -Use when designing, reviewing, or refactoring Contentstack content models before creating or changing schemas. +Use another skill for: -## User Problem +- Taxonomy hierarchy design and taxonomy filters on the CDA → `cms-taxonomy` +- Rendering JSON RTE content once it's modeled → `cms-json-rte` +- Personalization variants of an entry → `cms-variants-personalization` +- Locales and fallback chains → `cms-localization` +- Making schema changes safely on a branch → `cms-branches-aliases` +- Querying the entries a model produces → `cms-entries` -Developers need a practical way to choose the right Contentstack construct so editors can work efficiently, delivery code stays simple, and schemas stay reusable, governed, and easy to query. +## Before you answer -## Success Criteria +Gather the business goal, the current or proposed model, target channels and delivery needs, localization, reuse and governance requirements, sample content, and any performance or query constraints. -Recommend the simplest valid model, explain tradeoffs clearly, preserve editorial usability, avoid unnecessary abstraction, and keep the schema stable, shallow, and aligned with localization and governance needs. - -## Expected Inputs - -- Business goal or use case -- Current or proposed model -- Target channels and delivery needs -- Localization requirements -- Reuse and governance requirements -- Sample content or entries -- Performance or query constraints - -## Expected Outputs - -- Recommended modeling approach -- Construct-by-construct guidance -- Tradeoff explanations -- Warnings about anti-patterns -- Localization and governance recommendations -- Query and performance considerations -- Optional sample model or decision summary -- Migration cautions when schema changes are implied - -## Example User Requests - -- How should I model a landing page with reusable sections in Contentstack? -- Should this data be a global field, group, or content type? -- Review this content model and tell me what to simplify. -- What is the best way to handle localization for shared content? -- How do I model product categories for filtering and reuse? - -## Workflow Summary +## Instructions 1. Identify the domain concept, editorial workflow, delivery channels, localization needs, reuse requirements, and query constraints. 2. Choose the simplest fitting construct: content type, reference, global field, group, modular block, JSON RTE, taxonomy, tag, or plain field. @@ -61,8 +38,6 @@ Recommend the simplest valid model, explain tradeoffs clearly, preserve editoria 6. Call out anti-patterns and suggest simpler alternatives. 7. Return a concise recommendation with migration cautions if needed. -## Instructions - ### Understand the goal Identify the domain concept, editorial workflow, delivery channels, localization needs, reuse requirements, and query constraints before recommending changes. @@ -95,18 +70,31 @@ Give a concise recommendation, compare alternatives only when useful, and includ Use a content type for a real domain concept with its own lifecycle. Use a reference for reusable content with independent ownership. Use a global field for the same nested field set across multiple content types. Use a group for parent-owned nested data inside one content type. Use modular blocks for page-local composition. Use JSON RTE for narrative content. Use taxonomy for governed classification. Use tags for lightweight internal labels. -## Output Format +### Limits to design around + +- A content type schema can have up to 500 fields. A content type UID can be up to 200 characters. +- The number of content types per stack and the number of block types in one modular blocks field are plan limits. Product defaults are around 100 content types per stack and 10 block types per modular blocks field, so check the plan before designing a model that depends on more. +- Taxonomies can nest up to 10 levels deep. + +## MCP tools + +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): -Use concise, structured, instruction-oriented prose. Prefer bullets and short sections. State the recommended choice first when comparing options. Include warnings for anti-patterns and migration concerns when relevant. Do not expose secrets, API keys, or management tokens. +- Inspect: `get_all_content_types`, `get_a_single_content_type`, `get_all_references_of_ct`, `export_content_type`, `get_all_global_fields`, `get_a_single_global_field` (`cma`); `export_global_field` (`cma-extended`) +- Change: `create_a_content_type`, `update_content_type` (`cma`); `create_a_global_field`, `update_a_global_field` (`cma-extended`) +- Delete: `delete_content_type` (`cma`); `delete_a_global_field` (`cma-extended`) -## Tooling Notes +Read the existing model with the inspect tools before reviewing it. Make schema changes on a development branch first, and run `get_all_references_of_ct` before changing or deleting a content type that other types reference. -Read-only advisory skill. Prefer default CMS knowledge and documentation sources. If tools are used, restrict to read-only inspection and documentation lookup. Do not perform schema changes, publishing, or destructive actions. +## Output + +Use concise, structured, instruction-oriented prose. Prefer bullets and short sections. State the recommended choice first when comparing options. Include warnings for anti-patterns and migration cautions when relevant, and optionally a sample model or decision summary. ## Security ### Defaults +- Advisory by default. Use the MCP tools above only when the user asks for the change. - Never expose management tokens or API keys. - Never ask users to paste secrets into the prompt. - Use environment variables for credentials in any example code. @@ -116,7 +104,7 @@ Read-only advisory skill. Prefer default CMS knowledge and documentation sources ### Destructive Actions -Do not perform destructive actions. Do not delete, publish, unpublish, or modify Contentstack resources. Provide guidance only. +Before creating, updating or deleting a content type or global field, name the stack, branch and schema, explain the impact (removing a field or content type can remove the content stored in it, and every schema change is an API contract change for delivery code), and wait for confirmation. ### Secrets @@ -125,14 +113,3 @@ Treat all credentials as sensitive. Never request or display management tokens, ### Environment Variables Use environment variables for any credentialed examples or integrations. Prefer placeholders such as CONTENTSTACK_API_KEY, CONTENTSTACK_MANAGEMENT_TOKEN, and CONTENTSTACK_DELIVERY_TOKEN. Never hardcode secrets in examples or instructions. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-entries/SKILL.md b/skills/cms-entries/SKILL.md index 330153e..3c21d95 100644 --- a/skills/cms-entries/SKILL.md +++ b/skills/cms-entries/SKILL.md @@ -1,89 +1,103 @@ --- name: cms-entries -description: "Advise developers on querying, localizing, versioning, publishing, and structuring Contentstack entries for efficient delivery. Focus on CDA usage, reference expansion, pagination, bulk operations, and Sync API patterns. Use when developers ask about fetching entries, building CDA queries, handling localization, publishing workflows, versioning behavior, bulk operations, or entry-related performance issues." +description: "Advise developers on querying, localizing, versioning, publishing, and structuring Contentstack entries for efficient delivery. Focus on CDA usage, reference expansion, pagination, bulk operations, and Sync API patterns. Use when developers ask about fetching entries, building CDA queries, handling localization, publishing workflows, versioning behavior, bulk operations, or entry-related performance issues. For SDK code, use dx-delivery-sdk; for GraphQL, use cms-graphql." allowed-tools: Read Grep Glob --- # Entries -## Description +Advise on querying, publishing, versioning and paging through entries so delivery is efficient and editorial workflows behave as expected. -Advise developers on querying, localizing, versioning, publishing, and structuring Contentstack entries for efficient delivery. Focus on CDA usage, reference expansion, pagination, bulk operations, and Sync API patterns. +## When to use -## When to Use +- Building CDA queries: filters, references, field projection, sorting, locales. +- Paginating through every entry of a content type. +- Versioning, saving vs publishing, and bulk publish or unpublish. +- Choosing the Sync API over polling. +- Entry-related performance problems. -Use when developers ask about fetching entries, building CDA queries, handling localization, publishing workflows, versioning behavior, bulk operations, or entry-related performance issues. +Use another skill for: -## User Problem +- Writing the query with `@contentstack/delivery-sdk` → `dx-delivery-sdk` +- GraphQL queries → `cms-graphql` +- Rendering JSON RTE fields and embedded items → `cms-json-rte` +- Filtering by taxonomy terms → `cms-taxonomy` +- Locales and fallback chains in depth → `cms-localization` +- Environments, tokens and the publish queue → `cms-environments-publishing` +- Entry variants and personalization → `cms-variants-personalization` +- Bulk export, import or migration scripts with `csdx` → `dx-cli` -Developers need to query, publish, and structure entries so frontend delivery is efficient and editorial workflows behave as expected. +## Before you answer -## Success Criteria +Find out the query or filtering requirement, the content type structure, the locales involved, any publishing or scheduling needs, and any performance or pagination concerns. -Write correct CDA queries and explain the response shape. -Clarify versioning, publishing, and localization behavior. -Show how to expand references and paginate results efficiently. -Flag common mistakes, especially using the CMA for frontend reads. +## Instructions -## Expected Inputs +1. Confirm whether the user needs CDA or CMA guidance. +2. Give the correct query syntax, publishing approach or delivery pattern. +3. Explain versioning, localization and reference expansion as needed. +4. Flag anti-patterns and recommend best practices. -- Query or filtering requirements -- Content type structure -- Localization or locale requirements -- Publishing or scheduling needs -- Performance or pagination concerns +### CDA or CMA -## Expected Outputs +Say which API the answer is for. Use the Content Delivery API (CDA) with a delivery token for anything a site or app reads. Use the Content Management API (CMA) only for authoring, migration and automation on a server. Never use the CMA for frontend reads: it needs a management token, it isn't cached at the CDN, and it shares the organization's rate limit. -- Query syntax guidance with operators and examples -- Reference expansion patterns -- Publishing and versioning explanations -- Pagination and performance recommendations -- Warnings about common mistakes +### Query parameters -## Example User Requests +Filter with the `query` parameter, a JSON object matched against field values, for example `query={"title":"Welcome"}`. Common companions: -- How do I query entries filtered by a field inside Modular Blocks? -- How does entry versioning work in Contentstack? -- What is the difference between publishing and saving? -- How do I include referenced entries in my CDA response? -- How do I paginate through all entries of a content type? +- `include[]` resolves reference fields inline, up to 100 reference paths per request. Dot paths such as `include[]=section.author` go deeper, but each level multiplies the work behind the request, so keep includes shallow and only ask for the paths the page renders. +- `only[]` and `except[]` trim the response to the fields you need. +- `asc` and `desc` sort the results. +- `skip` and `limit` page through results. A request returns at most 100 entries. +- `include_count` returns the total so you know how many pages there are. +- `locale` picks the language. Add `include_fallback=true` to fall back along the locale chain when an entry isn't localized. +- `include_branch`, `include_publish_details` and `include_metadata` add branch, publish and metadata details to each entry. -## Workflow Summary +Request URLs are capped at 8 KB, and longer ones fail with `414 URI Too Long`. When a filter grows past that, simplify it: fewer `$in` values, fewer `include[]` paths, or several smaller requests. -Confirm whether the user needs CDA guidance or CMA guidance. -Provide the correct query syntax, publishing approach, or delivery pattern. -Explain versioning, localization, and reference expansion as needed. -Flag anti-patterns and recommend best practices. -Keep the answer concise and actionable. +### Pagination -## Instructions +To read every entry of a content type, request with `include_count=true` and `limit=100`, then loop with `skip` increasing by 100 until you have `count` entries. Keep the sort order fixed while paging so results don't shift between pages. To mirror a whole environment, use the Sync API instead of paging. + +### Versioning + +Every save increments a `_version` counter per entry and locale, starting at 1. Old versions are kept. Restoring an older version creates a new version with those values, so history is never rewritten. Publishing is separate from saving: a saved change stays a draft until it is published to an environment. + +### Publishing and bulk operations + +Publish entries together with the entries they reference. Bulk publish and bulk unpublish accept up to 100 items per request. To publish nested references along with their parents, call the bulk publish endpoint with the `api_version: 3.2` header, which publishes references up to five levels deep. Bulk actions are limited to 1 request per second per organization, and other CMA calls to 10 requests per second per organization, so scripts should back off on `429` responses. -[] +### Sync API -## Output Format +Use the Sync API to keep a full local copy of an environment, for static builds, search indexes or offline apps. The first call returns everything published plus a `sync_token`. Later calls pass that token and receive only what changed: publishes, unpublishes, deletes, and content type and locale changes, with a fresh token each time. Prefer it over polling the CDA. -Be concise and practical. -State whether the guidance applies to CDA or CMA. -Show inline query syntax when helpful. -Avoid unnecessary background unless it prevents a common mistake. +## MCP tools -## Tooling Notes +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): -Read-only advisory skill. -Do not create, update, publish, or delete entries. +- Inspect: `get_all_entries`, `get_single_entry`, `get_references_of_an_entry` (`cma`); `get_all_versions_of_an_entry` (`cma-extended`); `get_all_entries_cdn`, `get_a_single_entry_cdn` (`cda`, to check what the live site receives) +- Change: `create_an_entry`, `update_an_entry`, `publish_an_entry` (can schedule), `localize_an_entry` (`cma`); `set_entry_version_name` (`cma-extended`) +- Delete or withdraw: `delete_an_entry`, `unpublish_an_entry`, `unlocalize_an_entry` (`cma`); `delete_entry_version_name` (`cma-extended`) + +There are no bulk publish or Sync API tools; use the CMA bulk endpoints or `csdx` for bulk work, and the Sync API from code. + +## Output + +Be concise and practical. State whether the guidance applies to the CDA or the CMA, show inline query syntax when helpful, and skip background unless it prevents a common mistake. ## Security ### Defaults -Never expose tokens or API keys. -Delivery tokens are safe for client-side code; management tokens are not. -Use environment variables for credentials in example code. +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Never expose tokens or API keys. +- Delivery tokens are safe for client-side code; management tokens are not. +- Use environment variables for credentials in example code, and route CMA calls through a server-side proxy in browser apps. ### Destructive Actions -Do not perform destructive actions. Do not delete, unpublish, or modify entries. Provide guidance only. +Before creating, updating, publishing, unpublishing, unlocalizing or deleting entries, name the stack, branch, content type, entries, locales and environments, explain the impact (unpublishing removes content from the live site), and wait for confirmation. Run `get_references_of_an_entry` before a delete to see which entries point to it. ### Secrets @@ -92,14 +106,3 @@ Never reveal management tokens, API keys, or other secrets. Prefer environment v ### Environment Variables Use environment variables for all credentials in sample code. Never hardcode delivery tokens, management tokens, or stack identifiers in client-side examples. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-environments-publishing/SKILL.md b/skills/cms-environments-publishing/SKILL.md index bcd6bb5..6ec7424 100644 --- a/skills/cms-environments-publishing/SKILL.md +++ b/skills/cms-environments-publishing/SKILL.md @@ -1,90 +1,98 @@ --- name: cms-environments-publishing -description: "Advise developers on configuring environments, publishing content, using delivery and preview tokens, leveraging the Sync API, and understanding CDN and publish queue behavior in Contentstack. Use when developers ask about environment setup, publishing behavior, delivery or preview tokens, the Sync API, scheduling, or CDN and caching configuration in Contentstack." +description: "Advise developers on configuring environments, publishing content, using delivery and preview tokens, leveraging the Sync API, and understanding CDN and publish queue behavior in Contentstack. Use when developers ask about environment setup, publishing behavior, delivery or preview tokens, the Sync API, scheduling, or CDN and caching configuration in Contentstack. For Launch hosting environments, use launch-platform." allowed-tools: Read Grep Glob --- # Contentstack Environments & Publishing -## Description +Advise on how content moves from draft to live: environments, publishing and scheduling, the token for each job, the Sync API, the publish queue and CDN behavior. -Advise developers on configuring environments, publishing content, using delivery and preview tokens, leveraging the Sync API, and understanding CDN and publish queue behavior in Contentstack. +## When to use -## When to Use +- Designing environments for a deployment pipeline. +- Content that doesn't appear on the live site after publishing. +- Choosing between delivery, preview and management tokens. +- Scheduling publishes and reading the publish queue. +- Setting up the Sync API, regional CDA hosts and rate limits. -Use when developers ask about environment setup, publishing behavior, delivery or preview tokens, the Sync API, scheduling, or CDN and caching configuration in Contentstack. +Use another skill for: -## User Problem +- Launch hosting environments, builds and deploys → `launch-platform` +- Token types, scopes and auth in depth → `cms-tokens-authentication` +- Publishing many entries together on a schedule → `cms-releases` +- Approval stages and publish rules → `cms-workflows` +- Rebuilding a site when content publishes → `cms-webhooks` +- Entry queries and bulk publish details → `cms-entries` +- Branch and alias deployment → `cms-branches-aliases` -Developers need to understand how content moves from draft to live, how environments and tokens work together, and how to keep frontends in sync. +## Before you answer -## Success Criteria +Find out the deployment pipeline and environments, the frontend framework or static site generator, the token or auth question, and any scheduling or publish queue concern. -Explains the publishing pipeline clearly. -Identifies the correct token type for the scenario. -Recommends the Sync API when appropriate. -Avoids suggesting any unsafe client-side secret handling. +## Instructions -## Expected Inputs +1. Understand the deployment pipeline. +2. Recommend the environment structure. +3. Explain the token types and which one applies. +4. Guide publishing, scheduling and reference publishing. +5. Recommend the Sync API for static sites or local caches. +6. When content is missing after a publish, troubleshoot step by step. -- Deployment pipeline or environment requirements -- Frontend framework or static site generator -- Token or authentication questions -- Scheduling or publish queue concerns +### Environment design -## Expected Outputs +Treat environments as deployment targets such as development, staging and production. Keep them aligned with the real deployment pipeline. Environments are global modules, shared across branches. -- Environment configuration guidance -- Token usage recommendations -- Publishing workflow explanation -- Sync API setup guidance -- CDN and caching explanations +### Publishing fundamentals -## Example User Requests +Content is a draft until explicitly published to an environment. Publishing can target one or more environments and locales. For nested references, use the bulk publish API with the `api_version: 3.2` header, which publishes referenced entries up to five levels deep together with their parents. Always publish entries with their references. -- How many environments should I set up? -- What is the difference between a delivery token and a preview token? -- My content is not showing on the live site after publishing. -- How does the Sync API work? -- Can I schedule content to publish at a future time? +### Token types -## Workflow Summary +Use the correct token in every answer: Delivery Token for published content via the CDA, environment-scoped and safe for client-side use; Preview Token for unpublished draft content in Live Preview; Management Token for stack-level read/write access, server-side only, never exposed client-side. -Understand the deployment pipeline. -Recommend the environment structure. -Explain token types and their use cases. -Guide publishing, scheduling, and reference publishing. -Recommend the Sync API for static sites or local caches. +### SDK initialization -## Instructions +When relevant, mention stack API key plus delivery token plus environment name, and optionally branch or alias ID. CDA base URLs are region-specific: `cdn.contentstack.io` (AWS NA), `eu-cdn.contentstack.com` (AWS EU), `au-cdn.contentstack.com` (AWS AU), `azure-na-cdn.contentstack.com` (Azure NA), `azure-eu-cdn.contentstack.com` (Azure EU), `gcp-na-cdn.contentstack.com` (GCP NA) and `gcp-eu-cdn.contentstack.com` (GCP EU). + +### Sync API + +Recommend the Sync API for static sites, offline apps, or local content caches. The first request returns all published content plus a `sync_token`, and later requests return only changes such as created, updated, deleted, published, and unpublished items. Prefer it over polling when near-real-time updates are needed without excessive API usage. + +### Publish queue + +The publish queue tracks publish and unpublish operations and their status. Each branch has its own queue, and scheduled publishes can be cancelled before execution. -[{"heading":"Environment design","content":"Treat environments as deployment targets such as development, staging, and production. Keep them aligned with the real deployment pipeline. Default max is 5 per stack. Environments are global modules and are shared across branches."},{"heading":"Publishing fundamentals","content":"Explain that content is a draft until explicitly published to an environment. Publishing can target one or more environments and locales. For nested reference publishing, use api_version: 3.2 so the full reference tree is resolved and published automatically. Always publish entries with their references."},{"heading":"Token types","content":"Use the correct token in every answer: Delivery Token for published content via the CDA, environment-scoped and safe for client-side use; Preview Token for unpublished draft content in live preview; Management Token for stack-level read/write access, server-side only, never exposed client-side."},{"heading":"SDK initialization","content":"When relevant, mention Stack API key plus delivery token plus environment name, and optionally branch or alias ID. Note that CDA base URLs are region-specific, such as cdn.contentstack.io for AWS NA, eu-cdn.contentstack.com for AWS EU, and au-cdn.contentstack.com for AWS AU."},{"heading":"Sync API","content":"Recommend the Sync API for static sites, offline apps, or local content caches. Explain that the first request returns all published content plus a sync_token, and later requests return only changes such as created, updated, deleted, published, and unpublished items. Prefer it over polling when near-real-time updates are needed without excessive API usage."},{"heading":"Publish queue","content":"Explain that the publish queue tracks publish and unpublish operations and their status. Mention that each branch has its own queue and that scheduled publishes can be cancelled before execution."},{"heading":"Rate limits","content":"Mention the platform limits when relevant: 10 requests/second individual and 1 request/second bulk per organization. Recommend exponential backoff with jitter for scripts, and note that the CLI bulk publish plugin handles rate limiting automatically."}], +### Rate limits -## Output Format +The CMA allows 10 requests per second per organization, and bulk operations 1 request per second. CDA reads are mostly served from the CDN cache and don't count against the origin limit. Responses carry `X-RateLimit-Limit` and `X-RateLimit-Remaining` headers. Recommend exponential backoff with jitter for scripts, and note that the CLI bulk publish plugin handles rate limiting automatically. -Be concise and practical. -Always specify which token type applies. -Do not recommend client-side use of management tokens. -Prefer step-by-step troubleshooting when content is missing after publish. +## MCP tools -## Tooling Notes +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): -Read-only advisory skill. -Do not publish, unpublish, or modify environments. -If Claude tool restrictions are applied, use Read Grep Glob only. +- Inspect: `get_all_environments`, `get_an_environment`, `get_publish_queue` (`cma`); `get_publish_queue_activity`, `get_publish_rules` (`cma-extended`); `get_all_entries_cdn`, `get_a_single_entry_cdn` (`cda`, to confirm what an environment serves) +- Change: `create_an_environment`, `update_an_environment`, `publish_an_entry` (can schedule), `publish_an_asset`, `publish_variants_of_an_entry` (`cma`) +- Delete or withdraw: `delete_an_environment`, `unpublish_an_entry`, `unpublish_an_asset` (`cma`) + +There are no tools for tokens, the Sync API or cancelling a scheduled publish; use the UI or the CMA. For "published but not live", check `get_publish_queue` for the job's status, then `get_a_single_entry_cdn` with the environment's delivery token. + +## Output + +Be concise and practical. Always say which token type applies, never recommend client-side use of management tokens, and troubleshoot step by step when content is missing after a publish. ## Security ### Defaults -Delivery tokens are safe for client-side code. -Management tokens must never be exposed client-side. -Use environment variables for all token examples. -Never hardcode tokens in frontend code. +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Delivery tokens are safe for client-side code. +- Management tokens must never be exposed client-side; route CMA calls through a server-side proxy in browser apps. +- Use environment variables for all token examples, and never hardcode tokens in frontend code. ### Destructive Actions -Do not perform publishing, unpublishing, environment changes, or other write actions. Provide guidance only. +Before publishing, unpublishing, or creating, updating or deleting an environment, name the stack, branch, environments, locales and items, explain the impact (publishing to production changes the live site; deleting an environment affects every branch, since environments are global), and wait for confirmation. ### Secrets @@ -93,14 +101,3 @@ Never expose management tokens, API keys, or other secrets. Use environment vari ### Environment Variables Use environment variables for all token and API key examples. Prefer server-side injection for management credentials and client-safe delivery token usage only where appropriate. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-graphql/SKILL.md b/skills/cms-graphql/SKILL.md new file mode 100644 index 0000000..bca8c36 --- /dev/null +++ b/skills/cms-graphql/SKILL.md @@ -0,0 +1,115 @@ +--- +name: cms-graphql +description: "Advise developers on querying published Contentstack content with the GraphQL Content Delivery API. Cover regional endpoints, required headers, the generated schema, reference connections, modular blocks, JSON RTE embedded items, assets, filtering, pagination, query limits, rate limits, and Live Preview with GraphQL. Use when developers write or debug Contentstack GraphQL queries, see schema build errors or partial errors, hit GraphQL limits or 429s, paginate references, or wire GraphQL into Live Preview or Visual Editor. For REST CDA queries use cms-entries; for Delivery SDK code use dx-delivery-sdk; for preview failures use cms-live-preview-visual-editor-support-assistant." +allowed-tools: Read Grep Glob +--- + +# GraphQL Content Delivery API + +Advise on querying published content with the GraphQL Content Delivery API: endpoints, headers, schema shape, references, modular blocks, JSON RTE, assets, filtering, pagination, limits and Live Preview, without silently losing data to limits or partial errors. + +## When to use + +- Writing or fixing a GraphQL query against the generated schema. +- `SCHEMA_BUILD_ERROR`, partial errors on HTTP 200, 414s or 429s. +- Paginating references and staying inside query limits. +- Querying modular blocks, JSON RTE embedded items and assets. +- Wiring a GraphQL fetch layer into Live Preview or Visual Editor. + +Use another skill for: + +- REST Content Delivery API queries → `cms-entries` +- Delivery SDK code → `dx-delivery-sdk` +- Rendering the JSON RTE document the query returns → `cms-json-rte` +- Live Preview or Visual Editor failures → `cms-live-preview-visual-editor-support-assistant` +- Designing the content types the schema is generated from → `cms-data-modeling-best-practices` + +## Before you answer + +Find out the stack region, the content type and field UIDs, the query or the error returned, and whether the request runs in the browser, on a server or in a preview session. + +## Instructions + +1. Confirm the region, environment and branch. +2. Build the query against the generated schema. +3. Check depth, record and size limits; paginate where needed. +4. Check `errors` as well as `data`. +5. For preview sessions, switch host and add preview headers. + +### Endpoints and headers + +Send queries to `https://<host>/stacks/{api_key}?environment={environment}`. Hosts: `graphql.contentstack.com` (AWS NA), `eu-graphql.contentstack.com`, `au-graphql.contentstack.com`, `azure-na-graphql.contentstack.com`, `azure-eu-graphql.contentstack.com`, `gcp-na-graphql.contentstack.com`, `gcp-eu-graphql.contentstack.com`. Dedicated infrastructure uses its own host. + +Headers: `access_token` with the environment's delivery token (required), optional `branch` (branch UID or alias; `main` when omitted), and `Content-Type: application/json`. POST a JSON body with `query`, optional `variables` and `operationName`. GET works too, but the URL must stay under 2,000 bytes or the server returns 414. The API supports queries only: no mutations or subscriptions. + +### Schema shape + +Each content type becomes a type with a single-entry field and an `all_<content_type_uid>` collection field. Type names are the PascalCase form of the UID, so UIDs must not start with a number, must match `[_A-Za-z][_0-9A-Za-z]*`, and must not collide after PascalCase conversion. Collisions and invalid names cause `SCHEMA_BUILD_ERROR`. Use introspection in GraphiQL to see the generated schema, and `skip_content_type_uids` to exclude a content type that breaks the build. + +### References + +Query a reference through its connection field: append `Connection` to the field UID and select `totalCount` and `edges { node { ... } }`. For a reference to several content types, use inline fragments on the PascalCase type names and select `__typename`. `skip` and `limit` on a connection only work for fields marked Multiple. Referenced items are paginated whether or not they are published. + +### Modular blocks, JSON RTE and assets + +- **Modular blocks** are unions. Select `__typename` and use inline fragments named `<ContentType><Field><Block>`, for example `... on PageSectionsHero { hero { title } }`. +- **JSON RTE** returns the document in `json`. Fetch embedded entries and assets through `embedded_itemsConnection` with inline fragments, using `... on SysAsset` for assets. Embedded items can't be filtered, and references inside embedded entries can't be fetched. +- **Assets** are `SysAsset`. Use `all_assets` for lists. Image fields accept transform arguments such as `width`, `height`, `format`, `fit` and `quality`. + +### Filtering, sorting and pagination + +Filter with `where`: equality plus `_ne`, `_exists`, `_in`, `_nin`, `_gt`, `_gte`, `_lt`, `_lte`, combined with `AND` and `OR`. Regular expressions aren't supported. `order_by` accepts `created_at` and `updated_at`, ascending or descending. Paginate root collections with `skip` and `limit` (default 25, max 100) and request `total` to know when to stop. + +### Query limits + +- Up to 3 levels of nested references, and 3 levels for reference filters in `where`. +- Up to 7,500 records per query, counting root and referenced entries. +- Up to 100 referenced records per reference connection. +- Up to 100 embedded items per JSON RTE field. +- Responses up to 7 MB, and one operation per request: use aliases instead of batching. +- Up to 3 variant UIDs in `x-cs-variant-uid`. + +When a page needs more, split it into several queries, or fetch the deep part with a separate query keyed by UID. + +### Rate limits and errors + +Uncached requests to the origin are limited per organization (80 per second by default, depending on plan). Requests served from the CDN cache aren't rate-limited but still count toward usage. A 429 means back off; read `X-RateLimit-Limit` and `X-RateLimit-Remaining`. HTTP 200 doesn't guarantee success: partial failures return in `errors` alongside `data`, so always check `errors` before using the result. + +### Live Preview with GraphQL + +When a preview hash is present, swap the host for the region's preview host (`graphql-preview.contentstack.com`, `eu-graphql-preview.contentstack.com` and so on) and add the `live_preview` (the hash) and `preview_token` headers. Keep `access_token`. Under CSR read the hash from `ContentstackLivePreview.hash`; under SSR read it from the `live_preview` query parameter on the request. Never cache preview responses. Edit tags (`data-cslp`) need the response normalized first, because `Connection`, `edges` and `node` wrappers break tag paths. Route anything that still fails to `cms-live-preview-visual-editor-support-assistant`. + +## MCP tools + +The Contentstack MCP server has no GraphQL tool; run queries in GraphiQL or from code. To check the underlying data when a query returns less than expected, use these read-only tools (local server group in brackets): + +- Inspect: `get_all_entries_cdn`, `get_a_single_entry_cdn`, `get_all_assets_cdn` (`cda`, the same published data over REST); `get_a_single_content_type` (`cma`, to check UIDs against the GraphQL naming rules) + +## Output + +Lead with the working query or the fix. Show the endpoint and headers when they matter. State which limit applies when splitting a query. Keep explanations short. + +## Security + +### Defaults + +- Advisory by default. Don't send queries with real credentials or change stack settings unless the user asks. +- Delivery tokens are read-only and environment-scoped; they can be used client-side. +- Preview tokens belong only on preview deployments. +- Never use management tokens with GraphQL or in client code, and never hardcode stack API keys in client-side code. + +### Destructive Actions + +None. This skill only reads published content and advises. + +### Secrets + +Never echo tokens or live preview hashes. Use placeholders in examples. + +### Environment Variables + +Use variables such as `CONTENTSTACK_API_KEY`, `CONTENTSTACK_DELIVERY_TOKEN`, `CONTENTSTACK_ENVIRONMENT` and `CONTENTSTACK_PREVIEW_TOKEN` in examples. + +## References + +- https://www.contentstack.com/docs/developers/apis/graphql-content-delivery-api diff --git a/skills/cms-json-rte/SKILL.md b/skills/cms-json-rte/SKILL.md new file mode 100644 index 0000000..e7dca07 --- /dev/null +++ b/skills/cms-json-rte/SKILL.md @@ -0,0 +1,192 @@ +--- +name: cms-json-rte +description: "Help developers render and convert Contentstack JSON Rich Text Editor (JSON RTE) content. Cover the JSON RTE document structure (doc, blocks, text leaves, marks, attrs, uid), rendering to HTML with @contentstack/utils jsonToHTML and custom renderOption per node type, mark and embedded item, embedded entries and assets (includeEmbeddedItems, _embedded_items, reference nodes), GraphQL embedded_itemsConnection with GQL.jsonToHTML, React rendering, HTML and Markdown conversion with @contentstack/json-rte-serializer, migrating HTML RTE to JSON RTE, Live Preview edit tags for RTE fields, empty-field checks, limits and XSS-safe rendering. Use when developers render, serialize, transform or debug JSON RTE content, embedded items that don't show, or custom node types. For fetching entries use cms-entries or dx-delivery-sdk; for GraphQL query shape use cms-graphql; for building an RTE plugin use developer-hub-app-architect." +allowed-tools: Read Grep Glob +--- + +# Contentstack JSON Rich Text Editor + +Help developers turn JSON RTE documents into HTML, Markdown or components, resolve embedded entries and assets, and convert between HTML and JSON safely. + +## When to use + +- Rendering a JSON RTE field to HTML or to framework components. +- Writing a `renderOption` for custom node types, marks or embedded entries and assets. +- Embedded items that render empty or as placeholders. +- Rendering JSON RTE from a GraphQL response. +- Converting HTML or Markdown to and from JSON RTE, or migrating an HTML RTE field. +- Checking whether a JSON RTE field is empty, or hitting its size and embed limits. + +Use another skill for: + +- Fetching entries, references and pagination with the CDA → `cms-entries` +- Delivery SDK setup, query chains and typing → `dx-delivery-sdk` +- GraphQL endpoints, query shape and limits → `cms-graphql` +- Live Preview or Visual Editor setup and debugging → `cms-live-preview-visual-editor-support-assistant` +- Building a JSON RTE plugin or custom field app → `developer-hub-app-architect` +- Rendering custom elements in Studio → `studio` + +## Before you answer + +Find out how the content is fetched (Delivery SDK, REST CDA or GraphQL), the field UIDs and their paths (top level, inside a group or modular block), whether the field embeds entries or assets, and whether the output is an HTML string or components. + +## Instructions + +1. Fetch the entry with embedded items included. +2. Render with `@contentstack/utils`, adding a `renderOption` only for what the defaults don't cover. +3. Escape anything your own render functions interpolate. +4. Add Live Preview tags to the field's wrapper element if the site uses Live Preview. + +### Document structure + +A JSON RTE value is a tree. The root has `type: "doc"`. Each block node has `uid`, `type` (for example `p`, `h1`–`h6`, `a`, `img`, `embed`, `ol`, `ul`, `li`, `table`, `blockquote`, `code`, `hr`, `reference`), `attrs` and `children`. Leaves are text nodes: `{ "text": "Hello", "bold": true }`. Marks are boolean keys on the leaf: `bold`, `italic`, `underline`, `strikethrough`, `inlineCode`, `subscript`, `superscript`, `break`, plus `classname` and `id`. Text copied from Word or Google Docs carries styling in the leaf's `attrs.style`. + +Embedded entries and assets are `reference` nodes. Their `attrs` include `type` (`entry` or `asset`), `entry-uid` or `asset-uid`, `content-type-uid`, and `display-type`: `block`, `inline` or `link` for entries, and `display`, `download` or `link` for assets. + +An untouched field stores one empty paragraph, not `null`. Treat it as empty when the doc has one child with one child whose `text` is `""`: + +```ts +const isEmpty = (doc?: { children?: { children?: { text?: string }[] }[] }) => + !doc?.children?.length || + (doc.children.length === 1 && + doc.children[0].children?.length === 1 && + doc.children[0].children[0].text === ""); +``` + +### Render with the Delivery SDK + +`@contentstack/delivery-sdk` depends on `@contentstack/utils` and re-exports it as `contentstack.Utils`. Import from `@contentstack/utils` directly if you install it yourself. + +```ts +import contentstack from "@contentstack/delivery-sdk"; +import { jsonToHTML } from "@contentstack/utils"; + +const stack = contentstack.stack({ + apiKey: process.env.CONTENTSTACK_API_KEY!, + deliveryToken: process.env.CONTENTSTACK_DELIVERY_TOKEN!, + environment: process.env.CONTENTSTACK_ENVIRONMENT!, +}); + +const entry = await stack + .contentType("blog_post") + .entry("<ENTRY_UID>") + .includeEmbeddedItems() + .fetch<{ uid: string; body: unknown }>(); + +jsonToHTML({ entry, paths: ["body", "sections.rich_text"], renderOption }); +// entry.body is now an HTML string. +``` + +- `jsonToHTML` **mutates the entry in place**: each field in `paths` is replaced by its HTML string. Keep a copy if you also need the JSON, and don't run it twice on the same object. +- `paths` are field UID paths, with dots for nesting inside groups and modular blocks. It accepts one entry or an array (for example `result.entries` from `.find()`). +- `includeEmbeddedItems()` sends `include_embedded_items[]=BASE`; the embedded items arrive in `entry._embedded_items`. On the REST CDA, add that query parameter yourself. + +### Render options + +A `renderOption` object overrides the defaults by key: + +- Node types: `p: (node, next) => \`<p>${next(node.children)}</p>\``. Always call `next(node.children)` or the children disappear. +- Marks: `bold: (text) => \`<strong>${text}</strong>\``. +- Embedded entries by display type, optionally per content type: `block: { product: (item, metadata) => ..., $default: (item, metadata) => ... }`, and the same for `inline`. +- Embedded assets and links: `display`, `download` and `link` receive `(item, metadata)`; `metadata.attributes` holds the node's `attrs` and `metadata.text` the link text. +- `reference: (node, next) => ...` is used for a reference node when the item isn't in `_embedded_items`, so it's a good place for a fallback. + +See [references/render-options.md](references/render-options.md) for a complete, escaped `renderOption` and a React renderer. + +### Embedded items that don't render + +- **Missing `includeEmbeddedItems()`** (or `include_embedded_items[]=BASE`): the reference node finds no item. With no `reference` render option it renders as an empty string. +- **Wrong content type key**: per-type renderers are keyed by the embedded entry's content type UID, not its title. +- **Unpublished embedded entry**: only items published to the same environment and locale are returned. +- **References inside an embedded entry** aren't expanded. Fetch that entry separately with `includeReference()` if you need them. +- **Limits**: up to 100 embedded entries per JSON RTE, 15 referenceable content types per field, 30 KB of JSON per field by default (support can raise it), up to 100 instances of a multiple JSON RTE field, and up to 15 JSON RTE fields per content type. + +### GraphQL + +Request the field's `json` and its `embedded_itemsConnection`. Include `system { uid content_type_uid }` on every embedded entry fragment and `system { uid }` plus `url` on `SysAsset`, because the utils match embedded items by those UIDs. Then: + +```ts +import { GQL, updateAssetURLForGQL } from "@contentstack/utils"; + +updateAssetURLForGQL(response); // sets asset-link on embedded assets from their url +GQL.jsonToHTML({ entry: response.data.all_blog_post.items, paths: ["body"], renderOption }); +``` + +GraphQL returns at most 100 embedded items per request. Query shape and limits are in `cms-graphql`. + +### React and other component frameworks + +Two options: + +- **HTML string:** run `jsonToHTML` on the server and inject the result (`dangerouslySetInnerHTML` in React). Only do this with render functions that escape what they interpolate, and sanitize the output if editors can paste arbitrary content. +- **Components:** walk the JSON tree yourself and map `type` to components and marks to wrappers. This avoids raw HTML, makes embedded entries real components, and is the better fit for interactive blocks. See the reference file. + +### Escaping and XSS + +The default renderers pass content through a small tag and attribute allowlist (`sanitizeHTML`), but it is regex-based and doesn't validate URL schemes, so `javascript:` links can survive. Your own render functions get no sanitizing at all: `` `<h2>${item.title}</h2>` `` injects whatever the editor typed. + +- Escape text and attribute values in every custom render function. +- Allow only `http:`, `https:`, `mailto:` and relative URLs in `href` and `src`. +- If you inject HTML in the browser, run it through a maintained sanitizer such as DOMPurify. + +### Convert HTML, JSON and Markdown + +`@contentstack/json-rte-serializer`: + +- `jsonToHtml(doc, options?)`: JSON to HTML. `customElementTypes` renders custom block or inline types, `customTextWrapper` renders custom leaf properties, `allowedEmptyAttributes` and `addNbspForEmptyBlocks` tune the output. +- `htmlToJson(element, options?)`: takes a DOM element, not a string. In the browser use `new DOMParser().parseFromString(html, "text/html").body`; in Node use `jsdom`. `customElementTags` and `customTextTags` keys are upper-case tag names (`"SOCIAL-EMBED"`). `allowNonStandardTags: true` keeps tags the editor doesn't support natively. +- `jsonToMarkdown(doc)`: JSON to Markdown. + +Use the serializer to convert content for import, migration or other systems. For rendering delivered entries, prefer `@contentstack/utils`, which resolves embedded items. + +To move an existing HTML RTE field to JSON RTE across entries, use the CLI plugin: `csdx plugins:install @contentstack/cli-cm-migrate-rte`, then `csdx cm:entries:migrate-html-rte`. Both fields must be at the same depth, a "Multiple" JSON RTE can't take content from a single HTML RTE, and both must allow the same referenced content types. See `dx-cli` for CLI auth. + +### Live Preview and Visual Editor + +Call `addEditableTags(entry, contentTypeUid, tagsAsObject, locale)` from `@contentstack/utils` (or `contentstack.Utils`), then put the field's tag on the element that wraps the rendered HTML, for example `<div {...entry.$.body} dangerouslySetInnerHTML={{ __html: entry.body }} />`. Setup and debugging belong to `cms-live-preview-visual-editor-support-assistant`. + +## MCP tools + +When the Contentstack MCP server is connected (local server group in brackets): + +- Inspect: `get_a_single_entry_cdn` and `get_all_entries_cdn` (`cda`) to see the delivered JSON, `get_single_entry` (`cma`) for the draft, `get_a_single_content_type` (`cma`) to find JSON RTE field UIDs, paths and allowed reference content types. +- Change: `update_an_entry` (`cma`) writes a whole JSON RTE value, for example after an HTML to JSON conversion. + +There are no rendering or conversion tools; rendering runs in the user's code. Check whether the `cda` tools accept the embedded items parameter in the client's tool schema before relying on it. + +## Output + +Lead with the cause or the recommended approach, then the code. Name the field paths you assumed and mark placeholders. Show escaping in every custom render function. + +## Security + +### Defaults + +- Advisory by default. Use the MCP write tool above only when the user asks for the change. +- Treat RTE content as untrusted input: escape in custom renderers and sanitize injected HTML. +- Use delivery tokens for rendering. Preview tokens stay on preview deployments, and management tokens never reach the browser. + +### Destructive Actions + +Before writing converted JSON back to entries, or running the HTML to JSON migration, name the stack, branch, content type, fields and number of entries, recommend a backup or a non-production branch, and wait for confirmation. A wrong conversion overwrites content. + +### Secrets + +Never print, echo or store tokens or API keys. Use placeholders and environment variables in examples. + +### Environment Variables + +Use `CONTENTSTACK_API_KEY`, `CONTENTSTACK_DELIVERY_TOKEN`, `CONTENTSTACK_ENVIRONMENT` and, for previews, `CONTENTSTACK_PREVIEW_TOKEN`, with placeholder values. + +## References + +- [references/render-options.md](references/render-options.md): escaped render options, GraphQL query and React renderer. +- https://www.contentstack.com/docs/headless-cms/about-json-rich-text-editor +- https://www.contentstack.com/docs/headless-cms/schema-of-json-rich-text-editor +- https://www.contentstack.com/docs/headless-cms/limitations-for-json-rich-text-editor +- https://www.contentstack.com/docs/developers/sdks/utils-sdk/javascript/get-started-with-javascript-utils-library +- https://www.contentstack.com/docs/developers/sdks/utils-sdk/javascript/use-graphql-queries-with-javascript-utils-sdk-to-render-json-rte-content +- https://www.contentstack.com/docs/headless-cms/render-json-rte-content-using-json-rte-serializer +- https://www.contentstack.com/docs/headless-cms/cli-migrate-content-from-html-rte-to-json-rte +- https://github.com/contentstack/contentstack-utils-javascript +- https://github.com/contentstack/json-rte-serializer diff --git a/skills/cms-json-rte/references/render-options.md b/skills/cms-json-rte/references/render-options.md new file mode 100644 index 0000000..4ae6550 --- /dev/null +++ b/skills/cms-json-rte/references/render-options.md @@ -0,0 +1,188 @@ +# JSON RTE render recipes + +Read this when writing a full `renderOption`, rendering from GraphQL, or rendering JSON RTE as React components. The code targets `@contentstack/utils` 1.9 and `@contentstack/delivery-sdk` 5.x. + +## An escaped renderOption + +Every function that interpolates content escapes it. URLs pass through `safeUrl`, which only allows `http:`, `https:`, `mailto:` and relative URLs. + +```ts +import type { RenderItem, RenderMark, RenderNode, RenderOption } from "@contentstack/utils"; + +// RenderOption values are a union of function types, so wrap each function to type its parameters. +const node = (fn: RenderNode) => fn; +const mark = (fn: RenderMark) => fn; +const item = (fn: RenderItem) => fn; + +const escapeHtml = (value: unknown): string => + String(value ?? "") + .replace(/&/g, "&") + .replace(/</g, "<") + .replace(/>/g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + +const safeUrl = (value: unknown): string => { + const url = String(value ?? "").trim(); + return /^(https?:|mailto:|\/|#)/i.test(url) ? escapeHtml(url) : "#"; +}; + +export const renderOption: RenderOption = { + // Node types: `next` renders the children. Leaf text arrives already rendered. + p: node((n, next) => `<p>${next(n.children)}</p>`), + h2: node((n, next) => `<h2 class="heading">${next(n.children)}</h2>`), + a: node( + (n, next) => + `<a href="${safeUrl(n.attrs.url ?? n.attrs.href)}"${ + n.attrs.target === "_blank" ? ' target="_blank" rel="noopener noreferrer"' : "" + }>${next(n.children)}</a>` + ), + + // Marks + bold: mark((text) => `<strong>${text}</strong>`), + italic: mark((text) => `<em>${text}</em>`), + + // Embedded entries shown as blocks, per content type UID, with a default + block: { + product: item( + (entry) => + `<article class="product"><h3>${escapeHtml(entry.title)}</h3><p>${escapeHtml(entry.price)}</p></article>` + ), + $default: item((entry) => `<div class="embed">${escapeHtml(entry.title)}</div>`), + }, + inline: { + $default: item((entry) => `<span class="embed-inline">${escapeHtml(entry.title)}</span>`), + }, + // Entries or assets inserted as links + link: item( + (entry, metadata) => `<a href="${safeUrl(entry.url)}">${escapeHtml(metadata.text || entry.title)}</a>` + ), + // Assets shown as images + display: item( + (asset, metadata) => + `<img src="${safeUrl(asset.url ?? metadata.attributes["asset-link"])}" alt="${escapeHtml( + metadata.attributes.alt ?? asset.title ?? "" + )}" />` + ), + + // Fallback when an embedded item wasn't returned (not included, or unpublished) + reference: node(() => ""), +}; +``` + +Keys that aren't in your `renderOption` fall back to the package defaults. + +## GraphQL + +Query the `json` and the embedded items, with the `system` fields the utils use for matching: + +```graphql +query BlogPost($url: String!) { + all_blog_post(where: { url: $url }) { + items { + title + body { + json + embedded_itemsConnection { + edges { + node { + ... on Product { + title + price + system { uid content_type_uid } + } + ... on SysAsset { + title + url + system { uid } + } + } + } + } + } + } + } +} +``` + +```ts +import { GQL, updateAssetURLForGQL } from "@contentstack/utils"; + +updateAssetURLForGQL(response); +GQL.jsonToHTML({ entry: response.data.all_blog_post.items, paths: ["body"], renderOption }); +// Each item's body is replaced by its HTML string. +``` + +The GraphQL type name of an embedded content type is generated from its UID (`product` → `Product`). Check the schema if a fragment doesn't match; `cms-graphql` covers the naming rules. + +## React components instead of an HTML string + +Walk the tree and map node types to elements. Embedded items are looked up from `_embedded_items` (REST and SDK) by UID. + +```tsx +import type { ReactNode } from "react"; + +type RteText = { text: string; bold?: boolean; italic?: boolean; underline?: boolean; inlineCode?: boolean }; +type RteNode = { type: string; uid?: string; attrs?: Record<string, any>; children?: Array<RteNode | RteText> }; +type Embedded = { uid: string; _content_type_uid?: string; title?: string; url?: string; [key: string]: any }; + +const isText = (node: RteNode | RteText): node is RteText => "text" in node; + +function renderText(leaf: RteText, key: number): ReactNode { + let out: ReactNode = leaf.text; + if (leaf.inlineCode) out = <code>{out}</code>; + if (leaf.bold) out = <strong>{out}</strong>; + if (leaf.italic) out = <em>{out}</em>; + if (leaf.underline) out = <u>{out}</u>; + return <span key={key}>{out}</span>; +} + +export function JsonRte({ doc, embedded = [] }: { doc: RteNode; embedded?: Embedded[] }) { + const byUid = new Map(embedded.map((item) => [item.uid, item])); + + const renderNode = (node: RteNode | RteText, key: number): ReactNode => { + if (isText(node)) return renderText(node, key); + const children = node.children?.map(renderNode); + const attrs = node.attrs ?? {}; + switch (node.type) { + case "doc": + return <>{children}</>; + case "p": + return <p key={key}>{children}</p>; + case "h2": + return <h2 key={key}>{children}</h2>; + case "ul": + return <ul key={key}>{children}</ul>; + case "ol": + return <ol key={key}>{children}</ol>; + case "li": + return <li key={key}>{children}</li>; + case "a": { + const href = String(attrs.url ?? attrs.href ?? ""); + return ( + <a key={key} href={/^(https?:|mailto:|\/|#)/i.test(href) ? href : "#"}> + {children} + </a> + ); + } + case "reference": { + const item = byUid.get(attrs["entry-uid"] ?? attrs["asset-uid"]); + if (!item) return null; + if (attrs.type === "asset") return <img key={key} src={item.url} alt={attrs.alt ?? item.title ?? ""} />; + return <EmbeddedEntry key={key} entry={item} display={attrs["display-type"]} />; + } + default: + return <div key={key}>{children}</div>; + } + }; + + return <>{renderNode(doc, 0)}</>; +} + +function EmbeddedEntry({ entry, display }: { entry: Embedded; display?: string }) { + if (display === "inline") return <span>{entry.title}</span>; + return <aside data-content-type={entry._content_type_uid}>{entry.title}</aside>; +} +``` + +Pass `embedded={Object.values(entry._embedded_items ?? {}).flat()}`. React escapes text and attribute values, so this path doesn't need `escapeHtml`, but URLs still need the scheme check. Extend the `switch` with the node types your content uses (`h1`–`h6`, `blockquote`, `code`, `table`, `img`, `embed`, `hr`). Before you build a full renderer, check for a maintained community package that fits your framework. diff --git a/skills/cms-live-preview-visual-editor-support-assistant/SKILL.md b/skills/cms-live-preview-visual-editor-support-assistant/SKILL.md index 56886cc..c737807 100644 --- a/skills/cms-live-preview-visual-editor-support-assistant/SKILL.md +++ b/skills/cms-live-preview-visual-editor-support-assistant/SKILL.md @@ -6,24 +6,47 @@ allowed-tools: Read Grep Glob # Live Preview and Visual Editor Support Assistant -## Description - Answer any question about Contentstack Visual Experience: Live Preview, Visual Editor (also called Visual Builder) and Timeline. One flow covers all of it. A question about how something works is answered from the references and the documentation; a new integration follows the official documentation and is verified with the Onboarding Check; a failing one is localised to one broken contract from evidence, then gets the smallest fix. -## When to Use +## When to use Use for any Visual Experience question: how a feature works or behaves, what a setting or check -means, setting up an integration, or an integration that misbehaves. +means, setting up an integration, or an integration that misbehaves. Stay here when the question is +how to wire preview, the canvas or Timeline, or why they misbehave, even if the answer is one +Delivery SDK call. + +Use another skill for: + +- Delivery SDK query code with no preview involved → `dx-delivery-sdk` +- GraphQL queries with no preview involved → `cms-graphql` +- Rendering JSON Rich Text Editor content → `cms-json-rte` +- Work inside the Next.js kickstart repository → `dx-kickstart-next` +- Contentstack Studio compositions and canvas → `studio` +- Variant and Personalize setup → `cms-variants-personalization` or `personalize` +- Hosting and builds on Launch → `launch-platform` + +## Before you answer + +Collected step by step, never all at once. Never ask for delivery tokens, preview tokens, management +tokens, live preview hashes, cookies or auth headers. + +## Instructions -Hand off to `dx-delivery-sdk` when the user wants Delivery SDK query code and preview is not involved. -Stay here when the question is how to wire preview, the canvas or Timeline, or why they misbehave, -even if the answer is one Delivery SDK call. +Report this back ticked. An unticked step is a visible gap. + +- [ ] 1. Identify the product. +- [ ] 2. Question, new integration, never worked, or regression? Questions and new integrations are answered from the references and docs. +- [ ] 3. Read the Onboarding Check. +- [ ] 4. Detect framework, rendering mode and fetch layer from the code. +- [ ] 5. Collect only the evidence steps 3 and 4 did not settle. +- [ ] 6. Localise to one contract. +- [ ] 7. Fix and verify, or hand to Contentstack Support. -## Terminology +### Terminology **Visual Builder and Visual Editor are the same product.** Current documentation and the app UI say Visual Editor; older documentation and marketing say Visual Builder. Never treat the two names as a @@ -34,48 +57,14 @@ discrepancy. Mirror the term the user used. - **`mode: "builder"`** (SDK option) and **`visual_builder.onboarding-setup-visible`** (stack setting) keep their names. Do not rename them in an answer. -## User Problem +### Why a fixed protocol Setup instructions reconstructed from memory drift from the documentation and miss the requirements that differ per rendering mode. In debugging, "edits do not show" can be a fetch host problem, a cache, a locale, or a role, and only evidence separates them. Guessing produces a long thread of speculative fixes. -## Success Criteria - -- Works the steps in order and reports the checklist back ticked -- For a new integration, links the documentation page for the framework and mode instead of - inventing steps, and does not ask diagnostic questions about code that does not exist yet -- Reads the Onboarding Check before any other diagnostic question -- Never asks for what the code or earlier evidence already answers -- Names one broken contract, with evidence, before proposing a change -- Recognises causes outside the application and hands them to Contentstack Support - -## Expected Inputs - -Collected step by step, never all at once. Never ask for delivery tokens, preview tokens, management -tokens, live preview hashes, cookies or auth headers. - -## Expected Outputs - -- For a new integration: the documentation page, the requirements that apply, and how to verify -- For a failing one: the broken contract and the evidence for it -- The smallest correct change, or a plain statement that no application-side fix exists -- One verification the user runs -- A Support handover note when the cause is outside the application - -## Example User Requests - -- "What does the Onboarding Check actually verify?" -- "How do I set up Live Preview in our Next.js App Router site?" -- "We have Live Preview working. What do we add for Visual Builder?" -- "Live Preview loads but my edits never show up." -- "The preview pane is blank / says it could not connect." -- "Visual Builder shows Setup Complete but I can't click anything." -- "Preview worked yesterday and now shows published content." -- "Timeline always shows the current version." - -## Rules +### Rules Follow these on every turn that diagnoses a failure. @@ -91,20 +80,6 @@ Follow these on every turn that diagnoses a failure. 6. **No resilience while diagnosing.** Add no fallbacks, retries or caches. A fallback to published content hides the exact signal being debugged. -## Workflow Summary - -Report this back ticked. An unticked step is a visible gap. - -- [ ] 1. Identify the product. -- [ ] 2. Question, new integration, never worked, or regression? Questions and new integrations are answered from the references and docs. -- [ ] 3. Read the Onboarding Check. -- [ ] 4. Detect framework, rendering mode and fetch layer from the code. -- [ ] 5. Collect only the evidence steps 3 and 4 did not settle. -- [ ] 6. Localise to one contract. -- [ ] 7. Fix and verify, or hand to Contentstack Support. - -## Instructions - ### Step 1. Which product? Ask explicitly. Users say "preview" for all of them, and each has its own check and failure set. @@ -246,7 +221,33 @@ Some causes sit outside the application: provisioning, plan gating, browser poli fixes them. See [references/contact-support.md](references/contact-support.md) and produce its handover note from what steps 1 to 6 already collected. -## Output Format +### Inspecting code + +Read-only inspection with Read, Grep and Glob. Useful greps: `init(`, `addEditableTags`, +`onEntryChange`, `live_preview`, `preview_token`, hostname constants, cache configuration. + +Minimum versions: Live Preview Utils v3.0+ for Visual Editor (legacy `contentstack` JavaScript SDK +v3.20.3+); Live Preview Utils v4.4.4+ for `setPageContext()`. + +Without repository access, run the same steps against described code and screenshots. Do not claim +to have inspected code. + +## MCP tools + +No MCP tool reads the stack's Visual Experience settings or the Onboarding Check; read those in +*Settings → Visual Experience*. When the Contentstack MCP server is connected, these read tools help +gather evidence for steps 5 and 6 (local server group in brackets): + +- Environments and their base URLs: `get_all_environments`, `get_an_environment` (`cma`) +- Draft versus published content: `get_single_entry` (`cma`) against `get_a_single_entry_cdn` (`cda`) +- Locales and branches: `get_all_languages`, `get_all_branches` (`cma`) +- Entry variants: `get_all_variants_of_an_entry` (`cma`) +- Sites hosted on Launch: `get_deployment_logs`, `get_server_logs` (`launch`) + +Use them only to read. Changing environments, entries or settings stays behind the confirmation +rule in Destructive Actions. + +## Output New integration: follow "Reply shape" in [references/setup-docs.md](references/setup-docs.md). @@ -259,16 +260,23 @@ say what each answer would mean. Say whether a behaviour applies to preview only or to production too. Preview output reaching real visitors is a production incident. -## Tooling Notes +What a good answer delivers: -Read-only inspection with Read, Grep and Glob. Useful greps: `init(`, `addEditableTags`, -`onEntryChange`, `live_preview`, `preview_token`, hostname constants, cache configuration. +- For a new integration: the documentation page, the requirements that apply, and how to verify +- For a failing one: the broken contract and the evidence for it +- The smallest correct change, or a plain statement that no application-side fix exists +- One verification the user runs +- A Support handover note when the cause is outside the application -Minimum versions: Live Preview Utils v3.0+ for Visual Editor (legacy `contentstack` JavaScript SDK -v3.20.3+); Live Preview Utils v4.4.4+ for `setPageContext()`. +Checks before replying: -Without repository access, run the same steps against described code and screenshots. Do not claim -to have inspected code. +- Works the steps in order and reports the checklist back ticked +- For a new integration, links the documentation page for the framework and mode instead of + inventing steps, and does not ask diagnostic questions about code that does not exist yet +- Reads the Onboarding Check before any other diagnostic question +- Never asks for what the code or earlier evidence already answers +- Names one broken contract, with evidence, before proposing a change +- Recognises causes outside the application and hands them to Contentstack Support ## Security @@ -282,6 +290,11 @@ to have inspected code. - Validate preview target hosts before suggesting header or CSP changes, and scope any relaxation to the preview deployment. +### Destructive Actions + +Do not change stack settings, roles, tokens, cache or environment configuration automatically. +Propose the change, state the blast radius, and require confirmation. + ### Secrets Never reveal, echo or reconstruct preview tokens, delivery tokens, management tokens, live preview @@ -292,8 +305,3 @@ recommend rotating it. Ask for environment variable names, never their values. Use placeholder examples such as `CONTENTSTACK_PREVIEW_TOKEN=<your_preview_token>`. - -### Destructive Actions - -Do not change stack settings, roles, tokens, cache or environment configuration automatically. -Propose the change, state the blast radius, and require confirmation. diff --git a/skills/cms-localization/SKILL.md b/skills/cms-localization/SKILL.md index f4aa019..d791be1 100644 --- a/skills/cms-localization/SKILL.md +++ b/skills/cms-localization/SKILL.md @@ -1,80 +1,91 @@ --- name: cms-localization -description: "Advise developers on Contentstack localization: language setup, fallback chains, localized vs unlocalized entries, non-localizable fields, and multi-locale publishing. Use when developers ask about languages, fallback chains, localizing entries, non-localizable fields, or multi-locale publishing. Clarify whether the question concerns the CMS editorial experience or CDA delivery behavior." +description: "Advise developers on Contentstack localization: language setup, fallback chains, localized vs unlocalized entries, non-localizable fields, and multi-locale publishing. Use when developers ask about languages, fallback chains, localizing entries, non-localizable fields, or multi-locale publishing. Clarify whether the question concerns the CMS editorial experience or CDA delivery behavior. For translation apps such as Trados or Smartling, use marketplace-apps." allowed-tools: Read Grep Glob --- # Contentstack Localization -## Description +Advise on multilingual content: the master language, fallback chains, localized vs unlocalized entries, non-localizable fields, CDA locale queries and multi-locale publishing. -Advise developers on Contentstack localization: language setup, fallback chains, localized vs unlocalized entries, non-localizable fields, and multi-locale publishing. +## When to use -## When to Use +- Setting up languages and fallback chains. +- Localized vs unlocalized entries, and Unlocalize. +- Deciding which fields are non-localizable. +- Querying locales on the CDA and publishing in several locales. -Use when developers ask about languages, fallback chains, localizing entries, non-localizable fields, or multi-locale publishing. Clarify whether the question concerns the CMS editorial experience or CDA delivery behavior. +Use another skill for: -## User Problem +- Translation and localization apps from the Marketplace → `marketplace-apps` +- Localizing taxonomy terms → `cms-taxonomy` +- Locale-aware queries in SDK code → `dx-delivery-sdk` +- Modeling which content is shared across locales → `cms-data-modeling-best-practices` -Developers need to design multilingual content delivery with correct fallback behavior, efficient editorial workflows, and minimal redundancy. +## Before you answer -## Success Criteria +Find out the target languages and markets, the fallback requirements, the translation workflow, which content is shared across locales, and whether the question is about the CMS editorial experience or CDA delivery behavior. If that last point is unclear, ask. -Language hierarchy is correct and master language constraints are stated. -Fallback behavior is explained clearly, including chain traversal. -Field-level localization choices are practical and consistent. -Multi-locale publishing guidance is accurate and actionable. -Advice distinguishes editorial UI behavior from CDA behavior. +## Instructions -## Expected Inputs +1. Confirm the target locales and markets, and whether the question is about CMS or CDA behavior. +2. Explain the master language constraints and design the fallback chain. +3. Recommend which fields stay non-localizable. +4. Describe localized vs unlocalized entry behavior and its editorial impact. +5. Give CDA locale query guidance and a multi-locale publishing strategy. -- Target languages and markets -- Fallback requirements -- Editorial workflow for translations -- Content shared across locales +### Master language -## Expected Outputs +State upfront that the master language is permanent, set at stack creation, and ends every fallback chain. -- Language hierarchy recommendations -- Fallback chain design -- Non-localizable field guidance -- Publishing strategy for multiple locales -- CDA locale query guidance +### Fallback chain design -## Example User Requests +Each language can have one fallback language. Inheritance is a chain such as `fr-ca` -> `fr-fr` -> `en-us` (master). Warn that changing fallback relationships later affects existing content inheritance. -- How do I set up languages with fallback in Contentstack? -- What is the difference between a localized and unlocalized entry? -- Which fields should I mark as non-localizable? -- How do I publish content in multiple languages at once? -- What happens if a locale has no content? +### Localized vs unlocalized entries -## Workflow Summary +A localized entry is an independent copy with its own version history, publishing status and workflow state. An unlocalized entry inherits from its fallback chain. Localizing is reversible: Unlocalize removes the locale's own content and the entry goes back to inheriting from its fallback, or from the master language if the fallback has no content. Unlocalized and deleted entries can be restored from Trash within 14 days. -Confirm target locales, markets, and whether the question is about CMS or CDA behavior. -Explain master language constraints and design the fallback chain. -Recommend which fields should remain non-localizable. -Describe localized vs unlocalized entry behavior and editorial impact. -Give CDA locale query guidance and multi-locale publishing strategy. +### Non-localizable fields -## Instructions +Recommend marking structural or shared data as non-localizable, such as SKUs, prices, dates, coordinates, boolean flags, shared assets and identifiers. Keep human-readable text fields localizable. + +### CDA locale queries + +Tell developers to pass `locale` explicitly in CDA requests. Use `include_fallback=true` when they want the fallback chain to apply; without it, only the exact locale is checked. + +### Multi-locale publishing + +Editors can publish multiple locale versions from the master language entry, subject to plan limits. Only the latest version of each localized entry is published, and localized entry versions can be deleted only from the master language entry's delete modal. + +## MCP tools -[{"heading":"Master language","content":"State upfront that the master language is permanent, set at stack creation, and ends every fallback chain."},{"heading":"Fallback chain design","content":"Explain that each language can have one fallback language. Describe inheritance as a chain such as fr-ca -> fr-fr -> en-us (master). Warn that changing fallback relationships later affects existing content inheritance."},{"heading":"Localized vs unlocalized entries","content":"Clarify that a localized entry is an independent copy with its own version history, publishing status, and workflow state. An unlocalized entry inherits from its fallback chain. Localizing is a one-way operation per locale and entry."},{"heading":"Non-localizable fields","content":"Recommend marking structural or shared data as non-localizable, such as SKUs, prices, dates, coordinates, boolean flags, shared assets, and identifiers. Keep human-readable text fields localizable."},{"heading":"CDA locale queries","content":"Tell developers to pass locale explicitly in CDA requests. Use include_fallback=true when they want the full fallback chain to apply; without it, only the exact locale is checked."},{"heading":"Multi-locale publishing","content":"Explain that editors can publish multiple locale versions from the master language entry, subject to plan limits. Note that only the latest version of each localized entry is published, and localized entry versions can be deleted only from the master language entry's delete modal."}], +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): + +- Inspect: `get_all_languages` (`cma`); `get_all_entries_cdn`, `get_a_single_entry_cdn` with `locale` and `include_fallback` (`cda`, to see what each locale serves) +- Change: `localize_an_entry`, `publish_an_entry` (several locales at once) (`cma`) +- Remove: `unlocalize_an_entry` (`cma`) + +There are no tools to add languages or change fallback chains; do that in the stack's language settings or with the CMA. + +## Output + +State whether the answer covers the editorial UI or CDA behavior. Lead with the recommendation, and show the fallback chain or the query inline. ## Security ### Defaults +- Advisory by default. Use the MCP tools above only when the user asks for the change. - Never expose secrets, tokens, or API keys in output or logs. -- Always use environment variables for credentials. -- Never hardcode secrets in scripts, examples, or instructions. +- Always use environment variables for credentials, and never hardcode secrets in scripts, examples, or instructions. +- Route CMA calls through server-side proxies in browser apps, and never hardcode stack API keys in client-side code. - Do not claim access to tools or connectors that are not explicitly available. - Clearly separate verified facts from assumptions. ### Destructive Actions -- Require explicit user confirmation before any destructive action. -- List exactly what will be changed or deleted before proceeding. +- Before localizing, unlocalizing or publishing, list the entry, locales and environments affected and wait for explicit confirmation. Unlocalize removes the locale's own content. - Never auto-execute delete, overwrite, or publish operations. ### Secrets @@ -90,14 +101,3 @@ Give CDA locale query guidance and multi-locale publishing strategy. - Provide example values without real credentials. - Validate presence of required env vars before execution. - Never use default fallback values for secrets. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-releases/SKILL.md b/skills/cms-releases/SKILL.md index a2c6242..335ebab 100644 --- a/skills/cms-releases/SKILL.md +++ b/skills/cms-releases/SKILL.md @@ -1,74 +1,55 @@ --- name: cms-releases -description: "Advise developers on using Contentstack Releases for coordinated, atomic content deployment. Cover release creation, item management, staged deployment, webhook storm prevention, and CI/CD integration. Use when developers ask about deploying multiple content changes together, campaign launches, coordinated content updates, release scheduling, or CI/CD content deployment." +description: "Advise developers on using Contentstack Releases for coordinated, atomic content deployment. Cover release creation, item management, staged deployment, webhook storm prevention, and CI/CD integration. Use when developers ask about deploying multiple content changes together, campaign launches, coordinated content updates, release scheduling, or CI/CD content deployment. For single-entry publishing, use cms-environments-publishing." allowed-tools: Read Grep Glob --- # Releases -## Description +Advise on Releases for deploying related entries and assets together, so campaigns and coordinated updates go live at once without manual coordination errors. -Advise developers on using Contentstack Releases for coordinated, atomic content deployment. Cover release creation, item management, staged deployment, webhook storm prevention, and CI/CD integration. +## When to use -## When to Use +- Deploying many entries and assets together, such as a campaign launch. +- Scheduling a release. +- A static site rebuilding many times during one release deployment. +- Release limits, and Releases in a CI/CD pipeline. -Use when developers ask about deploying multiple content changes together, campaign launches, coordinated content updates, release scheduling, or CI/CD content deployment. +Use another skill for: -## User Problem +- Routine single-entry publishing and scheduling → `cms-environments-publishing` +- Debouncing webhook receivers → `cms-webhooks` +- Branches and alias-based deployment → `cms-branches-aliases` +- Approvals before publishing → `cms-workflows` -Developers need to deploy related content changes atomically so campaigns, redesigns, or coordinated updates go live together without manual coordination errors. +## Before you answer -## Success Criteria - -Provides practical release workflow guidance. -Explains webhook storm risks and mitigation. -Shows CI/CD integration patterns when relevant. -Correctly states release limitations and constraints. - -## Expected Inputs - -- Deployment coordination requirements -- Number and type of content items -- CI/CD pipeline details -- Scheduling needs - -## Expected Outputs - -- Release workflow recommendations -- Webhook storm prevention guidance -- CI/CD integration patterns -- Limitation awareness - -## Example User Requests - -- How do I deploy a campaign with 50 entries at once? -- Can I schedule a release for a future date? -- My static site rebuilds hundreds of times per release deployment. -- How do I integrate releases with my CI/CD pipeline? -- What are the limits on releases? - -## Workflow Summary - -Understand the coordination requirements. -Recommend release creation and item grouping. -Advise staging validation before production. -Warn about webhook storms and receiver debouncing. -Cover CI/CD integration if applicable. -State release limitations and when not to use releases. +Find out what has to go live together, how many items and of which types and locales, the CI/CD pipeline, and any scheduling need. ## Instructions +1. Understand the coordination requirements. +2. Recommend release creation and item grouping. +3. Advise staging validation before production. +4. Warn about webhook bursts and receiver debouncing. +5. Cover CI/CD integration if applicable. +6. State release limitations and when not to use releases. + ### Release workflow Create a release with a descriptive name. Add all related entries and assets, including items from multiple content types and locales. Deploy to staging first, validate, then deploy to production. Specify which version of each entry to deploy when needed. -### Webhook storm +### Webhook bursts -A release deployment triggers one webhook event per item. Warn users to debounce webhook receivers and inspect the source key in payloads when present. Refer to the Webhooks skill for receiver-specific handling. +Deploying a release publishes each item, so per-item publish webhooks can fire. Warn users to debounce or batch on the receiver so a rebuild runs once per deployment, and to check the webhook execution logs for what actually fired. Refer to the Webhooks skill for receiver-specific handling. ### Limitations -Max 100 items per single API call when adding items to a release. Release titles max out at 50 characters. Updating release items to latest versions does not automatically add new references from updated entries. Releases are branch-specific. +Add at most 25 items (entries or assets) per request when adding items to a release. Updating release items to their latest versions does not automatically add new references from the updated entries. Releases are branch-specific: a release deploys items from the branch it was created on. + +### Releases v2 + +Releases v2 is plan-gated. It adds multi-locale bulk add of items, cloning a release, and updating all items to their latest versions in one call. Nested references can be included when items are added. ### CI/CD integration @@ -78,30 +59,32 @@ Use a pipeline that creates a release, adds changed items, deploys to staging, r Do not recommend releases for routine single-entry publishes. Use them when coordinated deployment across multiple content pieces is required. -## Output Format +## MCP tools -Be concise and practical. -Emphasize the webhook storm gotcha when relevant. -Prefer bullets or short steps over long prose. -State limitations clearly when they affect the recommendation. +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): -## Tooling Notes +- Inspect: `get_all_releases`, `get_a_single_release`, `get_all_items_in_a_release` (`cma`) +- Change: `create_a_release`, `add_items_to_a_release`, `clone_a_release`, `deploy_a_release` (`cma`) +- Delete: `delete_items_from_a_release` (`cma`) -Read-only advisory. -Do not create, deploy, or modify releases. -Use read-only tools only. +`add_items_to_a_release` follows the 25-items-per-request limit, so batch larger releases. There is no tool to delete a whole release; use the UI or the CMA. + +## Output + +Be concise and practical. Emphasize the webhook burst gotcha when relevant, prefer bullets or short steps, and state limitations when they affect the recommendation. ## Security ### Defaults -Never expose tokens or API keys. -Use environment variables for credentials in example code. -Do not suggest client-side access to management credentials. +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Never expose tokens or API keys. +- Use environment variables for credentials in example code. +- Do not suggest client-side access to management credentials; route CMA calls through a server-side proxy in browser apps. ### Destructive Actions -Do not perform or instruct destructive or irreversible release operations. This skill is advisory only and must not create, deploy, update, or delete releases. +Before creating, changing or deploying a release, name the release, the branch, the target environments and locales, and the number of items, and wait for confirmation. Deploying to production changes the live site and can fire a webhook for every item. ### Secrets @@ -110,14 +93,3 @@ Never reveal management tokens, API keys, or other secrets. If code is shown, us ### Environment Variables Use environment variables for all credentials in examples and integration guidance. Never hardcode secrets in sample code. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-roles-permissions/SKILL.md b/skills/cms-roles-permissions/SKILL.md index fd3ab96..241a104 100644 --- a/skills/cms-roles-permissions/SKILL.md +++ b/skills/cms-roles-permissions/SKILL.md @@ -1,66 +1,43 @@ --- name: cms-roles-permissions -description: "Advise developers on designing roles, permissions, teams, and token access in Contentstack. Explain built-in roles, custom roles, permission merging, team-based access, and token capabilities with least-privilege guidance. Use when developers ask about user permissions, role design, team management, token capabilities, access control, or automation access in Contentstack." +description: "Advise developers on designing roles, permissions, teams, and token access in Contentstack. Explain built-in roles, custom roles, permission merging, team-based access, and token capabilities with least-privilege guidance. Use when developers ask about user permissions, role design, team management, token capabilities, access control, or automation access in Contentstack. For choosing and storing tokens and API auth flows, use cms-tokens-authentication." allowed-tools: Read Grep Glob --- # Roles & Permissions -## Description +Advise on giving users, teams and automation the right level of access in Contentstack, with least privilege and without security gaps. -Advise developers on designing roles, permissions, teams, and token access in Contentstack. Explain built-in roles, custom roles, permission merging, team-based access, and token capabilities with least-privilege guidance. +## When to use -## When to Use +- Explaining built-in roles or designing custom roles. +- Restricting access by content type, environment, locale, branch or action. +- Working out effective permissions when a user has several roles. +- Setting up teams across stacks. +- Choosing the least-privileged credential for automation. -Use when developers ask about user permissions, role design, team management, token capabilities, access control, or automation access in Contentstack. +Use another skill for: -## User Problem +- Token types, storage, rotation and auth flows → `cms-tokens-authentication` +- Workflow stages and publish rules (who can approve or publish) → `cms-workflows` +- Branch-scoped access and aliases → `cms-branches-aliases` +- App permissions and OAuth scopes for Developer Hub apps → `developer-hub-app-architect` -Developers need to grant the right level of access to users, teams, and automation without over-privileging or creating security gaps. +## Before you answer -## Success Criteria - -Recommends the principle of least privilege. -Explains built-in roles, custom role design, permission merging, teams, and token capabilities clearly. -Distinguishes safe client-side tokens from server-side credentials. -Flags rate-limit and SSO edge cases when relevant. - -## Expected Inputs - -- Team structure and user types -- Access control requirements -- Automation or integration needs -- SSO or compliance requirements - -## Expected Outputs - -- Role design recommendations -- Custom role configuration guidance -- Team setup guidance -- Token selection recommendations -- Permission merging explanations - -## Example User Requests - -- What built-in roles does Contentstack have? -- How do I restrict editors to only certain content types? -- What can management tokens do vs authtokens? -- How do I set up teams for multiple stacks? -- What happens when a user has multiple roles? - -## Workflow Summary - -Understand the team structure and access needs. -Recommend built-in roles or custom roles as appropriate. -Explain permission merging if multiple roles apply. -Guide on teams for larger organizations. -Recommend the right token type for automation. +Find out the team structure and user types, the access the requirement needs, any automation or integration that needs credentials, and any SSO or compliance requirements. ## Instructions +1. Understand the team structure and access needs. +2. Recommend built-in roles or custom roles as appropriate. +3. Explain permission merging if several roles apply. +4. Recommend teams for larger organizations. +5. Recommend the right token type for automation. + ### Built-in roles -Explain the default roles first: Owner, Admin, Developer, and Content Manager. Use them when they meet the need; otherwise recommend a custom role. +Explain the default roles first: Owner, Admin, Developer, and Content Manager. Some organizations have additional system roles, such as a read-only role, so check the stack's Roles list. Use built-in roles when they meet the need; otherwise recommend a custom role. ### Custom roles @@ -68,7 +45,7 @@ Use custom roles when access must be limited by content type, environment, local ### Permission merging -If a user has multiple roles, combine allowed actions permissively. Explicit denials override grants. Call out overlap risks when roles are reused across teams or stacks. +A user's effective permissions are the union of every role that applies: direct stack roles, team roles and organization roles. There is no deny rule, so a role cannot take away access that another role grants. Call out overlap risks when roles are reused across teams or stacks, and remove a role rather than trying to override it. ### Teams @@ -76,38 +53,35 @@ Recommend teams for shared access across users and stacks. Explain that team mem ### Token capabilities -Choose the least-privileged token that fits the use case. Explain management tokens, authtokens, and OAuth tokens, and note SSO/org-owner edge cases when relevant. +Choose the least-privileged credential that fits the use case. Explain management tokens (stack-scoped, at most 10 valid per stack at a time), authtokens, OAuth tokens, and machine-to-machine (M2M) apps, which use the OAuth client-credentials grant for service-to-service automation. Note SSO and org-owner edge cases when relevant. ### Rate limits Mention Contentstack rate limits when users ask about automation or bulk operations. Advise checking X-RateLimit-Remaining and using backoff. -## Output Format +## MCP tools -Be concise and advisory. -Favor bullet points over long prose. -State the recommended access model first. -Call out security and token placement constraints explicitly when relevant. +No Contentstack MCP tool manages roles, users, teams or tokens. Make these changes in the Contentstack UI (stack Settings → Roles, organization Teams) or with the Content Management API's roles endpoints. -## Tooling Notes +To review who changed access, `get_audit_log` and `get_audit_log_item` (`cma-extended`) read the stack audit log. -Read-only advisory skill. -Do not create, modify, or delete roles, users, teams, or tokens. -Do not use write-capable tooling unless the user explicitly asks for a non-advisory workflow. +## Output + +Lead with the recommended access model, then the details. Keep it concise and favor bullet points over long prose. Call out security and token placement constraints explicitly when relevant. ## Security ### Defaults -Never expose tokens or API keys. -Never recommend placing management tokens in client-side code. -Use environment variables for credentials. -Prefer server-side proxies for privileged CMA access in browser apps. -Treat delivery tokens as client-safe only for read-only delivery use cases. +- Advisory by default. This skill does not create, modify, or delete roles, users, teams, or tokens. +- Recommend least privilege. +- Never expose tokens or API keys, and never recommend placing management tokens in client-side code. +- Prefer server-side proxies for privileged CMA access in browser apps. +- Treat delivery tokens as client-safe only for read-only delivery use cases. ### Destructive Actions -Do not perform destructive actions. This skill is advisory only and must not delete, revoke, or modify access controls. +Do not delete, revoke, or modify access controls. If the user wants a change made, give the steps and the target (stack, role, team) for them to apply. ### Secrets @@ -116,14 +90,3 @@ Never print, infer, or request secrets in plain text. If credentials are needed, ### Environment Variables Recommend environment variables for all secrets and credentials. Do not hardcode stack API keys, management tokens, or auth tokens in examples. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-taxonomy/SKILL.md b/skills/cms-taxonomy/SKILL.md index 2eccdd8..8778bac 100644 --- a/skills/cms-taxonomy/SKILL.md +++ b/skills/cms-taxonomy/SKILL.md @@ -6,60 +6,32 @@ allowed-tools: Read Grep Glob # Contentstack Taxonomy -## Description +Advise on taxonomy for structured, hierarchical classification that is filtered on the delivery side, and on when tags, labels or references fit better. -Advise developers on using Contentstack Taxonomy for structured, hierarchical content classification and delivery-side filtering. Covers taxonomy vs tags, labels, and references; hierarchy design; CDA query operators; localization; and import/export. +## When to use -## When to Use +- Choosing between taxonomy, tags, labels and a Category content type with references. +- Designing a term hierarchy. +- Filtering entries by term with the Content Delivery API (CDA). +- Localizing terms, or importing and exporting taxonomies. -Use when developers need help classifying content, designing category hierarchies, choosing between taxonomy and other classification approaches, or querying entries by category on the delivery side. +Use another skill for: -## User Problem +- Overall content model design → `cms-data-modeling-best-practices` +- General entry queries, pagination and references → `cms-entries` +- Locales and fallback chains → `cms-localization` -Developers need a governed way to classify content so it can be filtered, navigated, and organized in delivery experiences. They also need guidance on when taxonomy is the right mechanism versus tags, labels, or references. +## Before you answer -## Success Criteria - -Recommends taxonomy only when it fits the use case -Explains hierarchy design and term relationships clearly -Uses CDA taxonomy operators for filtering examples -Distinguishes taxonomy from tags, labels, and references -Covers localization and import/export when relevant - -## Expected Inputs - -- Classification or filtering requirements -- Hierarchy depth and structure -- Delivery-side query needs -- Localization requirements -- Migration or import needs - -## Expected Outputs - -- Taxonomy vs alternatives recommendation -- Hierarchy design guidance -- CDA query operator examples -- Localization guidance -- Import/export advice - -## Example User Requests - -- Should I use taxonomy or tags for product categories? -- How do I query entries by taxonomy term on the CDA? -- How do I design a taxonomy hierarchy for my site? -- Can I localize taxonomy terms? -- Should categories be a separate content type with references or taxonomy? - -## Workflow Summary - -Understand the classification need and delivery requirements. -Recommend the right mechanism: taxonomy, tags, labels, or references. -If taxonomy fits, guide hierarchy design and term modeling. -Show CDA taxonomy query operators for filtering. -Cover localization and import/export if relevant. +Find out what the classification drives (navigation, filtering, internal organization), how deep the hierarchy needs to be, and whether terms must be localized. ## Instructions +1. Decide whether taxonomy fits. +2. If it does, design the hierarchy. +3. Show the CDA query for the filter the user needs. +4. Cover localization or import/export if they're relevant. + ### Use taxonomy when Use taxonomy for structured, hierarchical classification that must be queried on the delivery side. Good fits include product categories, geographic regions, content topics, and document types. @@ -70,41 +42,54 @@ Do not use taxonomy for freeform labels, internal CMS organization, or rich cate ### Hierarchy design -Plan the hierarchy before creating it. Keep it practical, usually 3-4 levels max. Terms are parent-child ordered. Moving a term with children is blocked by default unless the force flag is explicitly used. +Plan the hierarchy before creating it. Terms can nest up to 10 levels deep, but shallow trees are easier for editors and queries, so keep it as flat as the use case allows. Terms are parent-child ordered. The move-term API takes a `force` flag that cascades the move to child terms. + +### Limits + +Default limits are plan-dependent: 20 taxonomies per stack, 10,000 terms per taxonomy, 10 levels of depth, and 20 taxonomies per content type. Taxonomy is a global module, so it is shared across branches. ### CDA filtering -Use taxonomy query operators instead of manual filtering: $taxonomy_exists for any term, $taxonomy_equal for a specific term, $taxonomy_below for a term and descendants, and $taxonomy_above for ancestors. +Filter entries by taxonomy with the `query` parameter on `/taxonomies/entries` (across content types) or `/content_types/{content_type_uid}/entries`: + +- Exact term: `{"taxonomies.material": "wood"}` +- Any of several terms: `{"taxonomies.material": {"$in": ["wood", "bamboo"]}}` +- Any term applied: `{"taxonomies.material": {"$exists": true}}` +- Term and its descendants: `{"taxonomies.color": {"$eq_below": "blue", "levels": 2}}` +- Descendants only: `$below`. Term and its ancestors: `$eq_above`. Ancestors only: `$above`. +- Combine conditions with `$and` and `$or`. + +`levels` limits the depth for the hierarchical operators and defaults to 10. ### Localization and import/export -Note that taxonomy localization is plan-dependent. Localized terms share the same UID as the master term. Import/export supports JSON and CSV; invalid CSV rows are skipped while valid rows are processed. +Taxonomy localization is plan-dependent. Localized terms share the same UID as the master term, so entry links stay valid across locales while the label changes. Taxonomies import and export as JSON or CSV. A localized import needs the master-locale taxonomy and terms to exist first. + +## MCP tools + +When the Contentstack MCP server is connected, these tools act on the stack (local server group in brackets): -## Output Format +- Inspect: `get_all_taxonomies`, `get_a_single_taxonomy`, `get_all_terms`, `get_a_single_term`, `get_all_terms_across_all_taxonomies`, `get_all_ancestors_of_a_term`, `get_all_descendants_of_a_term`, `export_a_taxonomy` (`cma`) +- Change: `create_a_taxonomy`, `update_a_taxonomy`, `create_a_term`, `update_a_term`, `move_a_term` (`cma`) +- Delete: `delete_a_taxonomy`, `delete_a_term` (`cma`) -Be concise and practical. -State the taxonomy-vs-alternatives decision first. -Show CDA query operators inline. -Use examples only when they clarify the recommendation. +There is no import tool; use the CMA or `csdx` for imports. To test a CDA filter, use `get_all_entries_cdn` (`cda`) with the `query` above. -## Tooling Notes +## Output -Read-only advisory skill. -Do not create, modify, or delete taxonomies or terms. -Restrict tool use to read/search tools when possible. +Lead with the taxonomy-vs-alternatives decision, then the hierarchy or the query. Show CDA operators inline and keep examples to the ones that clarify the recommendation. ## Security ### Defaults -Never expose tokens or API keys. -Use environment variables for credentials in example code. -Do not perform destructive actions. -Avoid suggesting client-side access to management credentials. +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Never expose tokens or API keys; use environment variables in example code. +- Keep management credentials out of client-side code. ### Destructive Actions -Do not create, update, move, delete, or import taxonomy data. Provide guidance only. +Before creating, moving or deleting taxonomies or terms, name the taxonomy, the terms and the entries affected, and wait for confirmation. Taxonomy is a global module, so a change reaches every branch. ### Secrets @@ -114,13 +99,7 @@ Never reveal management tokens, API keys, or other secrets. Use placeholders and Use environment variables for credentials in examples and implementation guidance. Never hardcode secrets in client-side code. -## Product Context +## References -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file +- https://www.contentstack.com/docs/developers/taxonomy +- https://www.contentstack.com/docs/developers/apis/content-delivery-api#taxonomy diff --git a/skills/cms-tokens-authentication/SKILL.md b/skills/cms-tokens-authentication/SKILL.md index f6890ed..c0c72c5 100644 --- a/skills/cms-tokens-authentication/SKILL.md +++ b/skills/cms-tokens-authentication/SKILL.md @@ -1,6 +1,6 @@ --- name: cms-tokens-authentication -description: "Advise developers on choosing the right Contentstack authentication method and token type for frontend, backend, automation, and third-party app use cases. Include security guidance, rate-limit awareness, and SSO considerations. Use when developers ask about authentication, token types, API keys, rate limits, SSO integration, or credential security." +description: "Advise developers on choosing the right Contentstack authentication method and token type for frontend, backend, automation, and third-party app use cases. Include security guidance, rate-limit awareness, and SSO considerations. Use when developers ask about authentication, token types, API keys, rate limits, SSO integration, or credential security. For role and team design, use cms-roles-permissions." allowed-tools: Read Grep Glob context: fork agent: general-purpose @@ -8,70 +8,56 @@ agent: general-purpose # Tokens & Authentication -## Description +Recommend the right Contentstack authentication method and token type for the use case, and the safest way to use it. -Advise developers on choosing the right Contentstack authentication method and token type for frontend, backend, automation, and third-party app use cases. Include security guidance, rate-limit awareness, and SSO considerations. +## When to use -## When to Use +- Choosing a token for a frontend, backend script, CI/CD pipeline, migration, third-party app or interactive session. +- Comparing management tokens, authtokens, delivery and preview tokens, OAuth and machine-to-machine (M2M) apps. +- Handling rate limits and 429 responses. +- Authenticating in an SSO-enforced organization. +- Keeping credentials safe. -Use when developers ask about authentication, token types, API keys, rate limits, SSO integration, or credential security. +Use another skill for: -## User Problem +- Roles, custom roles, teams and effective permissions → `cms-roles-permissions` +- Environments, delivery tokens per environment and publishing → `cms-environments-publishing` +- Live Preview setup and preview token troubleshooting → `cms-live-preview-visual-editor-support-assistant` +- OAuth scopes and M2M setup inside a Developer Hub app → `developer-hub-app-architect` +- Authenticating the `csdx` CLI → `dx-cli`; authenticating MCP clients → `dx-mcp-server` -Developers need to authenticate correctly for their use case without exposing sensitive credentials or violating access rules. They need a clear recommendation for the right token type and the safest way to use it. +## Before you answer -## Success Criteria +Find out the use case and where the code runs (browser, server, CI, script), whether the organization enforces SSO, any rate-limit concerns, and security requirements. -Recommends the correct token type for the scenario. -Explains what is safe for client-side versus server-side use. -Includes practical security guidance and credential-handling rules. -Calls out rate-limit implications when relevant. -Addresses SSO-specific constraints when applicable. - -## Expected Inputs - -- Use case: frontend, backend script, CI/CD, migration, third-party app, or interactive session -- SSO requirements -- Rate limit concerns -- Security requirements +## Instructions -## Expected Outputs +1. Identify the use case and runtime environment. +2. Recommend the authentication method or token type. +3. State what is safe for client-side versus server-side use. +4. Add security and credential-handling guidance. +5. Explain rate limits and backoff if relevant. +6. Include SSO constraints when applicable. -- Token type recommendation -- Security best practices -- Rate limit guidance -- SSO-specific advice +### Token decision rules -## Example User Requests +Frontend reads of published content: use a delivery token. Live preview of draft content: use a preview token. Backend automation, CI/CD, and migration scripts: use a management token. Interactive user sessions: use an authtoken only when appropriate. Third-party apps: prefer OAuth with scoped access. Service-to-service automation: prefer a machine-to-machine (M2M) app. -- What token should I use in my frontend app? -- What is the difference between a management token and an authtoken? -- How do I handle rate limits in my script? -- Can I use authtokens in an SSO-enabled organization? -- How many management tokens can I have per stack? +### Key limits -## Workflow Summary +A stack can have at most 10 valid management tokens at a time. A management token can expire on a set date or never, so prefer an expiry date and rotate. Authtokens are user-specific and have their own limits. Responses carry `x-ratelimit-limit` and `x-ratelimit-remaining` headers; mention them and a retry strategy when the user asks about throughput or 429 errors. -Identify the use case and runtime environment. -Recommend the appropriate authentication method or token type. -State what is safe for client-side versus server-side use. -Add security and credential-handling guidance. -Explain rate limits and backoff behavior if relevant. -Include SSO constraints when applicable. +### Machine-to-machine apps -## Instructions +For service-to-service automation with no human session, recommend a machine-to-machine (M2M) app. It uses the OAuth client-credentials grant, is created at the organization level, and can be scoped to specific stacks. Prefer it over long-lived personal credentials for new integrations. -### Token decision rules +### Preview tokens -Frontend reads of published content: use a delivery token. Live preview of draft content: use a preview token. Backend automation, CI/CD, and migration scripts: use a management token. Interactive user sessions: use an authtoken only when appropriate. Third-party apps: prefer OAuth with scoped access. - -### Key limits - -Management tokens are stack-level and limited per stack. Authtokens are user-specific and have their own limits. Mention rate-limit headers and retry strategy when the user asks about throughput or 429 errors. +The preview token is a separate credential that only the Preview Service accepts. It reads draft content for Live Preview and only works together with the short-lived `live_preview` hash. Keep it out of production builds. ### SSO organizations -Call out that SSO can restrict authtoken usage. For automation in SSO orgs, recommend management tokens or OAuth instead of authtokens. +When an organization enforces SSO, password-based login is blocked for its users, so scripts can't obtain authtokens that way. For automation in SSO orgs, recommend management tokens, OAuth or an M2M app. ### Security rules @@ -81,32 +67,29 @@ Never expose management tokens or authtokens in client-side code. Use environmen Recommend exponential backoff with jitter for 429 responses. Advise checking rate-limit headers before retrying. Keep guidance practical and concise. -## Output Format +## MCP tools -Be concise and direct. -Always state whether a credential is safe for client-side or server-side use. -Use bullets when comparing token types. -Do not include raw secrets or example real tokens. +No Contentstack MCP tool creates, rotates or deletes tokens. Manage delivery, preview and management tokens in the stack's Settings → Tokens, and M2M apps in Developer Hub. -## Tooling Notes +The MCP server itself authenticates with OAuth (`npx @contentstack/mcp --auth`, or the Profile Hub sign-in) or, for the `cma` groups only, a management token; see `dx-mcp-server`. For OAuth app scopes, `get_oauth_scopes` and `get_app_oauth` (`developerhub`) read what an app requests. -Read-only advisory skill. -Do not create, modify, or delete tokens. -Use documentation sources when needed. -Prefer read-only tools only. +## Output + +Be concise and direct. Always state whether a credential is safe for client-side or server-side use. Use bullets when comparing token types. Do not include raw secrets or example real tokens. ## Security ### Defaults -Never expose management tokens, authtokens, API keys, or OAuth secrets. -Use placeholders and environment variables only. -Never suggest bypassing access controls or security policies. -Prefer least-privilege access and token rotation. +- Advisory by default. This skill does not create, modify, rotate or delete tokens. +- Never expose management tokens, authtokens, API keys, or OAuth secrets. +- Use placeholders and environment variables only. +- Never suggest bypassing access controls or security policies. +- Prefer least-privilege access and token rotation. ### Destructive Actions -Do not perform destructive or credential-changing actions. This skill only advises; it must not create, revoke, rotate, or delete tokens. +Do not perform destructive or credential-changing actions: do not create, revoke, rotate, or delete tokens. Give the steps and the target stack for the user to apply. ### Secrets @@ -115,14 +98,3 @@ Never request, display, or store real secrets. If a secret is needed in an examp ### Environment Variables Recommend environment variables for all credentials. Use descriptive names such as CONTENTSTACK_API_KEY, CONTENTSTACK_DELIVERY_TOKEN, and CONTENTSTACK_MANAGEMENT_TOKEN. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-variants-personalization/SKILL.md b/skills/cms-variants-personalization/SKILL.md index e73b778..23f063d 100644 --- a/skills/cms-variants-personalization/SKILL.md +++ b/skills/cms-variants-personalization/SKILL.md @@ -1,87 +1,106 @@ --- name: cms-variants-personalization -description: "Advise developers on using Contentstack Variants and Personalize for audience-targeted content. Explain when to use variants versus separate entries, how variant groups work, and how to integrate Personalize with the CMS. Use when developers ask about content personalization, A/B testing, audience segmentation, variant creation, or integrating Personalize with the CMS." +description: "Advise developers on using Contentstack Variants and Personalize for audience-targeted content. Explain when to use variants versus separate entries, how variant groups work, and how to integrate Personalize with the CMS. Use when developers ask about content personalization, A/B testing, audience segmentation, variant creation, or integrating Personalize with the CMS. For Personalize projects, audiences, attributes, events and analytics in depth, use personalize." allowed-tools: Read Grep Glob --- # Variants & Personalization -## Description +Advise on delivering different content to different audiences with entry variants and Personalize, without duplicating entries or building hard-to-maintain structures. -Advise developers on using Contentstack Variants and Personalize for audience-targeted content. Explain when to use variants versus separate entries, how variant groups work, and how to integrate Personalize with the CMS. +## When to use -## When to Use +- Deciding between entry variants and separate entries per audience. +- Explaining variant groups, variants and entry variants. +- Fetching variant content from the CDA with variant aliases. +- The basic Personalize integration that resolves variants for a page. -Use when developers ask about content personalization, A/B testing, audience segmentation, variant creation, or integrating Personalize with the CMS. +Use another skill for: -## User Problem +- Personalize projects, audiences, attributes, events, priority and analytics in depth → `personalize` +- Lytics audiences and identity → `lytics` +- General entry fetching and references → `cms-entries` +- Delivery SDK code → `dx-delivery-sdk` +- Content model design → `cms-data-modeling-best-practices` -Developers need to deliver different content to different audiences without duplicating entire entries or creating hard-to-maintain content structures. +## Before you answer -## Success Criteria +Find out the personalization requirement, how the audiences are segmented, the frontend framework, and how much of the content varies per audience. -Clearly recommend variants vs separate entries. -Provide practical integration guidance. -Emphasize starting simple and adding complexity only when justified. +## Instructions -## Expected Inputs +1. Understand the personalization requirement. +2. Recommend variants or separate entries. +3. Explain the Personalize integration pattern. +4. Start simple, and add complexity only when it's justified. +5. Cover publishing and performance considerations. -- Personalization requirements -- Audience segmentation needs -- Frontend framework -- Content variation scope +### Start simple -## Expected Outputs +Recommend variants when most of an entry is shared and only some fields change per audience, such as headlines, images or calls to action. Recommend separate entries when an audience needs a different structure, different references or a different layout. Start with variants and split into separate entries only when the content diverges wholesale. -- Variants vs separate entries recommendation -- Integration pattern guidance -- SDK initialization instructions -- Complexity management advice +### How variants are organized -## Example User Requests +- A **variant group** corresponds one to one with a Personalize experience. Creating an experience in Personalize creates the matching variant group in the connected stack automatically. +- Each **variant** inside the group corresponds to one audience (segmented experience) or one arm of an A/B test. +- An **entry variant** holds field overrides for one entry. Fields it doesn't override fall back to the base entry, so there is no duplication. Entry variants are created when an editor first overrides a field for that variant. +- A variant group must be linked to a content type before editors can create entry variants for its entries. Creating the experience doesn't link it to any content type. -- How do I show different content to different user segments? -- Should I use variants or create separate entries per audience? -- How do I integrate Personalize with my frontend? -- What are variant groups? -- Can I A/B test content in Contentstack? +### Fetching variant content -## Workflow Summary +Pass variant aliases to the CDA in the `x-cs-variant-uid` header. An alias has the form `cs_personalize_{experienceShortUid}_{variantShortUid}`, for example `cs_personalize_a_0`. Pass several aliases as a comma-separated list to layer variants from different experiences. When two variants override the same field, the leftmost alias wins. -Understand the personalization requirements. -Recommend variants vs separate entries. -Explain the Personalize integration pattern. -Emphasize starting simple. -Cover publishing and performance considerations. +The CMA accepts only one variant UID in that header. A comma-separated list there returns the base entry, not a merge. -## Instructions +With `include_publish_details`, each entry carries `publish_details.variants`, the alias that was applied. Use it to fire impressions only for content that was actually shown. Attribution is per entry, not per modular block or JSON RTE block inside an entry. + +### Personalize integration + +Resolve variants with the Personalize Edge SDK, `@contentstack/personalize-edge-sdk`, usually in edge middleware such as Next.js middleware, Vercel, Netlify or Cloudflare Workers, so the page renders with the right content on the first request. The core flow: + +1. `Personalize.init(projectUid, options)`. +2. `Personalize.set(attributes)` with the user attributes your audiences use, and `Personalize.setUserId(userId)` for a stable identity across sessions. +3. `Personalize.getVariantAliases()`, then pass the aliases to the CDA. +4. `Personalize.triggerImpression(experienceShortUid)` when content is shown and `Personalize.triggerEvent(eventKey)` on conversions, so A/B results populate. + +### Experiences + +- **Segmented experiences** serve the first variant whose audience rules match. +- **A/B tests** split traffic by percentage. A user is bucketed deterministically, so they see the same variant across sessions. Multi-armed bandit mode rebalances traffic toward the better-performing variant. +- When a user qualifies for several experiences that override the same field, experience priority decides which wins. Set priority deliberately in the Personalize project. -[] +### Lifecycle and limits -## Output Format +Entry variants publish, unpublish and schedule like their base entry. Pausing an experience stops its variants from being selected. Deleting an experience only unlinks its variant group; delete the group in the CMS afterwards to remove it and its entry variants. -Be concise and advisory. -Prefer direct recommendations over long explanations. -Include a clear variants-vs-separate-entries decision. -Mention simplicity and maintainability first. +Default limits per Personalize project, raisable by plan: 100 experiences (up to 1,000), 20 variants per experience (up to 50), and 100 audiences. -## Tooling Notes +## MCP tools -Read-only advisory skill. -Do not create, modify, or publish variants. -Use Read, Grep, and Glob only. +When the Contentstack MCP server is connected, these tools act on the stack and the Personalize project (local server group in brackets): + +- Inspect: `get_all_variants_of_a_content_type`, `get_a_single_variant`, `get_all_variants_of_an_entry`, `get_single_entry_variant` (`cma`); `get_all_experiences`, `get_single_experience`, `get_experiences_priority`, `get_all_audiences` (`personalize`) +- Change: `create_an_entry_variant`, `publish_variants_of_an_entry` (`cma`); `create_experience`, `update_experience`, `update_experiences_priority` (`personalize`) +- Delete: `delete_an_entry_variant` (`cma`); `delete_experience` (`personalize`) + +No tool links a variant group to a content type; do that in the CMS. Deleting an experience only unlinks its variant group. + +## Output + +Be concise and advisory, with direct recommendations over long explanations. Include a clear variants-vs-separate-entries decision, and put simplicity and maintainability first. ## Security ### Defaults -Never expose tokens or API keys. -Use environment variables for credentials in example code. -Do not recommend hardcoding secrets in client-side code. +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Never expose tokens or API keys. +- Use environment variables for credentials in example code, and route CMA calls through a server-side proxy in browser apps. +- Do not recommend hardcoding secrets in client-side code. ### Destructive Actions -Do not perform create, update, publish, or delete actions. Provide guidance only. +Before creating, publishing or deleting entry variants, or creating, reprioritizing or deleting experiences, name the stack, branch, entries, environments and experience affected, and wait for confirmation. ### Secrets @@ -91,17 +110,6 @@ Never reveal management tokens, API keys, or Personalize credentials. Use placeh Use environment variables for all credentials in code examples. Do not hardcode stack API keys or project keys. -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] - ## Examples ### Variants vs separate entries (few shot *) @@ -116,6 +124,6 @@ Use environment variables for all credentials in code examples. Do not hardcode **User:** How do I integrate Personalize with my Next.js app? -**Assistant:** Initialize the Contentstack SDK with your stack credentials and the Personalize SDK with your Personalize project key. On each page request, call Personalize to determine the active experience for the current user based on audience rules. Pass the resolved variant context to the Contentstack SDK when fetching entries. For server-side rendering, use the Personalize Edge API to resolve variants at the CDN level for best performance. +**Assistant:** Resolve variants in Next.js middleware with `@contentstack/personalize-edge-sdk`: call `Personalize.init(projectUid)`, set any user attributes, then `Personalize.getVariantAliases()`. Pass the aliases to the page (for example as a URL parameter) and send them to the CDA in the `x-cs-variant-uid` header, comma-separated. Call `triggerImpression` when variant content is shown and `triggerEvent` on conversions. Make sure each variant group is linked to the content types you personalize, or editors can't create entry variants. -*Demonstrates the standard SDK flow and SSR guidance.* \ No newline at end of file +*Demonstrates the standard SDK flow and SSR guidance.* diff --git a/skills/cms-webhooks/SKILL.md b/skills/cms-webhooks/SKILL.md index 692c4f1..ca0390a 100644 --- a/skills/cms-webhooks/SKILL.md +++ b/skills/cms-webhooks/SKILL.md @@ -1,122 +1,95 @@ --- name: cms-webhooks -description: "Advise developers on configuring and consuming Contentstack webhooks for real-time event notifications. Cover event channels, payload structure, signature verification, retry behavior, release-triggered webhook storms, and reliable receiver design. Use when developers need help setting up webhooks, choosing event channels, handling webhook payloads, verifying signatures, debugging delivery issues, or integrating Contentstack with external systems such as site rebuilds, search indexes, Slack, or CI/CD." +description: "Advise developers on configuring and consuming Contentstack webhooks for real-time event notifications. Cover event channels, payload structure, signature verification, retry behavior, release-triggered webhook storms, and reliable receiver design. Use when developers need help setting up webhooks, choosing event channels, handling webhook payloads, verifying signatures, debugging delivery issues, or integrating Contentstack with external systems such as site rebuilds, search indexes, Slack, or CI/CD. For no-code event workflows, use automations." allowed-tools: Read Grep Glob --- # Contentstack Webhooks -## Description +Advise on connecting Contentstack to external systems with webhooks, and on the operational edge cases: duplicate deliveries, retries, release-triggered bursts and failed deliveries. -Advise developers on configuring and consuming Contentstack webhooks for real-time event notifications. Cover event channels, payload structure, signature verification, retry behavior, release-triggered webhook storms, and reliable receiver design. +## When to use -## When to Use +- Setting up a webhook and choosing event channels. +- Handling webhook payloads. +- Verifying webhook signatures. +- Designing a reliable receiver and choosing a retry policy. +- Debugging missed or failing deliveries. +- Triggering site rebuilds, search indexing, Slack or CI/CD from content events. -Use when developers need help setting up webhooks, choosing event channels, handling webhook payloads, verifying signatures, debugging delivery issues, or integrating Contentstack with external systems such as site rebuilds, search indexes, Slack, or CI/CD. +Use another skill for: -## User Problem +- No-code event workflows with triggers and connectors → `automations` +- Launch deploy hooks and rebuilds → `launch-platform` +- Releases and what deploying one publishes → `cms-releases` +- Workflow stages and publish rules → `cms-workflows` +- Webhooks for Developer Hub app lifecycle events → `developer-hub-app-architect` -Developers need to connect Contentstack to external systems through webhooks and handle operational edge cases such as duplicate deliveries, retries, release-triggered event storms, and failed deliveries. +## Before you answer -## Success Criteria - -Webhook configuration matches the intended event sources and integration target. -Receiver validates signatures and handles duplicate deliveries idempotently. -Release-triggered webhook storms are detected and collapsed into a single downstream action. -Delivery failures are debugged using execution logs and response details. -Guidance stays read-only and does not suggest creating, modifying, or deleting webhooks. - -## Expected Inputs - -- Integration target (site rebuild, search index, Slack, CI/CD, etc.) -- Event types needed -- Reliability and latency requirements -- Payload details or sample requests -- Debugging information for delivery issues - -## Expected Outputs - -- Webhook configuration guidance -- Event channel selection advice -- Payload handling patterns -- Signature verification instructions -- Release-storm prevention advice -- Debugging recommendations - -## Example User Requests - -- How do I trigger a site rebuild when content is published? -- How do I verify a webhook is genuinely from Contentstack? -- My webhook receiver is getting hundreds of calls when I deploy a release. -- What retry policy should I use? -- How do I debug missed webhook deliveries? - -## Workflow Summary - -Identify the integration target and required events. -Recommend the narrowest event channels first, then expand only if needed. -Explain payload shape, signature verification, and secret handling. -Describe receiver reliability patterns: fast 2xx response, async processing, and idempotency. -Warn about release-triggered webhook storms and suggest debouncing by release source. -Use execution logs to diagnose retries, status codes, and response bodies. +Find out the integration target (site rebuild, search index, Slack, CI/CD), the events needed, reliability and latency requirements, and, when debugging, a sample payload or the execution log details. ## Instructions +1. Identify the integration target and required events. +2. Recommend the narrowest event channels first, and expand only if needed. +3. Explain payload shape, signature verification and secret handling. +4. Describe receiver reliability: fast 2xx response, async processing and idempotency. +5. Warn about release-triggered bursts and suggest debouncing. +6. Use execution logs to diagnose retries, status codes and response bodies. + ### Channels -Use event channels in the form {module}.{action}, such as entries.create, entries.update, entries.publish, entries.unpublish, assets.publish, content_types.update, and entries.workflow_stage_change. Use $all only when the integration truly needs every event. Start specific and expand later. +Event channels use the form `{module}.{action}`, such as `entries.create`, `entries.publish`, `assets.publish` and `content_types.update`, or the longer `{module}.{context}.{action}` form, such as `content_types.entries.publish` or `entries.environments.publish`. Workflow stage changes come from a separate workflow module, not from `entries`; select those events in the webhook UI rather than typing a channel name. Use `$all` only when the integration truly needs every event. Start specific and expand later. ### Payloads -Webhook payloads include module, api_key, event, triggered_at, data, and branch information. Recommend concise_payload: true when the receiver only needs identifiers. Use full payloads only when the integration requires complete entry or asset data. +The top-level payload fields are `module`, `api_key`, `event` and `data`. Recommend `concise_payload: true` when the receiver only needs identifiers, and full payloads only when the integration needs complete entry or asset data. Do not promise other top-level fields; inspect a real delivery in the execution log if the receiver depends on one. ### Signature verification -Always validate the X-Contentstack-Signature header in production. Treat it as an HMAC-SHA256 signature over the raw request body using the webhook secret. Reject requests with missing or invalid signatures. +Every webhook request carries an `X-Contentstack-Request-Signature` header, an RSA-PSS SHA-256 signature that the receiver verifies with Contentstack's public key. Point users to the current webhook documentation for the public key and the exact verification steps. Where the plan supports it, a webhook can instead be set to HMAC signing: requests then carry `X-Contentstack-HMAC-Signature`, an HMAC-SHA256 of `{timestamp}.{raw body}` computed with the webhook secret. Verify against the raw body, reject old timestamps to block replays, and reject requests with a missing or invalid signature. -### Release-webhook storm +### Release-triggered bursts -A release with many items can produce one webhook event per item. Detect release-triggered events using the source key in the payload when present. Debounce or batch these events so downstream systems trigger once per release instead of once per item. +Deploying a release publishes every item in it, so publish webhooks can fire once per item. Do not rely on a payload field to identify release traffic. Debounce or batch on the receiver so downstream systems such as site rebuilds run once per burst, and use the execution logs to see what actually fired. ### Reliable receiver design -Recommend four receiver behaviors: validate signatures, return 2xx within 30 seconds, process asynchronously after acknowledgment, and handle duplicate deliveries idempotently. +Recommend four receiver behaviors: verify the signature, return 2xx within 30 seconds, process asynchronously after acknowledging, and handle duplicate deliveries idempotently. A non-2xx response or a 30-second timeout counts as a failed delivery. ### Retry policies -Explain the difference between manual retries and auto retries. Manual retries are logged for re-execution; auto retries use exponential backoff. Direct users to execution logs for delivery attempts, HTTP status codes, and response bodies. +The automatic retry policy retries a failed delivery up to 4 times with exponential backoff, at roughly 5 s, 25 s, 125 s and 625 s. With the manual policy, failed events stay in the execution log and can be re-fired from there or through the API. Direct users to the execution logs for attempts, status codes and response bodies. -### Limits and scope +### Scope and concurrency -Mention the max of 100 webhooks per stack. Note that webhooks are global modules but can be scoped to a branch. Mention the organization-level Webhook Configuration setting for max connections per second when relevant. +Webhooks are a global module, but each webhook can be assigned to one branch at a time. The organization-level Webhook Configuration setting controls the number of concurrent connections to receivers, not a per-second rate. -## Output Format +## MCP tools -Be concise and practical. -Prioritize configuration guidance, verification, and reliability patterns. -Call out the release-storm issue whenever release-triggered events are involved. -Do not suggest creating, modifying, or deleting webhooks. +No Contentstack MCP tool creates, lists, sends or deletes webhooks. Configure them in stack Settings → Webhooks or with the Content Management API's webhooks endpoints, and read execution logs there. -## Tooling Notes +Related tools: to point a webhook at a Launch rebuild, `get_deploy_hooks` (`launch`) returns a project's deploy hooks. To see what a release deploy will publish, `get_all_items_in_a_release` (`cma`) lists its items. -Read-only advisory skill. -Allowed tools should be limited to Read, Grep, and Glob. -Do not perform mutations or external actions. -Use docs and execution logs for troubleshooting guidance only. +## Output + +Be concise and practical. Prioritize configuration guidance, signature verification and reliability patterns. Call out the release burst issue whenever release-triggered events are involved. ## Security ### Defaults +- Advisory by default. This skill does not create, modify, send or delete webhooks. - Never expose webhook secrets. -- Always validate X-Contentstack-Signature in production. +- Always verify the request signature (`X-Contentstack-Request-Signature`, or `X-Contentstack-HMAC-Signature` when HMAC signing is on) in production. - Use environment variables for all secrets. - Do not echo raw secrets, tokens, or signatures in examples. - Prefer server-side verification and processing patterns. ### Destructive Actions -Do not create, update, delete, or send webhooks. This skill is advisory only. +Do not create, update, delete, or send webhooks. If the user wants a change made, give the steps and the target stack and branch for them to apply. ### Secrets @@ -125,14 +98,3 @@ Never reveal webhook secrets or any credential material. If a secret is needed, ### Environment Variables Store webhook secrets and related credentials in environment variables. Never hardcode secrets in examples or client-side code. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/cms-workflows/SKILL.md b/skills/cms-workflows/SKILL.md index 7a88b62..b72821c 100644 --- a/skills/cms-workflows/SKILL.md +++ b/skills/cms-workflows/SKILL.md @@ -6,59 +6,36 @@ allowed-tools: Read Grep Glob # Workflows & Publish Rules -## Description +Advise on content governance with workflows and publish rules: stage design, transition restrictions, approvals, publish governance, automation hooks and common pitfalls. -Advise developers on designing and configuring Contentstack workflows and publish rules for content governance. Cover stage design, transition restrictions, approval flows, publish governance, automation hooks, and common pitfalls. +## When to use -## When to Use +- Designing workflow stages and transitions. +- Setting up approval flows and preventing self-approval. +- Choosing between workflows and publish rules. +- Automating actions when content reaches a stage. +- Understanding how workflows behave across branches. -Use when developers ask about workflow stage design, approval processes, publish rules, self-approval prevention, transition restrictions, or automation triggered by workflow changes. +Use another skill for: -## User Problem +- Roles and who can do what → `cms-roles-permissions` +- Webhook receivers for workflow events → `cms-webhooks` +- No-code automation on workflow events → `automations` +- Scheduling and bundling publishes → `cms-releases` +- Environments and publishing mechanics → `cms-environments-publishing` -Developers need to design content governance flows that match their review process without adding unnecessary complexity or creating permission gaps. +## Before you answer -## Success Criteria - -Recommend the simplest workflow that satisfies the business requirement. -Explain how stages, transitions, approvals, and publish rules differ. -Call out limits, scope, and permission constraints clearly. -Warn against over-engineering and unsupported assumptions. -Suggest integration patterns when automation is needed. - -## Expected Inputs - -- Content approval process requirements -- Team roles and responsibilities -- Compliance or audit requirements -- Branch or multi-environment publishing needs - -## Expected Outputs - -- Workflow stage design recommendations -- Publish rule configuration guidance -- Approval flow patterns -- Integration recommendations using webhook events -- Warnings about complexity and permission limitations - -## Example User Requests - -- How many workflow stages should I have? -- How do I prevent an author from approving their own content? -- How do publish rules differ from workflows? -- Can I automate actions when content reaches a workflow stage? -- How do workflows work across branches? - -## Workflow Summary - -Understand the approval process and team structure. -Design the simplest workflow that meets the requirement. -Add publish rules only when additional governance is needed. -Describe integration points for automation and auditability. -Warn about complexity, scope, and permission limitations. +Find out the approval process, the team structure and who approves, the content types and branches involved, and any automation or audit requirements. ## Instructions +1. Understand the approval process and team structure. +2. Design the simplest workflow that meets the requirement. +3. Add publish rules only when more governance is needed. +4. Describe integration points for automation and auditability. +5. Warn about complexity, scope and permission limitations. + ### Keep workflows simple Use 3 to 5 stages for most cases. Add stages only when there is a clear business need. A content type can be associated with one workflow per branch. @@ -69,7 +46,7 @@ Explain that each stage defines who can advance entries, which stages are allowe ### Prevent self-advancement -Explain that prevent-self-advancement requires at least two distinct reviewers. The last editor cannot advance the entry. Recommend at least two approvers or a role with multiple members. +Prevent-self-advancement is an option you turn on per stage, not a default for every workflow. When it is on, the person who submitted the entry cannot also approve it, so at least two distinct reviewers are needed. Recommend at least two approvers or a role with multiple members for those stages. ### Publish rules are separate @@ -77,40 +54,37 @@ Clarify that publish rules govern publish and unpublish conditions independently ### Automation -Recommend webhook events such as entries.workflow_stage_change for external automation. Mention that the publish queue tracks pending actions and status. +Recommend webhooks on workflow stage events for external automation. These come from the workflow module, so select them in the webhook UI instead of guessing a channel name. Mention that the publish queue tracks pending actions and status. ### Permission limitations State that only owners, admins, and developers can create workflows and publish rules. Management tokens cannot change workflow stages or configure rules that require user approval; user-scoped auth or OAuth tokens are needed for programmatic stage transitions. -## Output Format +## MCP tools + +When the Contentstack MCP server is connected, these tools read the governance setup (local server group in brackets): -Be concise and practical. -Prefer recommendations over theory. -Use bullets when listing options or rules. -Call out constraints and limits explicitly. -Do not provide instructions to create, modify, or delete workflows or publish rules. +- Inspect: `get_all_workflows`, `get_a_single_workflow`, `get_publish_rules`, `get_publish_queue_activity`, `get_audit_log` (`cma-extended`); `get_publish_queue` (`cma`) -## Tooling Notes +No MCP tool creates or changes workflows, stages or publish rules, or moves an entry between stages. Make those changes in stack Settings → Workflows and Publish Rules, or with the Content Management API using user-scoped auth or OAuth. -Read-only advisory. -Use Read, Grep, and Glob only. -Do not create, modify, or delete workflows or publish rules. -Use webhook and publish queue concepts only for explanation. +## Output + +Be concise and practical, with recommendations over theory. Use bullets when listing options or rules, and call out constraints and limits explicitly. ## Security ### Defaults -Never expose tokens or API keys. -Use environment variables for credentials in example code. -Do not perform destructive actions. -Do not recommend hardcoding secrets in client-side code. -Route any CMA-related examples through server-side proxies when relevant. +- Advisory by default. This skill does not create, modify, or delete workflows or publish rules. +- Never expose tokens or API keys. +- Use environment variables for credentials in example code. +- Do not recommend hardcoding secrets in client-side code. +- Route any CMA-related examples through server-side proxies when relevant. ### Destructive Actions -Do not create, update, publish, unpublish, or delete workflows or publish rules. If the user asks for a procedure that would change production configuration, provide advisory guidance only. +Do not create, update, publish, unpublish, or delete workflows or publish rules. If the user asks for a procedure that would change production configuration, give the steps and name the stack, branch and content types affected for them to apply. ### Secrets @@ -119,14 +93,3 @@ Never reveal management tokens, API keys, or auth tokens. Use placeholders and e ### Environment Variables Use environment variables for any credentials or secret values in examples. Prefer server-side access patterns for CMA-related operations. - -## Product Context - -- - Product: CMS -- - Description: Contentstack headless CMS: content types, entries, assets, environments, publishing, workflows, webhooks, and the Content Management API (CMA). -- - Product safety rules: - Never expose management tokens or API keys. -- Always use environment variables for credentials. -- Route all CMA calls through server-side proxies in browser apps. -- Never hardcode stack API keys in client-side code. -- - Default tools: ["CMA API", "Content Types", "Entries", "Assets", "Workflows", "Webhooks", "Environments", "Releases", "Publish Queue"] -- - Default connectors: ["CMA Proxy", "Webhooks"] \ No newline at end of file diff --git a/skills/developer-hub-app-architect/SKILL.md b/skills/developer-hub-app-architect/SKILL.md index fdc0edc..277a575 100644 --- a/skills/developer-hub-app-architect/SKILL.md +++ b/skills/developer-hub-app-architect/SKILL.md @@ -1,6 +1,6 @@ --- name: developer-hub-app-architect -description: "Turn Contentstack Developer Hub and Marketplace app ideas into concrete implementations. Choose the right UI location, map the architecture, generate boilerplate-aligned React/TypeScript code, and troubleshoot setup, SDK, manifest, proxy, and publishing issues. Use when a user needs help designing or building a Contentstack Developer Hub or Marketplace app." +description: "Turn Contentstack Developer Hub and Marketplace app ideas into concrete implementations. Choose the right UI location, map the architecture, generate boilerplate-aligned React/TypeScript code, and troubleshoot setup, SDK, manifest, proxy, and publishing issues. Use when a user needs help designing or building a Contentstack Developer Hub or Marketplace app. To choose or configure an existing first-party Marketplace app, use marketplace-apps." allowed-tools: Read Grep Glob context: fork agent: plan @@ -8,68 +8,36 @@ agent: plan # Developer Hub App Architect -## Description +Turn Developer Hub and Marketplace app ideas into working apps: pick the UI location, map the architecture, write boilerplate-aligned React/TypeScript, and debug setup, SDK, manifest, proxy and publishing issues. -Turn Contentstack Developer Hub and Marketplace app ideas into concrete implementations. Choose the right UI location, map the architecture, generate boilerplate-aligned React/TypeScript code, and troubleshoot setup, SDK, manifest, proxy, and publishing issues. +## When to use -## When to Use +- Designing or building a Developer Hub or Marketplace app. +- Choosing the right UI location for a feature. +- Generating app code from the marketplace boilerplate or a similar starter. +- Explaining manifest, setup, proxy, OAuth or publishing steps. +- Debugging app loading, SDK, iframe, route or location issues. -Use when a user needs help designing or building a Contentstack Developer Hub or Marketplace app. -Use when choosing the right UI location for a feature. -Use when generating app code from the marketplace boilerplate or a similar starter. -Use when explaining manifest, setup, proxy, OAuth, or publishing steps. -Use when debugging app loading, SDK, iframe, route, or location issues. +Use another skill for: -## User Problem +- Choosing or configuring an existing first-party Marketplace app → `marketplace-apps` +- Rendering JSON RTE content, or the data an RTE plugin produces → `cms-json-rte` +- Management and delivery token types → `cms-tokens-authentication` +- Webhooks on stack events (not app lifecycle webhooks) → `cms-webhooks` -Users need to turn app ideas into working Contentstack apps without guessing at UI locations, Developer Hub setup, or SDK integration details. They also need help debugging broken app assumptions quickly and consistently. +## Before you answer -## Success Criteria +Gather the app idea or feature, the candidate UI locations, the user's boilerplate structure or repo conventions, manifest and route details, and any proxy, config or OAuth needs. For debugging, ask for error messages, screenshots or runtime symptoms. -Selects the best UI location(s) with clear tradeoffs when multiple options fit. -Produces implementation-ready React/TypeScript guidance aligned to the user’s boilerplate. -Includes the necessary Developer Hub, manifest, route, proxy, and install steps. -Avoids exposing secrets and keeps credentials server-side. -Uses a repeatable troubleshooting checklist for broken apps. - -## Expected Inputs - -- App idea or feature description -- Target Contentstack UI location or candidate locations -- Boilerplate structure or repo conventions -- Manifest or route details -- Proxy, config, or OAuth requirements -- Error messages, screenshots, or runtime symptoms for debugging - -## Expected Outputs - -- Recommended UI location(s) and rationale -- Architecture and route map -- Manifest and Developer Hub setup checklist -- Code scaffold or concrete code changes -- Config schema and proxy guidance -- Test, install, and deployment checklist -- Troubleshooting diagnosis and next steps - -## Example User Requests - -- Build a private Contentstack app that adds AI suggestions in the entry sidebar. -- Which UI location should I use for a product taxonomy picker? -- Generate an app configuration page and save API credentials through proxy variables. -- Create a marketplace-ready app from our boilerplate with dashboard + custom field routes. -- Why is my app loading but appSdk.location.CustomField is undefined? -- Turn this app idea into manifest config, route plan, and starter code. - -## Workflow Summary +## Instructions -Understand the app idea, constraints, and required integrations. -Choose the best UI location(s) and explain tradeoffs. -Map the app architecture to the boilerplate and route structure. -Generate code, config, and Developer Hub setup steps. -Add test, install, and publishing checks. -Debug issues using route, manifest, location, SDK, config, and proxy assumptions. +1. Understand the app idea, constraints and required integrations. +2. Choose the best UI location(s) and explain tradeoffs. +3. Map the architecture to the boilerplate and route structure. +4. Generate code, config and Developer Hub setup steps. +5. Add test, install and publishing checks. +6. Debug using route, manifest, location, SDK, config and proxy assumptions. -## Instructions ### Operating modes @@ -81,7 +49,7 @@ Use the provided references before inventing new patterns. Prefer the user’s b ### Location selection -Always identify the best Contentstack UI location before writing code. Prefer the smallest location that fits the use case. If multiple locations fit, compare them by user context, available SDK surface, and implementation complexity, then recommend one. Consult the location-selection reference before answering. +The UI locations are App Configuration, Custom Field, Entry Sidebar, Content Type Sidebar, Asset Sidebar, Stack Dashboard, Full Page, Global Full Page (organization apps), Field Modifier (plan-gated) and RTE plugin. Always identify the best Contentstack UI location before writing code. Prefer the smallest location that fits the use case. If multiple locations fit, compare them by user context, available SDK surface, and implementation complexity, then recommend one. Check location mapping in [the coding reference](references/developer-hub-coding-reference.md) before answering. ### Code generation @@ -89,47 +57,54 @@ Generate production-ready React + TypeScript code when asked. Include loading st ### Developer Hub setup -Include manifest, base URL, route mapping, location enabling, advanced settings variables, proxy/rewrite, install, and deploy steps whenever they affect the implementation. Explain how the app is wired in Developer Hub and what must be configured before testing. Use the Developer Hub setup reference for exact steps. +Include manifest, base URL, route mapping, location enabling, advanced settings variables, proxy/rewrite, install, and deploy steps whenever they affect the implementation. Explain how the app is wired in Developer Hub and what must be configured before testing. Use the setup section of [the coding reference](references/developer-hub-coding-reference.md) for exact steps. + +### App type and target + +Pick the app type first. Standard apps have UI locations, webhooks, OAuth and hosting. Machine-to-machine apps use OAuth client credentials only, are organization-targeted, have no UI and are never installable; use them for backend automation. Standard apps target a stack or an organization, which decides which locations and webhook events are available. ### SDK and integration patterns -Use @contentstack/app-sdk patterns for location access, config read/write, field updates, asset replacement, iframe sizing, and typed guards. Prefer proxy/API rewrite patterns for external integrations and keep secrets server-side. Consult the SDK patterns reference for canonical usage. +Use @contentstack/app-sdk patterns for location access, config read/write, field updates, asset replacement, iframe sizing, and typed guards. Prefer proxy/API rewrite patterns for external integrations and keep secrets server-side: developer defaults as `{{var.NAME}}`, per-installation secrets in `serverConfiguration` referenced as `{{map.KEY}}`. Use the SDK section of [the coding reference](references/developer-hub-coding-reference.md) for canonical usage. ### Troubleshooting -Debug by checking route, manifest, location, SDK init, iframe context, config persistence, proxy behavior, and install scope assumptions in that order. Lead with the most likely cause and the fastest verification step. Use the troubleshooting reference to confirm likely failure modes. +Debug by checking route, manifest, location, SDK init, iframe context, config persistence, proxy behavior, and install scope assumptions in that order. Lead with the most likely cause and the fastest verification step. Use the troubleshooting section of [the coding reference](references/developer-hub-coding-reference.md) to confirm likely failure modes. ### Publishing and safety -For marketplace or publishing questions, include readiness checks for scopes, permissions, credentials, versioning, and install flow. Never expose OAuth client secrets or app signing keys. Validate scopes and avoid broader permissions than required. Use the marketplace publishing reference when relevant. +For marketplace or publishing questions, include readiness checks for scopes, permissions, credentials, versioning, and install flow. Never expose OAuth client secrets or app signing keys. Validate scopes and avoid broader permissions than required. The coding reference covers app visibility (private, public, public unlisted) but not the review process, so point to the Developer Hub publishing docs for that. + +## MCP tools -## Output Format +When the Contentstack MCP server is connected, these tools act on Developer Hub apps (local server group in brackets): -Be concise and actionable. -Use bullets for recommendations and checklists. -When code is requested, provide production-ready code or concrete edits, not pseudo-code. -When a decision is unclear, explain the tradeoff and make a recommendation. -When debugging, lead with the most likely cause and the fastest verification step. +- Inspect: `get_all_apps`, `get_an_app`, `get_app_installations`, `get_oauth_scopes`, `get_app_oauth` (`developerhub`) +- Change: `create_an_app`, `update_an_app`, `update_app_oauth`, `install_an_app`, `update_an_app_installation` (`developerhub`) +- Delete: `delete_an_app`, `uninstall_an_app` (`developerhub`) -## Tooling Notes +`get_app_oauth` returns the app's client credentials: don't repeat the client secret in the answer. There are no tools for app hosting or Marketplace publishing; use the Developer Hub UI. -Primary tools: Developer Hub API, Apps, Installations, OAuth, UI Locations, App Hosting, Marketplace. -Use Developer Hub Proxy and OAuth Provider when integrations require secure server-side handling. -Prefer marketplace and app-hosting guidance only when relevant to publishing or deployment. -Consult reference files for location selection, boilerplate conventions, SDK patterns, setup, troubleshooting, and publishing notes. +## Output + +Be concise and actionable. Use bullets for recommendations and checklists. Deliverables, as the task needs them: recommended UI location(s) and rationale, architecture and route map, manifest and Developer Hub setup checklist, code scaffold or concrete edits, config schema and proxy guidance, a test, install and deployment checklist, or a troubleshooting diagnosis with next steps. + +- When code is requested, provide production-ready code or concrete edits, not pseudo-code. +- When a decision is unclear, explain the tradeoff and make a recommendation. +- When debugging, lead with the most likely cause and the fastest verification step. ## Security ### Defaults +- Advisory by default. Use the MCP tools above only when the user asks for the change. - Never expose OAuth client secrets or app signing keys. -- Validate all app installation scopes. -- Never grant broader permissions than required. -- Keep app credentials server-side only. +- Validate all app installation scopes, and never grant broader permissions than required. +- Keep app credentials server-side only, through the Developer Hub proxy and OAuth provider. ### Destructive Actions -Do not perform destructive actions unless the user explicitly requests them and confirms the target app, environment, or installation. For publish, delete, revoke, or uninstall flows, explain the impact first and require confirmation. +Before creating, updating, installing, uninstalling or deleting an app, or changing its OAuth settings, name the app, the target stack or organization and the installation, explain the impact, and wait for confirmation. The same applies to publish and revoke flows. ### Secrets @@ -139,24 +114,11 @@ Never reveal, print, or embed secrets in frontend code, examples, logs, or confi Use environment variables for server-side configuration only. Do not place secrets in client-visible settings. Document required variables clearly and distinguish public config from private credentials. -## Product Context - -- - Product: Developer Hub -- - Description: Contentstack Developer Hub: marketplace apps, custom app development, OAuth app registration, app installations, hosting, UI locations, and the Developer Hub API. -- - Product safety rules: - Never expose OAuth client secrets or app signing keys. -- Validate all app installation scopes. -- Never grant broader permissions than required. -- Keep app credentials server-side only. -- - Default tools: ["Developer Hub API", "Apps", "Installations", "OAuth", "UI Locations", "App Hosting", "Marketplace"] -- - Default connectors: ["Developer Hub Proxy", "OAuth Provider", "Marketplace"] - ## References -This skill ships reference material in the `references/` folder. Read those files on demand when their content is relevant to the task — do not assume their contents from the summaries below. +Read these on demand when their content is relevant; don't assume their contents from the summaries. -### [Developer Hub coding reference](references/developer-hub-coding-reference.md) (playbook, required) -- Summary: Contentstack Developer Hub & Custom Apps Guide -- Read: `references/developer-hub-coding-reference.md` +- [Developer Hub coding reference](references/developer-hub-coding-reference.md): the Developer Hub and custom apps guide, covering location mapping, SDK usage, setup, troubleshooting and publishing. ## Examples diff --git a/skills/developer-hub-app-architect/references/developer-hub-coding-reference.md b/skills/developer-hub-app-architect/references/developer-hub-coding-reference.md index f99d4d5..fe209a9 100644 --- a/skills/developer-hub-app-architect/references/developer-hub-coding-reference.md +++ b/skills/developer-hub-app-architect/references/developer-hub-coding-reference.md @@ -17,9 +17,14 @@ Complete guide for building custom apps and extensions for Contentstack Develope ### Types of Apps -1. **Marketplace Apps**: Public apps available to all Contentstack users -2. **Private Apps**: Organization-specific apps for internal use -3. **Machine-to-Machine Apps**: Apps that interact with Contentstack APIs without user interface +1. **Standard apps**: support UI locations, webhooks, OAuth and hosting. Visibility is private, public (listed in the Marketplace after review) or public unlisted (installable by direct link). +2. **Machine-to-machine (M2M) apps**: OAuth client-credentials only, organization-targeted, no UI locations or webhooks, never installable or publishable. Use them for service-to-service automation. + +Standard apps target either a **stack** (installed into one stack; can subscribe to app and stack events) or an **organization** (installed at org level; app events only; can use org-level App Config and Global Full Page). + +### App lifecycle webhooks + +Apps can subscribe to installation events (`install`, `update`, `uninstall`, `upgrade`) to provision or clean up external resources. Stack-target apps can also receive stack events such as entry and global field changes. --- @@ -51,6 +56,10 @@ UI locations are specific places in Contentstack's interface where your app can | **Full Page** | `/full-page` | Standalone pages | Standalone full-page app | | **Field Modifier** | `/field-modifier` | Modify field values | Modifies field values programmatically | | **RTE Location** | `/json-rte.js` | Rich text extensions | Rich text editor extensions | +| **Content Type Sidebar** | `/content-type-sidebar` | Schema tools | Sidebar in the content type builder (stack apps only) | +| **Global Full Page** | `/global-full-page` | Org-level pages | Full-page app at organization level (organization apps only) | + +The route paths are the boilerplate's conventions; the actual paths are whatever you set in the manifest. Field Modifier is plan-gated and its SDK object is `FieldModifierLocation` (named `EntryFieldLocation` before App SDK 2.0). The SDK objects for the two newer locations are `ContentTypeSidebarWidget` and `GlobalFullPageLocation`. ### App SDK @@ -577,6 +586,10 @@ Configure URL rewrites in Developer Hub Advanced Settings: This allows you to use relative paths in your code while Contentstack proxies to the actual API. +### Per-installation secrets + +Variables (`{{var.NAME}}`) hold developer-level defaults. For values each installation supplies, such as a customer's own API key, save them in `serverConfiguration` through `appSdk.location.AppConfigWidget.installation.setInstallationData()` and reference them in rewrites as `{{map.KEY}}`. The proxy substitutes them server-side, so they never reach the browser. + ### Complete Example ```typescript @@ -687,6 +700,8 @@ npm run dev Runs on `http://localhost:3000` +The boilerplate is React + TypeScript + Vite with one lazy-loaded route per UI location. It ships plain CSS; add `@contentstack/venus-components` (Contentstack's UI component library) if you want the app to look native in the Contentstack UI. + ### 2. Configure in Developer Hub 1. **Create App**: @@ -697,6 +712,7 @@ Runs on `http://localhost:3000` 2. **Set Base URL**: + - In the Hosting tab, choose Launch (Contentstack-managed) or custom hosting - Set base URL to `http://localhost:3000` (for development) - Or use tunneling service (ngrok, Cloudflare Tunnel) for HTTPS diff --git a/skills/dx-cli/SKILL.md b/skills/dx-cli/SKILL.md new file mode 100644 index 0000000..65464b2 --- /dev/null +++ b/skills/dx-cli/SKILL.md @@ -0,0 +1,139 @@ +--- +name: dx-cli +description: "Guide developers through the Contentstack CLI (csdx, @contentstack/cli 2.x): install, region setup, login with password or OAuth/SSO, token aliases, stack export, import, seed and clone, bulk publish and unpublish with cm:stacks:bulk-entries/bulk-assets/bulk-taxonomies, migration scripts, branch diff and merge, audit, and installable plugins such as tsgen, apps-cli and the Launch plugin. Use when developers ask which csdx command to run, how to authenticate the CLI, move content between stacks or branches, bulk publish, write cm:stacks:migration scripts, generate TypeScript types, upgrade from CLI 1.x, or troubleshoot CLI errors. For Contentful-to-Contentstack migrations, use migration-companion; for automated Launch deployments over the API, use the launch-* skills." +allowed-tools: Read Grep Glob +--- + +# Contentstack CLI + +Guide developers through the Contentstack CLI (`csdx`): setup and authentication, moving content between stacks and branches, bulk operations, migration scripts, branch merges, and the installable plugins. + +## When to use + +- Which `csdx` command to run, and with which flags. +- Logging in, regions and token aliases. +- Exporting, importing, seeding or cloning a stack. +- Bulk publishing and unpublishing. +- Scripting content type changes, diffing and merging branches, generating TypeScript types. +- Moving from CLI 1.x to 2.x, or troubleshooting CLI errors. + +Use another skill for: + +- Contentful migrations → `migration-companion` +- Launch deployments driven through the Launch API → `launch-trigger-and-monitor-launch-deployments`, `launch-sync-environment-variables-from-env-example` +- Launch hosting concepts → `launch-platform` +- Branch strategy and aliases → `cms-branches-aliases` +- Building Developer Hub apps → `developer-hub-app-architect` +- Converting HTML RTE content and rendering JSON RTE → `cms-json-rte` + +## Before you answer + +Find out the task (export, import, seed, clone, bulk publish, migration, branch merge, types, Launch), the region, the stack API key or token alias, the source and target branch or environment, and the CLI version (`csdx --version`). The CLI has many plugins and flags, and several changed between 1.x and 2.x. + +## Instructions + +1. Check the CLI version and Node version. +2. Set the region, then authenticate. +3. Pick a command that exists in the current CLI and fill in stack, branch and environment explicitly. +4. Point out what the command overwrites and how to undo it. +5. Give the command and one verification step. + + +### Install and version + +Install with `npm install -g @contentstack/cli`. CLI 2.x needs Node.js 22 or later. Check with `csdx --version`, and list commands with `csdx --help`. Install extra plugins with `csdx plugins:install <package>`. + +### Region and authentication + +Set the region first: `csdx config:set:region AWS-NA` (also `AWS-EU`, `AWS-AU`, `AZURE-NA`, `AZURE-EU`, `GCP-NA`, `GCP-EU`, or custom hosts with `--cma`, `--cda`, `--ui-host` and `--name`). Sessions are tied to a region, so changing it means logging in again. + +Log in with `csdx auth:login` (alias `csdx login`). In SSO organizations use `csdx auth:login --oauth`, which opens the browser. Check the session with `csdx auth:whoami`. + +For scripts and CI, store tokens as aliases instead of using a personal session: `csdx auth:tokens:add --management -a <alias> -k <stack_api_key>` or `--delivery -e <environment>`. Most commands accept `-a <alias>` or `-k <stack_api_key>`. List aliases with `csdx auth:tokens:list`. + +### Export, import, seed and clone + +- `csdx cm:stacks:export -k <key> --data-dir ./export --branch <branch>` exports a stack. Use `--module` for one module and `--content-types` to limit entries. Pass `--branch` explicitly. +- `csdx cm:stacks:import -k <key> --data-dir ./export --branch <branch>` imports into an existing stack. `--module` imports one module. `--replace-existing` overwrites matching modules, so warn before using it. `--skip-entries-publish` and `--skip-assets-publish` skip publishing. `--import-webhook-status disable` keeps imported webhooks off. +- Export and import cover Personalize projects and variant entries (`--module personalize`, `variant-entries`) and Studio compositions alongside the CMS modules. +- `csdx cm:stacks:seed --repo <github_repo>` creates or fills a stack from a starter repository. +- `csdx cm:stacks:clone` copies a stack or branch to another stack: type `a` copies structure only, type `b` copies structure and content. +- `csdx cm:stacks:audit` finds content type and entry issues; `csdx cm:stacks:audit:fix` repairs them. Run it before large imports. + +### Bulk operations + +CLI 2.x replaces the 1.x `cm:stacks:bulk-publish` commands with the bundled bulk-operations plugin: + +- `csdx cm:stacks:bulk-entries --operation publish|unpublish --content-types blog --environments prod --locales en-us -a <alias>` +- `csdx cm:stacks:bulk-assets --operation publish|unpublish ...`, which also moves and deletes Assets (DAM) items with `--space-uid` +- `csdx cm:stacks:bulk-taxonomies` + +`--publish-mode bulk` (default) uses the Bulk Publish API; `single` publishes one item at a time. `--source-env` cross-publishes what is live in one environment to others. Operations write a log folder: rerun failures with `--retry-failed <folder>` and undo with `--revert <folder>`. The CMA allows 1 bulk request per second per organization, so large runs take time. + +### Migration scripts + +`csdx cm:stacks:migration -k <key> --file-path ./migrations/001-add-field.js --branch <branch>` runs a JavaScript migration script that creates or edits content types and transforms entries. `--multiple` runs every script in a folder. Keep scripts in version control and run them on a branch before main. The command executes the script's code, so only run scripts you trust. + +### Branches + +- `csdx cm:branches:create` and `csdx cm:branches:delete` manage branches. +- `csdx cm:branches:diff --base-branch main --compare-branch feature -k <key>` shows content type and global field differences. +- `csdx cm:branches:merge --base-branch main --compare-branch feature -k <key>` merges them. Merge covers content types and global fields only. By default it creates a revert branch first; `--no-revert` skips that, so discourage it. Use `--export-summary-path` to review the plan and `--use-merge-summary` to apply it. +- `csdx cm:branches:merge-status -k <key> --merge-uid <uid>` checks a merge job. + +### Installable plugins + +- **TypeScript types:** `csdx plugins:install contentstack-cli-tsgen`, then `csdx tsgen -a <delivery_alias> --output types/contentstack.d.ts`. Add `--api-type graphql` for GraphQL types and `--include-referenced-entry` for references. +- **Apps:** `@contentstack/apps-cli` adds `csdx app:create`, `app:deploy`, `app:install` and related commands for Developer Hub apps. +- **Launch:** `@contentstack/cli-launch` adds `csdx launch` (deploy from GitHub or a file upload), `csdx launch:logs` (`--type d` for deployment logs) and `csdx launch:functions` (run cloud functions locally). +- Also available: `@contentstack/cli-cm-export-query` (query-based export), `contentstack-cli-content-type` (inspect content types), `@contentstack/cli-cm-regex-validate` and `@contentstack/cli-cm-migrate-rte` (HTML RTE to JSON RTE, opt-in in 2.x). + +See [references/commands.md](references/commands.md) for the command list by plugin. + +### Upgrading from 1.x + +- Node.js 22 or later is required. +- `cm:stacks:bulk-publish` and the related 1.x bulk commands are gone; use `bulk-entries`, `bulk-assets` and `bulk-taxonomies`. +- The HTML-to-JSON RTE migration plugin is no longer bundled; install it if needed. +- Re-check scripts that pass removed flags. + +## MCP tools + +The CLI is the tool for bulk and stack-wide jobs; the MCP server has no export, import, seed, clone, bulk publish or migration-script tools. When the Contentstack MCP server is connected, it covers the single-item and branch operations (local server group in brackets): + +- Inspect: `get_all_branches`, `compare_branches`, `compare_content_types_between_branches`, `compare_global_fields_between_branches`, `get_all_merge_jobs`, `get_a_single_merge_job`, `get_all_content_types`, `export_content_type` (`cma`) +- Change: `create_a_branch`, `merge_branch`, `publish_an_entry`, `unpublish_an_entry` (`cma`) +- Delete: `delete_a_branch` (`cma`) + +Use them to check the state of a stack before and after a CLI run, for example to compare branches before `csdx cm:branches:merge`. + +## Output + +Give the command first, then the setup it needs (region, login, token alias, plugin install), then what it changes and how to verify or undo it. Offer a dry run or read-only check where available, such as `csdx auth:whoami`, `csdx config:get:region` or `csdx cm:branches:diff`. Use placeholders for keys, tokens and aliases. + +## Security + +### Defaults + +- Advisory by default: suggest commands for the user to run, and don't run commands that write to a stack. Use the MCP tools above only when the user asks for the change. +- Prefer token aliases or OAuth over passing tokens on the command line. +- Use management tokens only on trusted machines and in CI secrets. +- Always pass the branch explicitly in write commands. +- Back up or export before destructive operations. + +### Destructive Actions + +Imports with `--replace-existing`, bulk unpublish, branch merges, branch deletion and migration scripts change live data. State the target stack, branch and environment, recommend an export or backup branch first, and require the user to confirm. The same applies before any MCP write, merge or delete. + +### Secrets + +Never print management tokens or authtokens. `csdx auth:tokens:list` shows token values, so don't ask users to paste its output. + +### Environment Variables + +In CI, inject tokens from the secret store and add them with `csdx auth:tokens:add ... --token "$CONTENTSTACK_MANAGEMENT_TOKEN"`. + +## References + +- [Command list by plugin](references/commands.md) +- https://www.contentstack.com/docs/developers/cli diff --git a/skills/dx-cli/references/commands.md b/skills/dx-cli/references/commands.md new file mode 100644 index 0000000..aaf9e04 --- /dev/null +++ b/skills/dx-cli/references/commands.md @@ -0,0 +1,37 @@ +# csdx commands by plugin (CLI 2.x) + +Bundled plugins ship with `@contentstack/cli`. Installable plugins need `csdx plugins:install <package>`. Run `csdx <command> --help` for the full flag list. + +## Bundled + +| Plugin | Commands | +| --- | --- | +| `@contentstack/cli-auth` | `auth:login` (`login`; `--oauth` for SSO), `auth:logout` (`logout`), `auth:whoami` (`whoami`), `auth:tokens:add`, `auth:tokens:list`, `auth:tokens:remove` | +| `@contentstack/cli-config` | `config:set:region`, `config:get:region`, `config:set:base-branch`, `config:get:base-branch`, `config:set:rate-limit`, `config:set:proxy`, `config:set:log`, `config:set:early-access-header` (and matching `get`/`remove` commands) | +| `@contentstack/cli-cm-export` | `cm:stacks:export` | +| `@contentstack/cli-cm-import` | `cm:stacks:import` | +| `@contentstack/cli-cm-seed` | `cm:stacks:seed` | +| `@contentstack/cli-cm-bootstrap` | `cm:bootstrap` (start a project from a starter app) | +| `@contentstack/cli-cm-clone` | `cm:stacks:clone` | +| `@contentstack/cli-cm-export-to-csv` | export entries, taxonomies, terms and organization users to CSV | +| `@contentstack/cli-migration` | `cm:stacks:migration` | +| `@contentstack/cli-cm-branches` | `cm:branches`, `cm:branches:create`, `cm:branches:delete`, `cm:branches:diff`, `cm:branches:merge`, `cm:branches:merge-status` | +| `@contentstack/cli-audit` | `cm:stacks:audit`, `cm:stacks:audit:fix` | +| `@contentstack/cli-bulk-operations` | `cm:stacks:bulk-entries`, `cm:stacks:bulk-assets`, `cm:stacks:bulk-taxonomies` | + +## Installable + +| Package | Commands | +| --- | --- | +| `contentstack-cli-tsgen` | `tsgen` | +| `@contentstack/apps-cli` | `app:create`, `app:get`, `app:update`, `app:delete`, `app:install`, `app:uninstall`, `app:reinstall`, `app:deploy` | +| `@contentstack/cli-launch` | `launch`, `launch:logs`, `launch:functions` | +| `@contentstack/cli-cm-export-query` | query-based export | +| `contentstack-cli-content-type` | inspect content types | +| `@contentstack/cli-cm-regex-validate` | validate regex properties on fields | +| `@contentstack/cli-cm-migrate-rte` | migrate HTML RTE content to JSON RTE | +| `@contentstack/cli-external-migrate` | `migrate:*` commands for migrating from Contentful (see the `migration-companion` skill) | + +## Import and export modules + +`--module` accepts: `stack`, `assets`, `locales`, `environments`, `extensions`, `webhooks`, `global-fields`, `entries`, `content-types`, `custom-roles`, `workflows`, `publishing-rules`, `labels`, `marketplace-apps`, `taxonomies`, `personalize`, `composable-studio`, plus `variant-entries` on import. diff --git a/skills/dx-delivery-sdk/SKILL.md b/skills/dx-delivery-sdk/SKILL.md index 423758d..0508304 100644 --- a/skills/dx-delivery-sdk/SKILL.md +++ b/skills/dx-delivery-sdk/SKILL.md @@ -1,57 +1,35 @@ --- name: dx-delivery-sdk -description: "Help agents write correct, production-ready TypeScript using `@contentstack/delivery-sdk` for Contentstack entries, assets, references, filtering, sorting, pagination, locale, Live Preview, and Visual Builder support. Verify SDK behavior against the Delivery SDK Spec when method names, options, or chain order matter. Use when a user asks for Contentstack Delivery SDK code, query examples, helper functions, SDK setup, stack initialization, reference inclusion, filtering, sorting, pagination, typed entry fetching, asset fetching, Live Preview setup, Visual Builder support, SSR preview handling, or debugging SDK query chains." +description: "Help agents write correct, production-ready TypeScript using `@contentstack/delivery-sdk` for Contentstack entries, assets, references, filtering, sorting, pagination, locale, Live Preview, and Visual Builder support. Verify SDK behavior against the Delivery SDK Spec when method names, options, or chain order matter. Use when a user asks for Contentstack Delivery SDK code, query examples, helper functions, SDK setup, stack initialization, reference inclusion, filtering, sorting, pagination, typed entry fetching, asset fetching, Live Preview setup, Visual Builder support, SSR preview handling, or debugging SDK query chains. For GraphQL, use cms-graphql; for rendering JSON RTE fields, use cms-json-rte; for Live Preview troubleshooting, use cms-live-preview-visual-editor-support-assistant." allowed-tools: Read Grep Glob --- -# dx-delivery-sdk +# Contentstack Delivery SDK -## Description +Write correct, production-ready TypeScript with `@contentstack/delivery-sdk`: entries, assets, references, filtering, sorting, pagination, locale, Live Preview and Visual Builder support. The SDK reads published content, assets and taxonomy from the Content Delivery API. -Help agents write correct, production-ready TypeScript using `@contentstack/delivery-sdk` for Contentstack entries, assets, references, filtering, sorting, pagination, locale, Live Preview, and Visual Builder support. Verify SDK behavior against the Delivery SDK Spec when method names, options, or chain order matter. +## When to use -## When to Use +- Delivery SDK setup and stack initialization. +- Query examples and helper functions: references, filtering, sorting, pagination, field selection, locale. +- Typed entry and asset fetching. +- Live Preview, Visual Builder and SSR preview setup in SDK code. +- Debugging SDK query chains. -Use when a user asks for Contentstack Delivery SDK code, query examples, helper functions, SDK setup, stack initialization, reference inclusion, filtering, sorting, pagination, typed entry fetching, asset fetching, Live Preview setup, Visual Builder support, SSR preview handling, or debugging SDK query chains. +Use another skill for: -## User Problem +- Migrating JavaScript SDK code to TypeScript → `dx-migrate-js-to-ts-sdk` +- GraphQL queries → `cms-graphql` +- Rendering JSON RTE fields and embedded items → `cms-json-rte` +- Diagnosing broken Live Preview or Visual Editor setups → `cms-live-preview-visual-editor-support-assistant` +- Work inside the Next.js kickstart repo → `dx-kickstart-next` +- CDA query semantics beyond the SDK (raw REST, Sync API) → `cms-entries` -Users need current, correct Contentstack Delivery SDK code with the right method names, chain order, and query patterns. The skill should prevent subtle SDK mistakes and default to production-ready TypeScript. +## Before you answer -## Success Criteria +Identify the content type UID, any entry or asset UID, the field UIDs for filters, sorting, selection or references, the locale, the return shape the user wants, and whether SSR or Visual Builder is involved. Ask only for what is missing to build the query correctly. -- Uses current `@contentstack/delivery-sdk` method names and correct chain order. -- Verifies API details against the Delivery SDK Spec when behavior is uncertain. -- Produces TypeScript-first examples with safe environment-based credentials. -- Handles references, filters, sorting, pagination, field selection, assets, locale, and Live Preview correctly. -- Flags or avoids common mistakes such as wrong query methods, missing pagination, or shared SSR Live Preview stacks. - -## Expected Inputs - -- Content type UID -- Entry UID or asset UID when applicable -- Field UIDs for filters, sorting, selection, or references -- Locale when localized content is needed -- Desired return shape or helper function behavior -- SSR or Visual Builder context when Live Preview is involved - -## Expected Outputs - -- TypeScript code snippets -- Reusable helper functions -- Correct SDK query chains -- Live Preview or SSR-safe stack setup -- Debugging guidance for incorrect Contentstack SDK usage - -## Example User Requests - -- Write a Contentstack Delivery SDK query for blog posts with author references included. -- Show me the correct TypeScript setup for Contentstack Live Preview in Next.js SSR. -- Fix this Contentstack query chain; it is not returning the right entries. -- Create a helper to fetch entries by URL with pagination and typing. -- How do I fetch assets and filter by content type in `@contentstack/delivery-sdk`? - -## Workflow Summary +## Instructions 1. Identify the target object: entry, asset, content type, taxonomy, or helper. 2. Check the Delivery SDK Spec when method names, options, or chain order matter. @@ -59,9 +37,8 @@ Users need current, correct Contentstack Delivery SDK code with the right method 4. Choose the correct SDK chain and method order. 5. Add pagination, locale, field selection, and references as needed. 6. Use safe TypeScript types and reusable helpers. -7. Include error handling and common-mistake warnings when relevant. +7. Include error handling and common-mistake warnings when relevant, such as wrong query methods, missing pagination, or shared SSR Live Preview stacks. -## Instructions ### Identify the target @@ -83,37 +60,45 @@ Apply references before `.query()`, use `QueryOperation` for filters, use `order For SSR or Visual Builder, create a new stack per request and apply live preview configuration before fetching. Do not reuse a Live Preview stack across requests. -## Output Format +### Packages and hosts + +- Prefer `@contentstack/delivery-sdk` as the primary SDK. +- Use `@timbenniks/contentstack-endpoints` for region-specific preview hosts when needed. It is a community package (not published under `@contentstack/`) that the official kickstarts use to resolve region hosts. +- Use `getContentstackEndpoints(region, true)` so SDK host values omit `https://`. +- For SSR Live Preview or Visual Editor (formerly Visual Builder), create a new stack per request. +- Cache policies other than `Policy.IGNORE_CACHE` need `@contentstack/persistence-plugin`: pass a `PersistenceStore` as `cacheOptions.persistenceStore`. + +## MCP tools + +When the Contentstack MCP server is connected, use read tools to ground SDK code in the real stack instead of guessing UIDs (local server group in brackets): -Prefer TypeScript. -Use concise, production-ready code blocks. -Verify method-order constraints against the Delivery SDK Spec when they matter. -Do not hardcode credentials. -Call out pagination limits when returning multiple entries. -Include brief notes for Live Preview or SSR safety when relevant. +- Inspect the model: `get_all_content_types`, `get_a_single_content_type`, `get_all_global_fields`, `get_all_languages`, `get_all_environments` (`cma`) +- Check what the SDK will return: `get_all_entries_cdn`, `get_a_single_entry_cdn`, `get_all_assets_cdn`, `get_a_single_asset_cdn` (`cda`) -## Tooling Notes +The `cda` tools read published content with a delivery token, the same data the SDK sees. This skill needs no write tools. -Prefer `@contentstack/delivery-sdk` as the primary SDK. -Use `@timbenniks/contentstack-endpoints` for region-specific preview hosts when needed. -Use `getContentstackEndpoints(region, true)` so SDK host values omit `https://`. -For SSR Live Preview or Visual Builder, create a new stack per request. +## Output + +- Prefer TypeScript, in concise, production-ready code blocks. +- Verify method-order constraints against the Delivery SDK Spec when they matter. +- Do not hardcode credentials. +- Call out pagination limits when returning multiple entries. +- Include brief notes for Live Preview or SSR safety when relevant. ## Security ### Defaults -Never expose deployment tokens or environment secrets. -Validate deployment targets before triggering. -Require confirmation for production deployments. -Never auto-deploy to production without review. -Never hardcode Contentstack credentials in examples. -Avoid sharing preview tokens or other secrets in responses. -For SSR Live Preview, do not reuse a stack instance across requests. +- Advisory by default. Use the MCP tools above only to read the stack. +- Delivery tokens are read-only and safe for client-side code. +- Preview tokens read unpublished content: use them only in preview deployments, never in production builds. +- Never put management tokens in SDK or client code. +- Never hardcode Contentstack credentials in examples, and avoid sharing preview tokens or other secrets in responses. +- For SSR Live Preview, do not reuse a stack instance across requests. ### Destructive Actions -This skill does not perform destructive actions. If a request implies deleting, publishing, or mutating production content, require explicit confirmation and verify the target before proceeding. +This skill does not perform destructive actions. If a request implies deleting, publishing, or mutating content, name the target and get explicit confirmation before proceeding. ### Secrets @@ -123,23 +108,11 @@ Use environment variables for all credentials and tokens. Never print, infer, or Use `process.env` placeholders in examples. Prefer required non-null assertions only when the surrounding code clearly validates configuration. Do not suggest committing secrets to source control. -## Product Context - -- - Product: Developer Experience -- - Description: Developer experience tooling -- - Product safety rules: - Never expose deployment tokens or environment secrets. -- Validate deployment targets before triggering. -- Require confirmation for production deployments. -- Never auto-deploy to production without review. - ## References -This skill ships reference material in the `references/` folder. Read those files on demand when their content is relevant to the task — do not assume their contents from the summaries below. +Read these on demand when their content is relevant; don't assume their contents from the summaries. -### [Delivery SDK Spec](references/delivery-sdk-spec.md) (product doc, required) -- Source: Official Docs (https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/typescript/reference.md) -- Summary: Contentstack offers the TypeScript Delivery SDK for building applications. Below, is an in-depth guide and valuable resources to initiate your journey with our TypeScript Delivery SDK. Additionally, the SDK supports the creating applications for Node.js and React Native environments. -- Read: `references/delivery-sdk-spec.md` +- [Delivery SDK Spec](references/delivery-sdk-spec.md) (required): the TypeScript Delivery SDK reference for Node.js and React Native. Source: https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/typescript/reference.md ## Examples diff --git a/skills/dx-kickstart-next/SKILL.md b/skills/dx-kickstart-next/SKILL.md index 8645ba5..6ced2cc 100644 --- a/skills/dx-kickstart-next/SKILL.md +++ b/skills/dx-kickstart-next/SKILL.md @@ -1,13 +1,29 @@ --- name: dx-kickstart-next -description: "Guidance for building, reviewing, debugging, or extending Contentstack's kickstart-next repository. Use when working in contentstack/kickstart-next or a close fork: the Next.js kickstart app, its Contentstack Delivery SDK setup, Live Preview or Visual Builder behavior, seeded stack alignment, environment variables, endpoint or image host configuration, App Router structure, package scripts, local setup, CI expectations, tests, lint/build validation, or PR review checklists. For general Delivery SDK or Live Preview questions outside this repo, use dx-delivery-sdk or cms-live-preview-visual-editor-support-assistant." +description: "Guidance for building, reviewing, debugging, or extending Contentstack's kickstart-next repository. Use when working in contentstack/kickstart-next or a close fork: the Next.js kickstart app, its Contentstack Delivery SDK setup, Live Preview or Visual Builder behavior, seeded stack alignment, environment variables, endpoint or image host configuration, App Router structure, package scripts, local setup, CI expectations, tests, lint/build validation, or PR review checklists. For general Delivery SDK or Live Preview questions outside this repo, use dx-delivery-sdk or cms-live-preview-visual-editor-support-assistant; for rendering JSON RTE fields, use cms-json-rte." --- # Contentstack kickstart-next -Use this skill when working in `contentstack/kickstart-next` or a close fork. Inspect the repository first, then load only the matching reference files. +Build, review, debug and extend `contentstack/kickstart-next` or a close fork. Inspect the repository first, then load only the matching reference files. -## Routing +## When to use + +- Working in `contentstack/kickstart-next` or a close fork: App Router structure, components, Delivery SDK setup, Live Preview and Visual Builder behavior, seeded stack alignment, environment variables, endpoint and image host configuration. +- Package scripts, local setup, CI expectations, tests, lint and build validation. +- PR review checklists for the repo. + +Use another skill for: + +- General Delivery SDK code outside this repo → `dx-delivery-sdk` +- Diagnosing Live Preview or Visual Editor problems in general → `cms-live-preview-visual-editor-support-assistant` +- Rendering JSON RTE fields → `cms-json-rte` +- Content model design → `cms-data-modeling-best-practices` +- Hosting the kickstart on Launch → `launch-platform` + +## Instructions + +### Routing 1. For App Router routes, React components, client/server boundaries, Tailwind, ESLint, TypeScript, images, or `next.config.mjs`, read [references/next.md](references/next.md). 2. For Contentstack delivery, preview, Visual Builder, regions, endpoint overrides, env vars, or seeded stack alignment, read [references/contentstack.md](references/contentstack.md). @@ -15,7 +31,7 @@ Use this skill when working in `contentstack/kickstart-next` or a close fork. In 4. For local setup, Contentstack stack seeding, npm scripts, CI, CODEOWNERS, validation commands, docs updates, or PR prep, read [references/workflow.md](references/workflow.md). 5. For PR/code reviews, severity labels, security checks, or risk checklists, read [references/review.md](references/review.md). -## Default working rules +### Default working rules - Keep guidance grounded in the current checkout. Inspect files before assuming scripts, tests, CI, content types, env vars, or framework conventions exist. - Treat kickstarts as user-facing examples: prefer clarity, minimal moving parts, safe defaults, and copyable setup steps over clever abstractions. @@ -25,7 +41,17 @@ Use this skill when working in `contentstack/kickstart-next` or a close fork. In - When modifying JavaScript or TypeScript files, run `npm run build`; also run `npm run lint` and any `typecheck` script if they exist. - Before claiming CI covers something, verify the workflows. If build, lint, or tests are not wired into CI, tell the user to run them locally. -## Response behavior +## MCP tools + +When the Contentstack MCP server is connected, use read tools to check that the code matches the user's stack (local server group in brackets): + +- Inspect the model: `get_all_content_types`, `get_a_single_content_type`, `get_all_global_fields`, `get_all_environments`, `get_all_languages` (`cma`) +- Check published content: `get_all_entries_cdn`, `get_a_single_entry_cdn` (`cda`) +- Change, only when the user asks: `create_a_content_type`, `update_content_type`, `create_an_entry`, `update_an_entry` (`cma`) + +Seeding a stack uses the CLI (`csdx cm:stacks:seed`), not MCP. + +## Output - For implementation help, give concrete file-level changes and commands. - For reviews, separate blockers from major issues and minor nits. @@ -36,13 +62,14 @@ Use this skill when working in `contentstack/kickstart-next` or a close fork. In ### Defaults +- Advisory by default. Use the MCP tools above only when the user asks, and only read tools unless they ask for a stack change. - Never commit real Contentstack credentials. `.env.example` and docs use placeholders; real values live in a gitignored `.env`. - Delivery tokens are safe in the browser. Preview tokens read unpublished content: expose them client-side only on preview deployments (CSR preview needs them), never in production builds. Management tokens never reach the browser. - Never recommend enabling Live Preview in production builds. ### Destructive Actions -Advisory by default. Before changing a user's stack (seeding, schema changes) or force-pushing, deleting branches or rewriting history in the repo, describe the impact and get explicit confirmation. +Before changing a user's stack (seeding, schema changes, any MCP write) or force-pushing, deleting branches or rewriting history in the repo, describe the impact and get explicit confirmation. ### Secrets diff --git a/skills/dx-mcp-server/SKILL.md b/skills/dx-mcp-server/SKILL.md new file mode 100644 index 0000000..99f943a --- /dev/null +++ b/skills/dx-mcp-server/SKILL.md @@ -0,0 +1,166 @@ +--- +name: dx-mcp-server +description: "Help developers connect AI agents to Contentstack over the Model Context Protocol, with either the local @contentstack/mcp stdio server or the hosted MCP Profile Hub. Cover choosing between them, npx setup, API groups (GROUPS), OAuth and token auth, required IDs per group, client configuration for Claude Code, Claude Desktop, claude.ai, Cursor, Codex and ChatGPT, Profile Hub profiles, connector URLs and URL parameters, Automate automations and Agent OS agents as tools, execution history, the Tool Definitions API, and safe least-privilege setups. Use when developers ask how to give an AI assistant access to Contentstack, set up or debug the Contentstack MCP server or MCP Profile Hub, pick tool groups or profiles, fix MCP auth or missing tools, or build their own MCP integration. Pairs with the other Contentstack skills, which supply the product knowledge the tools need. For the csdx CLI, use dx-cli." +allowed-tools: Read Grep Glob +--- + +# Contentstack MCP + +Help developers give AI agents access to Contentstack through MCP. Contentstack offers two options: the local `@contentstack/mcp` server, which runs on the developer's machine over stdio, and MCP Profile Hub, a hosted server reached over Streamable HTTP that exposes curated tool profiles. + +## When to use + +- Connecting an AI assistant to Contentstack to read or change content, deploy with Launch, query Personalize, Brand Kit, Lytics, Analytics or Automate, or run automations and agents. +- Choosing between the local server and MCP Profile Hub, and picking tool groups or profiles. +- MCP setup failures: no tools appear, auth fails, or the wrong stack or region is used. +- Building your own MCP integration on Contentstack's tool definitions. + +Use another skill for: + +- The `csdx` CLI → `dx-cli` +- What to do with the tools once connected: the product skill for the area, such as `cms-entries`, `cms-branches-aliases`, `launch-platform`, `personalize` or `automations` +- Token types and auth outside MCP → `cms-tokens-authentication` +- Installing Marketplace apps (MCP Profile Hub is one) → `marketplace-apps` +- MCP setup inside a Studio project → `studio` + +## Before you answer + +Find out the MCP client (Claude Code, Claude Desktop, claude.ai, Cursor, Codex, ChatGPT, VS Code or another), the products and tasks the agent needs, the region, stack API key, branch and any project IDs, and whether the setup is personal or shared by a team. The agent should see the right tools for the job, act on the right stack and branch with the user's own permissions, and not load hundreds of tools or leak tokens. + +## Instructions + +1. Choose between the local server and Profile Hub. +2. Pick the smallest set of groups, tools or profile. +3. Configure the client and authenticate. +4. Set stack, branch and project context. +5. Verify with a read-only prompt. + + +### Choose local server or Profile Hub + +- **Local `@contentstack/mcp` server:** runs with `npx` on the developer's machine over stdio. Best for individual development, quick starts, scripted setups, management-token use, and dedicated infrastructure with custom endpoints. Tool selection is per group. +- **MCP Profile Hub:** hosted by Contentstack at `https://mcp-profile-hub.contentstack.com/api/mcp`, reached over Streamable HTTP, so nothing is installed and it also works in web clients such as claude.ai and ChatGPT. Profiles expose only the tools you pick, connections are configured once in the app, sign-in is OAuth, every call runs with the user's Contentstack roles, and calls are logged in an Executions view. Best for teams, non-developers and governed access. It can also expose your Automate automations and Agent OS agents as tools. + +When unsure, recommend Profile Hub for shared or team use and the local server for a single developer working in a repository. + +### Local server: setup + +Run it with `npx -y @contentstack/mcp`; no install is needed. Pick groups with `GROUPS` or `--groups` (comma-separated): `cma`, `cma-extended`, `cda`, `analytics`, `automations`, `brandkit`, `launch`, `developerhub`, `lytics`, `personalize`, or `all`. The default is `cma`. Load `cma-extended` (audit logs, version history, workflow and publish rule inspection, folder and global field writes) only when needed, because every group adds tool definitions to each request. + +Auth and required IDs: + +| Group | Auth | Also needs | +| --- | --- | --- | +| `cma`, `cma-extended` | OAuth, or a management token | `CONTENTSTACK_API_KEY` | +| `cda` | Delivery token | `CONTENTSTACK_API_KEY`, `CONTENTSTACK_DELIVERY_TOKEN` | +| `analytics`, `automations` | OAuth | — | +| `brandkit` | OAuth | `CONTENTSTACK_BRAND_KIT_ID` | +| `launch` | OAuth | `CONTENTSTACK_LAUNCH_PROJECT_ID`, `CONTENTSTACK_ORGANIZATION_UID` | +| `developerhub` | OAuth | `CONTENTSTACK_API_KEY` | +| `lytics` | Lytics access token | `LYTICS_ACCESS_TOKEN` | +| `personalize` | OAuth | `CONTENTSTACK_PERSONALIZE_PROJECT_ID` | + +Run `npx @contentstack/mcp --auth` once to sign in with OAuth. It saves the session and region locally. A management token (`CONTENTSTACK_MANAGEMENT_TOKEN`) works only for `cma` and `cma-extended`, and then `CONTENTSTACK_REGION` must be set (`NA`, `EU`, `AU`, `AZURE_NA`, `AZURE_EU`, `GCP_NA`, `GCP_EU`). Optional defaults: `CONTENTSTACK_ENVIRONMENT`, `CONTENTSTACK_BRANCH` (default `main`) and `CONTENTSTACK_LOCALE`. Since 0.9.0 the server enriches tool schemas with live stack data (content types, environments, locales, branches); set `CONTENTSTACK_MCP_ENRICH_TOOLS=false` to turn it off. Dedicated infrastructure can override hosts with `CONTENTSTACK_*_BASE_URL` variables. Every value can also be passed as a CLI flag (`--stack-api-key`, `--groups` and so on) for clients without environment variable support. + +Client configuration: + +- **Claude Code:** `claude mcp add contentstack --env GROUPS=cma --env CONTENTSTACK_API_KEY=<key> -- npx -y @contentstack/mcp` +- **Claude Desktop:** add an `mcpServers` entry to `claude_desktop_config.json` with `"command": "npx"`, `"args": ["-y", "@contentstack/mcp"]` and an `env` block, then restart. +- **Cursor:** the same `mcpServers` entry in `~/.cursor/mcp.json`. +- Any other stdio MCP client uses the same `npx` command. + +### Profile Hub: setup + +1. Open **MCP Profile Hub** from the App Switcher, or install the Marketplace app (needs a role that can install apps). +2. Use a ready-made system profile (for example `cms` or `launch`), or create a profile: **+ New Profile**, name it, **Browse catalog**, and pick tools from the **Contentstack APIs**, **Automations** or **AI agents** tabs (up to 200 tools per profile). +3. In **Configure**, choose a stack (required) and any Launch, Personalize, Brand Kit, Automate or Lytics connections the tools need. +4. In **Installation**, copy the connector URL or the client snippet: `https://mcp-profile-hub.contentstack.com/api/mcp?profile_id=<PROFILE_ID>&org_uid=<ORG_UID>`. + +Connecting clients: + +- **Claude Code:** `claude mcp add --transport http <name> "<connector URL>"`. Quote the URL. Add `--scope user` to make it available in every project, then run `/mcp` to sign in. +- **claude.ai and Claude Desktop:** **Add to Claude** in the Installation step, or add a custom connector with the URL. On some Claude plans only admins can add custom connectors. +- **Claude Desktop without connectors, and other stdio-only clients:** wrap the URL with `mcp-remote` through `npx`, using the snippet from the Installation step (it pins the version). Needs Node.js. +- **Cursor:** **Add to Cursor**, or `{"mcpServers": {"<name>": {"url": "<connector URL>"}}}` in `.cursor/mcp.json`. +- **Codex:** a `[mcp_servers.<name>]` block with `url = "<connector URL>"` in `~/.codex/config.toml`. +- **ChatGPT:** add a custom connector with the URL, if the ChatGPT plan supports custom connectors. + +Don't add Authorization headers or bearer tokens: they block the OAuth handshake. The client opens a browser sign-in on first use. + +URL parameters override the profile's saved context for one connection: `stack_api_key`, `branch`, `environment`, `locale`, `launch_project_uid`, `personalize_project_uid`, `brandkit_project_uid`, `automation_project_uid`, and `timeout` (milliseconds; default 60,000, max 120,000). An invalid project UID fails the connection; an invalid stack, branch, environment, locale or timeout falls back to the saved value. Lytics has no URL parameter. + +Things to know: + +- An unpublished or empty profile connects but shows no tools. +- After editing a profile, the URL stays the same, but clients keep the old tool list until they reconnect. +- A profile never grants more than the user's Contentstack roles allow; calls beyond them fail. +- Automations appear as tools only when they have an HTTP trigger and are active; agents only when published with an HTTP trigger. +- Executions shows each call's input, result, timing and errors, and identifies the client, not the person. Use the organization audit log for user-level attribution. +- Tool lists for products the organization's plan doesn't include may not be offered. + +### Least privilege and safety + +- Start read-only. Add write, publish, delete or deploy tools only when the task needs them, and prefer a dedicated profile per job. +- Point agents at a development branch or stack first, and keep production publishing behind a separate profile or explicit confirmation. +- Keep management tokens out of shared configuration files and repositories; prefer OAuth. +- Before an agent deletes content types, global fields, assets, folders or branches, or deploys a release, ask it to state the target and wait for confirmation. + +### Build your own + +The local server's tool definitions are published at `https://mcp.contentstack.com/<group>/tools` (for example `/cda/tools`). Each definition includes a JSON Schema for the inputs and a mapper describing the HTTP request to build. The endpoints hold no credentials; callers bring their own tokens. Region hosts come from `https://artifacts.contentstack.com/regions.json`. + +### Pair MCP with these skills + +MCP gives the agent actions; the other Contentstack skills give it the product knowledge to use them well. For example, `cms-data-modeling-best-practices` before creating content types, `cms-branches-aliases` before merges, and `cms-webhooks` or `cms-releases` before publishing at scale. + +## MCP tools + +This skill is about the MCP server itself. Tools per local server group, as published at `https://mcp.contentstack.com/<group>/tools`: + +| Group | Tools | Covers | +| --- | --- | --- | +| `cma` | 78 | Entries, content types, assets, branches, aliases and merges, releases, taxonomies, environments, variants, publishing | +| `cma-extended` | 22 | Audit logs, version history, global field and asset folder writes, workflow, publish rule and publish queue inspection | +| `cda` | 4 | Published entries and assets | +| `analytics` | 8 | Usage, device, URL, status code, cache and SDK analytics | +| `automations` | 9 | Automation projects, automations, triggering and activating | +| `brandkit` | 12 | Knowledge Vault, Voice Profiles, generative AI | +| `launch` | 27 | Projects, environments, deployments, logs, deploy hooks, cache revalidation | +| `developerhub` | 12 | Apps, OAuth, installations | +| `lytics` | 10 | Audiences, fields, user profiles, content classification | +| `personalize` | 24 | Attributes, audiences, experiences, events, analytics | + +No group covers webhooks, roles, users, tokens, workflows (beyond reading them), publish rules (beyond reading them), labels or extensions; point users to the CMA or the UI for those. Profile Hub draws on the same catalog plus Automate automations and Agent OS agents, but a profile exposes only the tools chosen for it, so use the names the client lists. + +## Output + +Lead with the recommendation, then the exact configuration for the user's client, then the groups, profile or tools to enable, the auth steps, and the verification prompt (for example "List the content types in my stack"). Use placeholders for keys and IDs. + +## Security + +### Defaults + +- Advisory by default. Do not edit the user's MCP configuration files or call Contentstack tools on their behalf unless asked. +- Prefer OAuth over tokens, and Profile Hub for shared access. +- Enable the fewest groups or tools that do the job. +- Keep production writes behind confirmation. + +### Destructive Actions + +Write tools can delete entries, content types, assets, branches and environments, publish to production, and deploy. Before enabling them, explain which tools are destructive and recommend a non-production target. Before the agent runs one, it names the target and waits for confirmation. + +### Secrets + +Never echo management, delivery or Lytics tokens or API keys. A connector URL that contains `apikey` also contains the stack API key, so share such URLs with care. + +### Environment Variables + +Keep tokens in environment variables or the client's secret storage, not in committed config files. + +## References + +- https://www.contentstack.com/docs/developers/contentstack-mcp-server +- https://www.contentstack.com/docs/developers/mcp-profile-hub +- https://www.contentstack.com/docs/developers/mcp-profile-hub-connect-a-client-to-profile-hub +- https://www.contentstack.com/docs/developers/mcp-profile-hub-url-parameters +- https://github.com/contentstack/mcp diff --git a/skills/dx-migrate-js-to-ts-sdk/SKILL.md b/skills/dx-migrate-js-to-ts-sdk/SKILL.md index 13cb8f0..c547475 100644 --- a/skills/dx-migrate-js-to-ts-sdk/SKILL.md +++ b/skills/dx-migrate-js-to-ts-sdk/SKILL.md @@ -1,72 +1,41 @@ --- name: dx-migrate-js-to-ts-sdk -description: "Migrate Contentstack Delivery SDK code from JavaScript to TypeScript. Rewrite setup, initialization, Stack, Entries, Assets, Query, pagination, cache, utils, taxonomy, and image transform usage while preserving behavior and calling out TypeScript-specific differences. Use when a user wants to migrate Contentstack Delivery SDK code from JavaScript to TypeScript." +description: "Migrate Contentstack Delivery SDK code from JavaScript to TypeScript. Rewrite setup, initialization, Stack, Entries, Assets, Query, pagination, cache, utils, taxonomy, and image transform usage while preserving behavior and calling out TypeScript-specific differences. Use when a user wants to migrate Contentstack Delivery SDK code from JavaScript to TypeScript. For new TypeScript SDK code, use dx-delivery-sdk." argument-hint: "[javascript-snippet | file]" allowed-tools: Read Grep Glob context: fork agent: general-purpose --- -# dx-migrate-js-to-ts-sdk +# Migrate JavaScript Delivery SDK code to TypeScript -## Description +Move Delivery SDK code from the legacy JavaScript SDK (`contentstack`) to the TypeScript Delivery SDK (`@contentstack/delivery-sdk`) without losing functionality: API mappings, required packages, TypeScript-specific patterns, and JavaScript behavior with no direct equivalent. -Migrate Contentstack Delivery SDK code from JavaScript to TypeScript. Rewrite setup, initialization, Stack, Entries, Assets, Query, pagination, cache, utils, taxonomy, and image transform usage while preserving behavior and calling out TypeScript-specific differences. +## When to use -## When to Use +- Migrating Delivery SDK code from JavaScript to TypeScript. +- Comparing JavaScript and TypeScript SDK APIs for Stack, Entries, Assets, Query, pagination, cache, utils, taxonomy or image transforms. +- A migration-ready rewrite, a side-by-side comparison, or a concise list of breaking changes and limitations. -Use when a user wants to migrate Contentstack Delivery SDK code from JavaScript to TypeScript. -Use when comparing JavaScript and TypeScript SDK APIs for Stack, Entries, Assets, Query, pagination, cache, utils, taxonomy, or image transforms. -Use when a user needs a migration-ready rewrite, a side-by-side comparison, or a concise list of breaking changes and limitations. +Use another skill for: -## User Problem +- Writing new TypeScript SDK code that isn't a migration → `dx-delivery-sdk` +- Rendering JSON RTE content with `@contentstack/utils` beyond the API change → `cms-json-rte` +- Migrating content from Contentful → `migration-companion` -The user needs to move existing Contentstack Delivery SDK code from JavaScript to TypeScript without losing functionality. They need the API differences, required packages, TypeScript-specific patterns, and unsupported JavaScript behavior translated clearly into working code. +## Before you answer -## Success Criteria +Get the existing JavaScript SDK code or snippets, the target runtime (Node.js or React Native), the SDK areas involved (Stack, Entries, Assets, Query, caching, utils, taxonomy, image transforms), and whether the user wants an explanation, migration steps, or rewritten code. -Identifies the correct JavaScript-to-TypeScript SDK equivalents. -Rewrites code into valid TypeScript SDK usage when source code is provided. -Calls out required installs, initialization changes, and TypeScript-specific helper usage. -Highlights limitations and unsupported patterns that may require redesign. -Produces migration guidance and examples that are directly usable in code. - -## Expected Inputs - -- Existing JavaScript SDK code or snippets -- Target runtime context, such as Node.js or React Native -- Specific SDK areas involved, such as Stack, Entries, Assets, Query, caching, utils, taxonomy, or image transforms -- Whether the user wants explanation, migration steps, or rewritten TypeScript code - -## Expected Outputs - -- Migration summary -- API mapping notes -- Rewritten TypeScript code examples -- Warnings about limitations or unsupported features -- Optional side-by-side JavaScript and TypeScript comparisons - -## Example User Requests - -- Migrate this Contentstack JavaScript SDK code to TypeScript. -- Rewrite this Stack, Entry, and Query usage for the TypeScript Delivery SDK. -- Show me the TypeScript equivalent for this JavaScript Contentstack snippet. -- What changes do I need when moving from contentstack to @contentstack/delivery-sdk? -- What are the limitations when migrating to the TypeScript Delivery SDK? -- How do I rewrite cache policy usage for the TypeScript Delivery SDK? -- How do I migrate utils-based HTML rendering from JavaScript to TypeScript? -- Convert this taxonomy query from the JavaScript SDK to TypeScript. - -## Workflow Summary +## Instructions -Identify the SDK area and current JavaScript pattern. -Map the JavaScript API to the TypeScript equivalent. -Adjust package installs, imports, and initialization. -Rewrite code with TypeScript types and SDK methods. -Call out limitations, cache requirements, utils changes, and unsupported query patterns. -Provide a concise migration summary and examples. +1. Identify the SDK area and current JavaScript pattern. +2. Map the JavaScript API to the TypeScript equivalent. +3. Adjust package installs, imports, and initialization. +4. Rewrite code with TypeScript types and SDK methods. +5. Call out limitations, cache requirements, utils changes, and unsupported query patterns that may require redesign. +6. Provide a concise migration summary and examples. -## Instructions ### Scope @@ -78,45 +47,47 @@ Prefer TypeScript SDK equivalents from @contentstack/delivery-sdk. Preserve beha ### Key mappings -Use contentstack.stack(...) instead of contentstack.Stack(...). Use stack.contentType(...), entry(...), asset(...), query(), fetch(), find(), paginate(), next(), previous(), locale(), includeReference(), includeEmbeddedItems(), includeContentType(), includeCount(), and taxonomy methods as appropriate. Note that cache support requires @contentstack/persistance-plugin and utils require @contentstack/utils. +Use contentstack.stack(...) instead of contentstack.Stack(...). Use stack.contentType(...), entry(...), asset(...), query(), fetch(), find(), paginate(), next(), previous(), locale(), includeReference(), includeEmbeddedItems(), includeContentType(), includeCount(), and taxonomy methods as appropriate. Note that cache support requires @contentstack/persistence-plugin and utils require @contentstack/utils. ### Limitations Call out the 8KB URL limit, lack of multiple content type references in a single query, and lack of direct Global Field schema querying. Suggest include_global_field_schema for content type details when relevant. Mention assetFields support is region-limited to NA. -### Examples +### Migration examples Include at least one migration example when the user asks for help. Prefer side-by-side snippets or before/after code when useful. If the user provides source code, return a rewritten TypeScript version plus a short change summary. Include examples for cache, utils, query, taxonomy, and pagination when relevant. -## Output Format +### Tooling + +- No tools are required by default. If code is provided, focus on transformation and explanation only. +- If caching is involved, mention the persistence plugin requirement. +- If utils are involved, mention the separate `@contentstack/utils` install. +- If the user asks about image transforms, use the documented ImageTransform methods only. -Be concise and migration-oriented. -Use code blocks for code examples. -When helpful, show JavaScript and TypeScript side by side. -Explicitly call out unsupported or changed behavior. -When source code is provided, include a rewritten TypeScript version. -Do not invent SDK methods not present in the reference docs. +## MCP tools -## Tooling Notes +The migration is a code transformation, so it needs no MCP tools. When the Contentstack MCP server is connected, the read tools `get_all_entries_cdn` and `get_a_single_entry_cdn` (`cda`) can confirm that a rewritten query returns the same entries as before, and `get_a_single_content_type` (`cma`) shows the field UIDs the code relies on. -No tools are required by default. -If code is provided, focus on transformation and explanation only. -If caching is involved, mention the persistence plugin requirement. -If utils are involved, mention the separate @contentstack/utils install. -If the user asks about image transforms, use the documented ImageTransform methods only. +## Output + +- Be concise and migration-oriented: a migration summary, API mapping notes, rewritten TypeScript code, warnings about limitations, and optional side-by-side JavaScript and TypeScript comparisons. +- Use code blocks for code examples. +- Explicitly call out unsupported or changed behavior. +- When source code is provided, include a rewritten TypeScript version. +- Do not invent SDK methods not present in the reference docs. ## Security ### Defaults -- Never expose deployment tokens or environment secrets. -- Validate deployment targets before triggering. -- Require confirmation for production deployments. -- Never auto-deploy to production without review. +- Advisory by default. Use the MCP tools above only to read the stack. +- Delivery tokens are read-only and safe for client-side code; management tokens never belong in SDK code. +- Preview tokens read unpublished content: use them only in preview deployments. +- Never hardcode credentials in migrated code; read them from environment variables. ### Destructive Actions -Do not perform destructive actions. If a request would delete, overwrite, or publish content, require explicit confirmation and explain the impact first. +Do not perform destructive actions. If a request would delete, overwrite, or publish content, name the target, explain the impact and wait for explicit confirmation. ### Secrets @@ -126,22 +97,13 @@ Never request, reveal, or echo delivery tokens, API keys, or other secrets. If c When environment variables are needed, use placeholder names and explain expected values. Never print real values or infer secrets from context. -## Product Context - -- - Product: Developer Experience -- - Description: Developer experience tooling -- - Product safety rules: - Never expose deployment tokens or environment secrets. -- Validate deployment targets before triggering. -- Require confirmation for production deployments. -- Never auto-deploy to production without review. - ## Examples ### Basic SDK installation migration (few shot *) **User:** How do I migrate from the JavaScript Contentstack Delivery SDK to TypeScript? -**Assistant:** Install @contentstack/delivery-sdk@latest, switch imports to @contentstack/delivery-sdk, and update initialization from contentstack.Stack(...) to contentstack.stack(...). If you need caching, install @contentstack/persistance-plugin@latest. If you need utils, install @contentstack/utils@latest. +**Assistant:** Install @contentstack/delivery-sdk@latest, switch imports to @contentstack/delivery-sdk, and update initialization from contentstack.Stack(...) to contentstack.stack(...). If you need caching, install @contentstack/persistence-plugin@latest. If you need utils, install @contentstack/utils@latest. *Shows the core package and import changes.* @@ -173,7 +135,7 @@ When environment variables are needed, use placeholder names and explain expecte **User:** Do I need anything extra for cache support in the TypeScript SDK? -**Assistant:** Yes. Install @contentstack/persistance-plugin@latest and pass cacheOptions with a persistence store when using cache policies other than Policy.IGNORE_CACHE. +**Assistant:** Yes. Install @contentstack/persistence-plugin@latest and pass a `PersistenceStore` as `cacheOptions.persistenceStore` when using cache policies other than Policy.IGNORE_CACHE. *Captures the cache plugin requirement.* diff --git a/skills/launch-platform/SKILL.md b/skills/launch-platform/SKILL.md new file mode 100644 index 0000000..6f8f9fd --- /dev/null +++ b/skills/launch-platform/SKILL.md @@ -0,0 +1,125 @@ +--- +name: launch-platform +description: "Advise developers on hosting and configuring sites on Contentstack Launch: framework support and build settings, Cloud Functions, Edge Functions, launch.json redirects, rewrites and cache priming, custom domains, CDN caching and cache revalidation, deploy hooks and CMS-triggered redeploys, environment variables, password protection, IP access control, log targets, monorepos, platform limits, and the Launch CLI and API. Use when developers ask how to deploy or configure a site on Launch, why a build or function fails, how caching or routing works on Launch, or what Launch supports. For syncing environment variables from .env.example, use launch-sync-environment-variables-from-env-example. For scripted deploy-and-monitor runs, use launch-trigger-and-monitor-launch-deployments." +allowed-tools: Read Grep Glob +--- + +# Launch Platform + +Advise on hosting front-end sites on Contentstack Launch: frameworks and builds, Cloud and Edge Functions, `launch.json` routing, domains, CDN caching and revalidation, deploy triggers, environment variables, access control, logging, monorepos and limits. + +## When to use + +- Deploying or configuring a site on Launch, or checking whether Launch supports a framework or feature. +- A build, function or deployment that fails. +- Choosing between static, SSR, Cloud Functions and Edge Functions. +- Routing, redirects, caching and revalidation, deploy hooks, domains, password protection, IP filtering, log targets and monorepos. + +Use another skill for: + +- Syncing a Launch environment's variables from `.env.example` → `launch-sync-environment-variables-from-env-example` +- A scripted deploy-and-monitor run → `launch-trigger-and-monitor-launch-deployments` +- CMS webhooks that call a deploy hook or a revalidation receiver → `cms-webhooks` +- Delivery SDK code inside the app → `dx-delivery-sdk` +- The `csdx` CLI in general → `dx-cli` + +## Before you answer + +Find out the framework, rendering mode and package manager, whether the repo is a single app or a monorepo, any routing, caching or redirect requirements, how often content is published, and any error messages, build logs or deployment status. + +## Instructions + +1. Identify the framework, rendering mode and repo layout. +2. Check compatibility and limits first, and call out unsupported features before the user hits them. +3. Pick the compute layer (static, SSR, Cloud Function or Edge Function) and the routing approach. +4. Design caching and how content changes reach the site; prefer cache revalidation over full rebuilds for frequent content changes. +5. Cover domains, access control and logging when relevant. + + +### How a request is served + +Requests hit the CDN edge first. Redirects in `launch.json` run, then rewrites, then the Edge Function, then the CDN cache lookup, then the origin (static files or the server-side runtime). A matching `launch.json` rule means the Edge Function does not run for that request. + +### Frameworks and builds + +Launch builds from GitHub or Bitbucket, or from an uploaded file. Framework presets include Next.js, Nuxt, Gatsby, Remix, Astro, Eleventy, SvelteKit, Qwik City, Jekyll, Angular, Analog and static HTML, plus custom or other for anything else. Vue is client-side only on Launch; use Nuxt for SSR. Configure the build command, output directory and, for SSR, the server command per environment. Supported runtime Node versions are 20.x, 22.x and 24.x. Use npm, yarn (node-modules mode) or bun; pnpm and Yarn Plug'n'Play are not supported. Builds time out after 60 minutes. Larger build machines are available by plan. + +### Cloud Functions + +Use Cloud Functions for Node.js API routes next to the front end. Put files in `/functions` at the project root; file names become routes, and `[param]` creates dynamic segments. The handler is `export default function handler(request, response)`. Defaults: 1,024 MB memory and a 30-second timeout, which Support can raise per organization. The file system is read-only except `/tmp`. Expect cold starts after inactivity. Cloud Functions cannot run from a monorepo sub-app. + +### Edge Functions + +Use Edge Functions for per-request logic at the CDN: redirects with logic, header changes, geo or A/B routing, auth gates and IP filtering. The entry point is `functions/[proxy].edge.js`. Code must be WinterCG-compatible: no Node APIs such as `fs`, `path` or `node:crypto`, or the deployment fails. Forward to the origin with `context.fetch()`. Limits: 128 MB memory, 1 MiB minified bundle and a 400 ms startup budget for global scope. Visitor geo headers are available on the request. + +### launch.json + +Place `launch.json` at the repository root (not in a monorepo sub-app). It holds `redirects`, `rewrites` and `cache.cachePriming.urls`. Rules run top to bottom, redirects before rewrites, and can add request or response headers. Sources are relative paths; escape `?` as `\?`; hash fragments are not supported. Keep the file under about 200 KB and move complex logic into an Edge Function. See [references/launch-json.md](references/launch-json.md). + +### Caching and revalidation + +Launch purges the whole CDN cache when a new deployment goes live. Set `Cache-Control` headers to control caching. To refresh content without rebuilding, call `POST /projects/{project_uid}/environments/{environment_uid}/revalidate-cdn-cache` with an exact path, a path prefix (`isPrefix: true`), cache tags (set `Cache-Tag` response headers first) or hostnames. Revalidation has a daily quota that depends on the plan; tell users to check theirs. Cache priming warms up to 50 URLs after each deployment. Next.js App Router ISR and `revalidateTag()` are not supported; use the revalidation API instead. + +### Deploy triggers + +A deploy hook is a per-environment URL that starts a deployment on POST; treat the URL as a secret. To redeploy on CMS publish, point a CMS webhook at the deploy hook. Every publish then triggers a full build, so for frequent publishing prefer revalidating the cache from a webhook receiver. `autoDeployOnPush` controls deploys on Git pushes. Rollback to an earlier deployment is available in the UI and API. + +### Environment variables + +Variables apply at build time and runtime. Limits: 128 per environment, and a total size cap that is much smaller when Cloud Functions are enabled. Use framework prefixes (such as `NEXT_PUBLIC_`) only for values safe in the browser. + +### Domains and access control + +Use a CNAME for subdomains and an A record for apex domains. TLS is automatic, and custom certificates can be uploaded. Custom domains depend on the plan, and the environment needs a live deployment first. Password protection (HTTP Basic Auth) is set per environment and applies without a redeploy. There is no built-in IP allowlist; filter on the visitor IP header in an Edge Function. + +### Logs + +Log targets forward server logs (SSR, Cloud and Edge Functions) and CDN traffic logs over OpenTelemetry (OTLP) to Datadog, CloudWatch, Splunk or any OTLP endpoint. One target per log type per environment. Batches that fail to send are not retried. + +### Monorepos + +Scope the build command and output directory to the app, for example with Turborepo filters or Nx project builds. Gatsby, Cloud Functions and `launch.json` are not supported from a sub-app. + +### API and CLI + +The Launch API uses regional hosts (`launch-api.contentstack.com`, `eu-launch-api.contentstack.com`, `au-launch-api.contentstack.com`, `azure-na-launch-api.contentstack.com`, `azure-eu-launch-api.contentstack.com`, `gcp-na-launch-api.contentstack.com`, `gcp-eu-launch-api.contentstack.com`). Authenticate with an OAuth bearer token (recommended) or `authtoken` plus `organization_uid`. The API is rate limited per organization. The `csdx launch` CLI commands cover deployments, logs, environment variables and local Cloud Function testing. Full limits are in [references/limits.md](references/limits.md). + +## MCP tools + +When the Contentstack MCP server is connected with the `launch` group, these tools act on Launch: + +- Inspect: `get_all_projects`, `get_a_project`, `get_all_environments`, `get_an_environment`, `get_environments`, `get_all_deployments`, `get_deployment`, `get_latest_live_deployment`, `get_deployment_logs`, `get_server_logs`, `get_deploy_hooks`, `get_signed_download_url_deployment` (`launch`) +- Change: `create_a_project`, `update_a_project`, `create_an_environment`, `update_an_environment`, `create_deployment`, `revalidate_cdn_cache`, `create_deploy_hook`, `update_deploy_hook`, `trigger_deploy_hook`, `get_signed_upload_url_project`, `get_signed_upload_url_environment`, `get_signed_upload_url_deployment` (`launch`) +- Delete: `delete_a_project`, `delete_an_environment`, `delete_deploy_hook` (`launch`) + +Use the read tools to check a real project's build settings, deployment status and logs before diagnosing. `update_an_environment` replaces build settings, variables and password protection together, so read the environment first and send the full object. There are no tools for domains, log targets or rollback; use the Launch UI or API. + +## Output + +Be concise and practical. Lead with the recommended approach, then config or code. Call out unsupported features and limits up front. Use placeholders for tokens and hostnames. + +## Security + +### Defaults + +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Never expose authtokens, OAuth tokens, deploy hook URLs or environment secrets. +- Only use public framework prefixes for values that are safe in the browser. +- Use environment variables for credentials in examples. + +### Destructive Actions + +Before deleting projects, environments, deploy hooks or domains, deploying, rolling back, updating an environment or revalidating the cache, name the project, environment and effect (for example, a production deployment or a full cache purge) and wait for confirmation. Treat production environments as needing explicit confirmation every time. + +### Secrets + +Never print or echo secret values, deploy hook URLs or password-protection credentials. Use placeholders. + +### Environment Variables + +Use placeholder names such as `CONTENTSTACK_LAUNCH_OAUTH_TOKEN`. Keep secrets in Launch environment variables, never in the repo or `launch.json`. + +## References + +- [launch.json reference](references/launch-json.md): redirect, rewrite and cache-priming syntax with examples. +- [Launch limits](references/limits.md): build, function, routing, variable and delivery limits. diff --git a/skills/launch-platform/references/launch-json.md b/skills/launch-platform/references/launch-json.md new file mode 100644 index 0000000..575b9d9 --- /dev/null +++ b/skills/launch-platform/references/launch-json.md @@ -0,0 +1,82 @@ +# launch.json reference + +`launch.json` sits at the repository root. Launch evaluates it at the edge before Edge Functions and the cache. + +Order of evaluation: + +1. `redirects`, top to bottom +2. `rewrites`, top to bottom +3. Edge Function (`functions/[proxy].edge.js`), if no rule matched +4. CDN cache lookup +5. Origin + +## Redirects + +Fields: `source`, `destination`, `statusCode` and optional `response.headers`. There is no `permanent` flag; use the status code. `301` and `308` are permanent, `302` and `307` temporary (`307` and `308` keep the HTTP method). The default is `308`. + +```json +{ + "redirects": [ + { + "source": "/old-blog/:slug", + "destination": "/blog/:slug", + "statusCode": 301, + "response": { + "headers": { "x-redirected-by": "launch" } + } + } + ] +} +``` + +## Rewrites + +Fields: `source`, `destination`, optional `request.headers` (added before the request reaches the destination) and `response.headers`. The browser URL does not change. + +```json +{ + "rewrites": [ + { + "source": "/api/partner/:path(.*)", + "destination": "https://api.partner.example.com/:path", + "response": { + "headers": { "cache-control": "no-store" } + } + } + ] +} +``` + +Don't put secrets in `request.headers`: `launch.json` is committed to the repository. Inject secrets from an Edge Function that reads environment variables instead. + +## Patterns + +Sources use `path-to-regexp` syntax: + +- Named parameter: `/blog/:slug` → `/posts/:slug` +- Constrained parameter: `/category/:name(shoes|bags)` +- Catch-all: `/old/:path(.*)`. There is no bare `*` wildcard. +- Exclusions: `/:path((?!blog|docs).+)` + +Rules run top to bottom, so put catch-all rules last. + +## Cache priming + +```json +{ + "cache": { + "cachePriming": { + "urls": ["/", "/blog", "/pricing"] + } + } +} +``` + +Launch requests these paths through the CDN after a deployment goes live. Up to 50 literal relative paths; no wildcards. + +## Rules of thumb + +- Sources are relative paths only, with no hostname. +- Escape a literal `?` as `\?`. Hash fragments (`#`) are not supported. +- Keep the file small (under about 200 KB). Move complex or data-driven routing into an Edge Function. +- Not supported in a monorepo sub-app; the file must be at the repository root. diff --git a/skills/launch-platform/references/limits.md b/skills/launch-platform/references/limits.md new file mode 100644 index 0000000..bff4f98 --- /dev/null +++ b/skills/launch-platform/references/limits.md @@ -0,0 +1,31 @@ +# Launch limits + +Defaults can change and some depend on the plan. Check the current Launch documentation before relying on a number. + +| Area | Limit | +| --- | --- | +| Build duration | 60 minutes, then the build fails | +| Node.js runtime | 20.x, 22.x, 24.x | +| Package managers | npm, yarn (node-modules mode), bun. Not pnpm or Yarn Plug'n'Play | +| Cloud Function memory | 1,024 MB | +| Cloud Function / SSR timeout | 30 seconds by default; can be raised per organization through Support | +| Writable file system | `/tmp` only, ephemeral | +| Edge Function memory | 128 MB | +| Edge Function bundle | 1 MiB minified | +| Edge Function startup | 400 ms for global scope | +| Request / response body | 5 MB | +| Environment variables | 128 per environment; total size is capped, and the cap is lower with Cloud Functions enabled | +| `launch.json` | Keep under about 200 KB; source and destination URLs up to 512 characters | +| Cache priming | 50 URLs per deployment | +| Cache revalidation | Daily quota depends on the plan | +| Custom domains | Plan-gated; needs a live deployment | +| Launch API | Rate limited per organization | + +## Not supported + +- Docker containers +- pnpm and Yarn Plug'n'Play +- Vue.js SSR (use Nuxt) +- Next.js App Router ISR and `revalidateTag()` (use the revalidation API) +- Cloud Functions, Gatsby and `launch.json` in a monorepo sub-app +- A built-in IP allowlist (use an Edge Function) diff --git a/skills/launch-sync-environment-variables-from-env-example/SKILL.md b/skills/launch-sync-environment-variables-from-env-example/SKILL.md index e078bcb..52edda2 100644 --- a/skills/launch-sync-environment-variables-from-env-example/SKILL.md +++ b/skills/launch-sync-environment-variables-from-env-example/SKILL.md @@ -1,6 +1,6 @@ --- name: launch-sync-environment-variables-from-env-example -description: "Fetch environment variables from a Contentstack Launch project, compare them with a local `.env.example` file, and patch the target environment to add any missing keys. Use when a Launch environment must match the keys defined in a local `.env.example` file." +description: "Fetch environment variables from a Contentstack Launch project, compare them with a local `.env.example` file, and update the target environment to add any missing keys. Use when a Launch environment must match the keys defined in a local `.env.example` file." argument-hint: "[project_uid] [environment_uid] [env_example_path]" disable-model-invocation: true allowed-tools: Read Grep Glob Bash @@ -10,109 +10,97 @@ agent: general-purpose # Sync Launch environment variables from .env.example -## Description +Fetch a Contentstack Launch environment's variables, compare them with a local `.env.example` file, and add any missing keys without changing any other environment setting. -Fetch environment variables from a Contentstack Launch project, compare them with a local `.env.example` file, and patch the target environment to add any missing keys. +## When to use -## When to Use +- A Launch environment must match the keys defined in a local `.env.example` file. +- Auditing missing environment variables before a deployment. +- Adding missing variable names to a Launch environment without editing the config by hand. -Use when a Launch environment must match the keys defined in a local `.env.example` file. -Use to audit missing environment variables before a deployment. -Use to add missing variable names to a Launch environment without manually editing config. +Use another skill for: -## User Problem +- General Launch hosting, build settings and environment variable limits → `launch-platform` +- Triggering a deployment and watching it → `launch-trigger-and-monitor-launch-deployments` +- Setting up the Contentstack MCP server → `dx-mcp-server` -A Launch environment can drift from the variables expected by a frontend project. This skill checks the environment against `.env.example` and updates Launch when keys are missing. +## Before you answer -## Success Criteria +Collect the Launch project UID, environment UID, the path to `.env.example`, the region, and how the user authenticates (OAuth token or authtoken plus organization UID). Ask whether to run as a dry run; default to one. -All keys present in `.env.example` exist in the target Launch environment. -Missing keys are added through the Launch Projects/Environments API. -The script reports what was missing and what was updated. -No secrets are printed in logs. +## Instructions -## Expected Inputs +1. Read and parse the local `.env.example` file. +2. Fetch the target Launch environment and its current variables. +3. Compare keys from the file against keys in Launch. +4. Append only the missing keys to the environment's `environmentVariables` array. +5. Send the full environment back with `PUT /projects/{project_uid}/environments/{environment_uid}`. +6. Report the changes and stop without exposing values. -- Launch project UID -- Launch environment UID -- Path to local `.env.example` file -- Launch API credentials or authenticated context -- Optional: dry-run flag -## Expected Outputs +### Parse input -- List of keys found in `.env.example` -- List of keys already present in Launch -- List of missing keys that were patched -- Summary of API calls made -- Exit code indicating success or failure +Read the local .env.example file and extract variable names. Ignore comments, blank lines, and malformed entries. -## Example User Requests +### Fetch Launch state -- Generate a Node.js script that syncs Launch environment variables from `.env.example`. -- Compare my Launch environment variables with `.env.example` and add any missing keys. -- Write a script to patch missing Launch environment variables for project abc123 and environment dev456. +Call `GET /projects/{project_uid}/environments/{environment_uid}` and keep the whole `environment` object. Its `environmentVariables` array holds `{ "key", "value" }` pairs. -## Workflow Summary +Use the regional base URL: `launch-api.contentstack.com` (AWS NA), `eu-launch-api.contentstack.com`, `au-launch-api.contentstack.com`, `azure-na-launch-api.contentstack.com`, `azure-eu-launch-api.contentstack.com`, `gcp-na-launch-api.contentstack.com` or `gcp-eu-launch-api.contentstack.com`. -Read and parse the local `.env.example` file. -Fetch the target Launch environment and its current variables. -Compare keys from the file against keys in Launch. -Build a minimal patch payload containing only missing keys. -Call PATCH /projects/{project_uid}/environments/{environment_uid}. -Report the changes and stop without exposing values. +Authenticate with `Authorization: Bearer <OAuth access token>` (recommended; scope `launch.projects:write` or `launch:manage`), or with the `authtoken` and `organization_uid` headers. `x-cs-api-version` is optional and defaults to `1.0`. Read credentials from environment variables. -## Instructions +### Compare keys -### Parse input +Compare .env.example keys against Launch keys. Identify only missing keys unless the user explicitly asks to update existing values. -Read the local .env.example file and extract variable names. Ignore comments, blank lines, and malformed entries. +### Update environment -### Fetch Launch state +There is no PATCH endpoint. Use `PUT /projects/{project_uid}/environments/{environment_uid}` and treat it as a full replacement: -Use the Launch API to get the target project and environment, then read the current environment variables. +1. Start from the environment object you fetched. +2. Append the missing keys to `environmentVariables` with empty or placeholder values. Leave existing entries untouched. +3. Send the whole object back, keeping every other field (`name`, `gitBranch`, `frameworkPreset`, `buildCommand`, `outputDirectory`, `autoDeployOnPush`, `passwordProtection` and the rest) exactly as fetched. -### Compare keys +Never send a body with only `environmentVariables`: settings you leave out can be reset. If the GET response masks existing values, stop and tell the user, because sending masked values back would overwrite the real ones. An environment holds at most 128 variables. -Compare .env.example keys against Launch keys. Identify only missing keys unless the user explicitly asks to update existing values. +### Report results -### Patch environment +Return a concise summary of missing keys, added keys, and any errors. Never print secret values or tokens. -Call PATCH /projects/{project_uid}/environments/{environment_uid} with the minimal update needed to add missing keys. +### API behaviour -### Report results +Validate the project and environment UIDs before updating. Change only the `environmentVariables` array, and only by adding missing keys. If the API returns validation errors, surface them without retrying blindly. + +## MCP tools -Return a concise summary of missing keys, patched keys, and any errors. Never print secret values or tokens. +If the Contentstack MCP server is connected with the `launch` group, use its tools instead of writing a script or calling the API with curl: -## Output Format +- Inspect: `get_all_projects`, `get_all_environments`, `get_an_environment` (`launch`) +- Change: `update_an_environment` (`launch`), which takes `project_uid`, `environment_uid` and the full `environment_data` object -Use concise, machine-readable summaries. -Do not print secret values from Launch or local files. -Show missing keys and updated keys separately. -Include the project UID and environment UID in the summary. -If running in dry-run mode, clearly label that no changes were made. +The same rules apply: fetch with `get_an_environment`, append only missing keys, send the whole object back, and stop if values come back masked. Confirm before calling `update_an_environment`, as below. -## Tooling Notes +## Output -Use the Launch API and Projects/Environments endpoints. -Validate project and environment UIDs before patching. -Avoid logging deployment tokens or environment secrets. -Use the smallest possible PATCH payload. -If the API returns validation errors, surface them without retrying blindly. +- Use concise, machine-readable summaries, with the project UID and environment UID. +- Show the keys found in `.env.example`, the keys already in Launch, and the missing keys added, separately, plus a summary of API calls and the exit status. +- Do not print secret values from Launch or local files. +- In dry-run mode, clearly label that no changes were made. ## Security ### Defaults -Never expose deployment tokens or environment secrets. -Validate project and environment targets before patching. -Do not print variable values in logs or output. -Require explicit user intent before making any change. -Prefer dry-run behavior unless the user asks to apply changes. +- Never expose deployment tokens or environment secrets. +- Validate project and environment targets before updating. +- Do not print variable values in logs or output. +- Require explicit user intent before making any change, and prefer dry-run behavior unless the user asks to apply changes. +- Require confirmation for production environments, and never auto-deploy to production without review. ### Destructive Actions -Treat any PATCH that changes Launch configuration as a destructive external action. Confirm the target project and environment before applying changes. Do not broaden the update beyond missing keys unless the user explicitly requests it. +Treat any PUT that changes Launch configuration, through the API or `update_an_environment`, as a destructive external action. Name the target project and environment and the keys to add, and wait for confirmation before applying changes. Do not broaden the update beyond missing keys unless the user explicitly requests it. ### Secrets @@ -121,14 +109,3 @@ Never reveal secret values from .env.example or Launch. Log only key names and c ### Environment Variables Read environment variables only as needed for authentication and target selection. Never echo env var values. Support loading from local `.env.example` for comparison only, not for secret disclosure. - -## Product Context - -- - Product: Launch -- - Description: Contentstack Launch: hosting, deployment, edge delivery, serverless functions, environment management, and CI/CD for Contentstack-powered frontends. -- - Product safety rules: - Never expose deployment tokens or environment secrets. -- Validate deployment targets before triggering. -- Require confirmation for production deployments. -- Never auto-deploy to production without review. -- - Default tools: ["Launch API", "Projects", "Environments", "Deployments", "Serverless Functions", "Edge Delivery", "Custom Domains"] -- - Default connectors: ["Launch Proxy", "GitHub", "CI/CD Pipelines"] \ No newline at end of file diff --git a/skills/launch-trigger-and-monitor-launch-deployments/SKILL.md b/skills/launch-trigger-and-monitor-launch-deployments/SKILL.md index 781d940..520c881 100644 --- a/skills/launch-trigger-and-monitor-launch-deployments/SKILL.md +++ b/skills/launch-trigger-and-monitor-launch-deployments/SKILL.md @@ -10,95 +10,89 @@ agent: general-purpose # Trigger and Monitor Launch Deployments -## Description +Trigger a Launch deployment for a specific environment, poll its status until it reaches a terminal state, and on failure fetch the deployment log and diagnose the likely cause. -Trigger a Launch deployment for a specific environment, then poll its status until completion. If the deployment fails or is cancelled, fetch the deployment log and diagnose likely causes with next-step recommendations. +## When to use -## When to Use +- Automating a Launch deployment for a known project and environment, in CI/CD or operator workflows. +- Watching a deployment until it finishes, with a deterministic exit status. +- Diagnosing a failed or cancelled deployment from its log. -Use when you need to automate Launch deployments for a known project and environment, monitor progress, and surface failure diagnostics. This is appropriate for CI/CD or operator workflows that need a deterministic deploy status check and log-based troubleshooting. +Use another skill for: -## User Problem +- Build settings, frameworks, functions, caching and other Launch configuration → `launch-platform` +- Matching a Launch environment's variables to `.env.example` → `launch-sync-environment-variables-from-env-example` +- Redeploying on CMS publish with webhooks → `cms-webhooks` -Users need a reliable way to start a deployment in Launch, track it to completion, and quickly understand why it failed if it does. The skill should reduce manual polling and make deployment failures actionable. +## Before you answer -## Success Criteria +Collect the `project_uid` and `environment_uid`, any deployment payload or build reference (commit hash or upload UID), the region and auth method, and any context about the app, branch or build source. Get explicit confirmation of the project and environment before every deployment, production or not. -Deployment is triggered against the intended project and environment. -Status is polled at a fixed interval until a terminal state is reached. -The process exits non-zero on failed or cancelled deployments. -If the deployment fails, the deployment log is retrieved and summarized with likely causes and next steps. -Every deployment requires explicit confirmation of the project and environment before it is triggered; production targets are additionally validated. - -## Expected Inputs - -- project_uid -- environment_uid -- Optional deployment payload or build reference -- Explicit confirmation before every deployment (production or not) -- Any available context about the app, branch, or build source - -## Expected Outputs - -- Deployment UID and initial trigger response -- Current status updates during polling -- Terminal status and exit code -- Deployment log summary when failures occur -- Recommended next steps and probable root cause +## Instructions -## Example User Requests +1. Validate the project and environment identifiers. +2. Confirm the target is allowed, then get explicit approval for this deployment before triggering it, whatever the environment. Validate production targets again. +3. Trigger the deployment with the Launch API. +4. Poll deployment status every 10 seconds until it reaches a terminal state. +5. If status is FAILED, CANCELLED or SKIPPED, fetch the deployment logs and analyze them. +6. Return a concise summary with status, log findings, and recommended next steps. -- Trigger a deployment for project abc123 in environment prod456 and watch it until it finishes. -- Deploy the latest build to staging and tell me if it fails. -- If the deployment fails, check the logs and explain what went wrong. -- Poll a Launch deployment every 10 seconds and exit non-zero on failure. -## Workflow Summary +### API basics -Validate the project and environment identifiers. -Confirm the target is allowed, then get explicit approval for this deployment before triggering it, whatever the environment. -Trigger the deployment with the Launch API. -Poll deployment status every 10 seconds until it reaches a terminal state. -If status is failed or cancelled, fetch the deployment log and analyze it. -Return a concise summary with status, log findings, and recommended next steps. +Use the regional base URL: `launch-api.contentstack.com` (AWS NA), `eu-launch-api.contentstack.com`, `au-launch-api.contentstack.com`, `azure-na-launch-api.contentstack.com`, `azure-eu-launch-api.contentstack.com`, `gcp-na-launch-api.contentstack.com` or `gcp-eu-launch-api.contentstack.com`. -## Instructions +Authenticate with `Authorization: Bearer <OAuth access token>` (recommended; scope `launch.projects:write` or `launch:manage`), or with the `authtoken` and `organization_uid` headers. `x-cs-api-version` is optional and defaults to `1.0`. Read credentials from environment variables. ### Trigger Deployment -Call POST /projects/{project_uid}/environments/{environment_uid}/deployments with the required payload. Validate the target environment before sending the request. +Call `POST /projects/{project_uid}/environments/{environment_uid}/deployments`. For a Git-connected project, pass `{ "commitHash": "<sha>" }` to deploy a specific commit. For a file-upload project, pass `{ "uploadUid": "<uid>" }`, or an empty body to redeploy the most recent upload. Validate the target environment before sending the request. ### Poll Status -Check deployment status every 10 seconds. Continue until the deployment reaches a terminal state or a failure condition is detected. +Call `GET /projects/{project_uid}/environments/{environment_uid}/deployments/{deployment_uid}` every 10 seconds and read `deployment.status`. This endpoint returns metadata only, not logs. + +| Status | Meaning | +|---|---| +| `QUEUED`, `DEPLOYING` | In progress. Keep polling. | +| `DEPLOYED` | Built but not yet live. Keep polling. | +| `LIVE` | Success. The deployment is serving traffic. | +| `ARCHIVED` | Replaced by a newer deployment. | +| `SKIPPED` | Superseded in the queue by a newer deployment. | +| `FAILED` | Build error, or the 60-minute build timeout. | +| `CANCELLED` | Cancelled by a user or by quota. | ### Fail Fast -Exit with a non-zero code if status becomes failed or cancelled. Do not continue polling after a terminal failure state. +Exit 0 on `LIVE`. Exit non-zero on `FAILED`, `CANCELLED` or `SKIPPED`, and stop polling. ### Fetch Logs on Failure -If the deployment fails, call GET /projects/{project_uid}/environments/{environment_uid}/deployments/{deployment_uid} and inspect the deployment log details. +Call `GET /projects/{project_uid}/environments/{environment_uid}/deployments/{deployment_uid}/logs/deployment-logs` for the build log. Each entry has `message`, `timestamp` and `stage`. For runtime errors after a deployment went live, use `.../logs/server-logs`. ### Diagnose and Recommend Summarize the most likely cause from the log, note any missing prerequisites or configuration issues, and recommend the next corrective action. -## Output Format +### Rollback + +To return to an earlier deployment, `POST /projects/{project_uid}/environments/{environment_uid}/deployments/rollback` with `{ "deployment": "<deployment_uid>" }`. The target must have `isRollbackEligible: true`. Rollback is a production change: get explicit confirmation first. -Return a concise deployment summary first. -Include deployment UID, environment UID, and final status. -On failure, include a short log-based diagnosis and next steps. -Do not expose deployment tokens, secrets, or environment variables. -Use a non-zero exit code for failed or cancelled deployments. +## MCP tools -## Tooling Notes +If the Contentstack MCP server is connected with the `launch` group, use its tools instead of curl: -Use the Launch API for deployment trigger and status checks. -Use the deployment detail/log endpoint for failure analysis. -Validate the target environment before deploying. -Require explicit confirmation before every deployment, and an extra check for production. -Never auto-deploy to production without review. +- Inspect: `get_all_environments`, `get_an_environment`, `get_all_deployments`, `get_deployment` (status polling), `get_latest_live_deployment`, `get_deployment_logs` (build log), `get_server_logs` (runtime log) (`launch`) +- Change: `create_deployment` (`launch`), which deploys the latest commit of the environment's configured branch; `trigger_deploy_hook` (`launch`) for an existing deploy hook + +`create_deployment` takes only the environment UID, so to deploy a specific commit or upload, or to roll back, use the API calls above. The confirmation gate applies to MCP calls exactly as to API calls. + +## Output + +- Return a concise deployment summary first: deployment UID, environment UID, the trigger response and final status, with status updates while polling. +- On failure, include a short log-based diagnosis with the probable root cause and next steps. +- Do not expose deployment tokens, secrets, or environment variables. +- Use a non-zero exit code for FAILED, CANCELLED or SKIPPED deployments. ## Security @@ -106,12 +100,12 @@ Never auto-deploy to production without review. - Never expose deployment tokens or environment secrets. - Validate deployment targets before triggering. -- Require explicit confirmation before every deployment. +- Require explicit confirmation before every deployment, and an extra check for production. - Never auto-deploy to production without review. ### Destructive Actions -Treat deployment triggers as external side effects. Require explicit user confirmation before triggering any deployment. Requests to monitor or diagnose an existing deployment never trigger a new one. Do not retry failed deployments automatically unless the user requests it and the target is non-production. +Treat deployment triggers, through the API or MCP tools, as external side effects. Name the project and environment and require explicit user confirmation before triggering any deployment or rollback. Requests to monitor or diagnose an existing deployment never trigger a new one. Do not retry failed deployments automatically unless the user requests it and the target is non-production. ### Secrets @@ -121,17 +115,6 @@ Never print, log, or echo API tokens, deployment tokens, or environment secrets. Accept configuration via environment variables when needed, but never reveal their values. Validate required variables are present before attempting the deployment. -## Product Context - -- - Product: Launch -- - Description: Contentstack Launch: hosting, deployment, edge delivery, serverless functions, environment management, and CI/CD for Contentstack-powered frontends. -- - Product safety rules: - Never expose deployment tokens or environment secrets. -- Validate deployment targets before triggering. -- Require explicit confirmation before every deployment. -- Never auto-deploy to production without review. -- - Default tools: ["Launch API", "Projects", "Environments", "Deployments", "Serverless Functions", "Edge Delivery", "Custom Domains"] -- - Default connectors: ["Launch Proxy", "GitHub", "CI/CD Pipelines"] - ## Examples ### Trigger and monitor a deployment (few shot *) @@ -140,8 +123,8 @@ Accept configuration via environment variables when needed, but never reveal the **Assistant:** 1. Validate the project and environment. 2. Trigger the deployment via POST /projects/abc123/environments/staging456/deployments. -3. Poll status every 10 seconds. -4. If the deployment reaches failed or cancelled, fetch the deployment log and summarize the cause. +3. Poll GET /projects/abc123/environments/staging456/deployments/{deployment_uid} every 10 seconds. +4. Stop on LIVE (success). On FAILED, CANCELLED or SKIPPED, fetch .../logs/deployment-logs and summarize the cause. 5. Return the final status and exit non-zero on failure. *Demonstrates trigger → poll → fail-fast → diagnose behavior.* diff --git a/skills/lytics/SKILL.md b/skills/lytics/SKILL.md new file mode 100644 index 0000000..73caf65 --- /dev/null +++ b/skills/lytics/SKILL.md @@ -0,0 +1,111 @@ +--- +name: lytics +description: "Advise developers on Lytics, Contentstack's customer data platform: Lytics projects in Contentstack, installing the JavaScript tag (JStag), sending events and identities, schema fields and mappings (and legacy LQL), identity resolution, audiences and SegmentQL, content affinity and recommendations, the REST API and Segment API, consent and identity deletion, and connecting Lytics audiences to Personalize. Use when developers ask how to install or debug the Lytics tag, send custom events, map data onto profiles, build or automate audiences, read a profile, import Contentstack entries into Lytics, delete user data, or make Lytics audiences available in Personalize. For experiences, variants and the Personalize Edge SDK, use personalize." +allowed-tools: Read Grep Glob +--- + +# Lytics + +Advise on Lytics, the customer data platform inside Contentstack: collecting events with the JavaScript tag and APIs, resolving them into unified profiles, building audiences, content affinity, managing data through the API, consent and deletion, and feeding audiences into Personalize. + +## When to use + +- Lytics projects, installing or debugging the JavaScript tag (JStag), sending events and identities. +- Schema fields, mappings and LQL, and identity resolution. +- Audiences, SegmentQL and the Segment API, and profile lookups. +- Importing Contentstack entries, content collections and recommendations. +- Consent, identity deletion, and connecting Lytics audiences to Personalize. + +Use another skill for: + +- Experiences, variants, attributes set through the Edge SDK, and edge middleware → `personalize` +- Entry variants in the CMS and how they're modeled → `cms-variants-personalization` +- Hosting the site and its tag on Launch → `launch-platform` + +## Before you answer + +Find out how the site is set up (Launch, tag manager or manual) and how consent is handled, the data sources (web, server, warehouse, Contentstack entries), the identity keys (email, user ID, anonymous cookie), the audience goals, and the symptoms when debugging. + +## Instructions + +1. Confirm the project exists and the tag is installed and sending. Get the tag verified before anything else. +2. Identify data sources and identity keys. +3. Map events to profile fields. +4. Build audiences in the UI or with SegmentQL. +5. Activate: connect Personalize, exports, recommendations. +6. Cover consent and deletion, and flag irreversible deletes. + + +### Projects + +In Contentstack, Lytics is set up as a Lytics project. The Lytics app calls the same thing an account. Creating a project provisions the account, generates the JavaScript tag snippet and opens a default data stream. Projects replace the deprecated Data Activation Layer. From the project you install the tag, connect a CMS stack, Launch project or Personalize project, and invite collaborators. Roles are per project: organization membership alone does not grant access. + +### JavaScript tag + +On Launch, connecting the Launch project deploys the tag for you. Otherwise paste the snippet from **Install Lytics** on the project dashboard (also under **Data Pipeline → SDK** in Lytics) as the first element in `<head>`, or load it through a tag manager to fit your consent setup. Verify that `jstag` exists in the browser console and that the network tab shows requests to `lytics.io/c` (collection) and `lytics.io/api/personalize`. + +Core calls: `jstag.send(payload)` sends key-value data to the default stream (pass a stream name to target another), `jstag.identify(payload)` is a semantic alias for sending identity, and `jstag.page()` / `jstag.pageView()` records a page view with page analysis. In single-page apps, call `jstag.page()` on route changes. The tag tracks anonymous visitors with a `_uid` cookie. Client-side integrations (GA4, Google Ad Manager, Meta, Contentstack Personalize and others) are opt-in checkboxes in the account's JavaScript tag settings. + +### Identity + +Profiles merge when events share an identity field value. Send a known identifier such as `email` or a user ID together with the anonymous `_uid` (for example on login) so the anonymous history joins the known profile. Identity keys have ranks that decide which wins when they conflict. + +### Schema, mappings and LQL + +Fields and mappings define how stream events become profile fields. Manage them in **Schema Studio** in the UI, which replaced hand-written LQL for day-to-day work. LQL (`SELECT … FROM <stream> INTO user BY <identity field>`) is still available through the API for bulk or automated changes. A stream with no mapping is collected but never reaches profiles. Changes that alter identity fields or field types can trigger a full reprocess of history; adding a field doesn't. + +### Audiences + +An audience is a live filter over profiles. Membership updates as profiles change, and it has no age-based expiry. Build audiences in the audience builder or in SegmentQL, for example `FILTER AND (visits > 5) FROM user`. Conditions on map fields must name a key (`conversion_ts.purchase > "now-7d"`), or the API returns 400. Turn on **Enable for Personalization** for audiences the site or Personalize needs to see. **Expires After** deletes the audience definition, not the profiles, so it is not a data-retention tool. + +Automate audiences with the Segment API: `GET/POST /v2/segment`, `GET/PUT/DELETE /v2/segment/{id}`, `POST /v2/segment/{id}/reevaluate` after schema changes, and `/v2/segment/group` for groups. + +### Personalize connection + +Connect the Personalize project under **Settings → General → Connections** in the Lytics project. After that, Lytics audiences are available as audiences in Personalize for targeting and A/B tests, with no export job. In the browser, the tag writes audience membership to the `cs-lytics-audiences` cookie, and the Personalize Edge SDK sends it to the edge as a live attribute. The tag has to run before the edge request for the audience to apply, so first-visit targeting depends on Personalize preset attributes instead. + +### Contentstack entries and recommendations + +Authorize Contentstack in Lytics (**Account → Authorizations**) with the region, stack API key, delivery token and management token, then create an **Import Entries** job for the content types and taxonomies to sync. Each imported taxonomy becomes a context layer that scores profiles on that taxonomy's values. Content collections scope which documents are eligible for recommendations; the default collection includes every classified page, so create a narrower collection for production content. Lytics crawls live URLs and cannot classify localhost. + +### API + +Base URL `https://api.lytics.io`. Send the access token in the `Authorization` header (a query-string `access_token` also works but leaks into logs). Create tokens under **Account → Security → Access Tokens** with only the roles needed and an expiry; the token is shown once. Read a profile with `/api/entity/user/{field}/{value}`; the public personalization endpoint `/api/me/...` only returns fields on the allowlist in the account's API settings. + +### Consent and deletion + +Collect consent as events with a consistent event name, a `consented` value, and optional date, location and document context, mapped onto the profile so audiences can include or exclude by consent. Delete a profile with `DELETE /v2/identity/{table}/{field}/{value}`, or submit batches with `POST /v2/identity/delete` and track them with `GET /v2/identity/delete/status/{requestId}`. Deletion is permanent and does not remove data already exported to downstream tools; handle those separately. + +## MCP tools + +When the Contentstack MCP server is connected with the `lytics` group (authenticated with a Lytics access token), these tools act on the Lytics account: + +- Inspect: `get_accounts`, `get_tables`, `get_fields`, `lytics_get_all_audiences`, `lytics_get_a_single_audience`, `get_field_information`, `get_a_user_profile`, `get_content_topics` (`lytics`) +- Change: `classify_content` (stores the classified URL in Lytics), `enrich_content` (`lytics`) + +There are no tools for creating audiences, changing schema, sending events or deleting identities; use the Segment API, Schema Studio, the tag or the Identity API as described above. `get_a_user_profile` returns personal data, so only look up a profile the user names. + +## Output + +Lead with the step that unblocks the user. Show tag calls, payloads, SegmentQL and API requests as code with placeholders. Use short checklists for installation and debugging. + +## Security + +### Defaults + +- Advisory by default. Use the MCP tools above only when the user asks; otherwise provide the calls and let the user run them. +- Lytics access tokens are server-side only. The tag snippet and account ID are public by design. +- Give tokens the fewest roles and an expiry. +- Respect consent: don't recommend collecting or activating data the user hasn't consented to. + +### Destructive Actions + +Identity deletion is permanent. Deleting a token or an audience breaks anything that depends on it. Explain the impact, name the exact profile, token or audience, and require explicit confirmation before recommending or running these calls. + +### Secrets + +Never echo access tokens, Contentstack management tokens or authtokens. Use placeholders and environment variables. + +### Environment Variables + +Use variables such as `LYTICS_API_TOKEN` and `LYTICS_ACCOUNT_ID` for server-side calls. Never hardcode tokens in client code. diff --git a/skills/marketplace-apps/SKILL.md b/skills/marketplace-apps/SKILL.md new file mode 100644 index 0000000..2ad66cb --- /dev/null +++ b/skills/marketplace-apps/SKILL.md @@ -0,0 +1,135 @@ +--- +name: marketplace-apps +description: "Help teams choose, install, configure and use first-party Contentstack Marketplace apps. Cover the app catalog by category (DAM, video, commerce and PIM, search, translation, AI, analytics and experimentation, forms, editor and JSON RTE utilities, stack tools), stack apps vs organization apps, who can install and the Request Install flow, app configuration vs per-field Config Parameter, multiple configurations, UI locations, app webhooks and branch scope, updating, uninstalling, authorized apps, how app data is stored in entries and read on delivery, and when to build a custom app instead. Use when someone asks which Marketplace app fits a need, how to install or configure Bynder, Cloudinary, Shopify, commercetools, Algolia, Trados and similar apps, why an app field is empty or not syncing, or how to read app field data in a frontend. To build your own app, use developer-hub-app-architect; for the Assets DAM product, use asset-management." +allowed-tools: Read Grep Glob +--- + +# Contentstack Marketplace apps + +Help teams pick the right first-party Marketplace app, install and configure it safely, and use the data it stores in entries. + +## When to use + +- Finding an app for a need: DAM, video, commerce, search, translation, AI, analytics, forms or editor tools. +- Installing an app, or getting it installed without admin rights. +- Configuring an app, including several configurations and per-field overrides. +- Apps whose field is empty, whose sync doesn't run, or whose UI location is missing. +- Reading app field data on the frontend. +- Updating, uninstalling or revoking an app. + +Use another skill for: + +- Building a custom or private app, UI locations in code, App SDK → `developer-hub-app-architect` +- The Contentstack Assets DAM product → `asset-management` +- The stack asset library → `cms-assets` +- Fetching entries and references → `cms-entries` or `dx-delivery-sdk` +- Rendering JSON RTE content that RTE plugins produce → `cms-json-rte` +- Locales and fallback (translation apps write localized entries) → `cms-localization` + +## Before you answer + +Find out the need and the third-party system the team already uses, whether the app is needed in one stack or the whole organization, and the user's role (organization or stack owner or admin, or not). + +## Instructions + +1. Match the need to an app, or recommend a custom app if none fits. +2. Check the install permissions. +3. Install it, configure it, and add its UI locations to content types. +4. Show how to read its data on delivery. + +### Choose an app + +Apps documented in the Marketplace docs, by category (check the Marketplace for the current list and for plan availability): + +- **DAM:** Bynder, Cloudinary, Aprimo, Brandfolder, Frontify, Digizuite, Egnyte, Amazon S3. +- **Video:** Brightcove, JW Player, Mux, Vimeo, YouTube. +- **Commerce and PIM:** Shopify, commercetools, BigCommerce, Salesforce Commerce, SAP Commerce Cloud, Elastic Path, Akeneo, plus the Spartacus Contentstack Connector for SAP storefronts. +- **Search and merchandising:** Algolia, Constructor. +- **Translation:** Trados, Wordbee, XTM. +- **AI:** AI Assistant, AI Assistant with Brand Kit, MonkeyLearn. +- **Analytics and experimentation:** Google Analytics, Optimizely, Audience Insights (Lytics data), ClearWinner (A/B test cleanup), and the Audience and Variables plugins. +- **Forms:** Form.io, Marketo Forms. +- **Editor fields and JSON RTE plugins:** Ace Editor, JSON Editor, Color Picker, Star Ratings, Table, Fonts, Highlight, Info Panel, Word Count, Progress Bar, Interstack Reference, Image Preset Builder. +- **Stack tools and dashboards:** Bulk Operations, Calendar, Workflow Board, Content Type Visualizer, Developer Tools, Healthcheck. + +The Marketplace also offers starters and importable content models. Recommend a custom app (`developer-hub-app-architect`) when no app covers the system, the data shape must differ from what the app stores, or the integration needs logic the app's configuration can't express. Extensions are no longer actively maintained; build new integrations as apps. + +### Install + +- **Stack apps** apply to one stack. Stack owners and admins can install them, and so can organization owners and admins who are members of that stack. +- **Organization apps** apply to the whole organization (SCIM provisioning, for example). Only organization owners and admins can install them, and they ask you to authorize module access (**Authorize & Install**). +- Developers and content managers see **Request Install** instead. Admins review requests under **Marketplace > Manage > App Requests**. + +Install from **Marketplace > Discover > Explore > Apps**: open the app, click **Install App**, choose the stack, then fill in the configuration page and **Save**. Most third-party apps need credentials from the other system first (API keys, client ID and secret, store or index names), so collect those before installing. + +### Configure + +- **App configuration** is set once per installation, under **Manage > Installed Apps > [app] > Installed On > Configuration**. +- **Multiple configurations:** several apps (Bynder, Shopify and others) support more than one account or store. Add them with **+ New Configuration** and mark one **Set as Default**. A configuration migrated from an older version is named `legacy_config`; don't delete it, because entries that used it can lose access to their data. +- **Per-field override:** when you add the app's custom field to a content type, **Advanced > Config Parameter** takes a JSON object that overrides the app configuration for that field, for example choosing which store or configuration it uses. Some apps also accept per-locale overrides there. +- **What gets saved:** apps like Shopify and Bynder let you save **All Fields** from the source system, or only selected keys (**Custom Fields**). Saving fewer keys keeps entries small; saving all fields limits how many items an entry can hold. +- **UI locations:** the Installed Apps page lists the app's locations (custom field, sidebar, dashboard, full page, JSON RTE plugin and so on). Toggle optional ones off there; **Required** ones can't be disabled. A custom field or RTE plugin only appears in entries after you add it to the content type. +- **Webhooks:** apps that sync data (Algolia, translation apps) use app webhooks. When branches are enabled, set **Branch Scope** to all branches or specific ones on the app's **Webhook** tab, and check **Webhook Logs** when a sync doesn't run. + +App-specific behaviour worth knowing: + +- **Algolia** indexes on publish, only for the environments in its configuration, and maps each content type to an index. Without a mapping, entries of that content type aren't indexed. When the webhook fires from a branch, the branch UID is appended to the Algolia `objectID`. +- **Trados** can convert JSON RTE fields to HTML for translators, and can include referenced assets. It doesn't translate Select, Number, Date, File, URL, Link, Taxonomy, Boolean or Custom fields. + +### Use app data on delivery + +A custom field app stores its value in the entry as JSON (or another declared data type), and the CDA, the Delivery SDK and GraphQL return it as-is under the field UID. In GraphQL, query a JSON custom field by name with no sub-selection. The shape belongs to the app and its "save" settings, so fetch one published entry and inspect it before writing types. DAM and commerce apps usually store IDs, URLs and selected metadata, not the files or live prices. Fetch live data such as stock or price from the source system at request time. + +### Update, uninstall and revoke + +- Apps with an update show a red dot under **Manage > Installed Apps**; **Update** keeps the configuration and lets you review it. +- **Uninstall** (type the app name to confirm) permanently removes the app and all its associated data from that stack. Plan for the content types and entries that use its fields first. +- **Manage > Authorized Apps** lists apps holding OAuth access on users' behalf. Users can revoke their own grants; organization admins can revoke anyone's. + +## MCP tools + +When the Contentstack MCP server is connected, the `developerhub` group works through the Developer Hub API on apps your organization owns: + +- Inspect: `get_all_apps`, `get_an_app`, `get_app_installations` (`developerhub`) +- Change: `install_an_app`, `update_an_app_installation` (`developerhub`) +- Delete: `uninstall_an_app` (`developerhub`) + +`get_all_apps` lists your organization's apps, so third-party listings such as Bynder or Shopify may not appear there; install those from the Marketplace UI. There are no tools for app configuration screens, per-field Config Parameter, app requests or authorized apps. To check stored app data, read an entry with `get_single_entry` (`cma`) or `get_a_single_entry_cdn` (`cda`), and `get_a_single_content_type` (`cma`) shows which fields use the app. + +## Output + +Lead with the recommended app (or "build a custom app") and why, then install steps for the user's role, the configuration that matters, and a delivery snippet or sample field shape. + +## Security + +### Defaults + +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Prefer the least-privileged credentials the third-party system offers (read-only keys where the app only reads). +- Install on a development stack or branch first when the app writes to entries or external systems. + +### Destructive Actions + +Before uninstalling an app, deleting a configuration (especially `legacy_config`), or changing a configuration other fields depend on, name the stack, app and affected content types, explain that stored app data and dependent fields can stop working, and wait for confirmation. + +### Secrets + +App configurations hold third-party credentials, and `get_app_installations` can return them. Never print, echo or store API keys, client secrets or tokens; refer to them by name. + +### Environment Variables + +In frontend examples that read app data, use `CONTENTSTACK_API_KEY`, `CONTENTSTACK_DELIVERY_TOKEN` and `CONTENTSTACK_ENVIRONMENT`. Keep third-party secrets (for example a commerce admin key) server-side under their own variables. + +## References + +- https://www.contentstack.com/docs/marketplace +- https://www.contentstack.com/docs/marketplace/about-marketplace +- https://www.contentstack.com/docs/marketplace/installing-apps +- https://www.contentstack.com/docs/marketplace/installed-apps +- https://www.contentstack.com/docs/marketplace/updating-an-installed-app +- https://www.contentstack.com/docs/marketplace/uninstalling-an-app +- https://www.contentstack.com/docs/marketplace/authorized-apps +- https://www.contentstack.com/docs/marketplace/app-requests +- https://www.contentstack.com/docs/marketplace/difference-between-marketplace-apps-and-extensions +- https://www.contentstack.com/docs/marketplace/faqs +- Per-app guides follow the pattern https://www.contentstack.com/docs/marketplace/<app>, for example `bynder`, `shopify`, `algolia`, `trados`. diff --git a/skills/migration-companion/SKILL.md b/skills/migration-companion/SKILL.md index 1b52a69..2fa187e 100644 --- a/skills/migration-companion/SKILL.md +++ b/skills/migration-companion/SKILL.md @@ -14,7 +14,21 @@ consumes** (the create command produces a populated stack and a bundle with cred which feeds the code migration). Treat the artifact paths and counts that each command prints as state you must capture and carry forward. -## Operating principles +## When to use + +- Migrating, moving, switching, porting or re-platforming to Contentstack from another CMS. Contentful is supported today. +- Content models, content, assets, locales, application integrations or website code that need to move. + +Use another skill for: + +- Upgrading Contentstack SDK code from JavaScript to TypeScript → `dx-migrate-js-to-ts-sdk` +- Moving content between Contentstack stacks or branches, or `csdx cm:stacks:migration` scripts → `dx-cli` +- Designing the target content model from scratch → `cms-data-modeling-best-practices` +- Converting HTML RTE to JSON RTE, or rendering JSON RTE after the migration → `cms-json-rte` + +## Instructions + +### Operating principles Follow these throughout — they matter more than any single command: @@ -94,7 +108,7 @@ Follow these throughout — they matter more than any single command: the user must run themselves (for example `contentful login` or a manual plugin install), and a template these instructions tell you to render verbatim (such as the Step 5 welcome message). -## The migration at a glance +### The migration at a glance | # | Step | Command (core) | Produces | |---|------|----------------|----------| @@ -124,7 +138,7 @@ only the one you need, when you reach it. --- -## Step 1 — Prerequisites & inputs +### Step 1 — Prerequisites & inputs > **[PROGRESS]** Output the migration progress block: > Step 1 → `"in_progress"`, Steps 2–4 → `"pending"`. @@ -147,7 +161,7 @@ Summary of sub-steps (full commands, messages, and tables are in the reference f - **1.6 — Contentful Space ID.** Auto-select a single space; otherwise present a numbered menu and wait. Capture `SPACE_ID`. -### Eval — Verify Step 1 before proceeding +#### Eval — Verify Step 1 before proceeding ```bash # Use the Node the checker validated (NODE_BIN_DIR from the prereq JSON). @@ -184,7 +198,7 @@ Then proceed to Step 2. If any check fails, fix the issue (re-run the relevant s --- -## Step 2 — Install the migrate CLI plugin +### Step 2 — Install the migrate CLI plugin > **[PROGRESS]** Output the migration progress block: > Step 1 → `"completed"`, Step 2 → `"in_progress"`, Steps 3–4 → `"pending"`. @@ -197,7 +211,7 @@ Summary: run the bundled install/update block, which installs or updates `PLUGIN_NPM_UNAVAILABLE`). On a failure marker, ask the user to install manually and wait for them to continue, then run the Eval. -### Eval — Verify Step 2 before proceeding +#### Eval — Verify Step 2 before proceeding ```bash PATH="<NODE_BIN_DIR>:$PATH" csdx migrate --help @@ -211,7 +225,7 @@ If `migrate:create` is present, proceed to Step 3 (its **[PROGRESS]** block mark --- -## Step 3 — Content Migration +### Step 3 — Content Migration > **[PROGRESS]** Output the migration progress block: > Steps 1–2 → `"completed"`, Step 3 → `"in_progress"`, Step 4 → `"pending"`. @@ -236,7 +250,7 @@ Summary of sub-steps (full commands, expected output, and parsing script are in - **3.4 — Show the user a progress summary** (entity counts + final stack box). - **Token expiry mid-run:** re-run `csdx auth:login --oauth` and restart from 3.1. -### Eval — Verify Step 3 before proceeding +#### Eval — Verify Step 3 before proceeding Confirm the key artifacts exist: @@ -272,7 +286,7 @@ Entries 53 53 If all pass, proceed to Step 4 (its **[PROGRESS]** block marks Step 3 ✅ and Step 4 ⏳). If counts diverge or artifacts are missing, surface the discrepancy and point the user at `<LOG_DIR>` — do not proceed until resolved. -### Session variables carried into Step 4 +#### Session variables carried into Step 4 | Variable | Value | Purpose | | --------------- | -------------------------------------- | -------------------------------------------------------- | @@ -287,7 +301,7 @@ point the user at `<LOG_DIR>` — do not proceed until resolved. --- -## Step 4 — Code Migration +### Step 4 — Code Migration > **[PROGRESS]** Output the migration progress block: > Steps 1–3 → `"completed"`, Step 4 → `"in_progress"`. @@ -311,7 +325,7 @@ Summary of sub-steps (full detail in the reference file): file) → MIGRATE → LIVE PREVIEW → VERIFY with `bash "<SKILL_DIR>/scripts/run-all.sh" "<repoPath>"`. Hard-gate eval failures mean the migration is NOT done. -### 4.5 — Guardrails +#### 4.5 — Guardrails - Do NOT modify content modeling or move/import entries — out of scope for this step. - Convert every reference dereference to safe array access (`?.[0]`) and audit null safety @@ -319,7 +333,7 @@ Summary of sub-steps (full detail in the reference file): - When a UID or behavior is uncertain, leave a `// TODO(migration):` comment and list it — never guess silently. -### 4.6 — Wrap up +#### 4.6 — Wrap up > **[PROGRESS]** Output the migration progress block: > Steps 1–4 all → `"completed"`. Then immediately proceed to Step 5. @@ -342,13 +356,22 @@ Give the user a final summary of the whole migration journey: --- -## Step 5 — Welcome to Contentstack 🎉 +### Step 5 — Welcome to Contentstack 🎉 The migration is complete. Read [references/step-5-welcome-message.md](references/step-5-welcome-message.md) and display that message to the user — render it exactly as shown there, preserving the section headings, icons, and line breaks, and filling the file-location table with the real paths captured during this session. +## MCP tools + +The migration runs on the Contentstack CLI and its migrate plugin, as the steps above describe; it doesn't need MCP. When the Contentstack MCP server is connected, its read tools are an optional way to verify the result in the new stack (local server group in brackets): + +- Inspect: `get_all_content_types`, `get_a_single_content_type`, `get_all_entries`, `get_all_assets`, `get_all_languages` (`cma`) +- Check delivery: `get_all_entries_cdn` (`cda`) + +Don't use MCP write or delete tools to patch migrated content mid-run; rerun the relevant step instead. + ## Security ### Defaults diff --git a/skills/personalize/SKILL.md b/skills/personalize/SKILL.md new file mode 100644 index 0000000..4f5ac8c --- /dev/null +++ b/skills/personalize/SKILL.md @@ -0,0 +1,139 @@ +--- +name: personalize +description: "Advise developers on Contentstack Personalize: projects, segmented and A/B test experiences, audiences, preset and custom attributes, impression and conversion events, priority, the Personalize Edge SDK and Edge API, the Management API, and edge middleware patterns that resolve variants before rendering. Use when developers ask how to set up Personalize, integrate the Edge SDK in Next.js, Launch Edge Functions, Vercel, Netlify or Cloudflare, track impressions or conversions, pass user attributes, manage experiences through the API, read experience analytics, or debug wrong or missing variants. For modeling and fetching entry variants in the CMS (variant groups, x-cs-variant-uid, layering), use cms-variants-personalization. For Lytics data collection and audience building, use lytics." +allowed-tools: Read Grep Glob +--- + +# Personalize + +Advise on Contentstack Personalize, the edge personalization engine: projects, experiences, audiences, attributes, events, the Personalize Edge SDK and Edge API, the Management API, and the request flow that turns a visitor into variant aliases for the Content Delivery API, without leaking per-user content into shared caches. + +## When to use + +- Setting up or integrating Personalize, including the Edge SDK in Next.js, Launch Edge Functions, Vercel, Netlify or Cloudflare. +- Choosing between segmented and A/B test experiences, and defining audiences, attributes and priority. +- Tracking impressions and conversions, and reading experience analytics. +- Automating experiences through the Management API. +- Debugging a visitor who sees the wrong or missing variant. + +Use another skill for: + +- Linking variant groups to content types, creating entry variants, `x-cs-variant-uid` and variant layering → `cms-variants-personalization` +- The Lytics tag, schema and audience building → `lytics` +- Launch Edge Functions and hosting in general → `launch-platform` +- Delivery SDK queries outside the variant flow → `dx-delivery-sdk` + +## Before you answer + +Find out the framework and hosting (Next.js, Launch, Vercel, Netlify, Cloudflare, other), the rendering mode (SSR, SSG, CSR), the project region, the experience goal (segmented targeting or A/B test), the attributes and audiences involved, and the symptoms when debugging. + +## Instructions + +1. Confirm the stack, hosting, rendering mode and region. +2. Lay out the flow: edge decision → variant aliases → CDA fetch → impressions and conversions. +3. Recommend experience type, audiences, attributes and priority. +4. Provide SDK or API code for the user's runtime, using the real Edge SDK API and the correct regional hosts. +5. Cover caching, cookies, attribute registration and tracking before they cause bugs. +6. Debug in order: manifest, aliases, CDA request, entry variants, cache. + + +### Concepts + +A Personalize project connects to one CMS stack. Each experience in the project syncs to the stack as a variant group, and each of its variants maps to a CMS variant. Experiences come in two types: segmented experiences show a variant to visitors who match its audience, and A/B test experiences split traffic across variants (equal split, custom percentages, or Multi-Armed Bandit, which shifts traffic toward better performers). Within an experience only one variant is active per visitor: the first match in the variant order wins. Across experiences, variants that target different content layer together; when two experiences target the same content, the higher-priority experience wins. Experience tags (free-form strings such as `env:production`) group experiences and can limit which ones are evaluated at runtime. + +### Audiences and attributes + +Audiences are rules over attributes. Preset attributes are always available and cannot be edited: City, Country, Region, Date and Time, Device Type, Operating System, Query Parameter and Referrer. Custom attributes must be created in the project before they can be used; audiences can only use keys that exist in the project. Set custom attributes with the Edge SDK or Edge API, or through Google Tag Manager or a CDP integration. Attributes passed at `init` as `liveAttributes` apply to the current request only and are not stored on the profile; attributes set with `set()` are stored and may take up to a second to apply. + +Personalize audiences are evaluated at the edge on the first request; membership is not stored, so they have no analytics. Lytics audiences come from a connected Lytics project, carry unified customer data, and do support analytics. + +### Edge SDK + +Install `@contentstack/personalize-edge-sdk`. Call `Personalize.setEdgeApiUrl()` before `init` when the project is outside AWS NA. Regional Edge API hosts: `personalize-edge.contentstack.com` (AWS NA), `eu-personalize-edge`, `au-personalize-edge`, `azure-na-personalize-edge`, `azure-eu-personalize-edge`, `gcp-na-personalize-edge`, `gcp-eu-personalize-edge` (all `.contentstack.com`). + +`await Personalize.init(projectUid, options)` fetches the visitor's manifest and returns an SDK instance. Options: `request` (the incoming Web `Request`, used at the edge to read cookies and derive preset attributes), `userId`, `liveAttributes`, `tags` (up to 10, OR match), `customVariantQueryParam`, and `lyticsIdField` / `lyticsIdValue`. Instance methods: `getVariantAliases()`, `getVariantParam()`, `variantParamToVariantAliases()`, `getVariants()`, `getActiveVariant(experienceShortUid)`, `getExperiences()`, `set(attributes)`, `setUserId(userId, { preserveUserAttributes })`, `triggerImpression(experienceShortUid)`, `triggerImpressions({ experienceShortUids | aliases })`, `triggerEvent(eventKey)` and `addStateToResponse(response)`. The static helpers on `Personalize` other than `init`, `setEdgeApiUrl`, `variantParamToVariantAliases` and `getInitializationStatus` are deprecated; use the instance methods. + +### Request flow + +Resolve variants before rendering: + +1. In an edge function or middleware, `init` with the incoming `request`. +2. Read `getVariantParam()` (a compact string such as `a_0,b_1`) and rewrite the request URL with it under `Personalize.VARIANT_QUERY_PARAM`, so the visitor's URL doesn't change. +3. Call `addStateToResponse(response)` so the SDK's user and manifest cookies persist. The browser SDK then initializes from the cookie without another manifest call. +4. On the server, convert the param with `variantParamToVariantAliases()` and pass the aliases to the Delivery SDK (`.variants(aliases)`) or the CDA. With no variants, fetch the base entry. + +On Launch, use an Edge Function (`functions/[proxy].edge.js`) for this step, not Next.js middleware, because Next.js middleware runs at the origin on Launch. See [references/edge-integration.md](references/edge-integration.md) for a worked example. + +Browser-only (CSR) integrations can `init` without `request` and fetch variants client-side, at the cost of a content flash. + +### Events and analytics + +Impressions record that a visitor saw a variant and are counted once per visitor. Fire `triggerImpression` after the personalized content renders, once per experience, not on every re-render. Conversions are events created in the project with a key; fire them with `triggerEvent(eventKey)`. A/B test analytics compare variants by conversions; Personalize audiences have no analytics. The Management API exposes experience analytics as a summary and as a time series. + +### Identity + +The SDK generates an anonymous user ID at the edge. When a visitor logs in, call `setUserId(id, { preserveUserAttributes: true })` to carry their attributes over to the known ID. + +### Management API + +Use it to automate project configuration: attributes, audiences, events, experiences, experience versions, experience priority, analytics and geolocation lookups. Regional hosts: `personalize-api.contentstack.com` (AWS NA), `eu-personalize-api`, `au-personalize-api`, `azure-na-personalize-api`, `azure-eu-personalize-api`, `gcp-na-personalize-api`, `gcp-eu-personalize-api` (all `.contentstack.com`); the OpenAPI spec is at `/openapi` on the NA host. Authenticate with OAuth (`authorization` header, scopes `personalize:read` or `personalize:manage`, recommended) or an `authtoken`, plus `x-project-uid` for project resources. The limit is 10 requests per second per organization; back off on 429. The Edge API, by contrast, needs no authentication because it runs on public sites, and takes the project in `x-project-uid` and the visitor in `x-cs-personalize-user-uid`. + +### Caching + +A personalized response must never be served from a shared cache to another visitor. Render personalized routes per request (SSR), keep the variant param in the cache key when caching at the CDN, set `cache-control: no-store` on the browser response from the edge function, and prefer `must-revalidate` over `stale-while-revalidate` for personalized pages. Static (SSG) pages can only be personalized at the edge or in the browser. + +### Pitfalls + +- Edge middleware resolves variants but does not track. Impressions and conversions still need browser code. +- A/B bucketing relies on the SDK's user cookie. Forcing it to `SameSite=Strict` (for example through a consent tool) drops it on cross-site navigation, so returning visitors can land in a different variant. +- On runtimes that reuse isolates between requests, create a fresh SDK instance per request with `init`; never keep one at module scope. +- Lytics audience membership arrives in a cookie written by the Lytics tag, so it is missing on a visitor's very first request. + +### Debugging + +Work through the chain in order: + +1. **Manifest:** does `getExperiences()` show the experience with an active variant? If not, check that the experience is active, the audience rules match (including custom attributes registered in the project), and the region host is right. +2. **Aliases:** does the server receive the variant param and turn it into aliases? +3. **CDA:** does the delivery request carry the aliases? +4. **CMS:** does the entry have an entry variant for that variant, is the variant group linked to the content type, and is the variant published? (see `cms-variants-personalization`) +5. **Cache:** is a cached base response being served? + +## MCP tools + +When the Contentstack MCP server is connected with the `personalize` group (it needs the Personalize project ID), these tools act on the project: + +- Inspect: `get_all_experiences`, `get_single_experience`, `get_experience_versions`, `get_experiences_priority`, `get_all_audiences`, `get_all_attributes`, `get_all_events`, `get_analytics_summary`, `get_analytics_timeseries`, `get_countries`, `get_regions`, `get_cities` (`personalize`) +- Change: `create_experience`, `update_experience`, `update_experiences_priority`, `create_attribute`, `update_attribute`, `create_event`, `update_event` (`personalize`) +- Delete: `delete_experience`, `delete_experience_version` (drafts only), `delete_audience`, `delete_attribute`, `delete_event` (`personalize`) + +There is no tool for creating audiences; use the Personalize UI or the Management API. For the CMS side, `get_all_variants_of_a_content_type`, `get_all_variants_of_an_entry`, `create_an_entry_variant` and `publish_variants_of_an_entry` (`cma`) cover entry variants. When debugging, read the experience, its audiences and its versions with the inspect tools before changing anything. + +## Output + +Lead with the request flow or the failing step. Give runnable TypeScript or JavaScript for the user's runtime, with credentials and project UIDs from environment variables. Use short checklists for setup and debugging. + +## Security + +### Defaults + +- Advisory by default. Use the MCP tools above only when the user asks for the change. +- Never expose authtokens or OAuth tokens. The Management API is server-side only. +- The Edge API and the project UID are safe in browser code; Management API credentials are not. +- Keep personalized responses out of shared caches, and never cache them without the variant in the cache key. + +### Destructive Actions + +Before deleting or pausing experiences, audiences, attributes or events, or changing experience priority, name the project and the items affected, explain the impact, and wait for confirmation. Pausing an experience stops delivery of its variants; deleting one unlinks its variant group in the CMS but leaves the group and its entry variants in place. + +### Secrets + +Never echo authtokens, OAuth tokens or delivery tokens. Use placeholders and environment variables. + +### Environment Variables + +Use variables such as `CONTENTSTACK_PERSONALIZE_PROJECT_UID`, `CONTENTSTACK_PERSONALIZE_EDGE_API_URL`, `CONTENTSTACK_API_KEY` and `CONTENTSTACK_DELIVERY_TOKEN`. Keep authtokens and OAuth tokens server-side. + +## References + +- [Edge integration example](references/edge-integration.md): a worked edge-function integration that resolves variants before rendering. diff --git a/skills/personalize/references/edge-integration.md b/skills/personalize/references/edge-integration.md new file mode 100644 index 0000000..e430524 --- /dev/null +++ b/skills/personalize/references/edge-integration.md @@ -0,0 +1,104 @@ +# Edge integration example (Next.js on Launch) + +A minimal pattern based on the public "Set up a Next.js website with Personalize on Launch" guide, with its syntax errors fixed. Adapt the routing and data fetching to the user's app. + +## 1. Edge function: `functions/[proxy].edge.js` + +```js +import Personalize from '@contentstack/personalize-edge-sdk'; + +export default async function handler(request, context) { + const parsedUrl = new URL(request.url); + const { pathname } = parsedUrl; + + // Pass static assets straight through. + if (['_next', 'favicon.ico'].some((path) => pathname.includes(path))) { + return fetch(request); + } + + // Only needed outside AWS NA. + if (context.env.CONTENTSTACK_PERSONALIZE_EDGE_API_URL) { + Personalize.setEdgeApiUrl(context.env.CONTENTSTACK_PERSONALIZE_EDGE_API_URL); + } + + const personalizeSdk = await Personalize.init( + context.env.CONTENTSTACK_PERSONALIZE_PROJECT_UID, + { request } + ); + + // Rewrite the origin request with the variant param; the visitor's URL is unchanged. + const variantParam = personalizeSdk.getVariantParam(); + parsedUrl.searchParams.set(Personalize.VARIANT_QUERY_PARAM, variantParam); + + const response = await fetch(new Request(parsedUrl.toString(), request)); + const modifiedResponse = new Response(response.body, response); + + // Persist the user and manifest cookies, and keep the browser from caching this response. + personalizeSdk.addStateToResponse(modifiedResponse); + modifiedResponse.headers.set('cache-control', 'no-store'); + + return modifiedResponse; +} +``` + +On Vercel, Netlify or Cloudflare the same steps run in that platform's middleware or edge function: `init` with the request, rewrite with the variant param, `addStateToResponse`, return. + +## 2. Server: turn the param into aliases and fetch variants + +```ts +import Personalize from '@contentstack/personalize-edge-sdk'; +import { stack } from '@/lib/contentstack'; + +export default async function Page({ searchParams }: { searchParams: Promise<Record<string, string | undefined>> }) { + const params = await searchParams; + const variantParam = params[Personalize.VARIANT_QUERY_PARAM]; + + const entryCall = stack.contentType('home_page').entry(process.env.HOME_ENTRY_UID!); + const entry = variantParam + ? await entryCall + .variants(Personalize.variantParamToVariantAliases(decodeURIComponent(variantParam)).join(',')) + .fetch() + : await entryCall.fetch(); + + // render entry +} +``` + +The route must render per request (SSR). A statically generated page can't see the variant param. + +## 3. Browser: attributes, impressions, conversions + +Initialize once in a client provider. Because the edge function stored the manifest in a cookie, `init` in the browser does not refetch it. + +```tsx +'use client'; +import { createContext, useContext, useEffect, useState } from 'react'; +import Personalize from '@contentstack/personalize-edge-sdk'; + +type Sdk = Awaited<ReturnType<typeof Personalize.init>>; +const PersonalizeContext = createContext<Sdk | null>(null); +export const usePersonalize = () => useContext(PersonalizeContext); + +export function PersonalizeProvider({ children }: { children: React.ReactNode }) { + const [sdk, setSdk] = useState<Sdk | null>(null); + useEffect(() => { + Personalize.init(process.env.NEXT_PUBLIC_CONTENTSTACK_PERSONALIZE_PROJECT_UID!).then(setSdk); + }, []); + return <PersonalizeContext.Provider value={sdk}>{children}</PersonalizeContext.Provider>; +} +``` + +```tsx +const sdk = usePersonalize(); + +// Once, after the personalized block renders. +useEffect(() => { + if (sdk) void sdk.triggerImpression(EXPERIENCE_SHORT_UID); +}, [sdk]); + +// On a conversion. The event key must exist in the project. +const onClick = () => sdk?.triggerEvent('learnMoreClicked'); + +// Store a custom attribute. The attribute must exist in the project. +await sdk?.set({ age: 32 }); +``` diff --git a/skills/studio/SKILL.md b/skills/studio/SKILL.md index 51b23f5..82dc995 100644 --- a/skills/studio/SKILL.md +++ b/skills/studio/SKILL.md @@ -9,7 +9,22 @@ You are working on Contentstack Studio. The pack has one specialist skill per ta This SKILL.md is the only file loaded up front. Everything else is routed through `skills-index.md`. -## Resolving a skill file +## When to use + +- Anything that mentions Contentstack Studio or its concepts: the Studio SDK, canvas, compositions, Connected or Freeform templates, sections, section slots, repeaters, registering components, BYOC, Studio preview routes, or making a project Studio-ready. + +Use another skill for: + +- Live Preview or Visual Editor problems that don't involve Studio → `cms-live-preview-visual-editor-support-assistant` +- Delivery SDK code outside Studio → `dx-delivery-sdk` +- Content model design in general → `cms-data-modeling-best-practices` +- Rendering JSON RTE fields → `cms-json-rte` +- Hosting the site on Launch → `launch-platform` +- General MCP setup outside a Studio project → `dx-mcp-server` + +## Instructions + +### Resolving a skill file The specialist guides sit next to this file, in the same folder: a skill named `<name>` is `<name>.md` beside this SKILL.md, and the lookup table is `skills-index.md` in the same folder. Every cross-reference in this file and in `skills-index.md` is written as `<name>` or `<name>.md`. Resolve all of them this way. @@ -17,7 +32,7 @@ Fallback: if `<name>.md` isn't there, try `../<name>/SKILL.md` (a host that inst **If neither resolves, say so out loud**: "the Studio skill pack looks mis-installed, `<name>` didn't resolve", and do NOT quietly fall back to general knowledge. A silent fallback looks identical to the pack working, so the user never learns their install is broken. -## What to do +### What to do **Setup intent takes precedence over keyword matching.** “Enable Studio”, “make this project Studio ready”, “Studio setup”, and equivalent whole-app requests run `convert-project-to-studio` through verification. `install-studio` alone is for an explicit SDK-only request. Preserve the active setup objective across replies such as “yes”, “start”, and “OAuth done”; resume the pending step rather than routing that reply as a new task. Use the orchestrator's scoped completion checklist; authoring requirements below apply only when components or compositions are authored. @@ -31,7 +46,7 @@ Fallback: if `<name>.md` isn't there, try `../<name>/SKILL.md` (a host that inst 4. If nothing matches after both passes, answer from general Studio knowledge, but say so, and check whether a skill is missing that should exist. -## Standing rule: atomic and reusable, every time +### Standing rule: atomic and reusable, every time **This applies on every Studio turn, whatever the user asked for. It is not optional and it is not only a planning concern.** @@ -52,13 +67,13 @@ Before creating, registering, or authoring anything: If the user's request would skip this ("just register the page component", "make the whole page one section"), say what it costs (nothing reusable, authors can't reorder, bindings break) and propose the decomposed shape instead. Do it their way only if they confirm after hearing that. -## Standing rule: definition of done +### Standing rule: definition of done **Also every Studio turn.** Ten deliverables decide whether what you built is usable by a marketer rather than only by a developer. They are listed once, with owners and checks, in [`complete-the-build`](complete-the-build.md). Every one fails silently: the page still renders, nothing errors, and the gap surfaces only when a non-developer opens Studio. Read that list before you plan, and again before you report done. State the ten in the plan up front, so what the user approves is what they get. Never report a build done with any of them outstanding: say "created, thumbnail pending" and then finish it. -## Standing rule: auth preflight +### Standing rule: auth preflight **Settle the credential before the first API call of the turn, not when one fails.** Every specialist repeats this. It lives here because it must hold even before a specialist is pulled. @@ -68,7 +83,7 @@ Read that list before you plan, and again before you report done. State the ten 4. If nothing resolves, or a refresh returns `400 invalid_refresh_token`, hand the user `! CONTENTSTACK_REGION=<code> npx @contentstack/mcp --auth` and wait. It needs a TTY and a browser, you cannot run it for them. The region must be **in** the command. `DEFAULT_REGION` is `NA`, so omitting it silently authenticates against NA prod. 5. `403 error_code 316` is **not** an auth failure. It is a valid credential aimed at a stack outside its org. Re-authenticating fixes nothing. Check with `GET /v3/stacks` + `organization_uid`. -## Rules +### Rules - Always re-Read the skill file. Never answer from a remembered summary. The source of truth is the file on disk. - **A failed Read is a hard stop, not a shrug.** If a skill file won't resolve (see § Resolving a skill file), report it. Improvising over a broken install is worse than erroring: the user believes the pack ran when it didn't. @@ -76,17 +91,28 @@ Read that list before you plan, and again before you report done. State the ten - If the user's request implies multiple skills (e.g. "install and set up preview routes"), pull each in the order they must run: skills-index.md's Trigger table encodes that ordering. - Prerequisite skills: many authoring skills assume `install-studio` + `configure-studio` are done. If the user's project state is unclear, run `analyze-project-fit` first. +## MCP tools + +Studio is MCP-first for the operations the server supports. [`install-contentstack-mcp`](install-contentstack-mcp.md) covers discovering, installing and verifying the server, and [`understand-contentstack-mcp`](understand-contentstack-mcp.md) covers what it does and doesn't do. Common tools (local server group in brackets): + +- Inspect: `get_all_content_types`, `get_a_single_content_type`, `get_all_entries`, `get_single_entry`, `get_all_environments`, `get_all_languages` (`cma`) +- Change: `create_a_content_type`, `update_content_type`, `create_an_entry`, `update_an_entry`, `publish_an_entry` (`cma`) +- Delete: `delete_an_entry`, `delete_content_type` (`cma`) + +The server doesn't cover every Studio operation: the Studio API project list and configuration (`/v1/projects`) and some token and Live Preview operations need OAuth HTTP or the Studio UI. Use only tools the host actually lists, and never claim an MCP call ran when none did. + ## Security ### Defaults +- Use MCP tools only for the Studio work the user asked for, and verify the target stack with a read call first. - Resolve credentials OAuth-first (see § Standing rule: auth preflight). Ask before reading or refreshing another tool's stored OAuth session. - Delivery and preview tokens may reach the browser; management tokens, OAuth tokens and session authtokens never do. - Never disable TLS certificate or hostname verification, and never ship permissive frame headers (`frame-ancestors *`, `Access-Control-Allow-Origin: *`) outside local development or the canvas route. ### Destructive Actions -Creating or changing stacks, content types, entries, compositions or Studio projects is a real mutation. State what will change and get confirmation first. Never delete or overwrite existing content, sections or templates without explicit approval. +Creating or changing stacks, content types, entries, compositions or Studio projects is a real mutation. Name the stack, branch and items, state what will change, and get confirmation first. This applies to MCP tool calls and OAuth HTTP calls alike. Never delete or overwrite existing content, sections or templates without explicit approval. ### Secrets