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