Appendix A: MCP Tools Reference
Complete reference documentation for all Vibe CMS Model Context Protocol (MCP) tools. This appendix provides detailed specifications for every tool available through Claude Code and other MCP clients.
Overview
Vibe CMS provides 18 MCP tools organized into 6 functional categories:
- Collections (2 tools): Query and manage content collections
- Fields (4 tools): Add, update, reorder, and delete collection fields
- Content (4 tools): Create, read, update, and delete content items
- Locales (2 tools): Manage project localization settings
- Folders (2 tools): Organize files in hierarchical folders
- Files (5 tools): Upload, manage, and preview files
Collections Tools
collections()
Query collections with optional slug filter to get schema information.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
slug |
string | null |
No | Collection slug (e.g., 'blog-posts'). If provided, returns single collection with fields. If omitted, lists all collections. |
Return Value:
When slug is provided (single collection):
{
collection: {
name: string,
slug: string,
description: string,
is_singleton: boolean,
fields: [
{
field_name: string,
field_type: 'text' | 'markdown' | 'number' | 'boolean' | 'file',
interface_type: 'input' | 'textarea' | 'markdown' | 'single_file' | 'multiple_files',
is_required: boolean,
sort_order: number
}
]
},
message: string
}
When slug is omitted (list all):
{
collections: Array<{...}>,
count: number
}
Usage Examples:
// List all collections
const result = await mcp.collections();
console.log(result.collections); // Array of all collections
// Get specific collection with field schema
const blogPosts = await mcp.collections({ slug: 'blog-posts' });
console.log(blogPosts.collection.fields); // Field definitions
Common Errors:
Collection 'xyz' not found- Invalid slug, usecollections()without parameters to list available collections
Related Tools: manage_collection, add_collection_field
manage_collection()
Create, update, or delete collections with a unified interface.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
'create' | 'update' | 'delete' |
Yes | Operation type |
slug |
string |
Yes | Collection slug (URL-safe identifier) |
name |
string | null |
Conditional | Display name (required for create/update) |
description |
string | null |
No | Optional description |
is_singleton |
boolean | null |
No | Single item collection (e.g., 'Homepage') |
confirm_delete |
boolean |
No | Must be true to confirm deletion (default: false) |
Return Value:
Success response:
{
success: true,
collection: {...}, // Filtered collection object
message: string,
next_steps?: string // For create action
}
Error response:
{
error: string,
suggestion?: string
}
Usage Examples:
// Create new collection
await mcp.manage_collection({
action: 'create',
slug: 'team-members',
name: 'Team Members',
description: 'Company team directory',
is_singleton: false
});
// Update collection
await mcp.manage_collection({
action: 'update',
slug: 'team-members',
name: 'Team Directory' // Rename
});
// Delete collection (requires confirmation)
await mcp.manage_collection({
action: 'delete',
slug: 'old-collection',
confirm_delete: true
});
Common Errors:
name is required for create action- Must provide name when creatingCollection with slug 'xyz' already exists- Slug must be uniqueDeletion requires confirmation- Must setconfirm_delete: true
Related Tools: collections, add_collection_field
Field Tools
add_collection_field()
Add a new field to an existing collection with type and interface configuration.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
collection_slug |
string |
Yes | Slug of collection (e.g., 'blog-posts') |
name |
string |
Yes | Field name (lowercase, letters/numbers/underscores, must start with letter) |
field_type |
string |
Yes | Data type: 'text', 'markdown', 'number', 'boolean', 'file' |
interface_type |
string |
Yes | UI interface: 'input', 'textarea', 'markdown', 'single_file', 'multiple_files' |
is_required |
boolean |
No | Whether field is required (default: false) |
sort_order |
number |
No | Field ordering, lower numbers first (default: 0) |
Field Type & Interface Compatibility:
| field_type | Compatible interface_type | Use Case |
|---|---|---|
text |
input, textarea |
Short text (input) or long text (textarea) |
markdown |
markdown |
Rich content with formatting |
number |
input |
Numeric values |
boolean |
input |
True/false values (checkbox) |
file |
single_file, multiple_files |
One file or file gallery |
Reserved Field Names:
Cannot use: id, created_at, updated_at, data, select, from, where, and, or, not, null, true, false, table, column
Return Value:
{
success: true,
field: {
field_name: string,
field_type: string,
interface_type: string,
is_required: boolean,
sort_order: number
},
message: string
}
Usage Examples:
// Add title field (short text)
await mcp.add_collection_field({
collection_slug: 'blog-posts',
name: 'title',
field_type: 'text',
interface_type: 'input',
is_required: true,
sort_order: 1
});
// Add content field (rich text)
await mcp.add_collection_field({
collection_slug: 'blog-posts',
name: 'content',
field_type: 'markdown',
interface_type: 'markdown',
is_required: true,
sort_order: 2
});
// Add featured image (single file)
await mcp.add_collection_field({
collection_slug: 'blog-posts',
name: 'featured_image',
field_type: 'file',
interface_type: 'single_file',
is_required: false,
sort_order: 3
});
Common Errors:
Field name must start with lowercase letter...- Invalid field name format'id' is a reserved word- Cannot use reserved field namesInterface 'textarea' not compatible with field type 'number'- Invalid type/interface combinationField with name 'title' already exists- Field names must be unique within collection
Related Tools: update_collection_field, reorder_collection_fields, delete_collection_field
update_collection_field()
Update field interface, required status, or sort order. Cannot change field type or rename field.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
collection_slug |
string |
Yes | Slug of collection |
field_name |
string |
Yes | Name of field to update |
interface_type |
string | null |
No | New UI interface (must be compatible with field_type) |
is_required |
boolean | null |
No | New required status |
sort_order |
number | null |
No | New sort order |
Return Value:
{
success: true,
field: {...},
message: string
}
Usage Examples:
// Change text field from input to textarea
await mcp.update_collection_field({
collection_slug: 'blog-posts',
field_name: 'summary',
interface_type: 'textarea'
});
// Make field required
await mcp.update_collection_field({
collection_slug: 'blog-posts',
field_name: 'author',
is_required: true
});
// Update sort order
await mcp.update_collection_field({
collection_slug: 'blog-posts',
field_name: 'published_date',
sort_order: 5
});
Common Errors:
At least one field property must be provided- Must update at least one propertyInterface 'markdown' not compatible with field type 'text'- Interface must match field typeField 'xyz' not found- Invalid field name
Related Tools: add_collection_field, reorder_collection_fields
reorder_collection_fields()
Reorder all fields in a collection by providing complete ordered list.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
collection_slug |
string |
Yes | Slug of collection |
field_names |
string[] |
Yes | List of ALL field names in desired order. ALL existing fields must be included. |
Return Value:
{
success: true,
message: string,
new_order: string[] // Field names in new order
}
Usage Examples:
// Reorder blog post fields
await mcp.reorder_collection_fields({
collection_slug: 'blog-posts',
field_names: [
'title', // First
'slug', // Second
'author', // Third
'content', // Fourth
'featured_image', // Fifth
'published_date' // Last
]
});
Important: You MUST include ALL existing fields. Any omitted fields will cause an error.
Common Errors:
field_names list cannot be empty- Must provide at least one fieldMissing fields: title, content- All fields must be included in reorder
Related Tools: add_collection_field, update_collection_field
delete_collection_field()
Permanently delete a field from collection, removing all data.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
collection_slug |
string |
Yes | Slug of collection |
field_name |
string |
Yes | Name of field to delete |
confirm |
boolean |
No | Must be true to confirm deletion (default: false) |
Return Value:
{
success: true,
message: string,
deleted: {
collection_slug: string,
field_name: string
}
}
Usage Examples:
// Delete deprecated field (requires confirmation)
await mcp.delete_collection_field({
collection_slug: 'blog-posts',
field_name: 'legacy_category',
confirm: true
});
Warning: This permanently deletes the field and ALL its data across ALL content items. This action cannot be undone.
Common Errors:
Deletion not confirmed- Must setconfirm: trueField 'xyz' not found- Invalid field name
Related Tools: add_collection_field, update_collection_field
Content Tools
content()
Get content items - list all in collection or get single item with translations.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
collection_slug |
string |
Yes | Collection slug (e.g., 'blog-posts') |
content_item_id |
string | null |
No | Specific content item ID. If provided, returns single item. |
locale |
string | null |
No | Filter by locale (e.g., 'en-US'). Only used with content_item_id. |
Return Value:
When content_item_id is provided:
{
id: string,
collection_slug: string,
description: string,
status: 'draft' | 'published' | 'archived',
translations: [
{
data: {...}, // Field values
locale: string
}
]
}
When content_item_id is omitted:
{
items: Array<{id: string, ...}>,
count: number,
collection_slug: string
}
Usage Examples:
// List all blog posts
const posts = await mcp.content({
collection_slug: 'blog-posts'
});
console.log(posts.count); // Total count
// Get specific post with all translations
const post = await mcp.content({
collection_slug: 'blog-posts',
content_item_id: 'abc-123'
});
console.log(post.translations); // All language versions
// Get specific post in English only
const enPost = await mcp.content({
collection_slug: 'blog-posts',
content_item_id: 'abc-123',
locale: 'en-US'
});
Common Errors:
Content item 'xyz' not found- Invalid content item IDCollection 'xyz' not found- Invalid collection slug
Related Tools: create_content, update_content_translation, delete_content
create_content()
Create new content item metadata without translation data.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
collection_slug |
string |
Yes | Collection slug |
description |
string | null |
No | Optional description of content item |
status |
string |
No | Initial status: 'draft', 'published', 'archived' (default: 'draft') |
Return Value:
{
id: string, // Use this for update_content_translation
collection_slug: string,
status: string,
description: string,
message: string
}
Usage Examples:
// Create new blog post (draft)
const result = await mcp.create_content({
collection_slug: 'blog-posts',
description: 'Article about AI trends',
status: 'draft'
});
const contentItemId = result.id;
// Next: Use update_content_translation to add actual content
Workflow: After creating, use update_content_translation() to add actual field data for each locale.
Common Errors:
Invalid status 'xyz'- Status must be 'draft', 'published', or 'archived'Collection 'xyz' not found- Invalid collection slug
Related Tools: update_content_translation, content, delete_content
update_content_translation()
Create or update content item translation with schema validation.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string |
Yes | Content item UUID |
locale |
string |
Yes | Locale code (e.g., 'en-US', 'de-DE') |
data |
object |
Yes | Content data matching collection field schema |
status |
string | null |
No | Optional status update (draft/published/archived) |
description |
string | null |
No | Optional description update |
Return Value:
{
success: true,
content_item_id: string,
locale: string,
message: string
}
Usage Examples:
// Add English translation
await mcp.update_content_translation({
content_item_id: 'abc-123',
locale: 'en-US',
data: {
title: 'Getting Started with Vibe CMS',
slug: 'getting-started',
content: '# Introduction\n\nWelcome to Vibe CMS...',
author: 'Jane Doe',
published_date: '2025-11-03',
featured_image: 'file-id-456'
},
status: 'published'
});
// Add German translation
await mcp.update_content_translation({
content_item_id: 'abc-123',
locale: 'de-DE',
data: {
title: 'Erste Schritte mit Vibe CMS',
slug: 'erste-schritte',
content: '# Einführung\n\nWillkommen bei Vibe CMS...',
author: 'Jane Doe',
published_date: '2025-11-03',
featured_image: 'file-id-456'
},
status: 'published'
});
Important: The data object must match the collection's field schema. All required fields must be included.
Common Errors:
Unknown field(s): xyz- Field not defined in collection schemaMissing required field: title- Required field missing from dataContent item 'xyz' not found- Invalid content item ID
Related Tools: create_content, content, delete_content
delete_content()
Delete content item or specific translation.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string |
Yes | Content item UUID |
locale |
string | null |
No | If provided, deletes only that translation. If omitted, deletes entire item. |
confirm_delete |
boolean |
No | Must be true to confirm deletion (default: false) |
Return Value:
{
success: true,
deleted: {
content_item_id: string,
locale?: string,
translations_deleted?: number
},
message: string
}
Usage Examples:
// Delete German translation only
await mcp.delete_content({
content_item_id: 'abc-123',
locale: 'de-DE',
confirm_delete: true
});
// Delete entire content item with all translations
await mcp.delete_content({
content_item_id: 'abc-123',
confirm_delete: true
});
Note: If you delete the last remaining translation, the content item is automatically deleted.
Common Errors:
Deletion not confirmed- Must setconfirm_delete: trueContent item 'xyz' not found- Invalid content item ID
Related Tools: content, create_content, update_content_translation
Locale Tools
locales()
List all locales configured for the project.
Parameters: None
Return Value:
{
locales: [
{
locale_code: string,
display_name: string,
is_default: boolean,
is_active: boolean
}
],
default_locale: {...},
count: number,
active_count: number
}
Usage Examples:
const result = await mcp.locales();
console.log(result.count); // Total locales
console.log(result.active_count); // Active locales
console.log(result.default_locale.locale_code); // e.g., 'en-US'
Related Tools: manage_locale
manage_locale()
Create, update, or delete locale with BCP 47 locale codes.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
'create' | 'update' | 'delete' |
Yes | Operation type |
locale_code |
string |
Yes | BCP 47 code (e.g., 'en-US', 'fr-FR', 'de-DE') |
display_name |
string | null |
Conditional | Human-readable name (required for create/update) |
is_default |
boolean | null |
No | Whether this should be default locale |
is_active |
boolean | null |
No | Whether this locale is active |
confirm_delete |
boolean |
No | Must be true to confirm deletion (default: false) |
Return Value:
{
success: true,
locale?: {...}, // For create/update
message: string
}
Usage Examples:
// Create German locale
await mcp.manage_locale({
action: 'create',
locale_code: 'de-DE',
display_name: 'German (Germany)',
is_active: true,
is_default: false
});
// Set as default locale
await mcp.manage_locale({
action: 'update',
locale_code: 'en-US',
is_default: true
});
// Delete locale (deletes all translations)
await mcp.manage_locale({
action: 'delete',
locale_code: 'fr-FR',
confirm_delete: true
});
Common Locale Codes:
en-US- English (United States)en-GB- English (United Kingdom)de-DE- German (Germany)fr-FR- French (France)es-ES- Spanish (Spain)ja-JP- Japanese (Japan)zh-CN- Chinese (Simplified)
Common Errors:
display_name is required for create action- Must provide display nameLocale 'xyz' already exists- Locale code must be uniqueDeletion requires confirmation- Must setconfirm_delete: true
Related Tools: locales
Folder Tools
folders()
List all folders with optional parent path filter.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
parent_path |
string | null |
No | Filter by parent path (e.g., '/images', '/documents/2024') |
Return Value:
{
folders: [
{
name: string,
path: string,
parent_path: string | null
}
],
count: number,
filter_applied: string | null
}
Usage Examples:
// List all folders
const all = await mcp.folders();
// List folders under /images
const imageFolders = await mcp.folders({
parent_path: '/images'
});
// List root-level folders only
const rootFolders = await mcp.folders({
parent_path: '/'
});
Related Tools: manage_folder, files
manage_folder()
Create, update (rename), or delete folder.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
'create' | 'update' | 'delete' |
Yes | Operation type |
path |
string |
Yes | Folder path (e.g., '/images', '/teams') |
new_path |
string | null |
Conditional | New path for rename (required for update) |
confirm_delete |
boolean |
No | Must be true to confirm deletion (default: false) |
Return Value:
{
success: true,
folder?: {...}, // For create/update
message: string,
old_path?: string, // For update
new_path?: string // For update
}
Usage Examples:
// Create folder
await mcp.manage_folder({
action: 'create',
path: '/images/products'
});
// Rename folder
await mcp.manage_folder({
action: 'update',
path: '/images/old-products',
new_path: '/images/products-2024'
});
// Delete folder (files moved to parent)
await mcp.manage_folder({
action: 'delete',
path: '/temp',
confirm_delete: true
});
Note: When deleting a folder, contained files are moved to the parent folder (or root if no parent).
Common Errors:
new_path is required for update action- Must provide new path when renamingFolder already exists at path '/xyz'- Path must be uniqueDeletion requires confirmation- Must setconfirm_delete: true
Related Tools: folders, files, manage_file
File Tools
files()
Get file metadata by ID or list files with optional filters.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
file_id |
string | null |
No | File ID to get metadata for. If provided, returns single file with public URL. |
folder_path |
string | null |
No | Folder path filter for listing (e.g., '/images'). Only used when file_id is omitted. |
mime_type |
string | null |
No | MIME type filter (e.g., 'image/png', 'image/'). Only used when file_id is omitted. |
Return Value:
When file_id is provided:
{
id: string,
filename: string,
mime_type: string,
file_size: number,
alt_text: string,
title: string,
caption: string,
description: string,
focus_keyword: string,
width: number | null,
height: number | null,
public_url: string
}
When file_id is omitted:
{
files: [
{
id: string,
filename: string,
mime_type: string,
title: string
}
],
count: number,
filter_applied: {...}
}
Usage Examples:
// Get file by ID with public URL
const file = await mcp.files({ file_id: 'file-123' });
console.log(file.public_url); // Direct access URL
// List all files
const all = await mcp.files();
// List files in folder
const productImages = await mcp.files({
folder_path: '/images/products'
});
// List all images (partial MIME match)
const images = await mcp.files({
mime_type: 'image/' // Matches image/png, image/jpeg, etc.
});
// List specific file type
const pdfs = await mcp.files({
mime_type: 'application/pdf'
});
// Combine filters
const productPDFs = await mcp.files({
folder_path: '/documents/products',
mime_type: 'application/pdf'
});
Common Errors:
File not found: xyz- Invalid file ID
Related Tools: manage_file, upload_file_from_url, get_file_preview
manage_file()
Update file metadata or delete file permanently.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
'update' | 'delete' |
Yes | Action to perform |
file_id |
string |
Yes | File ID to manage |
alt_text |
string | null |
No | SEO alt text (update only) |
title |
string | null |
No | File title (update only) |
caption |
string | null |
No | File caption (update only) |
description |
string | null |
No | File description (update only) |
focus_keyword |
string | null |
No | SEO focus keyword (update only) |
folder_path |
string | null |
No | Move to new folder (update only) |
confirm_delete |
boolean |
No | Must be true for deletion (default: false) |
Return Value:
{
success: true,
action: 'update' | 'delete',
updated_fields?: string[], // For update
deleted_file_id?: string, // For delete
message?: string
}
Usage Examples:
// Update file metadata
await mcp.manage_file({
action: 'update',
file_id: 'file-123',
title: 'Product Hero Image',
alt_text: 'Smartphone with glowing screen in dark room',
focus_keyword: 'smartphone photography'
});
// Move file to different folder
await mcp.manage_file({
action: 'update',
file_id: 'file-123',
folder_path: '/images/featured'
});
// Delete file permanently
await mcp.manage_file({
action: 'delete',
file_id: 'file-123',
confirm_delete: true
});
Common Errors:
No fields provided to update- Must update at least one fieldFolder '/xyz' not found- Invalid folder pathDelete requires confirmation- Must setconfirm_delete: true
Related Tools: files, upload_file_from_url
get_file_preview()
Generate 512x512 preview image for image files only.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
file_id |
string |
Yes | File ID |
Return Value:
For images: Returns Image object with preview (512x512 max, maintains aspect ratio)
For non-images:
{
error: string,
public_url: string,
mime_type: string,
filename: string
}
Usage Examples:
// Get preview for image file
const preview = await mcp.get_file_preview({ file_id: 'image-123' });
// Returns 512x512 preview image
// Try to get preview for PDF (returns error with public URL)
const pdfPreview = await mcp.get_file_preview({ file_id: 'pdf-456' });
console.log(pdfPreview.public_url); // Access full file instead
Note: Only works for image files. For other file types, use files({ file_id }) to get public URL.
Common Errors:
File type 'application/pdf' does not support preview- Not an image fileFile not found: xyz- Invalid file ID
Related Tools: files, manage_file
upload_file_from_url()
Download file from URL and upload to CMS.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string |
Yes | URL to download from (must be from allowed domain) |
folder_path |
string | null |
No | Destination folder (e.g., '/images') - root if empty |
filename |
string | null |
No | Override filename (auto-detected if not provided) |
mime_type |
string | null |
No | Override MIME type (auto-detected if not provided) |
alt_text |
string | null |
No | SEO alt text for images |
title |
string | null |
No | File title |
caption |
string | null |
No | File caption |
description |
string | null |
No | File description |
focus_keyword |
string | null |
No | SEO focus keyword |
Allowed Domains:
example.comimages.unsplash.compicsum.photosvia.placeholder.com
File Size Limit: 50MB (52,428,800 bytes)
Return Value:
{
success: true,
file_id: string,
filename: string,
mime_type: string,
file_size: number,
public_url: string,
message: string,
next_steps: string
}
Usage Examples:
// Upload image from Unsplash
await mcp.upload_file_from_url({
url: 'https://images.unsplash.com/photo-123/hero.jpg',
folder_path: '/images/heroes',
alt_text: 'Modern office workspace with natural lighting',
title: 'Homepage Hero Image',
focus_keyword: 'modern workspace'
});
// Upload with custom filename
await mcp.upload_file_from_url({
url: 'https://example.com/document.pdf',
folder_path: '/documents',
filename: 'user-guide-v2.pdf',
title: 'User Guide Version 2'
});
Common Errors:
URL must be from allowed domain- Domain not in allowlistFile size exceeds 50MB limit- File too largeDownload timed out- Server too slow or file too largeFolder '/xyz' not found- Invalid folder path
Related Tools: files, manage_file, request_upload_token
request_upload_token()
Request temporary token for direct HTTP PUT file upload.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
filename |
string |
Yes | Filename (1-255 chars) |
mime_type |
string |
Yes | File MIME type (e.g., 'application/pdf') |
file_size |
number |
Yes | File size in bytes (max 50MB) |
folder_path |
string | null |
No | Destination folder - root if empty |
alt_text |
string | null |
No | SEO alt text (can be added later) |
title |
string | null |
No | File title (can be added later) |
Return Value:
{
success: true,
token: string,
upload_url: string,
expires_at: string, // ISO 8601 timestamp
expires_in_seconds: number,
max_file_size: number,
allowed_mime_types: string[],
instructions: string
}
Usage Examples:
// Request upload token
const result = await mcp.request_upload_token({
filename: 'large-video.mp4',
mime_type: 'video/mp4',
file_size: 25000000, // 25MB
folder_path: '/videos',
title: 'Product Demo Video'
});
// Use token to upload via HTTP PUT
// curl -X PUT --data-binary @large-video.mp4 {result.upload_url}
Token Expiration: 15 minutes from creation
Use Case: For large files or binary uploads not supported by upload_file_from_url.
Common Errors:
File size exceeds maximum of 50MB- File too largeFolder '/xyz' not found- Invalid folder path
Related Tools: upload_file_from_url, files
Tool Combination Patterns
Pattern 1: Create Complete Collection
// 1. Create collection
await mcp.manage_collection({
action: 'create',
slug: 'team-members',
name: 'Team Members'
});
// 2. Add fields
await mcp.add_collection_field({
collection_slug: 'team-members',
name: 'name',
field_type: 'text',
interface_type: 'input',
is_required: true,
sort_order: 1
});
await mcp.add_collection_field({
collection_slug: 'team-members',
name: 'bio',
field_type: 'markdown',
interface_type: 'markdown',
sort_order: 2
});
await mcp.add_collection_field({
collection_slug: 'team-members',
name: 'headshot',
field_type: 'file',
interface_type: 'single_file',
sort_order: 3
});
// 3. Upload image
const uploadResult = await mcp.upload_file_from_url({
url: 'https://images.unsplash.com/photo-123/headshot.jpg',
folder_path: '/images/team',
alt_text: 'Team member headshot'
});
const imageFileId = uploadResult.file_id;
// 4. Create content
const contentResult = await mcp.create_content({
collection_slug: 'team-members',
status: 'draft'
});
// 5. Add translation
await mcp.update_content_translation({
content_item_id: contentResult.id,
locale: 'en-US',
data: {
name: 'Jane Doe',
bio: '# About Jane\n\nJane is our CTO with 10 years experience.',
headshot: imageFileId
},
status: 'published'
});
Pattern 2: Multi-Language Content
// 1. Ensure locales exist
await mcp.manage_locale({
action: 'create',
locale_code: 'de-DE',
display_name: 'German (Germany)',
is_active: true
});
// 2. Create content in default locale
const item = await mcp.create_content({
collection_slug: 'articles'
});
await mcp.update_content_translation({
content_item_id: item.id,
locale: 'en-US',
data: {
title: 'Hello World',
content: 'Welcome to our blog.'
}
});
// 3. Add German translation
await mcp.update_content_translation({
content_item_id: item.id,
locale: 'de-DE',
data: {
title: 'Hallo Welt',
content: 'Willkommen in unserem Blog.'
}
});
// 4. Query specific locale
const germanVersion = await mcp.content({
collection_slug: 'articles',
content_item_id: item.id,
locale: 'de-DE'
});
Pattern 3: File Organization
// 1. Create folder structure
await mcp.manage_folder({ action: 'create', path: '/images' });
await mcp.manage_folder({ action: 'create', path: '/images/products' });
await mcp.manage_folder({ action: 'create', path: '/images/team' });
await mcp.manage_folder({ action: 'create', path: '/documents' });
// 2. Upload files to folders
await mcp.upload_file_from_url({
url: 'https://images.unsplash.com/photo-123/product.jpg',
folder_path: '/images/products',
alt_text: 'Product photo'
});
await mcp.upload_file_from_url({
url: 'https://example.com/user-guide.pdf',
folder_path: '/documents',
title: 'User Guide'
});
// 3. List files by folder
const productImages = await mcp.files({
folder_path: '/images/products'
});
const docs = await mcp.files({
folder_path: '/documents'
});
// 4. Move file to different folder
await mcp.manage_file({
action: 'update',
file_id: productImages.files[0].id,
folder_path: '/images/featured'
});
Error Handling
Error Response Format
All MCP tools return errors in a consistent format:
{
error: string, // Description of what went wrong
suggestion?: string, // How to fix it
code?: string // Error code (for some errors)
}
Common Error Codes
| Code | Description | Solution |
|---|---|---|
VALIDATION_ERROR |
Invalid parameters | Check parameter types and required fields |
NOT_FOUND |
Resource doesn't exist | Verify slug/ID is correct |
ALREADY_EXISTS |
Duplicate slug/name | Choose different identifier |
PERMISSION_DENIED |
Insufficient permissions | Check API key has write access |
CONFIRMATION_REQUIRED |
Safety confirmation missing | Add confirm_delete: true |
Error Handling Best Practices
Check for error property:
const result = await mcp.manage_collection({...}); if (result.error) { console.error(result.error); console.log(result.suggestion); // Helpful fix suggestion return; } // Success pathHandle specific errors:
const result = await mcp.create_content({...}); if (result.error) { if (result.error.includes('not found')) { // Collection doesn't exist - create it first } else if (result.error.includes('permission')) { // API key lacks write access } }Always confirm destructive operations:
// WRONG - will fail await mcp.delete_content({ content_item_id: 'abc' }); // RIGHT - explicit confirmation await mcp.delete_content({ content_item_id: 'abc', confirm_delete: true });
Best Practices
Field Naming
- Use lowercase letters only
- Start with a letter (not number or underscore)
- Use underscores for word separation
- Avoid reserved words (see Field Tools section)
Good: author_name, published_date, featured_image
Bad: AuthorName, 1_title, _description, select
Type & Interface Selection
- Short text (names, titles):
field_type: 'text',interface_type: 'input' - Long text (descriptions):
field_type: 'text',interface_type: 'textarea' - Rich content (articles):
field_type: 'markdown',interface_type: 'markdown' - Single image:
field_type: 'file',interface_type: 'single_file' - Image gallery:
field_type: 'file',interface_type: 'multiple_files'
Content Workflow
- Create collection -> 2. Add fields -> 3. Create content -> 4. Add translations
Locale Codes
Always use valid BCP 47 codes:
- Format:
language-COUNTRY(lowercase-UPPERCASE) - Examples:
en-US,de-DE,fr-FR,es-ES - Not:
en,EN-us,english
File Organization
- Create folder structure before uploading files
- Use descriptive folder names:
/images/products,/documents/legal - Set
alt_textfor all images (accessibility) - Set
titlefor all files (better organization)
Deletion Safety
All destructive operations require explicit confirmation:
confirm_delete: truefor content/files/foldersconfirm: truefor collection fields- Prevents accidental data loss
See Also
- Chapter 7: Working with Claude Code - Using MCP tools in Claude Code
- Chapter 8: Content Operations - Content management patterns
- Chapter 4: Content Modeling - Designing collection schemas
- Chapter 5: File Management - Working with files and folders
- Appendix B: Error Codes - Complete error reference