Skip to main content
Glama
ivo-toby

Contentful GraphQL MCP Server

graphql_list_content_types

Discover available content types in Contentful's GraphQL schema to understand data structure before querying. Use this first to identify what content you can access.

Instructions

IMPORTANT: Use this tool FIRST before attempting to write any GraphQL queries. This tool lists all available content types in the Contentful space's GraphQL schema. You should always use this tool to understand what content types are available before formulating GraphQL queries. The space ID and CDA token are automatically retrieved from environment variables.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
spaceIdNoOptional override for the space ID (defaults to SPACE_ID environment variable)
environmentIdNoOptional override for the environment ID (defaults to ENVIRONMENT_ID environment variable or 'master')

Implementation Reference

  • Core implementation of the graphql_list_content_types tool handler. Checks cache or queries GraphQL introspection for content types.
    listContentTypes: async (args: ListContentTypesArgs): Promise<ToolResponse> => {
      try {
        // Check cache first
        if (isCacheAvailable()) {
          const cachedContentTypes = getCachedContentTypes()
          if (cachedContentTypes) {
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify(
                    {
                      message:
                        "Available content types in this Contentful space (from cache). Use graphql_get_content_type_schema to explore a specific content type.",
                      contentTypes: cachedContentTypes,
                      cached: true,
                    },
                    null,
                    2,
                  ),
                },
              ],
            }
          }
        }
    
        // Fallback to API if cache not available
        const spaceId = args.spaceId || process.env.SPACE_ID
        const environmentId = args.environmentId || process.env.ENVIRONMENT_ID || "master"
        const accessToken = process.env.CONTENTFUL_DELIVERY_ACCESS_TOKEN
    
        if (!spaceId) {
          return {
            content: [
              {
                type: "text",
                text: "Space ID is required (set SPACE_ID environment variable or provide spaceId parameter)",
              },
            ],
            isError: true,
          }
        }
    
        if (!accessToken) {
          return {
            content: [
              {
                type: "text",
                text: "Content Delivery API (CDA) token is required for GraphQL queries (set CONTENTFUL_DELIVERY_ACCESS_TOKEN environment variable)",
              },
            ],
            isError: true,
          }
        }
    
        return await loadContentTypesFromAPI(spaceId, environmentId, accessToken)
      } catch (error) {
        return {
          content: [
            {
              type: "text",
              text: `Error fetching content types: ${error instanceof Error ? error.message : String(error)}`,
            },
          ],
          isError: true,
        }
      }
    },
  • TypeScript interface defining the input arguments for the listContentTypes handler.
    export interface ListContentTypesArgs {
      spaceId?: string // Optional override for environment variable
      environmentId?: string // Optional override for environment variable
    }
  • MCP tool schema definition including name, description, and input schema for graphql_list_content_types.
    GRAPHQL_LIST_CONTENT_TYPES: {
      name: "graphql_list_content_types",
      description:
        "IMPORTANT: Use this tool FIRST before attempting to write any GraphQL queries. This tool lists all available content types in the Contentful space's GraphQL schema. You should always use this tool to understand what content types are available before formulating GraphQL queries. The space ID and CDA token are automatically retrieved from environment variables.",
      inputSchema: getOptionalEnvProperties({
        type: "object",
        properties: {},
        required: [],
      }),
    },
  • src/index.ts:120-128 (registration)
    Registration of the tool handler in the main MCP server's getHandler function.
    const cdaOnlyHandlers = {
      // Only GraphQL operations are allowed with just a CDA token
      graphql_query: graphqlHandlers.executeQuery,
      graphql_list_content_types: graphqlHandlers.listContentTypes,
      graphql_get_content_type_schema: graphqlHandlers.getContentTypeSchema,
      graphql_get_example: graphqlHandlers.getExample,
      smart_search: graphqlHandlers.smartSearch,
      build_search_query: graphqlHandlers.buildSearchQuery,
    }
  • Helper function that performs the actual GraphQL introspection query to list content types, called by the handler when cache is unavailable.
    async function loadContentTypesFromAPI(
      spaceId: string,
      environmentId: string,
      accessToken: string,
    ): Promise<ToolResponse> {
      const endpoint = `https://graphql.contentful.com/content/v1/spaces/${spaceId}/environments/${environmentId}`
    
      const query = `
        query {
          __schema {
            queryType {
              fields {
                name
                description
                type {
                  kind
                  ofType {
                    name
                    kind
                  }
                }
              }
            }
          }
        }
      `
    
      const response = await fetch(endpoint, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify({ query }),
      })
    
      if (!response.ok) {
        const errorText = await response.text()
        return {
          content: [{ type: "text", text: `HTTP Error ${response.status}: ${errorText}` }],
          isError: true,
        }
      }
    
      const result = (await response.json()) as GraphQLContentTypesResponse
    
      if (result.errors) {
        return {
          content: [{ type: "text", text: JSON.stringify({ errors: result.errors }, null, 2) }],
          isError: true,
        }
      }
    
      const contentTypeFields = result.data.__schema.queryType.fields
        .filter(
          (field: any) =>
            field.name.endsWith("Collection") ||
            (field.type?.kind === "OBJECT" && field.type?.name?.endsWith("Collection")),
        )
        .map((field: any) => ({
          name: field.name.replace("Collection", ""),
          description: field.description || `Content type for ${field.name}`,
          queryName: field.name,
        }))
    
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                message:
                  "Available content types in this Contentful space. Use graphql_get_content_type_schema to explore a specific content type.",
                contentTypes: contentTypeFields,
              },
              null,
              2,
            ),
          },
        ],
      }
    }

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/ivo-toby/contentful-mcp-graphql'

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