Skip to main content
Glama

API-retrieve-a-page-property

Retrieve specific property values from a Notion page using page and property identifiers. Supports pagination for large datasets.

Instructions

Retrieve a page property item

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
page_idYesIdentifier for a Notion page
property_idYesIdentifier for a page [property](https://developers.notion.com/reference/page#all-property-values)
page_sizeNoFor paginated properties. The max number of property item objects on a page. The default size is 100
start_cursorNoFor paginated properties.

Implementation Reference

  • Core handler logic for API-retrieve-a-page-property tool calls within the MCP CallToolRequestSchema handler. Locates the OpenAPI operation and proxies the HTTP request via HttpClient, returning the response as MCP content.
    const operation = this.findOperation(name)
    if (!operation) {
      const error = `Method ${name} not found.`
      console.error(error)
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({
              status: 'error',
              message: error,
              code: 404
            }),
          },
        ],
      }
    }
    
    // Optimized parallel processing for API-get-block-children
    if (name === 'API-get-block-children') {
      // Create basic options for logging control
      const blockOptions: RecursiveExplorationOptions = {
        runInBackground: false, // Default to not showing logs for regular API calls
      };
      
      return await this.handleBlockChildrenParallel(operation, params, blockOptions);
    }
    
    // Other regular API calls
    console.log(`Notion API call: ${operation.method.toUpperCase()} ${operation.path}`)
    const response = await this.httpClient.executeOperation(operation, params)
    
    // Log response summary
    console.log('Notion API response code:', response.status)
    if (response.status !== 200) {
      console.error('Response error:', response.data)
    } else {
      console.log('Response success')
    }
    
    // Update cache with response data
    this.updateCacheFromResponse(name, response.data);
    
    // Convert response to MCP format
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(response.data),
        },
      ],
    }
  • Tool registration in ListToolsRequestSchema handler. Converts grouped OpenAPI methods into individual MCP tools like API-retrieve-a-page-property by combining toolName ('API') with method.name.
    Object.entries(this.tools).forEach(([toolName, def]) => {
      def.methods.forEach(method => {
        const toolNameWithMethod = `${toolName}-${method.name}`;
        const truncatedToolName = this.truncateToolName(toolNameWithMethod);
        tools.push({
          name: truncatedToolName,
          description: method.description,
          inputSchema: method.inputSchema as Tool['inputSchema'],
        })
        console.log(`- ${truncatedToolName}: ${method.description}`)
      })
    })
  • Generates the inputSchema JSON Schema for MCP tools from OpenAPI operation parameters and requestBody. Used for API-retrieve-a-page-property schema (page_id and property_id parameters).
    private convertOperationToJsonSchema(
      operation: OpenAPIV3.OperationObject,
      method: string,
      path: string,
    ): IJsonSchema & { type: 'object' } {
      const schema: IJsonSchema & { type: 'object' } = {
        type: 'object',
        properties: {},
        required: [],
        $defs: this.convertComponentsToJsonSchema(),
      }
    
      // Handle parameters (path, query, header, cookie)
      if (operation.parameters) {
        for (const param of operation.parameters) {
          const paramObj = this.resolveParameter(param)
          if (paramObj && paramObj.schema) {
            const paramSchema = this.convertOpenApiSchemaToJsonSchema(paramObj.schema, new Set())
            // Merge parameter-level description if available
            if (paramObj.description) {
              paramSchema.description = paramObj.description
            }
            schema.properties![paramObj.name] = paramSchema
            if (paramObj.required) {
              schema.required!.push(paramObj.name)
            }
          }
        }
      }
    
      // Handle requestBody
      if (operation.requestBody) {
        const bodyObj = this.resolveRequestBody(operation.requestBody)
        if (bodyObj?.content) {
          if (bodyObj.content['application/json']?.schema) {
            const bodySchema = this.convertOpenApiSchemaToJsonSchema(bodyObj.content['application/json'].schema, new Set())
            if (bodySchema.type === 'object' && bodySchema.properties) {
              for (const [name, propSchema] of Object.entries(bodySchema.properties)) {
                schema.properties![name] = propSchema
              }
              if (bodySchema.required) {
                schema.required!.push(...bodySchema.required)
              }
            }
          }
        }
      }
    
      return schema
    }
  • Helper method enrichPageProperties uses API-retrieve-a-page-property to fetch detailed property information for each page property.
    const operation = this.findOperation('API-retrieve-a-page-property');
    if (!operation) {
      if (options.runInBackground) {
        console.warn('API-retrieve-a-page-property method not found.');
      }
      return;
    }
    
    const response = await this.httpClient.executeOperation(operation, {
      page_id: pageId,
      property_id: propId
    }).catch(error => {
  • Low-level HTTP execution for OpenAPI operations. Called by the MCP handler to perform the actual Notion API request for retrieve-a-page-property.
    async executeOperation<T = any>(
      operation: OpenAPIV3.OperationObject & { method: string; path: string },
      params: Record<string, any> = {},
    ): Promise<HttpClientResponse<T>> {
      const api = await this.api
      const operationId = operation.operationId
      if (!operationId) {
        throw new Error('Operation ID is required')
      }
    
      // Handle file uploads if present
      const formData = await this.prepareFileUpload(operation, params)
    
      // Separate parameters based on their location
      const urlParameters: Record<string, any> = {}
      const bodyParams: Record<string, any> = formData || { ...params }
    
      // Extract path and query parameters based on operation definition
      if (operation.parameters) {
        for (const param of operation.parameters) {
          if ('name' in param && param.name && param.in) {
            if (param.in === 'path' || param.in === 'query') {
              if (params[param.name] !== undefined) {
                urlParameters[param.name] = params[param.name]
                if (!formData) {
                  delete bodyParams[param.name]
                }
              }
            }
          }
        }
      }
    
      // Add all parameters as url parameters if there is no requestBody defined
      if (!operation.requestBody && !formData) {
        for (const key in bodyParams) {
          if (bodyParams[key] !== undefined) {
            urlParameters[key] = bodyParams[key]
            delete bodyParams[key]
          }
        }
      }
    
      const operationFn = (api as any)[operationId]
      if (!operationFn) {
        throw new Error(`Operation ${operationId} not found`)
      }
    
      try {
        // If we have form data, we need to set the correct headers
        const hasBody = Object.keys(bodyParams).length > 0
        const headers = formData
          ? formData.getHeaders()
          : { ...(hasBody ? { 'Content-Type': 'application/json' } : { 'Content-Type': null }) }
        const requestConfig = {
          headers: {
            ...headers,
          },
        }
    
        // first argument is url parameters, second is body parameters
        const response = await operationFn(urlParameters, hasBody ? bodyParams : undefined, requestConfig)
    
        // Convert axios headers to Headers object
        const responseHeaders = new Headers()
        Object.entries(response.headers).forEach(([key, value]) => {
          if (value) responseHeaders.append(key, value.toString())
        })
    
        return {
          data: response.data,
          status: response.status,
          headers: responseHeaders,
        }
      } catch (error: any) {
        if (error.response) {
          console.error('Error in http client', error)
          const headers = new Headers()
          Object.entries(error.response.headers).forEach(([key, value]) => {
            if (value) headers.append(key, value.toString())
          })
    
          throw new HttpClientError(error.response.statusText || 'Request failed', error.response.status, error.response.data, headers)
        }
        throw error
      }
    }

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/Taewoong1378/notion-readonly-mcp-server'

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