Create and manage content entries for existing Contentrain models. Use when adding entries to collections, populating singletons, writing documents, or managing dictionary keys.
Installs into .claude/skills of the current project.
Are you the author of Contentrain Content?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/contentrain-contentrain-content)
---
name: contentrain-content
description: "Create and manage content entries for existing Contentrain models. Use when adding entries to collections, populating singletons, writing documents, or managing dictionary keys."
metadata:
author: Contentrain
version: "1.0.0"
---
# Skill: Create Content for Existing Models
> Generate and save content entries for models already defined in the project.
---
## When to Use
The user wants to create new content, add entries to a collection, populate a singleton, or says something like "add a blog post", "create content", "fill in the hero section".
---
## MUST Rules
- MUST call `contentrain_describe` before writing content (know the schema)
- MUST provide ALL required fields in entries
- MUST create entries for ALL supported locales when model has `i18n: true`
- MUST NOT set system fields (id, slug, createdAt, updatedAt, status, source)
- MUST run `npx contentrain generate` after adding new models or changing fields
---
## Steps
### 1. Check Project State
Call `contentrain_status` to get the full project context:
- Confirm the project is initialized.
- List available models, their kinds, domains, and field counts.
- Note supported locales and the source locale.
- Check for any pending changes or validation errors.
If `.contentrain/` does not exist, stop and suggest running `/contentrain-init` first.
### 2. Identify the Target Model
If the user specified a model, use it. Otherwise:
- Present the list of available models from status.
- Ask the user which model to create content for.
- If the user describes content without naming a model (e.g., "write a blog post about X"), infer the model from context.
### 3. Read the Model Definition
Call `contentrain_describe(model: "<model-id>", include_sample: true)` to get:
- All field definitions (name, type, required, constraints).
- A sample entry if one exists (use it as a structural reference).
- Relation fields and their target models.
If the user's request does not match an existing model, offer to create one first with `contentrain_model_save`.
### 4. Read Vocabulary and Context
- Check `.contentrain/vocabulary.json` for canonical terms. All content must use these terms consistently across locales. Do not use alternative spellings or synonyms for vocabulary-defined terms.
- Check `.contentrain/context.json` for tone conventions (professional, casual, technical).
- **For dictionaries:** Before creating any new key, call `contentrain_content_list` on the target model and scan existing values. If the value you intend to write already exists under a different key, REUSE the existing key instead of creating a new one. MCP will also warn you via `advisories` in the save response if duplicates are detected. Replacing an existing key's value is allowed — the response reports what was replaced, so read the advisories rather than assuming a save was purely additive.
### 5. Generate Content
Create content following the rules in `content-quality.md`:
- **Required fields:** Every required field must have a real, non-placeholder value.
- **Field constraints:** Respect `min`, `max`, `pattern`, and `options` constraints.
- **Unique fields:** Verify `unique` field values do not collide with existing entries.
- **Tone:** Match the tone defined in `.contentrain/context.json` → `conventions.tone`.
- **Vocabulary:** Use terms from `.contentrain/vocabulary.json` if it exists.
- **Content patterns:** Follow the appropriate content type pattern (blog post, landing page, documentation, etc.) from `content-quality.md` Section 3.
- **Consistency:** If existing entries exist, read 2-3 via `contentrain_content_list` to match the established style and structure.
**Relation integrity:** For `relation` and `relations` fields, verify referenced entries exist by calling `contentrain_content_list` on the target model.
### 6. Apply SEO Rules
For fields that affect SEO (from `seo-rules.md`):
- **Title:** 50-60 characters optimal, max 70. Primary keyword in the first 30 characters.
- **Slug:** Lowercase, hyphen-separated, 3-5 words, no stop words.
- **Description/excerpt:** 120-160 characters, complete sentence, summarizes value.
- **Alt text:** Descriptive, includes context, under 125 characters.
- **Heading hierarchy:** In markdown/richtext content: h1 → h2 → h3 (no skips).
### 7. Present Draft for Approval
Show the user the content draft before writing. Include:
- The model name and kind.
- The content for each locale (if i18n).
- Any relations being set.
- A summary of which quality rules were applied.
Wait for user confirmation before proceeding.
### 8. Save Content
Call `contentrain_content_save` with the approved content. The tool takes `model` and an `entries` array:
```json
contentrain_content_save({
"model": "<model-id>",
"entries": [
{ "locale": "en", "data": { "field": "value" } }
]
})
```
**Kind-specific entry format:**
- **singleton:** `{ "locale": "en", "data": { "title": "My Site", "cta": "Get Started" } }` -- no `id` or `slug`.
- **collection:** `{ "id": "optional-id", "locale": "en", "data": { "name": "John", "role": "CEO" } }` -- omit `id` to auto-generate, provide `id` to update.
- **document:** `{ "slug": "getting-started", "locale": "en", "data": { "title": "Getting Started", "body": "# Welcome\n..." } }` -- `slug` is required, use `"body"` key for markdown content.
- **dictionary:** `{ "locale": "en", "data": { "auth.login": "Log In", "auth.logout": "Log Out" } }` -- flat key-value pairs, no `id` or `slug`.
**Critical rules:**
- NEVER include system fields (`status`, `source`, `updated_by`, `approved_by`) in `data`. These are managed in meta files, not content. Temporal data (created/updated timestamps) comes from git history.
- Prefer batch mode -- send multiple entries in a single call when possible.
- Locale defaults to the project's default locale if omitted, but explicit locale is recommended.
### 9. Review Save Advisories
After `contentrain_content_save`, check the response for an `advisories` field. If present:
- Review each advisory for duplicate value warnings.
- If a duplicate is flagged, consider whether to:
- Remove the new key and reuse the existing one instead.
- Keep both keys if they serve semantically different purposes (document the reason).
- Report any advisories to the user for their decision.
### 10. Handle i18n Completeness
If the project has multiple supported locales and the model has `i18n: true`:
- Ask the user if they want translations created now.
- If yes, generate translations following `i18n-quality.md` rules:
- Translate meaning, not words.
- Respect string expansion ratios.
- Preserve tone across locales.
- Check `vocabulary.json` for approved term translations.
- Call `contentrain_content_save` for each target locale.
If the user defers translations, note incomplete locales in the final summary.
### 11. Validate
Call `contentrain_validate` to check all changes:
- Schema compliance (all required fields, correct types).
- Referential integrity (relations point to existing entries).
- i18n completeness (all locales have matching keys).
- Content policy compliance.
Fix any errors reported. Acknowledge any warnings.
For large content operations (10+ entries), also recommend running `contentrain doctor --usage` to detect unused keys and duplicate values across the project.
### 12. Submit
Call `contentrain_submit` to push branches to remote:
- Write operations already create branches and commit changes automatically.
- `contentrain_submit` pushes unmerged `cr/*` branches to the remote.
- In `auto-merge` mode, branches are already merged to the base branch during the write operation.
- In `review` mode, branches are pushed for team review.
Report the Studio URL if provided in the tool response -- the user can review and approve content there.
### After Save: SDK Regeneration
When new models are created or fields change, regenerate the SDK client:
```bash
npx contentrain generate
```
This updates TypeScript types for the new content. See: **contentrain-generate** skill.
### 13. Final Summary
Report to the user:
- How many entries were created/updated.
- Which locales were covered.
- The validation result.
- The submission status (auto-merged or pending review).
- Studio link for visual review (if available).
- Next steps: run `/contentrain-generate` to update SDK types if models changed.
## Related Skills
- **contentrain-serve** — Browser-based review for content branches
- **contentrain-generate** — SDK client regeneration after content changes
- **contentrain-quality** — Content quality, SEO, and accessibility rules
- **contentrain** — Core architecture and MCP tool catalog