Atlas / MCP servers / contentrain / ai

aiBLOCK

mcp/contentrain/ai

Repo-native content governance for AI agents. Extract, review, and deliver UI text, docs, and structured content from Git.

Verdict
BLOCK
Grade
F
Trust score
51 /100
Exposed tools
104 73r · 25w · 6d
Transport
stdio · streamable-http
License
MIT
Stars
6
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://www.npmjs.com/package/@contentrain/mcp) [](https://www.npmjs.com/package/contentrain) [](https://www.npmjs.com/package/@contentrain/query) [](https://agentskills.io) [](https://ai.contentrain.io) [](LICENSE)

Website · Docs · Discord · Twitter · LinkedIn

Extract, govern, and ship structured content from your codebase.

Contentrain helps teams turn hardcoded UI text, docs, and structured content into a governed, reviewable content layer. Agents can extract, create, translate, and update content, while Contentrain enforces schema, Git review, and portable file output.

Agent extracts or updates content → Contentrain standardizes → Human reviews → Any platform consumes

Try it in 30 seconds

npx contentrain init        # create .contentrain/ workspace
npx contentrain serve       # open the local review UI

That's it. You now have a governed content workspace with models, validation, review branches, and a local UI — no account, no cloud, no proprietary content format.

Start here:

What Contentrain is for

  • Rescuing hardcoded strings from existing apps and turning them into struc
Read from source at commit 680a73720388OBSERVED · 2026-10-11
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (npm)
claude mcp add mcp -- npx -y @contentrain/[email protected]
03

Exposed tools (104)

