Skip to main content
Glama

API-get-block-children

Retrieve child blocks from a Notion page or block to access nested content and structure within your Notion workspace.

Instructions

Retrieve block children

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
block_idYesIdentifier for a [block](ref:block)
start_cursorNoIf supplied, this endpoint will return a page of results starting after the cursor provided. If not supplied, this endpoint will return the first page of results.
page_sizeNoThe number of items from the full list desired in the response. Maximum: 100

Implementation Reference

  • Core implementation of the API-get-block-children tool. Fetches the first page of block children, then parallelizes subsequent paginated pages (using next_cursor) in batches of 5, merges all results into a single complete response without has_more.
    private async handleBlockChildrenParallel(
      operation: OpenAPIV3.OperationObject & { method: string; path: string }, 
      params: any,
      options?: RecursiveExplorationOptions
    ) {
      if (options?.runInBackground) {
        console.log(`Starting Notion API parallel processing: ${operation.method.toUpperCase()} ${operation.path}`);
      }
      
      // Get first page
      const initialResponse = await this.httpClient.executeOperation(operation, params);
      
      if (initialResponse.status !== 200) {
        if (options?.runInBackground) {
          console.error('Response error:', initialResponse.data);
        }
        return {
          content: [{ type: 'text', text: JSON.stringify(initialResponse.data) }],
        };
      }
      
      const results = initialResponse.data.results || [];
      let nextCursor = initialResponse.data.next_cursor;
      
      // Array for parallel processing
      const pageRequests = [];
      const maxParallelRequests = 5; // Limit simultaneous requests
      
      if (options?.runInBackground) {
        console.log(`Retrieved ${results.length} blocks from first page`);
      }
      
      // Request subsequent pages in parallel if available
      while (nextCursor) {
        // Clone parameters for next page
        const nextPageParams = { ...params, start_cursor: nextCursor };
        
        // Add page request
        pageRequests.push(
          this.httpClient.executeOperation(operation, nextPageParams)
            .then(response => {
              if (response.status === 200) {
                if (options?.runInBackground) {
                  console.log(`Retrieved ${response.data.results?.length || 0} blocks from additional page`);
                }
                return {
                  results: response.data.results || [],
                  next_cursor: response.data.next_cursor
                };
              }
              return { results: [], next_cursor: null };
            })
            .catch(error => {
              if (options?.runInBackground) {
                console.error('Error retrieving page:', error);
              }
              return { results: [], next_cursor: null };
            })
        );
        
        // Execute parallel requests when batch size reached or no more pages
        if (pageRequests.length >= maxParallelRequests || !nextCursor) {
          if (options?.runInBackground) {
            console.log(`Processing ${pageRequests.length} pages in parallel...`);
          }
          const pageResponses = await Promise.all(pageRequests);
          
          // Merge results
          for (const response of pageResponses) {
            results.push(...response.results);
            // Set next cursor for next batch
            if (response.next_cursor) {
              nextCursor = response.next_cursor;
            } else {
              nextCursor = null;
            }
          }
          
          // Reset request array
          pageRequests.length = 0;
        }
        
        // Exit loop if no more pages
        if (!nextCursor) break;
      }
      
      if (options?.runInBackground) {
        console.log(`Retrieved ${results.length} blocks in total`);
      }
      
      // Return merged response
      const mergedResponse = {
        ...initialResponse.data,
        results,
        has_more: false,
        next_cursor: null
      };
      
      return {
        content: [{ type: 'text', text: JSON.stringify(mergedResponse) }],
      };
    }
  • Dispatch in the main CallToolRequestSchema handler that specifically routes 'API-get-block-children' calls to the custom parallel handler instead of direct HTTP execution.
    // 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);
    }
  • Generic registration of all converted OpenAPI operations as MCP tools in the ListToolsRequestSchema handler, including 'API-get-block-children'.
    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}`)
      })
    })
  • Initializes the tools registry and operation lookup (including API-get-block-children) by converting the OpenAPI specification using OpenAPIToMCPConverter.
    const converter = new OpenAPIToMCPConverter(openApiSpec)
    const { tools, openApiLookup } = converter.convertToMCPTools()
    this.tools = tools
    this.openApiLookup = openApiLookup
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. 'Retrieve' implies a read-only operation, but it does not specify critical traits like pagination behavior (implied by 'start_cursor' and 'page_size' in the schema), rate limits, authentication needs, or error handling. The description adds minimal context beyond the basic action, leaving gaps in understanding how the tool behaves in practice.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description 'Retrieve block children' is extremely concise—just three words—and front-loaded with the core action. There is no wasted language or unnecessary elaboration, making it efficient for quick comprehension. Every word earns its place by directly stating the tool's function.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a paginated retrieval tool with no annotations and no output schema, the description is incomplete. It does not explain what 'block children' are, the return format, pagination details, or error conditions. While the schema covers inputs, the lack of behavioral and output information makes it inadequate for an agent to use the tool effectively without additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, meaning the input schema fully documents all parameters ('block_id', 'start_cursor', 'page_size') with clear descriptions. The description does not add any meaning beyond this, such as explaining relationships between parameters or usage examples. According to the rules, with high schema coverage, the baseline score is 3, as the description does not compensate but also does not detract.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Retrieve block children' states the verb ('Retrieve') and resource ('block children'), making the purpose clear. However, it lacks specificity about what 'block children' are (e.g., nested content in a Notion-like system) and does not differentiate from sibling tools like 'API-retrieve-a-block', which might retrieve a single block rather than its children. This vagueness prevents a higher score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It does not mention sibling tools such as 'API-retrieve-a-block' or 'API-retrieve-a-page', nor does it specify contexts like fetching hierarchical content. Without any usage context or exclusions, the agent must infer when to apply it, leading to potential misuse.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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