Skip to content

Commit 5d76ed9

Browse files
Merge pull request #19 from insightbuilder/notion-mcp-bd
Notion mcp Server to connect with Brain Dump Database
2 parents a750eac + 10beebd commit 5d76ed9

8 files changed

Lines changed: 975 additions & 0 deletions

File tree

docs/mcp_notion_brain.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# MCP Server to Brain Dump to Notion
2+
3+
Brain Dumping the ideas and tasks into Notion
4+
database and later managing them with due dates,
5+
areas and resources is a classic system. This MCP
6+
client just needs you to type out your tasks on a
7+
terminal. The server will then move it to the
8+
database.
9+
10+
MCP servers have the tools, and resources that can
11+
be made to work with notion database and its
12+
properties.
13+
14+
We are implementing the MCP Server to connect with
15+
Notion database through the notion integration
16+
API. We are building this so the brain dump
17+
process can be directly done from any terminal
18+
that support python.
19+
20+
## Project Details:
21+
22+
- Project Path: ../notion_brain_dump/
23+
24+
### Project setup commands:
25+
26+
```bash
27+
cd notion_brain_dump
28+
uv run mcpclient.py server.py
29+
30+
After the client start, you will be prompted for the query.
31+
32+
Query: Provide me the list of the tasks available.
33+
```
34+
35+
### Available MCP Server Tools:
36+
37+
- Add Task
38+
- List Tasks
39+
- Update Tasks
40+
- Remove Tasks
41+
- Add Area
42+
- Add Resource
43+
44+
These tool are using mcp resources that are
45+
connecting with the notion db.
46+
47+
When you need use mcp inspector to debug the code,
48+
use the command below. Ensure you have
49+
[npx](https://docs.npmjs.com/cli/v8/commands/npx)
50+
and [node](https://nodejs.org/en/download)
51+
installed
52+
53+
npx @modelcontextprotocol/inspector uv run
54+
server.py
55+
56+
### Project Description:
57+
58+
The server.py contains the tools to connect with
59+
notion database through its API integration. The
60+
mcpclient.py contains the code to connect with
61+
LLMs and user.
62+
63+
The functions used in the server.py is taken from
64+
the ../fw_ex/praw_spiked/vabired_app02.py. The MCP
65+
server and client are a different interface to the
66+
way we interact with the computers. So instead of
67+
using REST API servers, we will use plain english.
68+
69+
### Project References
70+
71+
- Server code referred from :
72+
[MCP Installation](https://github.com/modelcontextprotocol/python-sdk?tab=readme-ov-file#installation)
73+
74+
- Client code referred from:
75+
[Introducing Clients](https://modelcontextprotocol.io/quickstart/client)
76+
77+
- Notion Code referred from:
78+
[Notion Example code](../fw_ex/notionapi_spike/)
79+
80+
```
81+
82+
```

notion_brain_dump/.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Python-generated files
2+
__pycache__/
3+
*.py[oc]
4+
build/
5+
dist/
6+
wheels/
7+
*.egg-info
8+
9+
# Virtual environments
10+
.venv

notion_brain_dump/.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.11

notion_brain_dump/README.md

Whitespace-only changes.

notion_brain_dump/mcpclient.py

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import asyncio
2+
from typing import Optional
3+
from contextlib import AsyncExitStack
4+
5+
# pyright: reportMissingImports=false
6+
# pyright: reportOptionalSubscript=false
7+
8+
from mcp import ClientSession, StdioServerParameters
9+
from mcp.client.stdio import stdio_client
10+
11+
from anthropic import Anthropic
12+
from dotenv import load_dotenv
13+
14+
# uncomment this when running in your local environment
15+
# ensure you have updated the .env file with the Anthropic API Key
16+
# load_dotenv() # load environment variables from .env
17+
18+
19+
class MCPClient:
20+
def __init__(self):
21+
# Initialize session and client objects
22+
self.session: Optional[ClientSession] = None
23+
self.exit_stack = AsyncExitStack()
24+
self.anthropic = Anthropic()
25+
26+
# methods will go here
27+
async def connect_to_server(self, server_script_path: str):
28+
"""Connect to notion MCP server
29+
30+
Args:
31+
server_script_path: Path to the server script (.py or .js)
32+
"""
33+
is_python = server_script_path.endswith(".py")
34+
is_js = server_script_path.endswith(".js")
35+
if not (is_python or is_js):
36+
raise ValueError("Server script must be a .py or .js file")
37+
38+
command = "python" if is_python else "node"
39+
server_params = StdioServerParameters(
40+
command=command, args=[server_script_path], env=None
41+
)
42+
43+
stdio_transport = await self.exit_stack.enter_async_context(
44+
stdio_client(server_params)
45+
)
46+
self.stdio, self.write = stdio_transport
47+
self.session = await self.exit_stack.enter_async_context(
48+
ClientSession(self.stdio, self.write)
49+
)
50+
51+
await self.session.initialize()
52+
53+
# List available tools
54+
response = await self.session.list_tools()
55+
tools = response.tools
56+
print(
57+
"\nConnected to Notion MCP server with tools:",
58+
[tool.name for tool in tools],
59+
)
60+
61+
async def process_query(self, query: str) -> str:
62+
"""Process a query using Claude and available tools"""
63+
messages = [{"role": "user", "content": query}]
64+
65+
response = await self.session.list_tools()
66+
available_tools = [
67+
{
68+
"name": tool.name,
69+
"description": tool.description,
70+
"input_schema": tool.inputSchema,
71+
}
72+
for tool in response.tools
73+
]
74+
75+
# Initial Claude API call
76+
response = self.anthropic.messages.create(
77+
model="claude-3-5-haiku-20241022",
78+
max_tokens=1000,
79+
messages=messages,
80+
tools=available_tools,
81+
)
82+
83+
# Process response and handle tool calls
84+
tool_results = []
85+
final_text = []
86+
87+
for content in response.content:
88+
if content.type == "text":
89+
final_text.append(content.text)
90+
elif content.type == "tool_use":
91+
tool_name = content.name
92+
tool_args = content.input
93+
94+
# Execute tool call
95+
result = await self.session.call_tool(tool_name, tool_args)
96+
tool_results.append({"call": tool_name, "result": result})
97+
final_text.append(f"[Calling tool {tool_name} with args {tool_args}]")
98+
99+
# Continue conversation with tool results
100+
if hasattr(content, "text") and content.text:
101+
messages.append({"role": "assistant", "content": content.text})
102+
messages.append({"role": "user", "content": result.content})
103+
104+
# Get next response from Claude
105+
response = self.anthropic.messages.create(
106+
model="claude-3-5-haiku-20241022",
107+
max_tokens=1000,
108+
messages=messages,
109+
)
110+
111+
final_text.append(response.content[0].text)
112+
113+
return "\n".join(final_text)
114+
115+
async def chat_loop(self):
116+
"""Run an interactive chat loop"""
117+
print("\nMCP Client Started!")
118+
print("Type your queries or 'quit' to exit.")
119+
120+
while True:
121+
try:
122+
query = input("\nQuery: ").strip()
123+
124+
if query.lower() == "quit":
125+
break
126+
127+
response = await self.process_query(query)
128+
print("\n" + response)
129+
130+
except Exception as e:
131+
print(f"\nError: {str(e)}")
132+
133+
async def cleanup(self):
134+
"""Clean up resources"""
135+
await self.exit_stack.aclose()
136+
137+
138+
async def main():
139+
if len(sys.argv) < 2:
140+
print("Usage: python mcpclient.py mcpserver.py")
141+
sys.exit(1)
142+
143+
client = MCPClient()
144+
try:
145+
await client.connect_to_server(sys.argv[1])
146+
await client.chat_loop()
147+
finally:
148+
await client.cleanup()
149+
150+
151+
if __name__ == "__main__":
152+
import sys
153+
154+
asyncio.run(main())

notion_brain_dump/pyproject.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[project]
2+
name = "notion-brain-dump"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.11"
7+
dependencies = [
8+
"anthropic>=0.49.0",
9+
"mcp[cli]>=1.6.0",
10+
"notion-client>=2.3.0",
11+
"python-dotenv>=1.1.0",
12+
]

0 commit comments

Comments
 (0)