blocks
Manage Notion block content by getting, updating, appending, or deleting specific blocks using block IDs for precise content editing.
Instructions
Block-level content: get, children, append, update, delete. Page IDs are valid block IDs. Use for precise edits.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform | |
| block_id | Yes | Block ID | |
| content | No | Markdown content (for append/update) |
Implementation Reference
- src/tools/composite/blocks.ts:21-142 (handler)Primary handler function implementing block operations: get, retrieve children as markdown, append markdown as blocks, update text blocks with markdown, delete blocks.export async function blocks(notion: Client, input: BlocksInput): Promise<any> { return withErrorHandling(async () => { if (!input.block_id) { throw new NotionMCPError('block_id required', 'VALIDATION_ERROR', 'Provide block_id') } switch (input.action) { case 'get': { const block: any = await notion.blocks.retrieve({ block_id: input.block_id }) return { action: 'get', block_id: block.id, type: block.type, has_children: block.has_children, archived: block.archived, block } } case 'children': { const blocksList = await autoPaginate((cursor) => notion.blocks.children.list({ block_id: input.block_id, start_cursor: cursor, page_size: 100 }) ) const markdown = blocksToMarkdown(blocksList as any) return { action: 'children', block_id: input.block_id, total_children: blocksList.length, markdown, blocks: blocksList } } case 'append': { if (!input.content) { throw new NotionMCPError('content required for append', 'VALIDATION_ERROR', 'Provide markdown content') } const blocksList = markdownToBlocks(input.content) await notion.blocks.children.append({ block_id: input.block_id, children: blocksList as any }) return { action: 'append', block_id: input.block_id, appended_count: blocksList.length } } case 'update': { if (!input.content) { throw new NotionMCPError('content required for update', 'VALIDATION_ERROR', 'Provide markdown content') } const block: any = await notion.blocks.retrieve({ block_id: input.block_id }) const blockType = block.type const newBlocks = markdownToBlocks(input.content) if (newBlocks.length === 0) { throw new NotionMCPError('Content must produce at least one block', 'VALIDATION_ERROR', 'Invalid markdown') } const newContent = newBlocks[0] const updatePayload: any = {} // Build update based on block type if ( [ 'paragraph', 'heading_1', 'heading_2', 'heading_3', 'bulleted_list_item', 'numbered_list_item', 'quote' ].includes(blockType) ) { updatePayload[blockType] = { rich_text: (newContent as any)[blockType]?.rich_text || [] } } else { throw new NotionMCPError( `Block type '${blockType}' cannot be updated`, 'VALIDATION_ERROR', 'Only text blocks can be updated' ) } await notion.blocks.update({ block_id: input.block_id, ...updatePayload } as any) return { action: 'update', block_id: input.block_id, type: blockType, updated: true } } case 'delete': { await notion.blocks.delete({ block_id: input.block_id }) return { action: 'delete', block_id: input.block_id, deleted: true } } default: throw new NotionMCPError( `Unknown action: ${input.action}`, 'VALIDATION_ERROR', 'Supported actions: get, children, append, update, delete' ) } })() }
- src/tools/registry.ts:125-142 (schema)Input schema for the 'blocks' tool defining actions, required block_id, and optional markdown content.{ name: 'blocks', description: 'Block-level content: get, children, append, update, delete. Page IDs are valid block IDs. Use for precise edits.', inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['get', 'children', 'append', 'update', 'delete'], description: 'Action to perform' }, block_id: { type: 'string', description: 'Block ID' }, content: { type: 'string', description: 'Markdown content (for append/update)' } }, required: ['action', 'block_id'] } },
- src/tools/registry.ts:302-304 (registration)Registration of the 'blocks' tool handler in the main CallToolRequestSchema switch statement.case 'blocks': result = await blocks(notion, args as any) break
- src/tools/composite/blocks.ts:11-15 (schema)TypeScript interface defining the input parameters for the blocks handler.export interface BlocksInput { action: 'get' | 'children' | 'append' | 'update' | 'delete' block_id: string content?: string // Markdown format }
- src/tools/composite/blocks.ts:8-10 (helper)Imports of helper functions used in blocks handler: markdown conversion and pagination.import { blocksToMarkdown, markdownToBlocks } from '../helpers/markdown.js' import { autoPaginate } from '../helpers/pagination.js'