Skip to main content
Glama
index.ts10.3 kB
/** * MCP server setup and request handling */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequest, CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { NotionClientWrapper } from "../client/index.js"; import { filterTools } from "../utils/index.js"; import * as schemas from "../types/schemas.js"; import * as args from "../types/args.js"; /** * Start the MCP server */ export async function startServer( notionToken: string, enabledToolsSet: Set<string>, enableMarkdownConversion: boolean ) { const server = new Server( { name: "Notion MCP Server", version: "1.0.0", }, { capabilities: { tools: {}, }, } ); const notionClient = new NotionClientWrapper(notionToken); server.setRequestHandler( CallToolRequestSchema, async (request: CallToolRequest) => { console.error("Received CallToolRequest:", request); try { if (!request.params.arguments) { throw new Error("No arguments provided"); } let response; switch (request.params.name) { case "notion_append_block_children": { const args = request.params .arguments as unknown as args.AppendBlockChildrenArgs; if (!args.block_id || !args.children) { throw new Error( "Missing required arguments: block_id and children" ); } response = await notionClient.appendBlockChildren( args.block_id, args.children ); break; } case "notion_retrieve_block": { const args = request.params .arguments as unknown as args.RetrieveBlockArgs; if (!args.block_id) { throw new Error("Missing required argument: block_id"); } response = await notionClient.retrieveBlock(args.block_id); break; } case "notion_retrieve_block_children": { const args = request.params .arguments as unknown as args.RetrieveBlockChildrenArgs; if (!args.block_id) { throw new Error("Missing required argument: block_id"); } response = await notionClient.retrieveBlockChildren( args.block_id, args.start_cursor, args.page_size ); break; } case "notion_delete_block": { const args = request.params .arguments as unknown as args.DeleteBlockArgs; if (!args.block_id) { throw new Error("Missing required argument: block_id"); } response = await notionClient.deleteBlock(args.block_id); break; } case "notion_update_block": { const args = request.params .arguments as unknown as args.UpdateBlockArgs; if (!args.block_id || !args.block) { throw new Error("Missing required arguments: block_id and block"); } response = await notionClient.updateBlock( args.block_id, args.block ); break; } case "notion_retrieve_page": { const args = request.params .arguments as unknown as args.RetrievePageArgs; if (!args.page_id) { throw new Error("Missing required argument: page_id"); } response = await notionClient.retrievePage(args.page_id); break; } case "notion_update_page_properties": { const args = request.params .arguments as unknown as args.UpdatePagePropertiesArgs; if (!args.page_id || !args.properties) { throw new Error( "Missing required arguments: page_id and properties" ); } response = await notionClient.updatePageProperties( args.page_id, args.properties ); break; } case "notion_list_all_users": { const args = request.params .arguments as unknown as args.ListAllUsersArgs; response = await notionClient.listAllUsers( args.start_cursor, args.page_size ); break; } case "notion_retrieve_user": { const args = request.params .arguments as unknown as args.RetrieveUserArgs; if (!args.user_id) { throw new Error("Missing required argument: user_id"); } response = await notionClient.retrieveUser(args.user_id); break; } case "notion_retrieve_bot_user": { response = await notionClient.retrieveBotUser(); break; } case "notion_query_database": { const args = request.params .arguments as unknown as args.QueryDatabaseArgs; if (!args.database_id) { throw new Error("Missing required argument: database_id"); } response = await notionClient.queryDatabase( args.database_id, args.filter, args.sorts, args.start_cursor, args.page_size ); break; } case "notion_create_database": { const args = request.params .arguments as unknown as args.CreateDatabaseArgs; response = await notionClient.createDatabase( args.parent, args.properties, args.title ); break; } case "notion_retrieve_database": { const args = request.params .arguments as unknown as args.RetrieveDatabaseArgs; response = await notionClient.retrieveDatabase(args.database_id); break; } case "notion_update_database": { const args = request.params .arguments as unknown as args.UpdateDatabaseArgs; response = await notionClient.updateDatabase( args.database_id, args.title, args.description, args.properties ); break; } case "notion_create_database_item": { const args = request.params .arguments as unknown as args.CreateDatabaseItemArgs; response = await notionClient.createDatabaseItem( args.database_id, args.properties ); break; } case "notion_create_comment": { const args = request.params .arguments as unknown as args.CreateCommentArgs; if (!args.parent && !args.discussion_id) { throw new Error( "Either parent.page_id or discussion_id must be provided" ); } response = await notionClient.createComment( args.parent, args.discussion_id, args.rich_text ); break; } case "notion_retrieve_comments": { const args = request.params .arguments as unknown as args.RetrieveCommentsArgs; if (!args.block_id) { throw new Error("Missing required argument: block_id"); } response = await notionClient.retrieveComments( args.block_id, args.start_cursor, args.page_size ); break; } case "notion_search": { const args = request.params.arguments as unknown as args.SearchArgs; response = await notionClient.search( args.query, args.filter, args.sort, args.start_cursor, args.page_size ); break; } default: throw new Error(`Unknown tool: ${request.params.name}`); } // Check format parameter and return appropriate response const requestedFormat = (request.params.arguments as any)?.format || "markdown"; // Only convert to markdown if both conditions are met: // 1. The requested format is markdown // 2. The experimental markdown conversion is enabled via environment variable if (enableMarkdownConversion && requestedFormat === "markdown") { const markdown = await notionClient.toMarkdown(response); return { content: [{ type: "text", text: markdown }], }; } else { return { content: [ { type: "text", text: JSON.stringify(response, null, 2) }, ], }; } } catch (error) { console.error("Error executing tool:", error); return { content: [ { type: "text", text: JSON.stringify({ error: error instanceof Error ? error.message : String(error), }), }, ], }; } } ); server.setRequestHandler(ListToolsRequestSchema, async () => { const allTools = [ schemas.appendBlockChildrenTool, schemas.retrieveBlockTool, schemas.retrieveBlockChildrenTool, schemas.deleteBlockTool, schemas.updateBlockTool, schemas.retrievePageTool, schemas.updatePagePropertiesTool, schemas.listAllUsersTool, schemas.retrieveUserTool, schemas.retrieveBotUserTool, schemas.createDatabaseTool, schemas.queryDatabaseTool, schemas.retrieveDatabaseTool, schemas.updateDatabaseTool, schemas.createDatabaseItemTool, schemas.createCommentTool, schemas.retrieveCommentsTool, schemas.searchTool, ]; return { tools: filterTools(allTools, enabledToolsSet), }; }); const transport = new StdioServerTransport(); await server.connect(transport); }

Implementation Reference

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

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