73 read · 25 write · 6 destructive. Blast radius: 6 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
.NETreadMicrosoft .NET platform
AdareadWrites things.
AnalogreadAngular meta-framework
AngularreadPlatform for web applications
AstroreadContent-first web framework
DjangoreadPython web framework
ElectronreadCross-platform desktop apps
EleventyreadJavaScript static site generator
ExporeadReact Native toolchain
ExpressreadMinimal Node.js web framework
FastifyreadFast Node.js web framework
FlutterreadCross-platform UI toolkit (Dart)
GoreadGo programming language
HellowriteA post
HugoreadGo-based static site generator
JekyllreadRuby-based static site generator
LaravelreadPHP web framework
NestJSreadProgressive Node.js framework
Next.jsreadReact framework with SSR/SSG
Node.jsreadServer-side JavaScript runtime
NuxtreadVue meta-framework with SSR/SSG
OtherreadUnknown or unsupported framework
RailsreadRuby web framework
ReactreadUI library for web and native
RemixreadFull-stack React framework
RustreadRust programming language
SolidreadReactive UI library
SveltereadCompile-time UI framework
SvelteKitreadSvelte meta-framework
TaurireadLightweight desktop apps (Rust)
VuereadProgressive JavaScript framework
activityreadShow recent activity from Studio
branchesreadManage content branches on Studio
cdn-buildwriteTrigger a CDN rebuild
cdn-initwriteSet up CDN for content delivery
connectreadConnect this repository to a Contentrain Studio project
contentrainreadContentrain CMS architecture, content formats, and MCP tool usage
contentrain-bulkreadBatch operations on content entries
contentrain-contentwriteCreate and manage content entries for existing models
contentrain-diffreadView content diffs between branches
contentrain-doctorreadDiagnose project health issues
contentrain-generatereadGenerate the typed SDK client from models
contentrain-initreadInitialize a new Contentrain project
contentrain-migrate-wordpresswriteImport a WordPress site into a .contentrain store and wire it to a framework
contentrain-modelwriteDesign and save model definitions
contentrain-normalizewriteTwo-phase normalize: extract hardcoded strings and patch source files
contentrain-qualityreadContent quality, SEO, accessibility, and media rules
contentrain-reviewreadReview content changes before publishing
contentrain-sdkreadQuery SDK usage: #contentrain imports, QueryBuilder, type-safe content access
contentrain-servewriteStart the local review and normalize UI
contentrain-translatereadTranslate content across supported locales
contentrain-validate-fixreadValidate content and auto-fix structural issues
contentrain_applywriteApply normalize operations. Two modes:
contentrain_branch_deletedestructiveDelete a pending contentrain (cr/*) branch that will not be merged — e.g. a branch left behind by a failed operation, or a superseded draft. Only cr/* branches can be deleted; the contentrain branch is protected. This is destructive: the branch and its unmerged commits are removed.
contentrain_branch_listwriteList pending contentrain (cr/*) branches with their merge status against the contentrain branch. Use this to discover branch names for contentrain_merge / contentrain_branch_delete, and to monitor branch-health limits (warning at 50, blocked at 80 unmerged).
contentrain_bulkreadBatch operations on content entries. All operations are auto-committed to git.
contentrain_content_deletedestructiveDelete content entries. For dictionaries, use
contentrain_content_listreadList content entries (read-only). Returns data from .contentrain/ — do NOT manually create or modify content files.
contentrain_content_savewriteSave content entries. Entry format varies by model kind: DICTIONARY — provide
contentrain_describewriteGet full schema of a single model (read-only). Do NOT manually create content files — use contentrain_content_save instead.
contentrain_describe_formatreadDescribes the Contentrain content file format for any language/platform. Returns a comprehensive specification of the file structure, JSON formats, markdown conventions, meta files, and locale strategies.
contentrain_doctorreadProject health report (read-only). Returns structured checks: git, node, .contentrain/ structure, model parse, orphan content, branch pressure, SDK freshness. Pass
contentrain_initreadInitialize .contentrain/ structure. Changes are auto-committed to git — do NOT manually create .contentrain/ files.
contentrain_media_deletedestructiveDelete a media asset from the media stack. Content entries referencing its path are NOT rewritten — check references before deleting.
contentrain_media_getreadGet a single media asset by id, including its storage path, delivery URL, and metadata.
contentrain_media_ingestreadIngest a media asset from a source URL. The provider fetches the URL server-side under its own SSRF/MIME/size policy and stores the asset in the media stack. Returns the stored asset with its media/... path.
contentrain_media_listreadList media assets from the provider media stack. Returns storage paths (media/...) usable in media/image/file fields via contentrain_content_save, plus delivery URLs when available. Supports search, tag filter, and cursor pagination.
contentrain_media_updatewriteUpdate metadata (alt text, tags, filename) of an existing media asset. Does not touch the binary.
contentrain_mergewriteMerge a review-mode branch into contentrain. Local git operation — no external platform needed. Merges the feature branch into the contentrain branch, advances the base branch via update-ref, selectively syncs .contentrain/ files to the working tree, and prunes the merged branch. Target by exact
contentrain_model_deletedestructiveDelete a model and its content/meta. Changes are auto-committed to git — do NOT manually edit .contentrain/ files.
contentrain_model_savewriteCreate or update a model definition. Changes are auto-committed to git — do NOT manually edit .contentrain/ files after calling this tool.
contentrain_reconcilereadReconcile a diverged contentrain ↔ base-branch pair with a content-aware three-way merge.
contentrain_scaffoldreadTemplate-based project setup. Available templates: ${listTemplates().join(
contentrain_scanreadScan project source code for content strings. Three modes:
contentrain_statusreadGet full project status (read-only). Returns config, models, context. Do NOT manually edit .contentrain/ based on this output.
contentrain_submitwritePush contentrain/* branches to remote. MCP is push-only — PR creation is handled by the platform. Do NOT manually push or create PRs.
contentrain_validateread
contentrain_vocabulary_deletedestructiveRemove canonical vocabulary terms by slug. Content already using a term is not touched — the vocabulary only advises. Changes are auto-committed to git.
contentrain_vocabulary_savewriteAdd or update canonical vocabulary terms. Terms nest as {
deltawritePlan a WordPress source delta against the store (dry run only; applying goes through review)
describewriteShow the schema, stats, and import snippet for a model
describe-formatreadPrint the Contentrain content-format specification
diffreadReview pending contentrain branches
doctorreadCheck project health and environment
generatereadGenerate typed SDK client from models
importwriteImport a WordPress site (WXR export file or REST URL) into a .contentrain content store
initreadInitialize Contentrain in your project
loginreadAuthenticate with Contentrain Studio
logoutreadLog out from Contentrain Studio
mergewriteMerge one contentrain feature branch into the content branch
prunedestructiveDelete merged cr/* branches locally and on the remote
reconcilewriteMerge a diverged base branch back into the content branch, content-aware
record_answersreadRecord the answers for every item.
scaffoldwriteApply a Contentrain template (models + sample content + vocabulary)
servewriteStart the local content viewer or the MCP server (stdio for IDE agents, --mcpHttp for Studio / CI / remote drivers)
setupreadConfigure MCP server and AI rules for your IDE
skillswriteInstall, update, or list Contentrain AI skills and rules for your IDE
statusreadShow project status overview
studioreadInteract with Contentrain Studio
submissionsreadManage form submissions on Studio
usagereadShow workspace usage metrics
validatereadValidate project content against schemas
webhooksreadManage webhooks on Studio
whoamireadShow current Studio authentication status
04

Trust audit

BLOCKgrade F · trust 51/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (5 observation(s))
Network
declared (6 observation(s))
Shell
declared (5 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/cli/src/commands/serve.ts:179
exec(`${cmd} ${url}`)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/cli/src/utils/browser.ts:14
exec(command, () => {
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInventory / provenance · inv.binary · CWE-1104
packages/mcp/src/core/migration/allowlist.ts
allowlist.ts
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/cli/src/studio/auth/oauth-server.ts:55
const callbackUrl = `http://127.0.0.1:${port}/callback`
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/cli/src/studio/auth/oauth-server.ts:90
const url = new URL(req.url, `http://127.0.0.1:${port}`)
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/decide/src/test-support.ts:37
export const TOKEN = 'test-token-not-a-real-secret'
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/mcp/tests/providers/github/app-auth.test.ts:42
token: 'ghs_mockInstallationToken',
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/mcp/tests/tools/content-gate.test.ts:167
entries: [{ locale: 'en', data: { name: 'API', token: 'sk_live_abc123secret' } }],
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/types/src/index.test.ts:785
expect(detectSecrets('API-KEY: "q7x2m9v4k1p8z3w6h5j0"')).toHaveLength(1)
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/wp-import/src/acf.test.ts:111
const SECRET = 'GOLDEN-ACF-PASSWORD-SECRET'
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
packages/types/src/index.test.ts:1336
['a GitHub token', 'ghp_16C7e42F292c6912E7710c838347Ae178B4a'],
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
packages/rules/shared/security-rules.md:49
- **Private keys**: `-----BEGIN RSA PRIVATE KEY-----`, `-----BEGIN OPENSSH PRIVATE KEY-----`, `-----BEGIN PGP PRIVATE KEY BLOCK-----`, or similar PEM blocks
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
packages/skills/skills/contentrain/references/security.md:54
- **Private keys**: `-----BEGIN RSA PRIVATE KEY-----`, `-----BEGIN OPENSSH PRIVATE KEY-----`, `-----BEGIN PGP PRIVATE KEY BLOCK-----`, or similar PEM blocks
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
packages/types/src/index.test.ts:1340
['a private key block', '-----BEGIN RSA PRIVATE KEY-----'],
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
plugins/contentrain/skills/contentrain/references/security.md:54
- **Private keys**: `-----BEGIN RSA PRIVATE KEY-----`, `-----BEGIN OPENSSH PRIVATE KEY-----`, `-----BEGIN PGP PRIVATE KEY BLOCK-----`, or similar PEM blocks
MEDIUMHard-coded secrets · secret.stripe · CWE-798, CWE-321
packages/types/src/index.test.ts:1334
['a Stripe secret key', 'sk_live_51H8xY2abcdefghij'],
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
contentrain_branch_delete, contentrain_content_delete, contentrain_media_delete, contentrain_model_delete, contentrain_vocabulary_delete, prune
Why it matters. 6 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.oxlintrc.json
.oxlintrc.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/astro-kit/tests/dialog-openers-runtime.test.ts:50
const run = () => new Function(script)()
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/emitter-astro/src/emit.test.ts:688
const paths = new Function('data0', 'data1', `${fn}; return getStaticPaths()`)
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/emitter-astro/src/noindex.test.ts:55
return new Function(`${config.slice(start, end)}\nreturn ${filter}`)() as Filter
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
packages/wp-import/src/core.ts:39
export const hexId = (s: string): string => createHash('sha1').update(s).digest('hex').slice(0, 24)
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/astro-kit/scripts/visual.mjs:33
import { installLocalSdk } from '../../../scripts/local-sdk.mjs'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/astro-kit/scripts/visual.mjs:75
import Component from '../../components/kit/${c.id}/${main}'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/astro-kit/scripts/visual.mjs:76
import BaseLayout from '../../layouts/BaseLayout.astro'

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 680a73720388full audit observations/trust-audit/mcp-server/contentrain__ai.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11680a73720388BLOCKF51first audit
06

Questions

What is the ai MCP server?

Repo-native content governance for AI agents. Extract, review, and deliver UI text, docs, and structured content from Git.

What tools does ai expose?

104 in total: 73 read-only, 25 that write, and 6 that can delete or overwrite (contentrain_branch_delete, contentrain_content_delete, contentrain_media_delete, contentrain_model_delete, contentrain_vocabulary_delete). Every one is listed on this page with its risk.

Is ai safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (51/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 6 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does ai need?

It reads CONTENTRAIN_AUTHOR_EMAIL, CONTENTRAIN_AUTHOR_NAME, CONTENTRAIN_CDN_KEY, CONTENTRAIN_WP_APP_PASSWORD, CONTENTRAIN_WP_AUTH, GH_TOKEN, GITHUB_APP_PRIVATE_KEY, GITHUB_TOKEN and MCP_BEARER_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does ai run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as contentrain-astro-starter at 0.0.0.

How current is this page?

The grade is for one exact copy of the source (680a73720388), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement