@notionhq/notion-mcp-server 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.dockerignore ADDED
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ Dockerfile
3
+ docker-compose.yml
package/Dockerfile ADDED
@@ -0,0 +1,36 @@
1
+ # syntax=docker/dockerfile:1
2
+
3
+ # Use Node.js LTS as the base image
4
+ FROM node:20-slim AS builder
5
+
6
+ # Set working directory
7
+ WORKDIR /app
8
+
9
+ # Copy package.json and package-lock.json
10
+ COPY package*.json ./
11
+
12
+ # Install dependencies
13
+ RUN --mount=type=cache,target=/root/.npm npm ci --ignore-scripts --omit-dev
14
+
15
+ # Copy source code
16
+ COPY . .
17
+
18
+ # Build the package
19
+ RUN --mount=type=cache,target=/root/.npm npm run build
20
+
21
+ # Install package globally
22
+ RUN --mount=type=cache,target=/root/.npm npm link
23
+
24
+ # Minimal image for runtime
25
+ FROM node:20-slim
26
+
27
+ # Copy built package from builder stage
28
+ COPY scripts/notion-openapi.json /usr/local/scripts/
29
+ COPY --from=builder /usr/local/lib/node_modules/@notionhq/notion-mcp-server /usr/local/lib/node_modules/@notionhq/notion-mcp-server
30
+ COPY --from=builder /usr/local/bin/notion-mcp-server /usr/local/bin/notion-mcp-server
31
+
32
+ # Set default environment variables
33
+ ENV OPENAPI_MCP_HEADERS="{}"
34
+
35
+ # Set entrypoint
36
+ ENTRYPOINT ["notion-mcp-server"]
package/README.md CHANGED
@@ -21,7 +21,8 @@ For example, you can create a read-only integration token by giving only "Read c
21
21
 
22
22
  #### 2. Adding MCP config to your client:
23
23
 
24
- Add the following to your `.cursor/mcp.json` or `claude_desktop_config.json` (MacOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json`)
24
+ ##### Using npm:
25
+ Add the following to your `.cursor/mcp.json` or `claude_desktop_config.json` (MacOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json`)
25
26
 
26
27
  ```javascript
27
28
  {
@@ -37,6 +38,33 @@ For example, you can create a read-only integration token by giving only "Read c
37
38
  }
38
39
  ```
39
40
 
