MCP Notion Server
- src
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListResourcesRequestSchema,
ListToolsRequestSchema,
ReadResourceRequestSchema,
ListPromptsRequestSchema,
GetPromptRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import {
handleListDatabases,
handleCreateDatabase,
handleCreatePage,
handleUpdatePage,
handleAppendBlocks,
handleDeleteBlock,
handleGetPage,
handleGetDatabase,
handleQueryDatabase,
handleSearch
} from "./handlers/index.js";
const server = new Server(
{
name: "mcp-notion-server",
version: "0.1.0",
},
{
capabilities: {
resources: {},
tools: {},
prompts: {},
},
}
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "list_databases",
description: "List all accessible databases",
inputSchema: {
type: "object",
properties: {},
required: []
}
},
{
name: "create_database",
description: "Create a new database",
inputSchema: {
type: "object",
properties: {
parent_id: { type: "string", description: "ID of the parent page" },
title: { type: "string", description: "Title of the database" },
properties: { type: "object", description: "Database properties schema" }
},
required: ["parent_id", "title", "properties"]
}
},
{
name: "create_page",
description: "Create a new page",
inputSchema: {
type: "object",
properties: {
parent_type: {
type: "string",
enum: ["database", "page"],
description: "Type of parent (database or page)"
},
parent_id: { type: "string", description: "ID of the parent page or database" },
title: { type: "string", description: "Title of the page" },
properties: { type: "object", description: "Page properties (required for database pages)" },
content: { type: "string", description: "Content in markdown format" }
},
required: ["parent_type", "parent_id"]
}
},
{
name: "update_page",
description: "Update an existing page",
inputSchema: {
type: "object",
properties: {
page_id: { type: "string", description: "ID of the page to update" },
properties: { type: "object", description: "Updated page properties" }
},
required: ["page_id", "properties"]
}
},
{
name: "append_blocks",
description: "Append blocks to a page",
inputSchema: {
type: "object",
properties: {
page_id: { type: "string", description: "ID of the page" },
blocks: { type: "array", description: "Array of block objects to append" }
},
required: ["page_id", "blocks"]
}
},
{
name: "delete_blocks",
description: "Delete blocks from a page",
inputSchema: {
type: "object",
properties: {
block_id: { type: "string", description: "ID of the block to delete" }
},
required: ["block_id"]
}
},
{
name: "get_page",
description: "Retrieve a page by ID",
inputSchema: {
type: "object",
properties: {
page_id: { type: "string", description: "ID of the page to retrieve" }
},
required: ["page_id"]
}
},
{
name: "get_database",
description: "Retrieve a database by ID",
inputSchema: {
type: "object",
properties: {
database_id: { type: "string", description: "ID of the database to retrieve" }
},
required: ["database_id"]
}
},
{
name: "query_database",
description: "Query a database with filters and sorting",
inputSchema: {
type: "object",
properties: {
database_id: { type: "string", description: "ID of the database to query" },
filter: { type: "object", description: "Filter conditions" },
sorts: { type: "array", description: "Sorting parameters" },
page_size: { type: "number", description: "Number of results per page" },
start_cursor: { type: "string", description: "Pagination cursor" }
},
required: ["database_id"]
}
},
{
name: "search",
description: "Search pages and databases",
inputSchema: {
type: "object",
properties: {
query: { type: "string", description: "Search query" },
filter: {
type: "object",
description: "Filter by object type (page or database)"
},
sort: {
type: "object",
description: "Sort by last edited or created time"
},
page_size: { type: "number", description: "Number of results per page" },
start_cursor: { type: "string", description: "Pagination cursor" }
},
required: ["query"]
}
}
]
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
switch (request.params.name) {
case "list_databases":
return handleListDatabases();
case "create_database":
return handleCreateDatabase(request.params.arguments as any);
case "get_database":
return handleGetDatabase(request.params.arguments as any);
case "query_database":
return handleQueryDatabase(request.params.arguments as any);
case "get_page":
return handleGetPage(request.params.arguments as any);
case "create_page":
return handleCreatePage(request.params.arguments as any);
case "update_page":
return handleUpdatePage(request.params.arguments as any);
case "append_blocks":
return handleAppendBlocks(request.params.arguments as any);
case "delete_blocks":
return handleDeleteBlock((request.params.arguments as any).block_id);
case "search":
return handleSearch(request.params.arguments as any);
default:
throw new Error("Unknown tool");
}
} catch (error) {
if (error instanceof Error) {
throw new Error(`Operation failed: ${error.message}`);
}
throw new Error("Operation failed: An unknown error occurred");
}
});
server.setRequestHandler(ListPromptsRequestSchema, async () => ({
prompts: [
{
name: "summarize_notes",
description: "Summarize all notes",
}
]
}));
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch((error) => {
console.error("Server error:", error);
process.exit(1);
});