contentrain — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited contentrain (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Contentrain is a Git-based, AI-first content management system. Content lives in .contentrain/ as JSON and Markdown files, managed through MCP tools. This skill covers architecture, content formats, and tool usage.
Contentrain consists of 6 packages that work together:
| Package | Role | How agent uses it |
|---|---|---|
| @contentrain/mcp | 19 MCP tools (scan, apply, validate, merge, doctor...) | MCP tool calls |
| contentrain (CLI) | init, serve, generate, doctor, diff, status | Shell commands |
| @contentrain/types | Shared TypeScript contracts | Type safety |
| @contentrain/query | Generated SDK client (Prisma-pattern) | import from '#contentrain' |
| @contentrain/rules | Behavioral guardrails (~86 lines, always-loaded) | Auto-loaded by IDE |
| @contentrain/skills | Procedural workflows (this file) | On-demand by agent |
For workflows requiring human review (normalize, content review):
contentrain serve # http://localhost:3333| Page | When to use |
|---|---|
| /normalize | Extraction/reuse preview and approval |
| /branches | Merge or delete pending branches |
| /validate | Review validation errors visually |
| /content | Browse models and entries |
The system separates intelligence (agent) from infrastructure (MCP tools).
Agent responsibilities:
{t('key')} vs {{ $t('key') }})MCP responsibilities:
Rule: MCP does NOT make content decisions. It provides reliable, framework-agnostic tooling.
| Kind | Storage | Use For |
|---|---|---|
| Singleton | JSON object, one file per locale | Page sections, site config, navigation |
| Collection | Object-map by entry ID (sorted keys) | Team members, products, FAQs, categories |
| Document | Markdown + YAML frontmatter | Blog posts, documentation, changelogs |
| Dictionary | Flat key-value (all strings, no fields) | Error messages, UI strings, translations |
Singleton (content/{domain}/{model}/{locale}.json):
{ "cta": "Get Started", "title": "Build faster" }Collection (content/{domain}/{model}/{locale}.json):
{
"a1b2c3d4e5f6": { "name": "Ahmet", "role": "CEO" },
"f6e5d4c3b2a1": { "name": "Jane", "role": "CTO" }
}Document (content/{domain}/{model}/{slug}/{locale}.md):
---
title: Getting Started
slug: getting-started
---
# Getting Started with ContentrainDictionary (content/{domain}/{model}/{locale}.json):
{ "auth.expired": "Session expired", "auth.failed": "Authentication failed" }id (collection), slug (document), createdAt/updatedAt (Git-derived), status/source/updated_by/approved_by (metadata)| Tool | Purpose |
|---|---|
contentrain_status | Get full project state in one call |
contentrain_describe | Get schema + optional sample for one model |
contentrain_describe_format | Get storage and file-format contract |
contentrain_init | Initialize .contentrain/ directory |
contentrain_scaffold | Generate models from built-in template |
contentrain_model_save | Create or update a model definition (upsert) |
contentrain_model_delete | Delete a model and its content |
contentrain_content_save | Create or update content entries (upsert) |
contentrain_content_delete | Delete a content entry |
contentrain_content_list | List content entries for a model |
contentrain_scan | Scan project for structure or content candidates |
contentrain_apply | Apply normalize operation (extract or reuse) |
contentrain_validate | Validate content against model schemas |
contentrain_submit | Push contentrain/* branches to remote |
contentrain_merge | Merge a review-mode branch into contentrain locally |
contentrain_bulk | Run batch operations on existing content |
status --> init --> scaffold? --> model_save --> content_save --> validate --> submitstatus --> describe --> content_save --> validate --> submitstatus --> init? --> scan(graph) --> scan(candidates) --> [agent evaluates]
--> apply(extract, dry_run:true) --> [review] --> apply(extract, dry_run:false)
--> validate --> submitapply(reuse, dry_run:true) --> [review] --> apply(reuse, dry_run:false)
--> validate --> submit --> [repeat per model]These are enforced by MCP — violating them causes errors. Know them upfront:
contentrain_status before any write operation on existing projectscontentrain_describe_format before creating models or contentdry_run: true before contentrain_apply executecontentrain_validate before contentrain_submitnpx contentrain generate after model/content changes that affect SDK.contentrain/meta/, .contentrain/client/, .contentrain/context.json directlycontentrain_apply operation, review, then dry_run: false| Reference | Description |
|---|---|
| Schema Types | Complete 27-type catalog with field properties |
| Model Kinds | Detailed storage formats, relations, nesting rules |
| Content Formats | Directory structure, config.json, canonical serialization |
| MCP Tools | Complete tool parameters and usage details |
| MCP Pipelines | Calling sequences, error handling, Studio hints |
| Architecture | Full Contentrain schema and type architecture |
| i18n | Internationalization quality rules |
| Security | XSS prevention, secret detection, URL validation |
| Workflow | Git workflow, branch naming, conflict resolution |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.