Contentrain

io.github.Contentrain由 GitHub 账号 Contentrain 发布v3.12.3更新于 Nov 4, 2026

Git content governance, 23 deterministic MCP tools. Hosted: docs.contentrain.io/developer/mcp-cloud

已验证Streamable HTTP可网页运行效率与工作流知识与记忆开发者工具

概览

AI 生成的概览

以 Git 为原生的内容治理服务器,让助手定义内容模型、保存与发布多语言内容、校验内容并管理评审分支。

可以做什么
  • 查看项目:状态、模型结构、文件格式说明、健康报告与待处理评审分支
  • 搭建与建模:初始化内容目录、套用起始模板、创建或删除模型、维护词表术语
  • 管理条目:保存、列出、删除内容,变更发布状态,批量复制语言或批量删除
  • 校验内容是否符合模型结构并可自动修复,对分叉分支先试运行再执行三方合并
  • 规范化硬编码文案:扫描源码候选字符串,再抽取为内容文件或改写源文件
  • 交付变更:推送评审分支、本地合并分支、删除废弃分支
适用场景
适用于内容以 JSON/Markdown 形式存放在 git 仓库、由 Contentrain 管理的项目,希望助手代为编辑模型与条目、发布或归档内容,并把界面里的硬编码文案迁移为受管内容而不手工改文件。
运行要求
远程方式:托管端点,需 OAuth 及来自 Contentrain Studio MCP Cloud API 密钥的 Authorization 持有者令牌。本地方式:Node.js 22+、机器上安装 git、并有一份项目检出;可选安装 Vue/Astro/Svelte 编译器以提升源码扫描质量。可选的 GitHub 或 GitLab 后端需各自的令牌。
安装前请注意
多数工具会写入:模型与内容保存、删除、状态变更、批量操作以及 reuse 模式下的源文件改写都会自动提交到 git,部分标记为破坏性。破坏性工具需 confirm:true,apply 与 bulk 支持 dry_run,建议先预览。评审分支可能被推送到远端,合并后远端副本会被删除;本地模式可关闭推送。托管端点会把内容发送到 Contentrain Studio。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Contentrain,将其添加到工作区。
  2. 连接 所需的 凭据。它们会被私密存储,绝不会在公开页面上展示。
  3. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.Contentrain%2Fcontentrain/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。 客户端会在首次连接时完成 OAuth 登录。

{
  "mcpServers": {
    "contentrain": {
      "type": "http",
      "url": "https://studio.contentrain.io/api/mcp/remote"
    }
  }
}

README

@contentrain/mcp

[npm version] [GitHub source] [Docs]

Provider-agnostic MCP engine for Contentrain — local-first by default, with optional GitHub and GitLab backends and an HTTP transport for remote drivers such as Studio.

Start here:

Contentrain is a content governance ecosystem for teams and AI agents. In it, this engine works like this:

  • agent produces content decisions
  • MCP applies deterministic filesystem and git workflow
  • humans review and merge
  • the system keeps schema, locale, and serialization consistent

This package is the runtime core behind Contentrain's MCP integration. It can be used as:

  • a stdio MCP server (contentrain-mcp)
  • an embeddable server (createServer(projectRoot))
  • a low-level toolkit for config, models, content, validation, scanning, and git transaction flow

Install

bash
pnpm add @contentrain/mcp

Requirements:

  • Node.js 22+
  • git available on the machine

Optional parser support for higher-quality source scanning:

  • @vue/compiler-sfc
  • @astrojs/compiler
  • svelte

They are listed as optional dependencies. The scanner still works without them, but Vue/Astro/Svelte detection is stronger when they are installed.

What It Does

@contentrain/mcp manages a .contentrain/ directory in your project and exposes MCP tools for:

  • project initialization
  • model creation and deletion
  • content save, delete, and list
  • validation and auto-fix
  • normalize scan and apply flows
  • bulk operations
  • branch submission, review-mode merge, and branch-health awareness
  • project health checking (doctor)

