Building Notion MCP Server for Cursor IDE Integration

4 min readSargon Piraev

Learn how to build a production-ready MCP server that integrates Notion API with Cursor IDE for seamless workflow automation

Motivation

As a daily Cursor IDE user, I'm constantly looking for ways to enhance my development workflow. I love how Cursor's AI capabilities help me code faster, but I wanted to take it further by integrating the tools I use every day directly into my IDE. Notion has become an essential part of my documentation and knowledge management process, so building an MCP server to connect it with Cursor felt like a natural next step.

This project gave me a perfect opportunity to practice building MCP servers while adding real value to my development environment. I wanted to share my experience creating this integration, hoping it helps others looking to extend their Cursor IDE capabilities.

Implementation

Let's walk through building a production-ready MCP server for Notion API integration. I'll break down the key implementation steps and share the actual code patterns I used.

Project Structure

First, I set up the project structure:

mcp-server/
├── src/
│   ├── server.ts
│   └── main.ts
├── package.json
├── tsconfig.json
└── .env

Installing Dependencies

The core dependencies needed for the MCP server:

{
  "dependencies": {
    "@cursor/mcp-server": "^1.0.0",
    "axios": "^1.6.2",
    "zod": "^3.22.4",
    "dotenv": "^16.3.1"
  },
  "devDependencies": {
    "typescript": "^5.3.3",
    "@types/node": "^20.10.4"
  }
}

Environment Configuration

In server.ts, I started with environment setup:

import { config } from 'dotenv';
import { z } from 'zod';

config();

const envSchema = z.object({
  NOTION_API_KEY: z.string(),
  NOTION_API_VERSION: z.string().default('2022-06-28')
});

const env = envSchema.parse(process.env);

Creating the Notion Client

I created an axios client with proper authentication and versioning:

import axios from 'axios';

const notionClient = axios.create({
  baseURL: 'https://api.notion.com',
  headers: {
    'Authorization': `Bearer ${env.NOTION_API_KEY}`,
    'Notion-Version': env.NOTION_API_VERSION,
    'Content-Type': 'application/json'
  }
});

Setting Up the MCP Server

Next, I initialized the MCP server instance:

import { McpServer } from '@cursor/mcp-server';

const mcpServer = new McpServer({
  name: 'notion-mcp',
  version: '1.0.0'
});

Implementing Tools

Here's an example tool implementation for searching pages:

const searchSchema = z.object({
  query: z.string(),
  limit: z.number().optional().default(10)
});

mcpServer.tool({
  name: 'search_pages',
  description: 'Search Notion pages by title',
  parameters: searchSchema,
  handler: async ({ query, limit }) => {
    const response = await notionClient.post('/v1/search', {
      query,
      filter: { property: 'object', value: 'page' },
      page_size: limit
    });
    
    return response.data.results.map(page => ({
      id: page.id,
      title: page.properties.title?.title[0]?.plain_text || 'Untitled',
      url: page.url
    }));
  }
});

Entry Point

Finally, in main.ts, I created the server entry point:

import { server } from './server';

const port = process.env.PORT || 3000;
server.listen(port, () => {
  console.log(`Notion MCP server running on port ${port}`);
});

Usage

Let's look at how to set up and use the Notion MCP server with Cursor IDE.

Installation

Install the package globally:

npm install -g @sargonpiraev/notion-mcp

Configuration

Add the server to your Cursor IDE's mcp.json:

{
  "servers": [
    {
      "name": "notion-mcp",
      "command": "notion-mcp",
      "env": {
        "NOTION_API_KEY": "your-api-key-here"
      }
    }
  ]
}

Example Prompts

Here are some practical examples of using the Notion integration:

  1. "Search my Notion pages for project documentation"
Using notion_mcp.search_pages to find relevant pages...
Found 3 matching pages:
- Project Overview (https://notion.so/...)
- Technical Specs (https://notion.so/...)
- Implementation Guide (https://notion.so/...)
  1. "Create a new page for today's meeting notes"
Using notion_mcp.create_page to create a new page...
Created page "Team Meeting - 2024-01-09"
URL: https://notion.so/...
  1. "Update the status of my current project task"
Using notion_mcp.update_page to modify properties...
Updated status to "In Progress"
Page URL: https://notion.so/...

How It Works

Here's a visualization of how the Notion MCP server integrates with Cursor IDE:

Rendering diagram...

This flow shows how user requests in Cursor IDE are transformed into API calls through the MCP server, with results formatted and returned to enhance the IDE experience.