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
| Name | Required | Description | Default |
|---|---|---|---|
| field_rules | No | Field visibility rules for showing/hiding fields based on conditions | |
| options | No | Content type options like webpage/content block settings and URL patterns | |
| schema | Yes | Array 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 | |
| taxonomies | No | Taxonomies to associate with this content type | |
| title | Yes | Content type title | |
| uid | Yes | Content type UID (unique identifier) |
Implementation Reference
- src/index.ts:318-405 (handler)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, } } },
- src/index.ts:267-317 (schema)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, } } }, )