Skip to main content
Glama
README.md
# Notion MCP Server

[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](https://www.typescriptlang.org/)
[![Apify Ready](https://img.shields.io/badge/Apify-Ready-black)](https://apify.com/)

Connect **Claude Desktop** (and other MCP clients) directly to **Notion** using a real MCP server with **SSE** support.

No flaky local scripts. No tokens in URLs. Run it securely in the cloud.

## 🚀 Quick Start (Recommended)

The easiest way to run this securely 24/7 is on **Apify**.

[Deploy to Apify](https://apify.com/piskunlab/notion-mcp-server)

### Connect your MCP client

- **Base URL** (Apify Container URL):

  `https://<run-id>.runs.apify.net`

- **SSE endpoint**:

  `GET /sse`

- **Client-to-server messages**:

  `POST /message?sessionId=...`

Authentication is done via:

- **Authorization header**: `Authorization: Bearer <SECRET_TOKEN>`

## ✨ Features

- **MCP Protocol with SSE**
- **Secure Bearer Authentication**
- **Notion API access (CRUD via OpenAPI tools)**
- **Rate-limiting & basic DDoS protection** (`express-rate-limit`)
- **Security headers** (`helmet`)

## 💻 Local Development (For Geeks)

### Install

```bash
npm install
```

### Build

```bash
npm run build
```

### Run

```bash
npm start
```

### Docker (optional)

If you use Docker locally:

```bash
docker build -t notion-mcp-server .
docker run -p 8080:8080 --env-file .env notion-mcp-server
```

## ⚙️ Configuration

This project is designed to read configuration from environment variables (and Apify Actor input).

### Required ENV variables

- `NOTION_TOKEN`
  - Your Notion integration token.
- `SECRET_TOKEN`
  - Bearer token required to access `/sse` and `/message`.

Optional (advanced):

- `NOTION_API_VERSION` (default: `2022-06-28`)
- `OPENAPI_MCP_HEADERS` (JSON string of headers; overrides `NOTION_TOKEN` when present)
- `BASE_URL` (override OpenAPI server base URL)

### Claude Desktop configuration

Add (or merge) something like this into `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "notion": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/dist/start-apify.js"],
      "env": {
        "NOTION_TOKEN": "YOUR_NOTION_TOKEN",
        "SECRET_TOKEN": "YOUR_SECRET_TOKEN"
      }
    }
  }
}
```

On Apify, you typically configure secrets via **Actor input** / **secrets** and use the Container URL as the server endpoint.

## Security Notes

- Never commit `.env` files or Apify `storage/` directories.
- Use a strong `SECRET_TOKEN` and rotate it if it leaks.

## Contributing

PRs are welcome!