Skip to main content
Glama

create_content_type

Define and create custom content types with structured schemas, field rules, and taxonomies to organize and manage content efficiently.

Instructions

Creates a new content type with the specified schema, options, field rules, and taxonomies.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
field_rulesNoField visibility rules for showing/hiding fields based on conditions
optionsNoContent type options like webpage/content block settings and URL patterns
schemaYesArray of schema fields defining the content structure. Each field object should include properties like: - display_name: Field display name - uid: Unique identifier for the field - data_type: Type of data (text, number, boolean, file, etc.) - field_metadata: Additional metadata for the field - multiple: Whether field accepts multiple values - mandatory: Whether field is required - unique: Whether field values must be unique
taxonomiesNoTaxonomies to associate with this content type
titleYesContent type title
uidYesContent type UID (unique identifier)

Implementation Reference

  • The handler function that implements the core logic for creating a new content type. It prepares a payload with title, uid, schema, options, field rules, and taxonomies, then sends a POST request to the Contentstack API endpoint /content_types. Includes error handling with detailed schema guidance.
    async ({ title, uid, schema, options, field_rules, taxonomies }) => { try { // Prepare the content type payload const payload: ContentTypePayload = { content_type: { title, uid, schema: schema as ContentTypeSchema[], options: options || { is_page: true, singleton: false, title: 'title', sub_title: [], url_pattern: '/:title', url_prefix: '/', }, }, } // Add field_rules if provided if (field_rules && field_rules.length > 0) { payload.content_type.field_rules = field_rules as ContentTypeFieldRule[] } // Add taxonomies if provided if (taxonomies && taxonomies.length > 0) { // Add the taxonomies field to the content_type object directly, not in schema payload.content_type.taxonomies = taxonomies } console.log('Sending payload:', JSON.stringify(payload, null, 2)) const response = await axios.post<ContentTypeResponse>(`${API_BASE_URL}/content_types`, payload, { headers: getHeaders(), }) console.log('API response:', JSON.stringify(response.data, null, 2)) return { content: [ { type: 'text', text: `Content type "${title}" created successfully with UID "${uid}".`, }, ], } } catch (error) { const errorMessage = handleError(error as ApiError) return { content: [ { type: 'text', text: `Error creating content type: ${errorMessage}\n\nPlease ensure your schema adheres to the Contentstack schema specification. Schema should be an array of field objects. Example field objects: // Title field example { "display_name": "Title", "uid": "title", "data_type": "text", "mandatory": true, "unique": true, "field_metadata": { "_default": true }, "multiple": false } // Rich text editor example { "display_name": "Description", "uid": "description", "data_type": "text", "field_metadata": { "allow_rich_text": true, "description": "", "multiline": false, "rich_text_type": "advanced" }, "multiple": false, "mandatory": false, "unique": false }`, }, ], isError: true, } } },
  • Zod validation schema defining the input parameters for the tool: title, uid, schema (array of fields), options, field_rules (conditional visibility), and taxonomies.
    title: z.string().describe('Content type title'), uid: z.string().describe('Content type UID (unique identifier)'), schema: z .array(z.object({}).passthrough()) .describe( 'Array of schema fields defining the content structure. Each field object should include properties like:\n- display_name: Field display name\n- uid: Unique identifier for the field\n- data_type: Type of data (text, number, boolean, file, etc.)\n- field_metadata: Additional metadata for the field\n- multiple: Whether field accepts multiple values\n- mandatory: Whether field is required\n- unique: Whether field values must be unique', ), options: z .object({ is_page: z.boolean().optional().describe('Set to true for webpage content types, false for content blocks'), singleton: z.boolean().optional().describe('Set to true for single content types, false for multiple'), title: z.string().optional().describe('Field to use as the title'), sub_title: z.array(z.string()).optional().describe('Fields to use as subtitles'), url_pattern: z.string().optional().describe('Default URL pattern for entries'), url_prefix: z.string().optional().describe('Path prefix for entries'), }) .optional() .describe('Content type options like webpage/content block settings and URL patterns'), field_rules: z .array( z.object({ conditions: z.array( z.object({ operand_field: z.string().describe('Field on which to apply condition'), operator: z.string().describe('Operator for condition (e.g., equals, contains)'), value: z.any().describe('Expected value for the condition'), }), ), actions: z.array( z.object({ action: z.string().describe('Action to perform (show/hide)'), target_field: z.string().describe('Field to show/hide based on condition'), }), ), match_type: z.string().describe('Whether all or any conditions should be met'), }), ) .optional() .describe('Field visibility rules for showing/hiding fields based on conditions'), taxonomies: z .array( z.object({ taxonomy_uid: z.string().describe('Taxonomy UID to link'), max_terms: z.number().optional().describe('Maximum number of terms allowed (up to 25)'), mandatory: z.boolean().optional().describe('Whether this taxonomy is required'), non_localizable: z.boolean().optional().describe('Whether this taxonomy is non-localizable'), }), ) .optional() .describe('Taxonomies to associate with this content type'), },
  • src/index.ts:264-406 (registration)
    The server.tool() call that registers the 'create_content_type' tool with the MCP server, providing the name, description, input schema, and handler implementation.
    'create_content_type', 'Creates a new content type with the specified schema, options, field rules, and taxonomies.', { title: z.string().describe('Content type title'), uid: z.string().describe('Content type UID (unique identifier)'), schema: z .array(z.object({}).passthrough()) .describe( 'Array of schema fields defining the content structure. Each field object should include properties like:\n- display_name: Field display name\n- uid: Unique identifier for the field\n- data_type: Type of data (text, number, boolean, file, etc.)\n- field_metadata: Additional metadata for the field\n- multiple: Whether field accepts multiple values\n- mandatory: Whether field is required\n- unique: Whether field values must be unique', ), options: z .object({ is_page: z.boolean().optional().describe('Set to true for webpage content types, false for content blocks'), singleton: z.boolean().optional().describe('Set to true for single content types, false for multiple'), title: z.string().optional().describe('Field to use as the title'), sub_title: z.array(z.string()).optional().describe('Fields to use as subtitles'), url_pattern: z.string().optional().describe('Default URL pattern for entries'), url_prefix: z.string().optional().describe('Path prefix for entries'), }) .optional() .describe('Content type options like webpage/content block settings and URL patterns'), field_rules: z .array( z.object({ conditions: z.array( z.object({ operand_field: z.string().describe('Field on which to apply condition'), operator: z.string().describe('Operator for condition (e.g., equals, contains)'), value: z.any().describe('Expected value for the condition'), }), ), actions: z.array( z.object({ action: z.string().describe('Action to perform (show/hide)'), target_field: z.string().describe('Field to show/hide based on condition'), }), ), match_type: z.string().describe('Whether all or any conditions should be met'), }), ) .optional() .describe('Field visibility rules for showing/hiding fields based on conditions'), taxonomies: z .array( z.object({ taxonomy_uid: z.string().describe('Taxonomy UID to link'), max_terms: z.number().optional().describe('Maximum number of terms allowed (up to 25)'), mandatory: z.boolean().optional().describe('Whether this taxonomy is required'), non_localizable: z.boolean().optional().describe('Whether this taxonomy is non-localizable'), }), ) .optional() .describe('Taxonomies to associate with this content type'), }, async ({ title, uid, schema, options, field_rules, taxonomies }) => { try { // Prepare the content type payload const payload: ContentTypePayload = { content_type: { title, uid, schema: schema as ContentTypeSchema[], options: options || { is_page: true, singleton: false, title: 'title', sub_title: [], url_pattern: '/:title', url_prefix: '/', }, }, } // Add field_rules if provided if (field_rules && field_rules.length > 0) { payload.content_type.field_rules = field_rules as ContentTypeFieldRule[] } // Add taxonomies if provided if (taxonomies && taxonomies.length > 0) { // Add the taxonomies field to the content_type object directly, not in schema payload.content_type.taxonomies = taxonomies } console.log('Sending payload:', JSON.stringify(payload, null, 2)) const response = await axios.post<ContentTypeResponse>(`${API_BASE_URL}/content_types`, payload, { headers: getHeaders(), }) console.log('API response:', JSON.stringify(response.data, null, 2)) return { content: [ { type: 'text', text: `Content type "${title}" created successfully with UID "${uid}".`, }, ], } } catch (error) { const errorMessage = handleError(error as ApiError) return { content: [ { type: 'text', text: `Error creating content type: ${errorMessage}\n\nPlease ensure your schema adheres to the Contentstack schema specification. Schema should be an array of field objects. Example field objects: // Title field example { "display_name": "Title", "uid": "title", "data_type": "text", "mandatory": true, "unique": true, "field_metadata": { "_default": true }, "multiple": false } // Rich text editor example { "display_name": "Description", "uid": "description", "data_type": "text", "field_metadata": { "allow_rich_text": true, "description": "", "multiline": false, "rich_text_type": "advanced" }, "multiple": false, "mandatory": false, "unique": false }`, }, ], isError: true, } } }, )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/darekrossman/contentstack-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server