All write operations are designed around git-backed safety:

  • a dedicated contentrain branch serves as the content state single source of truth
  • each write creates a temporary worktree on a feature branch forked from contentrain (branch name: cr/{scope}/{target}/{timestamp}-{suffix}, e.g. cr/content/blog-post/1730000000-a1b2; bulk locale copies, locale-scoped status changes and scaffold add a {locale} segment before the timestamp)
  • auto-merge: feature merges into contentrain, baseBranch advanced via update-ref, .contentrain/ files selectively synced to developer's working tree when the base branch is the one checked out
  • baseBranch = CONTENTRAIN_BRANCH env → repository.default_branch → remote HEAD → main → master → checked-out branch → main (fallback). A write made on a feature branch never merges, moves or pushes that branch
  • plans are read from the working tree but committed on the fetched contentrain tip: JSON changes are carried over key by key, so entries another writer pushed are kept; a same-value conflict writes nothing and returns CONTENT_WORKING_TREE_STALE
  • on a checked-out feature branch, which writes do not update, .contentrain/** is read from the contentrain ref instead (source files still from the working tree); read tools report it as content_source
  • review: feature branch pushed to remote for team review; once merged (or deleted), its remote copy is removed too — best-effort, opt out with remoteBranchCleanup: false in config.json
  • local mode (git.push: false or CONTENTRAIN_NO_PUSH=1): nothing is ever pushed or deleted on the remote, and every result says so — see Git environment and local mode
  • every local write's git block names the resolved base_branch; when it is not the checked-out branch, the result's warning says your working tree was left alone
  • commit hooks: skipped on machine commits by default; git.verify: true or CONTENTRAIN_VERIFY=1 runs them, and a rejecting hook fails the write with its output — see Commit hooks
  • merged-branch detection survives base-history rewrites (ancestry check with a patch-id fallback), so rebases/squashes don't strand stale branches
  • developer's working tree is never mutated during MCP git operations (no stash, no checkout, no merge)
  • context.json never lands on feature branches — it is regenerated on the contentrain branch after merge (locally by the transaction layer; in remote flows by the orchestrator that owns the merge)
  • canonical JSON output — sorted keys, 2-space indent, trailing newline
  • validation + next-step hints surfaced to the caller

Tool Surface

23 MCP tools, plus 5 media tools on a media-capable provider such as Studio, with annotations (readOnlyHint, destructiveHint, idempotentHint, and openWorldHint: false everywhere except contentrain_media_ingest, which fetches a caller-supplied URL server-side) for client safety hints.

Tool listing is capability-aware. tools/list only advertises tools the resolved provider + projectRoot pair can actually satisfy. A local stdio server lists the 23 core tools; a session driven by a remote provider (GitHub/GitLab, no local checkout) lists only the remote-safe subset — status, describe, describe_format, model_save, model_delete, content_save, content_delete, content_list, content_status, vocabulary_save, vocabulary_delete, validate. The requirement map lives in TOOL_REQUIREMENTS (@contentrain/mcp/tools/availability).

ToolPurposeRead-onlyDestructive
contentrain_statusProject status, config, models, branch health, contextYes—
contentrain_describeFull schema and sample data for a modelYes—
contentrain_describe_formatFile-format and storage contract referenceYes—
contentrain_doctorProject health report (env, structure, models, orphans, local + remote branches, SDK)Yes—
contentrain_initCreate .contentrain/ structure and base config——
contentrain_scaffoldApply a starter template such as blog, docs, landing, saas——
contentrain_model_saveCreate or update a model definition—Yes
contentrain_model_deleteDelete a model definition—Yes
contentrain_content_saveSave content entries for any model kind—Yes
contentrain_content_deleteDelete content entries—Yes
contentrain_content_listRead content entries, each with its publish state under metaYes—
contentrain_content_statusChange entry status — publish, unpublish, archive (publishing validates first)—Yes
contentrain_validateValidate project content, optionally auto-fix structural issues——
contentrain_submitPush cr/* branches to remote, then lazily prune merged local + remote leftovers——
contentrain_mergeMerge a review-mode branch into contentrain locally (by exact branch or model); deletes its remote copy—Yes
contentrain_reconcileContent-aware three-way merge of a diverged contentrain ↔ base pair (dry_run first, resolutions second)——
contentrain_branch_listList pending cr/* branches with merge status (remote: true adds remote view)Yes—
contentrain_branch_deleteDelete a stale/failed cr/* branch locally and on the remote (contentrain branch protected)—Yes
contentrain_scanGraph- and candidate-based hardcoded string scanYes—
contentrain_applyNormalize extract/reuse execution with dry-run support——
contentrain_bulkBulk locale copy and deletes (dry_run previews; local only)—Yes
contentrain_vocabulary_saveAdd or update canonical vocabulary terms (merges with what exists)——
contentrain_vocabulary_deleteRemove canonical vocabulary terms by slug (confirm: true)—Yes
contentrain_media_listList media assets (search, tag filter, cursor pagination)Yes—
contentrain_media_getGet one media asset by idYes—
contentrain_media_ingestIngest an asset from a source URL (provider fetches server-side)——
contentrain_media_updateUpdate asset metadata (alt, tags, filename)——
contentrain_media_deleteDelete an asset from the media stack—Yes

The five contentrain_media_* tools are a deterministic passthrough to the provider's optional media facet (RepoProvider.media) and are registered only when the provider exposes one (e.g. Studio MCP Cloud). Local stdio servers and plain GitHub/GitLab providers never list them. Ingest is URL-based (MCP has no binary channel); the provider implementation owns SSRF/MIME/size policy for the fetch.

Quick Start

Configure via CLI (recommended)

bash
npx contentrain setup claude-code   # or: cursor, vscode, windsurf, copilot

This auto-creates the correct MCP config file for your IDE. See CLI docs for details.

Run as a standalone MCP server

bash
CONTENTRAIN_PROJECT_ROOT=/path/to/project npx -y @contentrain/mcp

If CONTENTRAIN_PROJECT_ROOT is omitted, the current working directory is used.

Git environment and local mode

These apply to the local provider (stdio, LocalProvider):

VariableDefaultEffect
CONTENTRAIN_BRANCHunsetBase branch the contentrain branch advances. Wins over repository.default_branch, then remote HEAD → main → master → the checked-out branch → main. Per process; never written to config
CONTENTRAIN_REMOTEoriginRemote used for every fetch and push (and remote branch cleanup)
CONTENTRAIN_NO_PUSHunset1/true turns local mode on; 0/false turns it off. Any other value is ignored
CONTENTRAIN_AUTHOR_NAME / CONTENTRAIN_AUTHOR_EMAILContentrain / [email protected]Author identity on Contentrain's commits
CONTENTRAIN_GIT_BINARYunsetAbsolute path of the git binary to use
CONTENTRAIN_VERIFYunset1/true runs the repository's commit hooks on Contentrain's commits; 0/false skips them. Wins over git.verify. Any other value is ignored

Local mode keeps every write on local branches: no branch push, no review push, no push after an auto-merge, approve or reconcile, and no remote branch delete or prune. Fetching is not a push and still happens when a remote exists. Turn it on for a project with "git": { "push": false } in .contentrain/config.json, or for one run with CONTENTRAIN_NO_PUSH=1.

Precedence: the env wins over the config in both directions. CONTENTRAIN_NO_PUSH=1 turns pushing off even when config allows it; CONTENTRAIN_NO_PUSH=0 turns it back on over git.push: false. With neither, pushing is on.

It is never a silent success. Each write's git block reports remote_push: "disabled" with remote_note: "not pushed (local mode)", and next_steps carries a LOCAL MODE line. contentrain_submit returns an error instead of pushing; land review branches with contentrain_merge. contentrain_merge and contentrain_branch_delete delete the local branch as usual and leave any remote copy untouched; contentrain_branch_delete reports remote_skipped: "local-mode", contentrain_merge reports remote: { deleted: false, skipped: "local-mode" }.

Commit hooks

By default Contentrain's machine commits (the cr/* content commit, the context.json commit, a reconcile merge commit, the seed commit of an empty repo) skip the repository's commit hooks (pre-commit, prepare-commit-msg, commit-msg). That keeps existing projects working: these commits are made in a temporary worktree without your node_modules, and their [contentrain] … subject fails a strict commitlint. Merges still run the merge hooks and pushes still run pre-push, as before.

To run commit hooks on every machine commit, set "git": { "verify": true } in .contentrain/config.json, or CONTENTRAIN_VERIFY=1 for one run (CONTENTRAIN_VERIFY=0 skips them over the config). With hooks on:

  • a hook that rejects the content commit fails the write: nothing lands, and the tool error carries the hook's output. Nothing is retried without hooks;
  • a hook that rejects only the follow-up context.json commit (the content is already on contentrain) is reported in the result's warning, not swallowed;
  • the hooks must work in a worktree under the system temp directory — a hook that runs npx lint-staged needs the tool available there.

Embed the server in your own process

ts
import { createServer } from '@contentrain/mcp/server'import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
const server = createServer(process.cwd())const transport = new StdioServerTransport()
await server.connect(transport)

createServer also accepts an options object: { provider, projectRoot?, instructions? }. instructions sets the MCP instructions string clients receive at initialize (defaults to defaultInstructions for the tools the server registers — with every tool available, DEFAULT_INSTRUCTIONS — kept under 512 characters; pass '' to omit). The HTTP entries (startHttpMcpServer, startHttpMcpServerWith) take the same instructions option.

Example MCP Flow

Typical agent workflow:

  1. Call contentrain_status
  2. If needed, call contentrain_init
  3. Create models with contentrain_model_save or contentrain_scaffold
  4. Save content with contentrain_content_save
  5. Validate with contentrain_validate
  6. For hardcoded strings, use contentrain_scan then contentrain_apply
  7. Push review branches with contentrain_submit

Normalize Flow

Normalize is intentionally split into two phases:

1. Extract

contentrain_scan finds candidate strings.

contentrain_apply with mode: "extract":

  • creates or updates models
  • writes content entries
  • records source tracking
  • creates a review branch (cr/normalize/extract/{timestamp}-{suffix})

2. Reuse

contentrain_apply with mode: "reuse":

  • patches source files using agent-provided expressions
  • adds imports when needed
  • enforces patch path safety and scope checks
  • creates a separate review branch (cr/normalize/reuse/{model or domain}/{timestamp}-{suffix})

This split keeps content extraction separate from source rewriting.

Transport / provider requirements

Normalize (contentrain_scan and contentrain_apply) requires local disk access — AST scanners walk the source tree and patch files in place. It runs only on a LocalProvider (stdio transport, or HTTP transport configured with a LocalProvider).

Remote providers such as GitHubProvider expose astScan: false, sourceRead: false, and sourceWrite: false, so a server built on one does not register contentrain_scan or contentrain_apply at all (see TOOL_REQUIREMENTS). A provider that can read the source tree but not write it lists contentrain_apply; its reuse mode then returns a uniform capability error:

json
{  "error": "contentrain_scan requires local filesystem access.",  "capability_required": "astScan",  "hint": "This tool is unavailable when MCP is driven by a remote provider (e.g. GitHubProvider). Use a LocalProvider or the stdio transport."}

Agents driving a remote transport should fall back to a local transport (or a local checkout) before invoking normalize.

Remote Providers

MCP supports three backends behind the same RepoProvider contract:

  • LocalProvider — simple-git + worktree. Every core tool (normalize included) works on it; the media tools need a provider with a media facet. Stdio transport defaults to this.
  • GitHubProvider — Octokit over the Git Data + Repos APIs. No clone, no worktree. @octokit/rest ships as an optional peer dependency.
  • GitLabProvider — gitbeaker over the GitLab REST API. No clone, no worktree. @gitbeaker/rest ships as an optional peer dependency. Supports gitlab.com and self-hosted CE / EE.

Each remote provider implements the same surface: reader (readFile / listDirectory / fileExists), writer (applyPlan — one atomic commit), branch ops (list / create / delete / diff / merge / isMerged / getDefaultBranch). mergeBranch goes straight through on GitHub; on GitLab it opens an MR and immediately accepts it so the final MergeResult shape matches either way. The GitHub provider also takes a full commit SHA as applyPlan's base (and createBranch's fromRef) for compare-and-set writes: a missing branch forks from that commit, and a branch that has moved away from it refuses the write with PROVIDER_CONFLICT.

GitLab — installation & usage

bash
pnpm add @gitbeaker/rest
ts
import { createGitLabProvider } from '@contentrain/mcp/providers/gitlab'import { createServer } from '@contentrain/mcp/server'
const provider = await createGitLabProvider({  auth: { type: 'pat', token: process.env.GITLAB_TOKEN! },  project: {    projectId: 'acme/site',             // or numeric project ID    host: 'https://gitlab.company.com', // omit for gitlab.com  },})
const server = createServer({ provider })// serve over stdio or the HTTP transport from @contentrain/mcp/server/http

Capabilities: sourceRead, sourceWrite, astScan, localWorktree are all false; pushRemote, branchProtection, pullRequestFallback are true. Normalize (scan / apply) is not registered on a GitLabProvider server — fall back to a local transport for those flows.

Bitbucket

There is no Bitbucket provider. A Bitbucket checkout works through the LocalProvider path like any other local Git repository.

Core Exports

The package also exposes low-level modules for embedding and advanced use:

  • @contentrain/mcp/server
  • @contentrain/mcp/server/http
  • @contentrain/mcp/core/config
  • @contentrain/mcp/core/context
  • @contentrain/mcp/core/model-manager
  • @contentrain/mcp/core/content-manager
  • @contentrain/mcp/core/validator
  • @contentrain/mcp/core/scanner
  • @contentrain/mcp/core/graph-builder
  • @contentrain/mcp/core/apply-manager
  • @contentrain/mcp/core/scan-config
  • @contentrain/mcp/core/doctor
  • @contentrain/mcp/core/contracts
  • @contentrain/mcp/core/ops — plan APIs (including planReconcile and its bindRef reader adapter) plus content-root-relative path helpers: contentDirPath, contentFilePath, documentFilePath, metaFilePath
  • @contentrain/mcp/core/overlay-reader
  • @contentrain/mcp/core/migration — the allowlisted migration write path: createMigrationWriter, scopeHash, decide. See Migration writes below
  • @contentrain/mcp/util/detect
  • @contentrain/mcp/util/fs
  • @contentrain/mcp/git/transaction
  • @contentrain/mcp/git/branch-lifecycle — branch health/cleanup plus the remote cr/* lifecycle: deleteRemoteBranch, listRemoteCrBranches, pruneMergedRemoteBranches, isRefMerged, classifyMergedBranches
  • @contentrain/mcp/git/base-branch — resolveBaseBranch, the one base-branch resolver every MCP write and contentrain status / serve use (env → repository.default_branch → <remote>/HEAD → main → master → checked-out branch → main); resolveBaseBranchSource (the same, plus which rung answered); resolveInitDefaultBranch (what init records as repository.default_branch, or null)
  • @contentrain/mcp/git/errors
  • @contentrain/mcp/git/reconcile — reconcileBranches, the local reconcile executor
  • @contentrain/mcp/tools/annotations
  • @contentrain/mcp/templates
  • @contentrain/mcp/providers/local
  • @contentrain/mcp/providers/github
  • @contentrain/mcp/providers/gitlab

These are intended for Contentrain tooling and advanced integrations, not for direct manual editing of .contentrain/ files.

Migration Writes

A migration does not deliver content, it delivers a codebase: src/, public/, package.json, a lockfile, deploy configuration. The content write path was never built for any of that, and widening it would quietly move a security boundary the whole product rests on — "Contentrain only writes .contentrain/" is a promise, not an implementation detail.

@contentrain/mcp/core/migration is the gate instead. It wraps a provider whose applyPlan can already write any path, and puts consent in front of it.

ts
import { createMigrationWriter, scopeHash } from '@contentrain/mcp/core/migration'
const scope = {  allow: ['src/**', 'public/**', 'package.json', 'astro.config.mjs'],  branch: 'migration/acme',  base: 'main',}
// Show the user `scope`, not the hash. Then bind their consent to it:const approval = {  scope_hash: await scopeHash(scope),  approver: { kind: 'human', id: userId, role: 'owner' },  approved_at: new Date().toISOString(),}
const writer = createMigrationWriter(provider, scope, approval)await writer.applyPlan({ ...plan, step: 'emit', actor })writer.audit  // which file, in which step, by which actor, in which commit

What it guarantees:

ScopeOnly paths an allowlist pattern covers. .contentrain/** is not implicit — a migration that wants the store asks for it, and the person approving sees that it does
ConsentOne approval, bound to the exact scope by scope_hash. An approval of src/** cannot be replayed against a scope that also has .github/workflows/**
BranchA migration/* ref. The contentrain branch is never a target and never a base — including through ApplyPlanInput's default, which a migration must not inherit
TrailOne MigrationAuditEntry per file: step, path, action, the pattern that allowed it, actor, timestamp, commit
UndoOne branch, delivered as one PR, revertable with one git revert

Every refusal happens before the provider is called, and a plan is refused whole: a plan with one path outside the scope writes nothing at all, not even its allowed part. A half-applied migration is harder to recover from than one that never started.

The path matcher is a security control and is written to fail closed. Traversal, absolute paths, backslash separators, percent-encoding, empty segments and control characters are refused before any pattern is consulted; patterns are anchored at both ends, so src/* does not cover src/a/b and nothing matches by being a prefix; and regex metacharacters in a pattern are literal, so an allowlist entry cannot silently cover more than it reads.

Design Constraints

Key design decisions in this package:

  • local-first by default — stdio transport + LocalProvider works without any network dependency
  • provider-agnostic engine — the core tools run over LocalProvider, GitHubProvider, or GitLabProvider behind a single RepoProvider contract (remote providers get the remote-safe subset); media tools ride the provider's optional media facet
  • remote provider SDKs (@octokit/rest, @gitbeaker/rest) are optional peer dependencies — pulled in only when their provider is used
  • JSON-only content storage
  • git-backed write workflow (worktree transaction locally, single atomic commit over the Git Data / REST APIs remotely)
  • canonical serialization — byte-deterministic output, sorted keys, trailing newline
  • framework-agnostic MCP layer
  • agent decides content semantics, MCP enforces deterministic execution
  • capability gates — tools that need a local checkout or source-tree access (scan, apply, doctor, init, scaffold, bulk, submit, merge, reconcile, branch tools) are not registered on remote providers; TOOL_REQUIREMENTS is the map

Development

From the monorepo root:

bash
pnpm --filter @contentrain/mcp buildpnpm --filter @contentrain/mcp testpnpm --filter @contentrain/mcp typecheckpnpm exec oxlint packages/mcp/src packages/mcp/tests

Related Packages

  • contentrain — CLI and local review tooling
  • @contentrain/query — generated runtime query SDK
  • @contentrain/rules — IDE/agent rules and prompts
  • @contentrain/types — shared schema and model types

Documentation

Full documentation at ai.contentrain.io/packages/mcp.

Part of the Contentrain ecosystem

Contentrain is a content governance ecosystem for teams and AI agents. This package is one of the open-source tools (docs). Studio is the team surface for review and roles; it drives this engine over the HTTP transport and hosts it for external agents as MCP Cloud, and the contentrain_media_* tools need a provider with a media stack such as Studio's. Migrate moves WordPress sites to Astro, and Bridge is a free WordPress plugin that exports a site as a Contentrain store.

License

MIT

Locale coverage (model.locales)

contentrain_validate checks an i18n: true model's parity against every locale in config.locales.supported. A model that declares locales — a subset of that list — is checked against the subset instead, which is how a partially-translated site states the truth rather than failing on translations it never had. Absent, as on every model that predates the field, means the whole project list.

A translation that was never written is a warning: an entry of a collection that one locale has and another lacks (Entry parity), like a document's missing translation. A dictionary key missing from a locale (Key parity) is a warning too. A locale with no content file (Locale file missing) is an error. Every message names the list it was evaluated against, so the two cases read apart:

Locale file missing: tr.json (checked against the model's own locales [en, tr])Entry parity: entry "a1b2c3" exists in en but missing in tr (checked against the project's supported locales [en, tr, da])

contentrain_model_save accepts locales and rejects a locale outside config.locales.supported. contentrain_validate fix:true reports a broken declaration but never invents one: narrowing a model's coverage is a content decision, and the only value the tool could derive — the locales that happen to have files today — would write the current gaps into the schema and silence the errors that reveal them.

Runtime model configuration

Structural contentrain_model_save edits preserve existing top-level form and comments blocks. These blocks belong to the runtime provider; the structural tool does not enable or change them. Its response lists preserved_blocks when configuration was carried forward.

来源:packages/mcp/README.md,提交 b3e0f74

工具

23

contentrain_status

Project Status

Get full project status (read-only). Returns config, models, context. Do NOT manually edit .contentrain/ based on this output.

无需输入参数。

contentrain_describe

Describe Model

Get full schema of a single model (read-only). Do NOT manually create content files — use contentrain_content_save instead.

输入参数model必填localeinclude_sample

contentrain_describe_format

Describe Format

Describes 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_init

Initialize Project

Initialize .contentrain/ structure. Changes are auto-committed to git — do NOT manually create .contentrain/ files.

输入参数stackdomainslocales

contentrain_scaffold

Scaffold Template

Template-based project setup. Available templates: blog, landing, docs, ecommerce, saas, i18n, mobile. Changes are auto-committed to git.

输入参数localestemplate必填with_sample_content

contentrain_model_save

Save Model

Create or update a model definition. Changes are auto-committed to git — do NOT manually edit .contentrain/ files after calling this tool.

输入参数id必填i18n必填kind必填name必填domain必填fieldslocalesdescriptiontitle_field必填content_pathlocale_strategy

contentrain_model_delete

Delete Model

Delete a model and its content/meta. Changes are auto-committed to git — do NOT manually edit .contentrain/ files.

输入参数model必填confirm必填

contentrain_content_save

Save Content

Save content entries. Entry format varies by model kind: DICTIONARY — provide "locale" and "data" (flat key-value, all string values); "id" and "slug" are ignored; data keys are the identities. COLLECTION — provide "locale" and "data"; "id" is optional (auto-generated if omitted); "slug" is ignored. DOCUMENT — provide "slug" (required), "locale", and "data"; use the "body" key inside data for markdown content. SINGLETON — provide only "locale" and "data". MEDIA FIELDS (image/video/file): for a media-library asset, pass its storage path ("media/...") or URL; in cloud mode these are automatically normalized to absolute public delivery URLs on save (in markdown bodies too), so saved content renders in a browser anywhere with no SDK — in local mode the relative path is kept as-is. For external images (e.g. a CDN or Unsplash URL), pass the URL directly; it is saved untouched. Changes are auto-committed to git — do NOT manually edit .contentrain/ files after calling this tool.

输入参数model必填entries必填

contentrain_content_delete

Delete Content

Delete content entries. For dictionaries, use "keys" to remove specific keys (omit to delete entire locale file). Changes are auto-committed to git — do NOT manually edit .contentrain/ files after calling this tool.

输入参数idkeysslugmodel必填localeconfirm必填

contentrain_content_list

List Content

List content entries (read-only). Each entry carries its publish state under "meta" — status, plus publish_at/expire_at when set — read from the listed locale's meta; singletons and dictionaries carry it at the top level. Local and remote sessions return the same shape. Change status with contentrain_content_status. Returns data from .contentrain/ — do NOT manually create or modify content files.

输入参数limitmodel必填filterlocaleoffsetresolve

contentrain_content_status

Change Entry Status

Change the status of content entries — this is how an entry is published, unpublished or archived. Address records the way their meta is laid out: COLLECTION — "entry_ids"; DOCUMENT — "slugs"; SINGLETON and DICTIONARY — neither (one record per locale). i18n models change every supported locale unless "locale" is given. Setting status "published" validates the targeted entries first; if they have errors, nothing is committed. Records already at the requested status are reported as unchanged and not rewritten. contentrain_content_list shows each entry's current status under "meta". Changes are committed to git and follow the project's review or auto-merge workflow — do NOT manually edit .contentrain/meta files.

输入参数model必填slugslocalestatus必填entry_ids

contentrain_vocabulary_save

Save Vocabulary Terms

Add or update canonical vocabulary terms. Terms nest as { "term-slug": { "en": "…", "tr": "…" } } — the OUTER key is the term, the INNER key is a locale. Merges with the existing vocabulary: a term you omit is untouched. Changes are auto-committed to git — do NOT manually edit .contentrain/vocabulary.json.

输入参数terms必填

contentrain_vocabulary_delete

Delete Vocabulary Terms

Remove canonical vocabulary terms by slug. Content already using a term is not touched — the vocabulary only advises. Changes are auto-committed to git.

输入参数terms必填confirm必填

contentrain_validate

Validate Project

Validate project content against model schemas. Detects required field violations, type mismatches, broken relations, secret leaks, i18n parity issues, and more. If fix:true, auto-fixes structural issues (canonical sort, orphan meta, missing locale files, stray non-i18n meta layout, scheduling keys an older content_save leaked into document frontmatter) and backfills a missing model title_field — do NOT manually edit .contentrain/ files. Content without meta gets meta with status published, matching what delivery already serves. A fix that would change whether an entry is delivered is listed in visibility_changes and left on its branch for review instead of auto-merged.

输入参数fixmodel

contentrain_submit

Submit Branches

Push cr/* branches to remote. MCP is push-only — PR creation is handled by the platform. Do NOT manually push or create PRs.

输入参数messagebranches

contentrain_merge

Merge Branch

Merge 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 "branch" name, or resolve by "model" (+ optional "locale"/"latest").

输入参数modelbranchlatestlocaleconfirm必填

contentrain_branch_list

List Branches

List 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).

输入参数remoteunmerged_only

contentrain_branch_delete

Delete Branch

Delete 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.

输入参数branch必填confirm必填

contentrain_reconcile

Reconcile Diverged Branches

Reconcile a diverged contentrain ↔ base-branch pair with a content-aware three-way merge. DRY RUN (default, dry_run:true): reports what would merge and which conflicts need a decision — touches nothing. EXECUTE (dry_run:false): performs the merge as a two-parent commit on contentrain and fast-forwards the base branch. Everything one side changed merges mechanically (entry-, key-, term+locale-level); only the same item changed differently on both sides becomes a conflict. Answer conflicts by passing resolutions (from the dry-run ids) and running again — a resolution whose values changed since the dry-run is dropped and the conflict re-reported. Recommended workflow: always run dry_run first, review the summary and conflicts, then execute.

输入参数dry_runresolutions

contentrain_scan

Scan Source Code

Scan project source code for content strings. Three modes: "graph" builds import/component graph for project intelligence, "candidates" extracts string literals with pre-filtering and pagination, "summary" provides quick overview stats. Read-only — no changes to disk or git. MCP finds strings deterministically; the agent decides what is content. Recommended workflow: start with "summary" or "graph" for orientation, then paginate through "candidates" to evaluate strings.

输入参数modelimitpathsoffsetexcludeincludemax_lengthmin_length

contentrain_apply

Apply Normalize

Apply normalize operations. Two modes: "extract" writes agent-approved strings to Contentrain content files (source untouched), "reuse" patches source files with agent-provided replacement expressions. DRY RUN (default, dry_run:true): validates inputs, resolves conflicts, and returns a full preview — NO changes to disk or git. EXECUTE (dry_run:false): writes files to disk, commits to a branch, and requires branch health check to pass. Recommended workflow: always run dry_run first, review the preview, then call again with dry_run:false to execute. Normalize operations always use review workflow (never auto-merge).

输入参数mode必填scopedry_runpatchesextractions

contentrain_bulk

Bulk Operations

Batch operations on content entries: copy a locale, or delete many collection entries. All operations are auto-committed to git. To publish or change status, use contentrain_content_status. DRY RUN (dry_run:true): runs the whole operation in a throwaway worktree and reports exactly what would change — nothing is committed and no branch survives. Recommended workflow: preview with dry_run:true, review the counts, then call again to execute.

输入参数model必填confirmdry_runentry_idsoperation必填source_localetarget_locale

contentrain_doctor

Project Health Report

Project health report (read-only). Returns structured checks: git, node, .contentrain/ structure, model parse, orphan content, branch pressure, SDK freshness. Pass `usage: true` for a deeper analysis of content-key references in source files (unused keys, duplicate dictionary values, locale coverage). Local-filesystem only — unavailable over remote providers.

输入参数usage

版本历史

48
  1. v3.12.3最新Nov 4, 2026
  2. v3.12.2Nov 4, 2026
  3. v3.12.0Nov 3, 2026
  4. v3.11.23Nov 3, 2026
  5. v3.11.22Oct 31, 2026
  6. v3.11.19Oct 30, 2026
  7. v3.11.18Oct 29, 2026
  8. v3.11.16Oct 25, 2026
  9. v3.11.15Oct 24, 2026
  10. v3.11.14Oct 23, 2026
  11. v3.11.11Oct 22, 2026
  12. v3.11.10Oct 22, 2026
  13. v3.11.9Oct 21, 2026
  14. v3.11.8Oct 21, 2026
  15. v3.11.7Oct 18, 2026
  16. v3.11.4Oct 18, 2026
  17. v3.11.3Oct 16, 2026
  18. v3.11.1Oct 10, 2026
  19. v3.11.0Oct 9, 2026
  20. v3.10.1Oct 9, 2026
  21. v3.10.0Oct 9, 2026
  22. v3.9.33Oct 7, 2026
  23. v3.9.31Oct 6, 2026
  24. v3.9.30Oct 6, 2026
  25. v3.9.28Oct 5, 2026
  26. v3.9.26Oct 5, 2026
  27. v3.9.25Oct 5, 2026
  28. v3.9.24Oct 5, 2026
  29. v3.9.22Oct 4, 2026
  30. v3.9.20Oct 4, 2026
  31. v3.9.17Oct 3, 2026
  32. v3.9.16Oct 3, 2026
  33. v3.9.11Oct 3, 2026
  34. v3.9.7Oct 3, 2026
  35. v3.9.6Oct 2, 2026
  36. v3.9.3Oct 2, 2026
  37. v3.9.2Sep 27, 2026
  38. v3.9.1Sep 27, 2026
  39. v3.8.2Sep 26, 2026
  40. v3.7.0Sep 26, 2026
  41. v3.6.7Sep 25, 2026
  42. v3.6.5Sep 23, 2026
  43. v3.6.2Sep 23, 2026
  44. v3.6.1Sep 22, 2026
  45. v3.6.0Sep 22, 2026
  46. v3.5.0Sep 18, 2026
  47. v3.4.3Sep 18, 2026
  48. v3.4.2Sep 16, 2026

评分

已满足适用检查项的 100%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分