Contentrain について
Contentrain は、スキーマと Git ベースのワークフローで AI 生成コンテンツを管理する、プロバイダー非依存の MCP エンジンです。確定的な変更やレビュー、多言語間で一貫したシリアライズを求めるチーム向けです。
主な機能
- 01コンテンツ管理用の 27 個の MCP ツール
- 02モデルとローカライズ済みコンテンツの管理
- 03プロジェクト内容の検証と正規化
- 04Git ベースのブランチとレビュー
- 05ローカル優先、GitHub と GitLab にも対応
活用シーン
- 01構造化された多言語プロジェクト内容の管理
- 02ソースファイルをスキャンしてハードコード文字列を正規化
- 03マージ前にブランチ上でコンテンツ変更をレビュー
MCP 対応
stdio と HTTP の MCP サーバーモードを提供し、createServer(projectRoot) でプロセスに組み込むこともできます。利用可能なツールはプロバイダーと projectRoot の機能に応じて変わります。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://studio.contentrain.io/api/mcp/remoteclaude mcp add --transport http contentrain-contentrain https://studio.contentrain.io/api/mcp/remote{"mcpServers":{"contentrain-contentrain":{"type":"http","url":"https://studio.contentrain.io/api/mcp/remote"}}}Cursor で開く{"servers":{"contentrain-contentrain":{"type":"http","url":"https://studio.contentrain.io/api/mcp/remote"}}}VS Code で開く{"mcpServers":{"contentrain-contentrain":{"type":"http","url":"https://studio.contentrain.io/api/mcp/remote"}}}{"mcpServers":{"contentrain-contentrain":{"serverUrl":"https://studio.contentrain.io/api/mcp/remote"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
https://studio.contentrain.io/api/mcp/remotehttps://studio.contentrain.io/api/mcp/v1/{project_id}/mcp認証が必要ツール
詳細
@contentrain/mcp
Contentrain 向けのプロバイダーに依存しない MCP エンジンです。デフォルトではローカルファーストで、オプションの GitHub および GitLab バックエンドと、Studio などのリモートドライバー向け HTTP トランスポートを利用できます。
まずはこちらをご覧ください:
Contentrain は、AI 生成コンテンツのガバナンス基盤です:
- エージェントがコンテンツに関する決定を行います
- MCP が決定論的なファイルシステムと Git のワークフローを適用します
- 人間がレビューしてマージします
- システムがスキーマ、ロケール、シリアライズの一貫性を保ちます
このパッケージは、Contentrain の MCP 統合を支えるランタイムコアです。次のように利用できます:
- stdio MCP サーバー(
contentrain-mcp) - 埋め込み可能なサーバー(
createServer(projectRoot)) - 設定、モデル、コンテンツ、検証、スキャン、Git のトランザクションフロー向けの低レベルツールキット
インストール
pnpm add @contentrain/mcp
要件:
- Node.js
22+ - マシンに git がインストールされていること
より高品質なソーススキャンを実現するオプションのパーサーサポート:
@vue/compiler-sfc@astrojs/compilersvelte
これらはオプションの依存関係として指定されています。これらがなくてもスキャナーは動作しますが、インストールすると Vue/Astro/Svelte の検出精度が向上します。
できること
@contentrain/mcp はプロジェクト内の .contentrain/ ディレクトリを管理し、以下の MCP ツールを提供します。
- プロジェクトの初期化
- モデルの作成と削除
- コンテンツの保存、削除、一覧表示
- 検証と自動修正
- 正規化のスキャンと適用のワークフロー
- 一括操作
- ブランチの送信、レビューモードでのマージ、ブランチの健全性の把握
- プロジェクトの健全性チェック(doctor)
すべての書き込み操作は、Git による安全性を前提に設計されています。
- 専用の
contentrainブランチが、コンテンツ状態の唯一の信頼できる情報源として機能します - 各書き込みでは、
contentrainから分岐したフィーチャーブランチ上に一時的なワークツリーを作成します(ブランチ名:cr/{operation}/{model}/{locale}/{timestamp}-{suffix}) - 自動マージ:フィーチャーブランチを
contentrainにマージし、update-ref で baseBranch を更新します。チェックアウト中のブランチが baseBranch の場合は、.contentrain/ファイルを選択的に開発者のワーキングツリーに同期します - baseBranch は
CONTENTRAIN_BRANCH環境変数 →repository.default_branch→ リモート HEAD →main→master→ チェックアウト中のブランチ(最終手段)の順に決定されます。フィーチャーブランチ上で行われた書き込みでは、そのブランチのマージ、移動、プッシュは行われません - プランはワーキングツリーから読み取られますが、取得した
contentrainの先端にコミットされます。JSON の変更はキーごとに引き継がれるため、別の書き込み元がプッシュしたエントリは保持されます。同じ値が競合した場合は何も書き込まず、CONTENT_WORKING_TREE_STALEを返します - チェックアウト中のフィーチャーブランチ上で書き込みが更新しない
.contentrain/**は、代わりにcontentrainの参照から読み取ります(ソースファイルは引き続きワーキングツリーから読み取ります)。読み取りツールは、その情報源をcontent_sourceとして報告します - レビュー:チームでのレビュー用にフィーチャーブランチをリモートへプッシュします。マージ(または削除)されると、そのリモートコピーも削除されます。これはベストエフォートで行われ、config.json で
remoteBranchCleanup: falseにすると無効にできます - ローカルモード(
git.push: falseまたはCONTENTRAIN_NO_PUSH=1):リモートへのプッシュやリモート上での削除は一切行われず、すべての結果でその旨が示されます。詳しくはGit 環境とローカルモードをご覧ください - ローカルでの各書き込みの
gitブロックには、解決されたbase_branchが記載されます。チェックアウト中のブランチと異なる場合は、結果のwarningにワーキングツリーを変更していないことが示されます - コミットフック:マシンによるコミットではデフォルトでスキップされます。
git.verify: trueまたはCONTENTRAIN_VERIFY=1を指定すると実行され、フックが拒否した場合は、その出力とともに書き込みが失敗します。詳しくはコミットフックをご覧ください - マージ済みブランチの検出は、ベースの履歴が書き換えられた場合にも機能します(祖先関係の確認と patch-id によるフォールバック)。このため、リベースやスカッシュによって古いブランチが取り残されることはありません
- MCP の Git 操作中に開発者のワーキングツリーが変更されることはありません(stash、checkout、merge は行いません)
context.jsonがフィーチャーブランチに含まれることはありません。マージ後にcontentrainブランチ上で再生成されます(ローカルではトランザクションレイヤーが、リモートのフローではマージを担当するオーケストレーターが生成します)- 正規化された JSON 出力:キーをソートし、インデントは 2 スペース、末尾に改行を付けます
- 検証結果と次の手順のヒントを呼び出し元に提示します
ツール一覧
MCP ツールは 27 個(コア 22 個 + メディア 5 個)で、クライアントの安全性に関するヒントとしてアノテーション(readOnlyHint、destructiveHint、idempotentHint、および contentrain_media_ingest 以外のすべてで openWorldHint: false)が付与されています。contentrain_media_ingest は、呼び出し元から指定された URL をサーバー側で取得します。
ツールの一覧は機能に応じて決まります。 tools/list は、解決されたプロバイダーと projectRoot の組み合わせで実際に利用できるツールのみを公開します。ローカルの stdio サーバーでは 22 個のコアツールが一覧表示されます。リモートプロバイダー(GitHub/GitLab、ローカルのチェックアウトなし)が制御するセッションでは、リモートで安全に利用できるツール(status、describe、describe_format、model_save、model_delete、content_save、content_delete、content_list、vocabulary_save、vocabulary_delete、validate)のみが一覧表示されます。要件マップは TOOL_REQUIREMENTS(@contentrain/mcp/tools/availability)にあります。
| ツール | 目的 | 読み取り専用 | 破壊的 |
|---|---|---|---|
contentrain_status | プロジェクトのステータス、設定、モデル、ブランチの状態、コンテキスト | はい | — |
contentrain_describe | モデルの完全なスキーマとサンプルデータ | はい | — |
contentrain_describe_format | ファイル形式とストレージの仕様リファレンス | はい | — |
contentrain_doctor | プロジェクトの健全性レポート(環境、構造、モデル、孤立項目、ローカルおよびリモートのブランチ、SDK) | はい | — |
contentrain_init | .contentrain/ の構造と基本設定を作成 | — | — |
contentrain_scaffold | ブログ、ドキュメント、ランディングページ、SaaS などのスターターテンプレートを適用 | — | — |
contentrain_model_save | モデル定義を作成または更新 | — | — |
contentrain_model_delete | モデル定義を削除 | — | はい |
contentrain_content_save | あらゆる種類のモデルのコンテンツエントリーを保存 | — | — |
contentrain_content_delete | コンテンツエントリーを削除 | — | はい |
contentrain_content_list | コンテンツエントリーを読み取る | はい | — |
contentrain_validate | プロジェクトのコンテンツを検証し、必要に応じて構造上の問題を自動修正 | — | — |
contentrain_submit | cr/* ブランチをリモートにプッシュし、その後、マージ済みのローカルおよびリモートの残存ブランチを遅延削除 | — | — |
contentrain_merge | レビューモードのブランチを contentrain にローカルでマージ(ブランチ名を完全一致で指定するか、モデルで指定)。リモート上のコピーは削除 | — | — |
contentrain_reconcile | 分岐した contentrain ↔ base のペアをコンテンツを考慮して三者マージ(最初に dry_run、次に解決方法を指定) | — | — |
contentrain_branch_list | マージ状況とともに、保留中の cr/* ブランチを一覧表示(remote: true を指定するとリモートの表示を追加) | はい | — |
contentrain_branch_delete | 古くなった、または失敗した cr/* ブランチをローカルとリモートで削除(contentrain ブランチは保護されます) | — | はい |
contentrain_scan | グラフおよび候補ベースのハードコード文字列スキャン | はい | — |
contentrain_apply | dry-run に対応した、抽出/再利用の正規化された実行 | — | — |
contentrain_bulk | ロケールの一括コピー、ステータス更新、削除(dry_run でプレビュー) | — | — |
contentrain_vocabulary_save | 正規の用語を追加または更新(既存の用語と統合) | — | — |
contentrain_vocabulary_delete | スラッグで正規の用語を削除(confirm: true) | — | はい |
contentrain_media_list | メディアアセットを一覧表示(検索、タグでの絞り込み、カーソルページネーション) | はい | — |
contentrain_media_get | ID でメディアアセットを 1 件取得 | はい | — |
contentrain_media_ingest | ソース URL からアセットを取り込む(プロバイダーがサーバー側で取得) | — | — |
contentrain_media_update | アセットのメタデータ(alt、タグ、ファイル名)を更新 | — | — |
contentrain_media_delete | メディアスタックからアセットを削除 | — | はい |
5 つの contentrain_media_* ツールは、プロバイダーのオプションのメディア機能(RepoProvider.media)への決定論的なパススルーであり、プロバイダーが機能を公開している場合(例:Studio MCP Cloud)に限り登録されます。ローカルの stdio サーバーや、標準の GitHub/GitLab プロバイダーには表示されません。取り込みは URL ベースです(MCP にはバイナリチャネルがありません)。取得時の SSRF/MIME/サイズに関するポリシーは、プロバイダー実装が担います。
クイックスタート
CLI で設定(推奨)
npx contentrain setup claude-code # or: cursor, vscode, windsurf, copilot
IDE に適した MCP 設定ファイルが自動作成されます。詳しくはCLI ドキュメントをご覧ください。
スタンドアロンの MCP サーバーとして実行
CONTENTRAIN_PROJECT_ROOT=/path/to/project npx -y @contentrain/mcp
CONTENTRAIN_PROJECT_ROOT を省略した場合は、現在の作業ディレクトリが使用されます。
Git 環境とローカルモード
これらはローカルプロバイダー(stdio、LocalProvider)に適用されます。
| 変数 | デフォルト | 効果 |
|---|---|---|
CONTENTRAIN_BRANCH | 未設定 | contentrain ブランチが進む基準ブランチです。repository.default_branch より優先され、その後はリモート HEAD → main → master → チェックアウト中のブランチの順になります。プロセスごとに適用され、設定には書き込まれません |
CONTENTRAIN_REMOTE | origin | すべてのフェッチとプッシュ(およびリモートブランチのクリーンアップ)に使用するリモートです |
CONTENTRAIN_NO_PUSH | 未設定 | 1/true でローカルモードを有効にし、0/false で無効にします。それ以外の値は無視されます |
CONTENTRAIN_VERIFY | 未設定 | 1/true で Contentrain のコミットにリポジトリのコミットフックを実行し、0/false でスキップします。git.verify より優先されます。それ以外の値は無視されます |
ローカルモードでは、すべての書き込みをローカルブランチにとどめます。ブランチのプッシュ、レビューのプッシュ、自動マージ後・承認後・リコンシル後のプッシュ、リモートブランチの削除やプルーニングは行いません。フェッチはプッシュではないため、リモートが存在すれば引き続き実行されます。.contentrain/config.json に "git": { "push": false } を設定するか、1 回の実行で CONTENTRAIN_NO_PUSH=1 を指定すると、プロジェクトでローカルモードを有効にできます。
優先順位:環境変数は、どちらの方向でも設定より優先されます。設定でプッシュが許可されていても CONTENTRAIN_NO_PUSH=1 でプッシュが無効になり、git.push: false が設定されていても CONTENTRAIN_NO_PUSH=0 でプッシュが有効になります。どちらも指定されていない場合、プッシュは有効です。
成功したかどうかが曖昧になることはありません。各書き込みの git ブロックには remote_push: "disabled" と remote_note: "not pushed (local mode)" が報告され、next_steps には LOCAL MODE の行が含まれます。contentrain_submit はプッシュせず、エラーを返します。レビュー用ブランチは contentrain_merge で取り込みます。contentrain_merge と contentrain_branch_delete は通常どおりローカルブランチを削除し、remote_skipped: "local-mode" を報告します。リモートのコピーはそのまま残ります。
コミットフック
デフォルトでは、Contentrain による機械的なコミット(cr/* コンテンツコミット、context.json コミット、リコンシルのマージコミット、空のリポジトリの初期コミット)では、リポジトリのコミットフック(pre-commit、prepare-commit-msg、commit-msg)をスキップします。これにより既存プロジェクトとの互換性を保てます。これらのコミットは node_modules のない一時ワークツリーで作成され、[contentrain] … という件名は厳格な commitlint のチェックに失敗するためです。従来どおり、マージではマージフックが実行され、プッシュでは pre-push が実行されます。
すべての機械的なコミットでコミットフックを実行するには、.contentrain/config.json に "git": { "verify": true } を設定するか、1 回の実行で CONTENTRAIN_VERIFY=1 を指定します(CONTENTRAIN_VERIFY=0 を指定すると、設定にかかわらずフックをスキップします)。フックを有効にした場合:
- コンテンツコミットを拒否するフックがあると、書き込みは失敗します。何も反映されず、ツールのエラーにはフックの出力が含まれます。フックなしで再試行することはありません。
- 後続の
context.jsonコミットだけを拒否するフックがある場合(コンテンツはすでにcontentrainに反映されています)、その内容は無視されず、結果のwarningで報告されます。 - フックはシステムの一時ディレクトリ配下のワークツリーで動作する必要があります。
npx lint-stagedを実行するフックの場合、そこで利用できるようにツールを用意してください。
サーバーを独自のプロセスに組み込む
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 はオプションオブジェクト { provider, projectRoot?, instructions? } も受け取ります。instructions は、クライアントが initialize 時に受け取る MCP の instructions 文字列を設定します(デフォルトはサーバーが登録するツールに応じた defaultInstructions で、すべてのツールが利用可能な場合は DEFAULT_INSTRUCTIONS です。512 文字以内に収められます。省略するには '' を渡します)。HTTP エントリ(startHttpMcpServer、startHttpMcpServerWith)も同じ instructions オプションを受け取ります。
MCP フローの例
エージェントの一般的なワークフロー:
contentrain_statusを呼び出します- 必要に応じて
contentrain_initを呼び出します contentrain_model_saveまたはcontentrain_scaffoldでモデルを作成しますcontentrain_content_saveでコンテンツを保存しますcontentrain_validateで検証します- ハードコードされた文字列には、
contentrain_scanを呼び出してからcontentrain_applyを使用します contentrain_submitでレビュー用ブランチをプッシュします
Normalize フロー
Normalize は意図的に 2 つのフェーズに分けられています。
1. 抽出
contentrain_scan は候補文字列を検出します。
contentrain_apply に mode: "extract" を指定すると、次の処理を行います。
- モデルを作成または更新します
- コンテンツエントリーを書き込みます
- ソースの追跡情報を記録します
- レビューブランチ(
cr/normalize/extract/{domain}/{timestamp})を作成します
2. 再利用
contentrain_apply に mode: "reuse" を指定すると、次の処理を行います。
- エージェントが提供する式を使ってソースファイルにパッチを適用します
- 必要に応じてインポートを追加します
- パッチ対象パスの安全性とスコープをチェックします
- 別のレビューブランチ(
cr/normalize/reuse/{model}/{locale}/{timestamp})を作成します
この分割により、コンテンツの抽出とソースの書き換えが分離されます。
トランスポート/プロバイダーの要件
Normalize(contentrain_scan と contentrain_apply)には、ローカルディスクへのアクセスが必要です。AST スキャナーがソースツリーを走査し、ファイルに直接パッチを適用するためです。Normalize は LocalProvider 上でのみ実行できます(stdio トランスポート、または LocalProvider を設定した HTTP トランスポート)。
GitHubProvider などのリモートプロバイダーでは、astScan: false、sourceRead: false、sourceWrite: false が公開されます。リモートプロバイダー経由でこれらのツールを呼び出すと、共通の機能エラーが返されます。
{
"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."
}
リモートトランスポートを利用するエージェントは、Normalize を呼び出す前にローカルトランスポート(またはローカルチェックアウト)に切り替えてください。
リモートプロバイダー
MCP では、同じ RepoProvider 契約のもと、3 つのバックエンドをサポートしています。
- LocalProvider — simple-git + worktree。Normalize を含むすべてのツールを利用できます。stdio トランスポートではこれがデフォルトです。
- GitHubProvider — Git Data API と Repos API を介した Octokit。クローンも worktree も不要です。
@octokit/restはオプションのピア依存関係として提供されます。 - GitLabProvider — GitLab REST API を介した gitbeaker。クローンも worktree も不要です。
@gitbeaker/restはオプションのピア依存関係として提供されます。gitlab.com とセルフホスト版 CE / EE をサポートしています。
各リモートプロバイダーは、同じインターフェースを実装します。リーダー(readFile / listDirectory / fileExists)、ライター(applyPlan — 1 つのアトミックなコミット)、ブランチ操作(list / create / delete / diff / merge / isMerged / getDefaultBranch)です。mergeBranch は GitHub では直接実行されます。GitLab では MR を作成してすぐに承認するため、どちらの場合も最終的な MergeResult の形式は同じです。また、GitHub プロバイダーでは applyPlan の base(および createBranch の fromRef)に完全なコミット SHA を指定でき、比較交換方式の書き込みが可能です。ブランチが存在しない場合はそのコミットから分岐し、ブランチがそのコミットから移動している場合は PROVIDER_CONFLICT を返して書き込みを拒否します。
GitLab — インストールと使用方法
pnpm add @gitbeaker/rest
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
機能:sourceRead、sourceWrite、astScan、localWorktree はすべて false、pushRemote、branchProtection、pullRequestFallback は true です。GitLabProvider では Normalize / scan / apply は機能エラーで拒否されます。これらのワークフローではローカルトランスポートに切り替えてください。
Bitbucket — 近日対応予定
Bitbucket Cloud + Data Center のサポートはロードマップに含まれています。プロバイダーが提供されるまでは、contentrain_describe_format ツールを使い、LocalProvider 経由で Bitbucket のチェックアウトから Contentrain のコンテンツ操作を手動で実行してください。
コアのエクスポート
このパッケージは、埋め込みや高度な用途向けに、低レベルのモジュールも公開しています。
@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—planReconcileとそのbindRefリーダーアダプターを含むプラン API、およびコンテンツルート相対のパスヘルパー:contentDirPath、contentFilePath、documentFilePath、metaFilePath@contentrain/mcp/core/overlay-reader@contentrain/mcp/core/migration— 許可リストに基づく移行書き込みパス:createMigrationWriter、scopeHash、decide。詳しくは、下記の移行の書き込みを参照してください@contentrain/mcp/util/detect@contentrain/mcp/util/fs@contentrain/mcp/git/transaction@contentrain/mcp/git/branch-lifecycle— ブランチの健全性確認/クリーンアップに加え、リモートの cr/* のライフサイクルも扱います:deleteRemoteBranch、listRemoteCrBranches、pruneMergedRemoteBranches、isRefMerged、classifyMergedBranches@contentrain/mcp/git/base-branch— すべての MCP 書き込みとcontentrain status/serveが使用する、ベースブランチを解決する単一の関数resolveBaseBranch(env →repository.default_branch→origin/HEAD→main→master→ チェックアウト中のブランチ)、同じ解決処理に加えてどの段階で決定したかを返すresolveBaseBranchSource、およびinitがrepository.default_branchに記録する値(またはnull)を返すresolveInitDefaultBranch@contentrain/mcp/git/errors@contentrain/mcp/git/reconcile— ローカルの調整実行関数reconcileBranches@contentrain/mcp/tools/annotations@contentrain/mcp/templates@contentrain/mcp/providers/local@contentrain/mcp/providers/github@contentrain/mcp/providers/gitlab
これらは、Contentrain のツールや高度な連携を目的としており、.contentrain/ ファイルを手動で直接編集するためのものではありません。
マイグレーションによる書き込み
マイグレーションが届けるのはコンテンツではなく、コードベースです。src/、public/、
package.json、ロックファイル、デプロイ設定などです。コンテンツの書き込み経路は、
こうしたもののために作られたことはありません。それを拡張すれば、製品全体の基盤となる
セキュリティ境界、「Contentrain は .contentrain/ にしか書き込まない」という約束を、
ひそかに動かすことになります。これは実装上の詳細ではなく、約束です。
代わりにゲートとなるのが @contentrain/mcp/core/migration です。これは、すでに任意の
パスに書き込める applyPlan を持つプロバイダーをラップし、その前に同意を求めます。
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
保証される内容は次のとおりです。
| スコープ | 許可リストのパターンに含まれるパスのみが対象です。.contentrain/** は暗黙に含まれません。ストアを必要とするマイグレーションはその許可を求め、承認者にもその旨が表示されます |
| 同意 | 1 回の承認は scope_hash によって正確なスコープに紐づきます。src/** の承認を、.github/workflows/** も含むスコープに対して再利用することはできません |
| ブランチ | migration/* ref を使用します。contentrain ブランチは対象にもベースにもなりません。マイグレーションが引き継いではならない ApplyPlanInput のデフォルト値を通じた場合も同様です |
| 履歴 | 各ファイルにつき 1 件の MigrationAuditEntry が記録されます。ステップ、パス、アクション、その操作を許可したパターン、実行者、タイムスタンプ、コミットが含まれます |
| 取り消し | 1 つのブランチで 1 つの PR として反映され、git revert 1 回で取り消せます |
拒否はすべてプロバイダーの呼び出し前に行われ、プラン全体が拒否されます。スコープ外のパスが 1 つでも含まれるプランは、許可された部分も含めて一切書き込みません。適用が途中で失敗したマイグレーションは、最初から開始されなかったマイグレーションより復旧が困難です。
パスマッチャーはセキュリティ制御であり、フェイルクローズするよう実装されています。パストラバーサル、絶対パス、バックスラッシュ区切り、パーセントエンコーディング、空のセグメント、制御文字は、パターンを参照する前に拒否されます。パターンは両端にアンカーが付けられているため、src/* は src/a/b を対象とせず、プレフィックスであることを理由にマッチすることもありません。また、パターン内の正規表現メタ文字はリテラルとして扱われるため、許可リストの項目が、記述された範囲を超えてひそかに対象を広げることはありません。
設計上の制約
このパッケージの主な設計上の決定事項は次のとおりです。
- デフォルトでローカルファースト — stdio トランスポートと LocalProvider は、ネットワークに依存せずに動作します
- プロバイダーに依存しないエンジン — 同じコアツールが、単一の
RepoProviderコントラクトのもとで、LocalProvider、GitHubProvider、GitLabProvider 上で動作します。メディアツールはプロバイダーのオプションのメディアファセットを使用します - リモートプロバイダー SDK(
@octokit/rest、@gitbeaker/rest)は任意のピア依存関係です。対応するプロバイダーを使用する場合にのみ読み込まれます - JSON のみのコンテンツストレージ
- git ベースの書き込みワークフロー(ローカルでは worktree トランザクション、リモートでは Git Data/REST API を介した単一のアトミックコミット)
- 正規化されたシリアライズ — バイト単位で決定的な出力、キーのソート、末尾の改行
- フレームワークに依存しない MCP レイヤー
- コンテンツの意味づけはエージェントが担い、決定的な実行は MCP が保証します
- ケイパビリティゲート — ソースツリーへのアクセスが必要なツール(normalize、scan、apply、doctor)は、リモートプロバイダー上で一律の
capability_requiredエラーを返します
開発
モノレポのルートから実行します。
pnpm --filter @contentrain/mcp build
pnpm --filter @contentrain/mcp test
pnpm --filter @contentrain/mcp typecheck
pnpm exec oxlint packages/mcp/src packages/mcp/tests
関連パッケージ
contentrain— CLI とローカルレビュー用ツール@contentrain/query— 生成されたランタイムクエリ SDK@contentrain/rules— IDE/エージェント向けのルールとプロンプト@contentrain/types— 共有スキーマとモデル型
ドキュメント
詳細なドキュメントは ai.contentrain.io/packages/mcp をご覧ください。
ライセンス
MIT
ロケールのカバレッジ(model.locales)
contentrain_validate は、i18n: true のモデルについて、config.locales.supported に含まれるすべてのロケールとの整合性を確認します。locales を宣言しているモデルは、そのリストの一部のみを対象として確認されます。これにより、一部のみ翻訳されたサイトは、存在しない翻訳についてエラーになるのではなく、実際の状況を正しく示せます。locales が指定されていない場合(このフィールドが導入される前のすべてのモデルなど)は、プロジェクト全体のロケールリストが対象になります。
未作成の翻訳は警告になります。たとえば、あるロケールにはあり、別のロケールにはないcollectionのエントリ(Entry parity)や、documentの翻訳が欠けている場合です。コンテンツファイルがないロケール(Locale file missing)と、ロケールに存在しないdictionaryキー(Key parity)はエラーになります。各メッセージには照合対象のリストが明記されるため、次の2つのケースを区別できます。
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 はlocalesを受け付け、config.locales.supportedに含まれないロケールは拒否します。contentrain_validate fix:true は宣言の不備を報告しますが、宣言を自動生成することはありません。モデルのカバレッジを狭めるかどうかはコンテンツに関する判断です。また、ツールが導き出せる値は、現在ファイルが存在するロケールだけです。その値を書き込むと、現在の不足をスキーマに反映してしまい、その不足を明らかにするエラーが表示されなくなるためです。
ランタイムモデル設定
構造を変更するcontentrain_model_saveの編集では、既存のトップレベルのformブロックとcommentsブロックが維持されます。これらのブロックはランタイムプロバイダーに属しており、構造変更ツールが有効化したり変更したりすることはありません。設定が引き継がれた場合、応答にはpreserved_blocksが含まれます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。