Contentrain MCP Server
OfficialProvides automated git operations including branch synchronization, commits, and structural 3-way merges to manage content within a git-based headless CMS.
Integrates with GitHub repositories to manage Contentrain CMS projects, ensuring content changes are automatically synchronized with the remote repository.
Allows for the management of Contentrain models and content entries using Markdown, supporting the creation and update of localized content through a standardized protocol.
Supports the management of Contentrain models and content using the MDX format, enabling AI agents to handle rich content creation and schema management.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Contentrain MCP ServerCreate a draft blog post titled 'Getting Started' in English"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@contentrain/mcp
MCP (Model Context Protocol) server for Contentrain CMS content management. Enables AI agents (Claude, Codex, Cursor, etc.) and humans to create, read, update, and delete Contentrain models, content, and assets — with automatic git branch synchronization.
Why?
Contentrain is a git-based headless CMS. This MCP server lets AI assistants directly manage your Contentrain content through a standardized protocol, so you can say things like:
"Create a blog post model with title, excerpt, and cover image fields"
"Add a new blog post in English and Turkish"
"List all FAQ entries and update the second one"
All changes are committed and pushed to your git repository automatically.
Prerequisites
A Contentrain project already set up via the Contentrain Web App
The project's GitHub repository cloned locally
Node.js >= 18
Important: Contentrain projects must be initialized through the Web App first. The Web App creates the repository structure, the
contentrainbranch, models, and environment configuration. This MCP server operates on an existing Contentrain project — it does not replace the initial setup.
Quick Start
1. Install
# From npm (when published)
npm install -g @contentrain/mcp
# Or from source
git clone https://github.com/Contentrain/contentrain-mcp.git
cd contentrain-mcp
pnpm install && pnpm build2. Configure your MCP client
Add to your MCP client configuration:
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"contentrain": {
"command": "contentrain-mcp",
"env": {
"CONTENTRAIN_REPO_PATH": "/path/to/your/contentrain-project",
"CONTENTRAIN_BRANCH": "contentrain"
}
}
}
}Cursor (.cursor/mcp.json in your project root):
{
"mcpServers": {
"contentrain": {
"command": "contentrain-mcp",
"env": {
"CONTENTRAIN_REPO_PATH": "/path/to/your/contentrain-project",
"CONTENTRAIN_BRANCH": "contentrain"
}
}
}
}Claude Code (.mcp.json in your project root):
{
"mcpServers": {
"contentrain": {
"command": "contentrain-mcp",
"env": {
"CONTENTRAIN_REPO_PATH": "/path/to/your/contentrain-project",
"CONTENTRAIN_BRANCH": "contentrain"
}
}
}
}If installed from source instead of globally, replace
"command": "contentrain-mcp"with"command": "node"and add"args": ["/absolute/path/to/contentrain-mcp/dist/index.mjs"].
3. Start using
Once configured, your AI assistant has access to 14 tools. Here's an example conversation:
You: List all my models
Agent: → calls contentrain_list_models
You have 3 models: blog (MD, localized), faq (JSON), authors (JSON)
You: Show me the blog model schema
Agent: → calls contentrain_describe_model { modelId: "blog" }
Blog model has fields: title (string, required), description (string),
category (one-to-one → blogcategories), imagesrc (media), author (one-to-one → authors)
You: Create a new blog post titled "Getting Started with Contentrain"
Agent: → calls contentrain_create_content {
modelId: "blog",
data: { title: "Getting Started with Contentrain", slug: "getting-started-with-contentrain", description: "..." },
locale: "en",
status: "draft",
content: "# Getting Started\n\nWelcome to Contentrain..."
}
Created entry e7f3a1b9c0d2 in blog model (draft).
Committed and pushed to contentrain branch.
You: Now publish it
Agent: → calls contentrain_update_content {
modelId: "blog",
entryId: "e7f3a1b9c0d2",
data: { status: "publish" },
locale: "en"
}
Updated and published.Environments
Contentrain uses git branches to manage environments. Each environment maps to a branch:
Environment | Branch | Description |
Default |
| Main content branch (created automatically) |
Staging |
| Preview/staging environment |
Production |
| Production environment |
Environments are created via the Contentrain Web App. The branch naming follows the pattern contentrain-{environment-name}.
Targeting a specific environment
Set the CONTENTRAIN_BRANCH environment variable to the target environment's branch:
{
"mcpServers": {
"contentrain": {
"command": "contentrain-mcp",
"env": {
"CONTENTRAIN_REPO_PATH": "/path/to/project",
"CONTENTRAIN_BRANCH": "contentrain-staging"
}
}
}
}Multiple environments simultaneously
You can register multiple MCP server instances — one per environment:
{
"mcpServers": {
"contentrain-default": {
"command": "contentrain-mcp",
"env": {
"CONTENTRAIN_REPO_PATH": "/path/to/project",
"CONTENTRAIN_BRANCH": "contentrain"
}
},
"contentrain-staging": {
"command": "contentrain-mcp",
"env": {
"CONTENTRAIN_REPO_PATH": "/path/to/project",
"CONTENTRAIN_BRANCH": "contentrain-staging"
}
}
}
}Available Tools
Model Management
Tool | Description |
| List all models with metadata |
| Get full schema with field definitions |
| Create a new model (JSON, MD, or MDX) |
| Add a field to an existing model |
| Delete a model and all its content |
Content Management
Tool | Description |
| List all entries for a model |
| Get a single entry by ID |
| Create a new entry with validation |
| Update specific fields of an entry |
| Delete an entry (all locales + markdown) |
| Dry-run validation against model schema |
Asset Management
Tool | Description |
| List all registered assets |
| Register an existing file as an asset |
| Remove an asset from the registry |
Environment Variables
Variable | Default | Description |
|
| Path to the git repository |
|
| Target environment branch |
|
| Git remote name |
|
| Contentrain directory name |
|
| Skip git operations (local changes only) |
| — | Git commit author name |
| — | Git commit author email |
Programmatic Usage
You can also use the writer directly in your own code:
import { ContentrainWriter } from '@contentrain/mcp'
const writer = new ContentrainWriter({
repoPath: '/path/to/your/project',
branch: 'contentrain',
})
// Read operations (no git transaction needed)
const models = await writer.model.list()
const entries = await writer.content.list('blog-posts')
// Write operations (uses git worktree + commit + push)
await writer.transaction(async (tx) => {
await tx.content.create('blog-posts', {
title: 'Hello World',
excerpt: 'My first post',
}, { status: 'draft' })
}, { message: 'add new blog post' })How Git Sync Works
Every write operation runs inside a transaction:
Creates an isolated git worktree from the target branch
Applies all changes inside the worktree
Commits and pushes to the target branch
If the push is rejected (remote advanced), performs a structural 3-way merge — diffing JSON entries by their
IDfield instead of text lines — then retries (up to 3 attempts)Cleans up the worktree
This means concurrent writes from multiple agents or the Contentrain web app won't conflict.
Development
pnpm install # Install dependencies
pnpm dev # Watch mode build
pnpm test # Run tests (watch mode)
pnpm test:run # Run tests once
pnpm lint # Lint with oxlint
pnpm build # Production buildLicense
MIT
Available Tools
14 toolscontentrain_add_fieldC
Add a new field to an existing model.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | Target model ID | |
| name | Yes | Display name of the field | |
| fieldId | Yes | Unique field identifier | |
| componentId | Yes | UI component (single-line-text, integer, one-to-one, media, etc.) | |
| fieldType | Yes | Data type (string, number, boolean, relation, media, date, array) | |
| options | No | Field options (title-field, default-value, reference, etc.) | |
| validations | No | Field validations (required-field, unique-field) |
contentrain_create_contentA
Create a new content entry. System fields (ID, createdAt, updatedAt, status) are auto-generated. For localized models, specify locale to create in that language. Call contentrain_describe_model first to know required fields.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | Target model ID | |
| data | Yes | Content data object with field values matching model schema | |
| locale | No | Locale code (e.g., "en") — required for localized models | |
| status | No | Entry status (default: "draft") | |
| content | No | Markdown body content (only for MD/MDX models) |
contentrain_create_modelA
Create a new Contentrain model with field definitions. System fields (ID, createdAt, updatedAt, status) are auto-added. For MD/MDX models, slug and content fields are also auto-added.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Display name of the model | |
| modelId | Yes | Unique model ID in kebab-case | |
| type | Yes | Content type | |
| localization | Yes | Whether the model supports multiple languages | |
| description | No | Model description | |
| path | No | Base path for MD/MDX files | |
| fields | No | Custom field definitions (system fields are auto-added) |
contentrain_delete_contentADestructive
Delete a content entry by ID. For localized models, removes from all locale files. For MD/MDX, also deletes markdown files.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | Model ID | |
| entryId | Yes | Entry ID to delete (12-char hex) |
contentrain_delete_modelADestructive
Delete a model and all its content. WARNING: This is destructive and cannot be undone.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | Model ID to delete |
contentrain_deregister_assetADestructive
Remove an asset from assets.json registry. Does NOT delete the physical file.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Asset path to deregister |
contentrain_describe_modelA
Get detailed schema for a model including all field definitions, types, validations, and options. Call this BEFORE creating or updating content to understand required fields.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | The model ID to describe |
contentrain_get_contentBRead-only
Get a single content entry by ID.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | Model ID | |
| entryId | Yes | Entry ID (12-char hex) | |
| locale | No | Locale code for localized models |
contentrain_list_assetsBRead-only
List all registered assets in assets.json.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
contentrain_list_contentARead-only
List all content entries for a model. For localized models, specify a locale.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | Model ID to list content from | |
| locale | No | Locale code (e.g., "en", "tr") for localized models |
contentrain_list_modelsB
List all Contentrain models with their metadata (type, localization, etc.)
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
contentrain_register_assetB
Register a new asset in assets.json. The file must already exist at the specified path in the repository.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path to the asset file (e.g., "contentrain/static/hero.png") | |
| mimetype | Yes | MIME type (e.g., "image/png", "image/jpeg", "application/pdf") | |
| alt | No | Alt text for the asset |
contentrain_update_contentB
Update an existing content entry. Only provide fields you want to change. updatedAt is auto-set.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | Model ID | |
| entryId | Yes | Entry ID to update (12-char hex) | |
| data | Yes | Fields to update | |
| locale | No | Locale code for localized models | |
| content | No | Updated markdown body (only for MD/MDX models) |
contentrain_validateARead-only
Validate content data against model schema without writing. Use for dry-run checks.
| Name | Required | Description | Default |
|---|---|---|---|
| modelId | Yes | Model ID to validate against | |
| data | Yes | Content data to validate |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
14 tool updates
v0.1.0- First observed
contentrain_add_field - First observed
contentrain_create_content - First observed
contentrain_create_model - First observed
contentrain_delete_content - First observed
contentrain_delete_model - First observed
contentrain_deregister_asset - First observed
contentrain_describe_model - First observed
contentrain_get_content - First observed
contentrain_list_assets - First observed
contentrain_list_content - First observed
contentrain_list_models - First observed
contentrain_register_asset - First observed
contentrain_update_content - First observed
contentrain_validate
TDQS
Scored across 14 tools
Each tool has a distinct purpose with clear boundaries: model management (create/delete/describe/list), content operations (create/get/list/update/delete/validate), and asset handling (register/deregister/list). No tools overlap in functionality, and the descriptions explicitly differentiate them (e.g., contentrain_describe_model is for schema inspection, while contentrain_validate is for dry-run validation).
All tools follow a consistent 'contentrain_verb_noun' pattern with snake_case throughout (e.g., contentrain_create_model, contentrain_list_content). Verbs are descriptive and aligned with CRUD operations (create, get, list, update, delete) and domain-specific actions (describe, validate, register, deregister), making the naming highly predictable and readable.
With 14 tools, the server is well-scoped for a content management system, covering model lifecycle, content CRUD, asset management, and validation. Each tool serves a clear, non-redundant function, and the count is typical for this domain (similar to the GitHub MCP example), avoiding bloat or thin coverage.
The toolset provides complete coverage for content management: full CRUD for models and content, asset registration/deregistration, schema inspection, and validation. There are no obvious gaps; agents can perform all core workflows from model creation to content operations and asset handling, with no dead ends in the lifecycle.
Related MCP Connectors
Git-backed platform for skills, tools, and context for AI agents
AI-native Git-based CMS for Astro. Create and publish content in the browser, without learning git.
Plain-English git for agents: 22 tools to branch, commit, push and tag. Free tier.
Runnable, versioned lists for agents: tools, prompts and lists as resources. Git under the hood.