41
+ ##### Using Docker:
42
+ You can also run the MCP server using Docker. First, build the Docker image:
43
+
44
+ ```bash
45
+ docker-compose build
46
+ ```
47
+
48
+ Then, add the following to your `.cursor/mcp.json` or `claude_desktop_config.json`:
49
+
50
+ ```javascript
51
+ {
52
+ "mcpServers": {
53
+ "notionApi": {
54
+ "command": "docker",
55
+ "args": [
56
+ "run",
57
+ "--rm",
58
+ "-i",
59
+ "-e",
60
+ "OPENAPI_MCP_HEADERS={\"Authorization\": \"Bearer ntn_****\", \"Notion-Version\": \"2022-06-28\"}",
61
+ "notion-mcp-server-notion-mcp-server"
62
+ ]
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
40
68
  Don't forget to replace `ntn_****` with your integration secret. Find it from your integration configuration tab:
41
69
 
42
70
  ![Copying your Integration token from the Configuration tab in the developer portal](https://github.com/user-attachments/assets/67b44536-5333-49fa-809c-59581bf5370a)
@@ -0,0 +1,6 @@
1
+ services:
2
+ notion-mcp-server:
3
+ build: .
4
+ stdin_open: true
5
+ tty: true
6
+ restart: unless-stopped
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "mcp",
7
7
  "server"
8
8
  ],
9
- "version": "1.5.0",
9
+ "version": "1.6.0",
10
10
  "license": "MIT",
11
11
  "type": "module",
12
12
  "scripts": {
@@ -964,6 +964,97 @@
964
964
  "properties": {
965
965
  "children": {
966
966
  "type": "array",
967
+ "items": {
968
+ "type": "object",
969
+ "properties": {
970
+ "paragraph": {
971
+ "type": "object",
972
+ "properties": {
973
+ "rich_text": {
974
+ "type": "array",
975
+ "items": {
976
+ "type": "object",
977
+ "properties": {
978
+ "text": {
979
+ "type": "object",
980
+ "properties": {
981
+ "content": {
982
+ "type": "string",
983
+ "maxLength": 2000
984
+ },
985
+ "link": {
986
+ "type": ["object", "null"],
987
+ "properties": {
988
+ "url": {
989
+ "type": "string"
990
+ }
991
+ },
992
+ "required": ["url"]
993
+ }
994
+ },
995
+ "additionalProperties": false,
996
+ "required": ["content"]
997
+ },
998
+ "type": {
999
+ "enum": ["text"]
1000
+ }
1001
+ },
1002
+ "additionalProperties": false,
1003
+ "required": ["text"]
1004
+ },
1005
+ "maxItems": 100
1006
+ }
1007
+ },
1008
+ "additionalProperties": false,
1009
+ "required": ["rich_text"]
1010
+ },
1011
+ "bulleted_list_item": {
1012
+ "type": "object",
1013
+ "properties": {
1014
+ "rich_text": {
1015
+ "type": "array",
1016
+ "items": {
1017
+ "type": "object",
1018
+ "properties": {
1019
+ "text": {
1020
+ "type": "object",
1021
+ "properties": {
1022
+ "content": {
1023
+ "type": "string",
1024
+ "maxLength": 2000
1025
+ },
1026
+ "link": {
1027
+ "type": ["object", "null"],
1028
+ "properties": {
1029
+ "url": {
1030
+ "type": "string"
1031
+ }
1032
+ },
1033
+ "required": ["url"]
1034
+ }
1035
+ },
1036
+ "additionalProperties": false,
1037
+ "required": ["content"]
1038
+ },
1039
+ "type": {
1040
+ "enum": ["text"]
1041
+ }
1042
+ },
1043
+ "additionalProperties": false,
1044
+ "required": ["text"]
1045
+ },
1046
+ "maxItems": 100
1047
+ }
1048
+ },
1049
+ "additionalProperties": false,
1050
+ "required": ["rich_text"]
1051
+ },
1052
+ "type": {
1053
+ "enum": ["paragraph", "bulleted_list_item"]
1054
+ }
1055
+ },
1056
+ "additionalProperties": false
1057
+ },
967
1058
  "description": "Child content to append to a container block as an array of [block objects](ref:block)"
968
1059
  },
969
1060
  "after": {
@@ -49,7 +49,6 @@ export class HttpClient {
49
49
  }
50
50
 
51
51
  private async prepareFileUpload(operation: OpenAPIV3.OperationObject, params: Record<string, any>): Promise<FormData | null> {
52
- console.error('prepareFileUpload', { operation, params })
53
52
  const fileParams = isFileUploadParameter(operation)
54
53
  if (fileParams.length === 0) return null
55
54
 
@@ -57,7 +56,6 @@ export class HttpClient {
57
56
 
58
57
  // Handle file uploads
59
58
  for (const param of fileParams) {
60
- console.error(`extracting ${param}`, {params})
61
59
  const filePath = params[param]
62
60
  if (!filePath) {
63
61
  throw new Error(`File path must be provided for parameter: ${param}`)
@@ -163,7 +161,6 @@ export class HttpClient {
163
161
  }
164
162
 
165
163
  // first argument is url parameters, second is body parameters
166
- console.error('calling operation', { operationId, urlParameters, bodyParams, requestConfig })
167
164
  const response = await operationFn(urlParameters, hasBody ? bodyParams : undefined, requestConfig)
168
165
 
169
166
  // Convert axios headers to Headers object
@@ -76,12 +76,10 @@ export class MCPProxy {
76
76
 
77
77
  // Handle tool calling
78
78
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
79
- console.error('calling tool', request.params)
80
79
  const { name, arguments: params } = request.params
81
80
 
82
81
  // Find the operation in OpenAPI spec
83
82
  const operation = this.findOperation(name)
84
- console.error('operations', this.openApiLookup)
85
83
  if (!operation) {
86
84
  throw new Error(`Method ${name} not found`)
87
85
  }