#
tokens: 2537/50000 5/5 files
lines: off (toggle) GitHub
raw markdown copy
# Directory Structure

```
├── .gitignore
├── mcp_instructions.md
├── notion_mcp_server.py
├── README.md
└── requirements.txt
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
.env
*.env
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# Notion Knowledge Base MCP Server

An MCP server that provides access to a Notion knowledge base through the Cline VSCode extension.

## Features

- Query your Notion knowledge base directly from Cline
- Get detailed answers with references to Notion pages
- Built with FastMCP for reliable performance
- Comprehensive error handling and logging

## Prerequisites

- Python 3.10 or higher
- [uv](https://github.com/astral-sh/uv) package manager
- [Cline VSCode extension](https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev)
- A Dify API key for accessing the Notion knowledge base

## Installation

1. Clone this repository:
   ```bash
   git clone https://github.com/yourusername/notion-mcp-server.git
   cd notion-mcp-server
   ```

2. Create a `.env` file with your Dify API key:
   ```bash
   echo "DIFY_API_BACKEND_KEY=your-api-key-here" > .env
   ```

3. Install the server in Cline:
   ```bash
   fastmcp install notion_mcp_server.py
   ```

   This will automatically:
   - Install all required dependencies using uv
   - Configure the server in Cline's settings
   - Make the server available to use with Cline

## Usage

Once installed, you can use the server in Cline by asking questions about your Notion knowledge base. For example:

```
Tell me about internal tooling
```

The server will respond with relevant information from your Notion knowledge base, including:
- Detailed answers
- Links to relevant Notion pages
- Page IDs for reference

## Configuration

The server is configured automatically during installation, but you can manually update the settings in Cline's configuration file if needed:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

Example configuration:
```json
{
  "mcpServers": {
    "notion-kb": {
      "command": "uv",
      "args": [
        "run",
        "--with", "fastmcp",
        "--with", "python-dotenv",
        "--with", "requests",
        "fastmcp",
        "run",
        "/absolute/path/to/notion_mcp_server.py"
      ],
      "env": {
        "DIFY_API_BACKEND_KEY": "your-api-key"
      }
    }
  }
}
```

## Development

For development and testing:

1. Install dependencies:
   ```bash
   pip install -r requirements.txt
   ```

2. Run the development server:
   ```bash
   fastmcp dev notion_mcp_server.py
   ```

This will start the MCP Inspector interface for testing the server.

## Troubleshooting

1. **Server not connecting**
   - Verify your API key in the `.env` file
   - Ensure the server path in Cline's config is absolute
   - Check that uv is installed and in your PATH

2. **Dependencies issues**
   - Try reinstalling with `fastmcp install notion_mcp_server.py --force`
   - Verify uv is installed correctly

3. **Server hangs**
   - Ensure you're using the uv run command as specified in the config
   - Check the server logs for errors

## Contributing

See [mcp_instructions.md](mcp_instructions.md) for detailed information about the server's implementation and architecture.

## License

MIT

```

--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------

```
fastmcp==0.4.1
python-dotenv
requests

```

--------------------------------------------------------------------------------
/notion_mcp_server.py:
--------------------------------------------------------------------------------

```python
#!/usr/bin/env python3
import os
import json
import requests
from dotenv import load_dotenv
from fastmcp import FastMCP, Context
from typing import Dict, Any
from pydantic import BaseModel, Field

# Initialize FastMCP server
mcp = FastMCP(
    name="Notion Knowledge Base",
    description="MCP server for querying a Notion knowledge base",
    version="0.1.0",
    dependencies=["python-dotenv", "requests"]
)

# Load environment variables
load_dotenv()

# Get API key from environment
API_KEY = os.getenv('DIFY_API_BACKEND_KEY')
if not API_KEY:
    raise ValueError("DIFY_API_BACKEND_KEY environment variable not set")

class NotionResponse(BaseModel):
    """Structure for Notion API responses."""
    answer: str = Field(default="")
    notion_page_url: str = Field(default="")
    notion_page_id: str = Field(default="")

    @classmethod
    def from_api_response(cls, data: Dict[str, Any]) -> "NotionResponse":
        """Create a NotionResponse from API response data."""
        outputs = data.get('data', {}).get('outputs', {})
        return cls(
            answer=outputs.get('answer', ''),
            notion_page_url=outputs.get('notion_page_url', ''),
            notion_page_id=outputs.get('notion_page_id', '')
        )

@mcp.tool()
def ask_notion_question(question: str, ctx: Context) -> Dict[str, Any]:
    """Ask a question about the Notion knowledge base.
    
    Args:
        question: The question to ask about the Notion knowledge base
        ctx: MCP context for logging and progress tracking
        
    Returns:
        Dictionary containing the answer and related Notion page information
        
    Raises:
        ValueError: If the API key is not set or if the request fails
    """
    ctx.info(f"Processing question: {question}")
    
    try:
        url = "https://dify.rickydata.com/v1/workflows/run"
        headers = {
            'Authorization': f"Bearer {API_KEY}",
            'Content-Type': 'application/json'
        }
        payload = {
            'inputs': {'question': question},
            'response_mode': 'blocking',
            'user': 'curation_agent_python'
        }
        
        ctx.debug("Sending request to Notion API")
        response = requests.post(url, headers=headers, json=payload)
        response.raise_for_status()
        
        data = response.json()
        if not data.get('data', {}).get('outputs', {}):
            raise ValueError("Invalid response format from API")
        
        result = NotionResponse.from_api_response(data)
        ctx.debug("Successfully received response from Notion API")
        
        return result.model_dump()
        
    except requests.RequestException as e:
        error_msg = f"API request failed: {str(e)}"
        ctx.error(error_msg)
        raise ValueError(error_msg)
    except json.JSONDecodeError as e:
        error_msg = f"Invalid JSON response: {str(e)}"
        ctx.error(error_msg)
        raise ValueError(error_msg)
    except Exception as e:
        error_msg = f"Unexpected error: {str(e)}"
        ctx.error(error_msg)
        raise ValueError(error_msg)

if __name__ == "__main__":
    mcp.run()

```

--------------------------------------------------------------------------------
/mcp_instructions.md:
--------------------------------------------------------------------------------

```markdown
# Building a Notion Knowledge Base MCP Server

This guide walks through the process of creating an MCP server that interfaces with a Notion knowledge base via the Dify API.

## Starting Point

We began with a Python example that demonstrated how to query the Dify API:

```python
def pull_dify_api_result_with_input(input_example="input_example"):
    load_dotenv()
    url = "https://dify.rickydata.com/v1/workflows/run"
    headers = {
        'Authorization': f"Bearer {os.getenv('DIFY_API_BACKEND_KEY')}",
        'Content-Type': 'application/json'
    }
    payload = {
        'inputs': {
            'input_example': input_example
        },
        'response_mode': 'blocking',
        'user': 'curation_agent_python'
    }
    
    response = requests.post(url, headers=headers, json=payload)
    response_data = response.json()
    
    if response_data.get('data', {}).get('outputs', {}):
        return response_data['data']['outputs']
    return response_data
```

## Implementation Steps

### 1. Project Setup
1. Create a new directory for the MCP server:
   ```bash
   mkdir notion_mcp_server
   cd notion_mcp_server
   ```

2. Create initial files:
   - `.env` for API key
   - `requirements.txt` for dependencies
   - `notion_mcp_server.py` for server implementation

### 2. Dependencies
Set up required dependencies in `requirements.txt`:
```
fastmcp==0.4.1
python-dotenv
requests
```

### 3. Server Implementation
1. Create a FastMCP server with proper configuration:
   ```python
   mcp = FastMCP(
       name="Notion Knowledge Base",
       description="MCP server for querying a Notion knowledge base",
       version="0.1.0",
       dependencies=["python-dotenv", "requests"]
   )
   ```

2. Define data models using Pydantic:
   ```python
   class NotionResponse(BaseModel):
       answer: str = Field(default="")
       notion_page_url: str = Field(default="")
       notion_page_id: str = Field(default="")
   ```

3. Implement the question-asking tool:
   ```python
   @mcp.tool()
   def ask_notion_question(question: str, ctx: Context) -> Dict[str, Any]:
       """Ask a question about the Notion knowledge base."""
       # Implementation details...
   ```

### 4. Error Handling and Logging
Add comprehensive error handling and logging:
```python
try:
    response = requests.post(url, headers=headers, json=payload)
    response.raise_for_status()
except requests.RequestException as e:
    error_msg = f"API request failed: {str(e)}"
    ctx.error(error_msg)
    raise ValueError(error_msg)
```

### 5. Testing
1. Test the basic Python implementation:
   ```bash
   python3 notion_api.py
   ```

2. Test the MCP server:
   ```bash
   fastmcp dev notion_mcp_server.py
   ```

### 6. Integration with Cline
1. Install the server in Cline:
   ```bash
   fastmcp install notion_mcp_server.py
   ```

2. Configure the server in Cline's settings:
   ```json
   {
     "mcpServers": {
       "notion-kb": {
         "command": "uv",
         "args": [
           "run",
           "--with", "fastmcp",
           "--with", "python-dotenv",
           "--with", "requests",
           "fastmcp",
           "run",
           "/path/to/notion_mcp_server.py"
         ],
         "env": {
           "DIFY_API_BACKEND_KEY": "your-api-key"
         }
       }
     }
   }
   ```

## Key Learnings

1. **Synchronous vs Async**: Keep the implementation synchronous for simplicity and reliability.
2. **Proper Dependencies**: Use `uv run` with explicit dependencies for better isolation.
3. **Error Handling**: Implement comprehensive error handling and logging.
4. **Configuration**: Use environment variables for sensitive data.
5. **Testing**: Test thoroughly at each step of implementation.

## Troubleshooting

1. If the server hangs, ensure you're using `uv run` instead of `python3` directly.
2. If connection fails, verify the API key is properly set in environment variables.
3. For "Not connected" errors, ensure the server is properly configured in Cline settings.

```