notion-mcp-server 0.0.2 → 1.0.1
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/README.md +29 -1
- package/build/config/index.js +1 -1
- package/build/schema/blocks.js +61 -0
- package/build/schema/comments.js +60 -0
- package/build/schema/database.js +25 -0
- package/build/schema/page.js +37 -0
- package/build/schema/users.js +39 -0
- package/build/server/index.js +1 -1
- package/build/services/loggs.js +13 -0
- package/build/tools/blocks.js +34 -0
- package/build/tools/comments.js +81 -0
- package/build/tools/database.js +16 -0
- package/build/tools/index.js +20 -38
- package/build/tools/pages.js +22 -0
- package/build/tools/searchPage.js +0 -4
- package/build/tools/users.js +75 -0
- package/build/types/blocks.js +2 -1
- package/build/types/comments.js +7 -0
- package/build/types/database.js +2 -1
- package/build/types/page.js +2 -1
- package/build/types/users.js +6 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
**Notion MCP Server** is a Model Context Protocol (MCP) server implementation that enables AI assistants to interact with Notion's API. This production-ready server provides a complete set of tools and endpoints for reading, creating, and modifying Notion content through natural language interactions.
|
|
11
11
|
|
|
12
|
-
> 🚧 **Active Development**: Database support is now available! If you find this project useful, please consider giving it a star - it helps me know that this work is valuable to the community and motivates further development.
|
|
12
|
+
> 🚧 **Active Development**: Database support is now available! Comments and user management tools have been added. If you find this project useful, please consider giving it a star - it helps me know that this work is valuable to the community and motivates further development.
|
|
13
13
|
|
|
14
14
|
<a href="https://glama.ai/mcp/servers/zrh07hteaa">
|
|
15
15
|
<img width="380" height="200" src="https://glama.ai/mcp/servers/zrh07hteaa/badge" />
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
- "Add bullet points to my meeting notes page"
|
|
57
57
|
- "Create a new database for tracking projects"
|
|
58
58
|
- "Add new entries to my task database"
|
|
59
|
+
- "Add a comment to my project page"
|
|
60
|
+
- "Show me all comments on this document"
|
|
61
|
+
- "List all users in my workspace"
|
|
62
|
+
- "Get information about a specific user"
|
|
59
63
|
|
|
60
64
|
### Cursor Integration
|
|
61
65
|
|
|
@@ -124,6 +128,8 @@ env NOTION_TOKEN=YOUR_KEY NOTION_PAGE_ID=YOUR_PAGE_ID npx -y notion-mcp-server
|
|
|
124
128
|
- **🔄 Batch Operations** - Perform multiple operations in a single request
|
|
125
129
|
- **🗑️ Archive & Restore** - Archive and restore Notion pages
|
|
126
130
|
- **🔎 Search Functionality** - Search Notion pages and databases by title
|
|
131
|
+
- **💬 Comments Management** - Get, create, and reply to comments on pages and discussions
|
|
132
|
+
- **👥 User Management** - Retrieve workspace users and user information
|
|
127
133
|
|
|
128
134
|
## 📚 Documentation
|
|
129
135
|
|
|
@@ -190,6 +196,28 @@ Delete multiple blocks in a single operation
|
|
|
190
196
|
##### `batch_mixed_operations`
|
|
191
197
|
Perform a mix of append, update, and delete operations in a single request
|
|
192
198
|
|
|
199
|
+
#### Comment Operations
|
|
200
|
+
|
|
201
|
+
##### `get_comments`
|
|
202
|
+
Retrieve comments from a page or block with pagination support
|
|
203
|
+
|
|
204
|
+
##### `add_page_comment`
|
|
205
|
+
Add a new comment to a Notion page
|
|
206
|
+
|
|
207
|
+
##### `add_discussion_comment`
|
|
208
|
+
Add a comment to an existing discussion thread
|
|
209
|
+
|
|
210
|
+
#### User Operations
|
|
211
|
+
|
|
212
|
+
##### `get_list_users`
|
|
213
|
+
Retrieve a paginated list of all users in the workspace
|
|
214
|
+
|
|
215
|
+
##### `get_user`
|
|
216
|
+
Get detailed information about a specific user by ID
|
|
217
|
+
|
|
218
|
+
##### `get_bot_user`
|
|
219
|
+
Retrieve the current bot user associated with the API token
|
|
220
|
+
|
|
193
221
|
### Available Resources
|
|
194
222
|
|
|
195
223
|
The server currently does not expose any resources, focusing instead on tool-based operations.
|
package/build/config/index.js
CHANGED
package/build/schema/blocks.js
CHANGED
|
@@ -207,3 +207,64 @@ export const BATCH_MIXED_OPERATIONS_SCHEMA = {
|
|
|
207
207
|
]))
|
|
208
208
|
.describe("Array of mixed operations to perform in a single batch"),
|
|
209
209
|
};
|
|
210
|
+
// Combined schema for all block operations
|
|
211
|
+
export const BLOCKS_OPERATION_SCHEMA = {
|
|
212
|
+
payload: z
|
|
213
|
+
.preprocess(preprocessJson, z.discriminatedUnion("action", [
|
|
214
|
+
z.object({
|
|
215
|
+
action: z
|
|
216
|
+
.literal("append_block_children")
|
|
217
|
+
.describe("Use this action to append children to a block."),
|
|
218
|
+
params: z.object(APPEND_BLOCK_CHILDREN_SCHEMA),
|
|
219
|
+
}),
|
|
220
|
+
z.object({
|
|
221
|
+
action: z
|
|
222
|
+
.literal("retrieve_block")
|
|
223
|
+
.describe("Use this action to retrieve a block."),
|
|
224
|
+
params: z.object(RETRIEVE_BLOCK_SCHEMA),
|
|
225
|
+
}),
|
|
226
|
+
z.object({
|
|
227
|
+
action: z
|
|
228
|
+
.literal("retrieve_block_children")
|
|
229
|
+
.describe("Use this action to retrieve children of a block."),
|
|
230
|
+
params: z.object(RETRIEVE_BLOCK_CHILDREN_SCHEMA),
|
|
231
|
+
}),
|
|
232
|
+
z.object({
|
|
233
|
+
action: z
|
|
234
|
+
.literal("update_block")
|
|
235
|
+
.describe("Use this action to update a block."),
|
|
236
|
+
params: z.object(UPDATE_BLOCK_SCHEMA),
|
|
237
|
+
}),
|
|
238
|
+
z.object({
|
|
239
|
+
action: z
|
|
240
|
+
.literal("delete_block")
|
|
241
|
+
.describe("Use this action to delete/archive a block."),
|
|
242
|
+
params: z.object(DELETE_BLOCK_SCHEMA),
|
|
243
|
+
}),
|
|
244
|
+
z.object({
|
|
245
|
+
action: z
|
|
246
|
+
.literal("batch_append_block_children")
|
|
247
|
+
.describe("Use this action to perform batch append operations on blocks."),
|
|
248
|
+
params: z.object(BATCH_APPEND_BLOCK_CHILDREN_SCHEMA),
|
|
249
|
+
}),
|
|
250
|
+
z.object({
|
|
251
|
+
action: z
|
|
252
|
+
.literal("batch_update_blocks")
|
|
253
|
+
.describe("Use this action to perform batch update operations on blocks."),
|
|
254
|
+
params: z.object(BATCH_UPDATE_BLOCKS_SCHEMA),
|
|
255
|
+
}),
|
|
256
|
+
z.object({
|
|
257
|
+
action: z
|
|
258
|
+
.literal("batch_delete_blocks")
|
|
259
|
+
.describe("Use this action to perform batch delete operations on blocks."),
|
|
260
|
+
params: z.object(BATCH_DELETE_BLOCKS_SCHEMA),
|
|
261
|
+
}),
|
|
262
|
+
z.object({
|
|
263
|
+
action: z
|
|
264
|
+
.literal("batch_mixed_operations")
|
|
265
|
+
.describe("Use this action to perform batch mixed operations on blocks."),
|
|
266
|
+
params: z.object(BATCH_MIXED_OPERATIONS_SCHEMA),
|
|
267
|
+
}),
|
|
268
|
+
]))
|
|
269
|
+
.describe("A union of all possible block operations. Each operation has a specific action and corresponding parameters. Use this schema to validate the input for block operations such as appending, retrieving, updating, deleting, and performing batch operations. Available actions include: 'append_block_children', 'retrieve_block', 'retrieve_block_children', 'update_block', 'delete_block', 'batch_append_block_children', 'batch_update_blocks', 'batch_delete_blocks', and 'batch_mixed_operations'. Each operation requires specific parameters as defined in the corresponding schemas."),
|
|
270
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { RICH_TEXT_ITEM_REQUEST_SCHEMA } from "./rich-text.js";
|
|
3
|
+
import { preprocessJson } from "./preprocess.js";
|
|
4
|
+
// Schema for getting comments
|
|
5
|
+
export const GET_COMMENTS_SCHEMA = {
|
|
6
|
+
block_id: z
|
|
7
|
+
.string()
|
|
8
|
+
.describe("The ID of the block or page to get comments from"),
|
|
9
|
+
start_cursor: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("The cursor to start from for pagination"),
|
|
13
|
+
page_size: z
|
|
14
|
+
.number()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Number of comments to return per page"),
|
|
17
|
+
};
|
|
18
|
+
// Schema for adding a comment to a page
|
|
19
|
+
export const ADD_PAGE_COMMENT_SCHEMA = {
|
|
20
|
+
parent: z.object({
|
|
21
|
+
page_id: z.string().describe("The ID of the page to add the comment to"),
|
|
22
|
+
}),
|
|
23
|
+
rich_text: z
|
|
24
|
+
.array(RICH_TEXT_ITEM_REQUEST_SCHEMA)
|
|
25
|
+
.describe("Rich text content for the comment"),
|
|
26
|
+
};
|
|
27
|
+
// Schema for adding a comment to a discussion
|
|
28
|
+
export const ADD_DISCUSSION_COMMENT_SCHEMA = {
|
|
29
|
+
discussion_id: z
|
|
30
|
+
.string()
|
|
31
|
+
.describe("The ID of the discussion to add the comment to"),
|
|
32
|
+
rich_text: z
|
|
33
|
+
.array(RICH_TEXT_ITEM_REQUEST_SCHEMA)
|
|
34
|
+
.describe("Rich text content for the comment"),
|
|
35
|
+
};
|
|
36
|
+
// Combined schema for all comment operations
|
|
37
|
+
export const COMMENTS_OPERATION_SCHEMA = {
|
|
38
|
+
payload: z
|
|
39
|
+
.preprocess(preprocessJson, z.discriminatedUnion("action", [
|
|
40
|
+
z.object({
|
|
41
|
+
action: z
|
|
42
|
+
.literal("get_comments")
|
|
43
|
+
.describe("Use this action to get comments from a block or page."),
|
|
44
|
+
params: z.object(GET_COMMENTS_SCHEMA),
|
|
45
|
+
}),
|
|
46
|
+
z.object({
|
|
47
|
+
action: z
|
|
48
|
+
.literal("add_page_comment")
|
|
49
|
+
.describe("Use this action to add a comment to a page."),
|
|
50
|
+
params: z.object(ADD_PAGE_COMMENT_SCHEMA),
|
|
51
|
+
}),
|
|
52
|
+
z.object({
|
|
53
|
+
action: z
|
|
54
|
+
.literal("add_discussion_comment")
|
|
55
|
+
.describe("Use this action to add a comment to a discussion."),
|
|
56
|
+
params: z.object(ADD_DISCUSSION_COMMENT_SCHEMA),
|
|
57
|
+
}),
|
|
58
|
+
]))
|
|
59
|
+
.describe("A union of all possible comment operations. Each operation has a specific action and corresponding parameters. Use this schema to validate the input for comment operations such as getting, adding to page, and adding to discussion. Available actions include: 'get_comments', 'add_page_comment', and 'add_discussion_comment'. Each operation requires specific parameters as defined in the corresponding schemas."),
|
|
60
|
+
};
|
package/build/schema/database.js
CHANGED
|
@@ -339,3 +339,28 @@ export const UPDATE_DATABASE_SCHEMA = {
|
|
|
339
339
|
.optional()
|
|
340
340
|
.describe("Updated cover image for the database")),
|
|
341
341
|
};
|
|
342
|
+
// Combined schema for all database operations
|
|
343
|
+
export const DATABASE_OPERATION_SCHEMA = {
|
|
344
|
+
payload: z
|
|
345
|
+
.preprocess(preprocessJson, z.discriminatedUnion("action", [
|
|
346
|
+
z.object({
|
|
347
|
+
action: z
|
|
348
|
+
.literal("create_database")
|
|
349
|
+
.describe("Use this action to create a new database."),
|
|
350
|
+
params: z.object(CREATE_DATABASE_SCHEMA),
|
|
351
|
+
}),
|
|
352
|
+
z.object({
|
|
353
|
+
action: z
|
|
354
|
+
.literal("query_database")
|
|
355
|
+
.describe("Use this action to query a database."),
|
|
356
|
+
params: z.object(QUERY_DATABASE_SCHEMA),
|
|
357
|
+
}),
|
|
358
|
+
z.object({
|
|
359
|
+
action: z
|
|
360
|
+
.literal("update_database")
|
|
361
|
+
.describe("Use this action to update a database."),
|
|
362
|
+
params: z.object(UPDATE_DATABASE_SCHEMA),
|
|
363
|
+
}),
|
|
364
|
+
]))
|
|
365
|
+
.describe("A union of all possible database operations. Each operation has a specific action and corresponding parameters. Use this schema to validate the input for database operations such as creating, querying, and updating databases. Available actions include: 'create_database', 'query_database', and 'update_database'. Each operation requires specific parameters as defined in the corresponding schemas."),
|
|
366
|
+
};
|
package/build/schema/page.js
CHANGED
|
@@ -97,3 +97,40 @@ export const SEARCH_PAGES_SCHEMA = {
|
|
|
97
97
|
.optional()
|
|
98
98
|
.describe("Number of results to return (1-100)"),
|
|
99
99
|
};
|
|
100
|
+
// Combined schema for all page operations
|
|
101
|
+
export const PAGES_OPERATION_SCHEMA = {
|
|
102
|
+
payload: z
|
|
103
|
+
.preprocess(preprocessJson, z.discriminatedUnion("action", [
|
|
104
|
+
z.object({
|
|
105
|
+
action: z
|
|
106
|
+
.literal("create_page")
|
|
107
|
+
.describe("Use this action to create a new page in the database."),
|
|
108
|
+
params: z.object(CREATE_PAGE_SCHEMA),
|
|
109
|
+
}),
|
|
110
|
+
z.object({
|
|
111
|
+
action: z
|
|
112
|
+
.literal("archive_page")
|
|
113
|
+
.describe("Use this action to archive an existing page, making it inactive."),
|
|
114
|
+
params: z.object(ARCHIVE_PAGE_SCHEMA),
|
|
115
|
+
}),
|
|
116
|
+
z.object({
|
|
117
|
+
action: z
|
|
118
|
+
.literal("restore_page")
|
|
119
|
+
.describe("Use this action to restore a previously archived page."),
|
|
120
|
+
params: z.object(RESTORE_PAGE_SCHEMA),
|
|
121
|
+
}),
|
|
122
|
+
z.object({
|
|
123
|
+
action: z
|
|
124
|
+
.literal("search_pages")
|
|
125
|
+
.describe("Use this action to search for pages based on a query."),
|
|
126
|
+
params: z.object(SEARCH_PAGES_SCHEMA),
|
|
127
|
+
}),
|
|
128
|
+
z.object({
|
|
129
|
+
action: z
|
|
130
|
+
.literal("update_page_properties")
|
|
131
|
+
.describe("Use this action to update the properties of an existing page."),
|
|
132
|
+
params: z.object(UPDATE_PAGE_PROPERTIES_SCHEMA),
|
|
133
|
+
}),
|
|
134
|
+
]))
|
|
135
|
+
.describe("A union of all possible page operations. Each operation has a specific action and corresponding parameters. Use this schema to validate the input for page operations such as creating, archiving, restoring, searching, and updating pages. Available actions include: 'create_page', 'archive_page', 'restore_page', 'search_pages', and 'update_page_properties'. Each operation requires specific parameters as defined in the corresponding schemas."),
|
|
136
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { preprocessJson } from "./preprocess.js";
|
|
3
|
+
// Schema for listing users with pagination
|
|
4
|
+
export const LIST_USERS_SCHEMA = {
|
|
5
|
+
start_cursor: z.string().optional().describe("Pagination cursor"),
|
|
6
|
+
page_size: z
|
|
7
|
+
.number()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Number of users to return per page"),
|
|
10
|
+
};
|
|
11
|
+
// Schema for getting a single user
|
|
12
|
+
export const GET_USER_SCHEMA = {
|
|
13
|
+
user_id: z.string().describe("The ID of the user to retrieve"),
|
|
14
|
+
};
|
|
15
|
+
// Combined schema for all user operations
|
|
16
|
+
export const USERS_OPERATION_SCHEMA = {
|
|
17
|
+
payload: z
|
|
18
|
+
.preprocess(preprocessJson, z.discriminatedUnion("action", [
|
|
19
|
+
z.object({
|
|
20
|
+
action: z
|
|
21
|
+
.literal("list_users")
|
|
22
|
+
.describe("Use this action to list users."),
|
|
23
|
+
params: z.object(LIST_USERS_SCHEMA),
|
|
24
|
+
}),
|
|
25
|
+
z.object({
|
|
26
|
+
action: z
|
|
27
|
+
.literal("get_user")
|
|
28
|
+
.describe("Use this action to get a single user."),
|
|
29
|
+
params: z.object(GET_USER_SCHEMA),
|
|
30
|
+
}),
|
|
31
|
+
z.object({
|
|
32
|
+
action: z
|
|
33
|
+
.literal("get_bot_user")
|
|
34
|
+
.describe("Use this action to get the bot user."),
|
|
35
|
+
params: z.object({}),
|
|
36
|
+
}),
|
|
37
|
+
]))
|
|
38
|
+
.describe("A union of all possible user operations. Each operation has a specific action and corresponding parameters. Use this schema to validate the input for user operations such as listing, getting a single user, and getting the bot user. Available actions include: 'list_users', 'get_user', and 'get_bot_user'. Each operation requires specific parameters as defined in the corresponding schemas."),
|
|
39
|
+
};
|
package/build/server/index.js
CHANGED
|
@@ -18,7 +18,7 @@ export async function startServer() {
|
|
|
18
18
|
try {
|
|
19
19
|
const transport = new StdioServerTransport();
|
|
20
20
|
await server.connect(transport);
|
|
21
|
-
console.
|
|
21
|
+
console.log(`${CONFIG.serverName} v${CONFIG.serverVersion} running on stdio`);
|
|
22
22
|
}
|
|
23
23
|
catch (error) {
|
|
24
24
|
console.error("Server initialization error:", error instanceof Error ? error.message : String(error));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function sendLog(level, message, data = null) {
|
|
2
|
+
fetch("http://localhost:4400/api/log", {
|
|
3
|
+
method: "POST",
|
|
4
|
+
headers: {
|
|
5
|
+
"Content-Type": "application/json",
|
|
6
|
+
},
|
|
7
|
+
body: JSON.stringify({
|
|
8
|
+
level, // 'debug', 'info', 'warn', 'error'
|
|
9
|
+
message,
|
|
10
|
+
data, // Optional additional data object or string
|
|
11
|
+
}),
|
|
12
|
+
}).catch((error) => console.error("Error sending log:", error));
|
|
13
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { handleNotionError } from "../utils/error.js";
|
|
2
|
+
import { appendBlockChildren } from "./appendBlockChildren.js";
|
|
3
|
+
import { retrieveBlock } from "./retrieveBlock.js";
|
|
4
|
+
import { retrieveBlockChildren } from "./retrieveBlockChildren.js";
|
|
5
|
+
import { updateBlock } from "./updateBlock.js";
|
|
6
|
+
import { deleteBlock } from "./deleteBlock.js";
|
|
7
|
+
import { batchAppendBlockChildren } from "./batchAppendBlockChildren.js";
|
|
8
|
+
import { batchUpdateBlocks } from "./batchUpdateBlocks.js";
|
|
9
|
+
import { batchDeleteBlocks } from "./batchDeleteBlocks.js";
|
|
10
|
+
import { batchMixedOperations } from "./batchMixedOperations.js";
|
|
11
|
+
export const registerBlocksOperationTool = async (params) => {
|
|
12
|
+
switch (params.payload.action) {
|
|
13
|
+
case "append_block_children":
|
|
14
|
+
return appendBlockChildren(params.payload.params);
|
|
15
|
+
case "retrieve_block":
|
|
16
|
+
return retrieveBlock(params.payload.params);
|
|
17
|
+
case "retrieve_block_children":
|
|
18
|
+
return retrieveBlockChildren(params.payload.params);
|
|
19
|
+
case "update_block":
|
|
20
|
+
return updateBlock(params.payload.params);
|
|
21
|
+
case "delete_block":
|
|
22
|
+
return deleteBlock(params.payload.params);
|
|
23
|
+
case "batch_append_block_children":
|
|
24
|
+
return batchAppendBlockChildren(params.payload.params);
|
|
25
|
+
case "batch_update_blocks":
|
|
26
|
+
return batchUpdateBlocks(params.payload.params);
|
|
27
|
+
case "batch_delete_blocks":
|
|
28
|
+
return batchDeleteBlocks(params.payload.params);
|
|
29
|
+
case "batch_mixed_operations":
|
|
30
|
+
return batchMixedOperations(params.payload.params);
|
|
31
|
+
default:
|
|
32
|
+
return handleNotionError(new Error(`Unsupported action, use one of the following: "append_block_children", "retrieve_block", "retrieve_block_children", "update_block", "delete_block", "batch_append_block_children", "batch_update_blocks", "batch_delete_blocks", "batch_mixed_operations"`));
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { notion } from "../services/notion.js";
|
|
2
|
+
import { handleNotionError } from "../utils/error.js";
|
|
3
|
+
const registerGetCommentsTool = async (params) => {
|
|
4
|
+
try {
|
|
5
|
+
const response = await notion.comments.list(params);
|
|
6
|
+
return {
|
|
7
|
+
content: [
|
|
8
|
+
{
|
|
9
|
+
type: "text",
|
|
10
|
+
text: `Comments retrieved successfully: ${response.results.length}`,
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: JSON.stringify(response, null, 2),
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return handleNotionError(error);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const registerAddPageCommentTool = async (params) => {
|
|
24
|
+
try {
|
|
25
|
+
const response = await notion.comments.create(params);
|
|
26
|
+
return {
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: `Comment created successfully: ${response.id}`,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: JSON.stringify(response, null, 2),
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return handleNotionError(error);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const registerAddDiscussionCommentTool = async (params) => {
|
|
44
|
+
try {
|
|
45
|
+
const response = await notion.comments.create(params);
|
|
46
|
+
return {
|
|
47
|
+
content: [
|
|
48
|
+
{
|
|
49
|
+
type: "text",
|
|
50
|
+
text: `Comment created successfully: ${response.id}`,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: "text",
|
|
54
|
+
text: JSON.stringify(response, null, 2),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return handleNotionError(error);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
// Combined tool function that handles all comment operations
|
|
64
|
+
export const registerCommentsOperationTool = async (params) => {
|
|
65
|
+
try {
|
|
66
|
+
const { payload } = params;
|
|
67
|
+
switch (payload.action) {
|
|
68
|
+
case "get_comments":
|
|
69
|
+
return registerGetCommentsTool(payload.params);
|
|
70
|
+
case "add_page_comment":
|
|
71
|
+
return registerAddPageCommentTool(payload.params);
|
|
72
|
+
case "add_discussion_comment":
|
|
73
|
+
return registerAddDiscussionCommentTool(payload.params);
|
|
74
|
+
default:
|
|
75
|
+
throw new Error(`Unsupported action, use one of the following: "get_comments", "add_page_comment", "add_discussion_comment"`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return handleNotionError(error);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { handleNotionError } from "../utils/error.js";
|
|
2
|
+
import { createDatabase } from "./createDatabase.js";
|
|
3
|
+
import { queryDatabase } from "./queryDatabase.js";
|
|
4
|
+
import { updateDatabase } from "./updateDatabase.js";
|
|
5
|
+
export const registerDatabaseOperationTool = async (params) => {
|
|
6
|
+
switch (params.payload.action) {
|
|
7
|
+
case "create_database":
|
|
8
|
+
return createDatabase(params.payload.params);
|
|
9
|
+
case "query_database":
|
|
10
|
+
return queryDatabase(params.payload.params);
|
|
11
|
+
case "update_database":
|
|
12
|
+
return updateDatabase(params.payload.params);
|
|
13
|
+
default:
|
|
14
|
+
return handleNotionError(new Error(`Unsupported action, use one of the following: "create_database", "query_database", "update_database"`));
|
|
15
|
+
}
|
|
16
|
+
};
|
package/build/tools/index.js
CHANGED
|
@@ -1,41 +1,23 @@
|
|
|
1
1
|
import { server } from "../server/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { deleteBlock } from "./deleteBlock.js";
|
|
13
|
-
import { batchAppendBlockChildren } from "./batchAppendBlockChildren.js";
|
|
14
|
-
import { batchUpdateBlocks } from "./batchUpdateBlocks.js";
|
|
15
|
-
import { batchDeleteBlocks } from "./batchDeleteBlocks.js";
|
|
16
|
-
import { batchMixedOperations } from "./batchMixedOperations.js";
|
|
17
|
-
import { createDatabase } from "./createDatabase.js";
|
|
18
|
-
import { queryDatabase } from "./queryDatabase.js";
|
|
19
|
-
import { updateDatabase } from "./updateDatabase.js";
|
|
20
|
-
import { updatePageProperties } from "./updatePageProperties.js";
|
|
2
|
+
import { PAGES_OPERATION_SCHEMA } from "../schema/page.js";
|
|
3
|
+
import { BLOCKS_OPERATION_SCHEMA } from "../schema/blocks.js";
|
|
4
|
+
import { DATABASE_OPERATION_SCHEMA } from "../schema/database.js";
|
|
5
|
+
import { COMMENTS_OPERATION_SCHEMA } from "../schema/comments.js";
|
|
6
|
+
import { USERS_OPERATION_SCHEMA } from "../schema/users.js";
|
|
7
|
+
import { registerPagesOperationTool } from "./pages.js";
|
|
8
|
+
import { registerBlocksOperationTool } from "./blocks.js";
|
|
9
|
+
import { registerDatabaseOperationTool } from "./database.js";
|
|
10
|
+
import { registerCommentsOperationTool } from "./comments.js";
|
|
11
|
+
import { registerUsersOperationTool } from "./users.js";
|
|
21
12
|
export const registerAllTools = () => {
|
|
22
|
-
|
|
23
|
-
server.tool("
|
|
24
|
-
|
|
25
|
-
server.tool("
|
|
26
|
-
|
|
27
|
-
server.tool("
|
|
28
|
-
|
|
29
|
-
server.tool("
|
|
30
|
-
|
|
31
|
-
server.tool("
|
|
32
|
-
// Register database tools
|
|
33
|
-
server.tool("create_database", "Create a new database in Notion", CREATE_DATABASE_SCHEMA, createDatabase);
|
|
34
|
-
server.tool("query_database", "Query a database in Notion", QUERY_DATABASE_SCHEMA, queryDatabase);
|
|
35
|
-
server.tool("update_database", "Update a database in Notion", UPDATE_DATABASE_SCHEMA, updateDatabase);
|
|
36
|
-
// Register batch operation tools
|
|
37
|
-
server.tool("batch_append_block_children", "Append children to multiple blocks in a single operation", BATCH_APPEND_BLOCK_CHILDREN_SCHEMA, batchAppendBlockChildren);
|
|
38
|
-
server.tool("batch_update_blocks", "Update multiple blocks in a single operation", BATCH_UPDATE_BLOCKS_SCHEMA, batchUpdateBlocks);
|
|
39
|
-
server.tool("batch_delete_blocks", "Delete multiple blocks in a single operation", BATCH_DELETE_BLOCKS_SCHEMA, batchDeleteBlocks);
|
|
40
|
-
server.tool("batch_mixed_operations", "Perform a mix of append, update, and delete operations in a single request", BATCH_MIXED_OPERATIONS_SCHEMA, batchMixedOperations);
|
|
13
|
+
// Register combined pages operation tool
|
|
14
|
+
server.tool("notion_pages", "Perform various page operations (create, archive, restore, search, update)", PAGES_OPERATION_SCHEMA, registerPagesOperationTool);
|
|
15
|
+
// Register combined blocks operation tool
|
|
16
|
+
server.tool("notion_blocks", "Perform various block operations (retrieve, update, delete, append children, batch operations)", BLOCKS_OPERATION_SCHEMA, registerBlocksOperationTool);
|
|
17
|
+
// Register combined database operation tool
|
|
18
|
+
server.tool("notion_database", "Perform various database operations (create, query, update)", DATABASE_OPERATION_SCHEMA, registerDatabaseOperationTool);
|
|
19
|
+
// Register combined comments operation tool
|
|
20
|
+
server.tool("notion_comments", "Perform various comment operations (get, add to page, add to discussion)", COMMENTS_OPERATION_SCHEMA, registerCommentsOperationTool);
|
|
21
|
+
// Register combined users operation tool
|
|
22
|
+
server.tool("notion_users", "Perform various user operations (list, get, get bot)", USERS_OPERATION_SCHEMA, registerUsersOperationTool);
|
|
41
23
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { handleNotionError } from "../utils/error.js";
|
|
2
|
+
import { registerCreatePageTool } from "./createPage.js";
|
|
3
|
+
import { archivePage } from "./updatePage.js";
|
|
4
|
+
import { restorePage } from "./updatePage.js";
|
|
5
|
+
import { searchPages } from "./searchPage.js";
|
|
6
|
+
import { updatePageProperties } from "./updatePageProperties.js";
|
|
7
|
+
export const registerPagesOperationTool = async (params) => {
|
|
8
|
+
switch (params.payload.action) {
|
|
9
|
+
case "create_page":
|
|
10
|
+
return registerCreatePageTool(params.payload.params);
|
|
11
|
+
case "archive_page":
|
|
12
|
+
return archivePage(params.payload.params);
|
|
13
|
+
case "restore_page":
|
|
14
|
+
return restorePage(params.payload.params);
|
|
15
|
+
case "search_pages":
|
|
16
|
+
return searchPages(params.payload.params);
|
|
17
|
+
case "update_page_properties":
|
|
18
|
+
return updatePageProperties(params.payload.params);
|
|
19
|
+
default:
|
|
20
|
+
return handleNotionError(new Error(`Unsupported action, use one of the following: "create_page", "archive_page", "restore_page", "search_pages", "update_page_properties"`));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -4,10 +4,6 @@ export async function searchPages(params) {
|
|
|
4
4
|
try {
|
|
5
5
|
const response = await notion.search({
|
|
6
6
|
query: params.query || "",
|
|
7
|
-
filter: {
|
|
8
|
-
value: "page",
|
|
9
|
-
property: "object",
|
|
10
|
-
},
|
|
11
7
|
sort: params.sort,
|
|
12
8
|
start_cursor: params.start_cursor,
|
|
13
9
|
page_size: params.page_size || 10,
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { notion } from "../services/notion.js";
|
|
2
|
+
import { handleNotionError } from "../utils/error.js";
|
|
3
|
+
export const registerGetListUsersTool = async (params) => {
|
|
4
|
+
try {
|
|
5
|
+
const response = await notion.users.list(params);
|
|
6
|
+
return {
|
|
7
|
+
content: [
|
|
8
|
+
{
|
|
9
|
+
type: "text",
|
|
10
|
+
text: `Users retrieved successfully: ${response.results.length}`,
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: JSON.stringify(response, null, 2),
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return handleNotionError(error);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
export const registerGetUserTool = async (params) => {
|
|
24
|
+
try {
|
|
25
|
+
const response = await notion.users.retrieve(params);
|
|
26
|
+
return {
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: `User retrieved successfully: ${response.id}`,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: JSON.stringify(response, null, 2),
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return handleNotionError(error);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export const registerGetBotUserTool = async () => {
|
|
44
|
+
try {
|
|
45
|
+
const response = await notion.users.me({});
|
|
46
|
+
return {
|
|
47
|
+
content: [
|
|
48
|
+
{
|
|
49
|
+
type: "text",
|
|
50
|
+
text: `Bot user retrieved successfully: ${response.id}`,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: "text",
|
|
54
|
+
text: JSON.stringify(response, null, 2),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return handleNotionError(error);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
// Combined tool function that handles all user operations
|
|
64
|
+
export const registerUsersOperationTool = async (params) => {
|
|
65
|
+
switch (params.payload.action) {
|
|
66
|
+
case "list_users":
|
|
67
|
+
return registerGetListUsersTool(params.payload.params);
|
|
68
|
+
case "get_user":
|
|
69
|
+
return registerGetUserTool(params.payload.params);
|
|
70
|
+
case "get_bot_user":
|
|
71
|
+
return registerGetBotUserTool();
|
|
72
|
+
default:
|
|
73
|
+
return handleNotionError(new Error(`Unsupported action, use one of the following: "list_users", "get_user", "get_bot_user"`));
|
|
74
|
+
}
|
|
75
|
+
};
|
package/build/types/blocks.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { APPEND_BLOCK_CHILDREN_SCHEMA, RETRIEVE_BLOCK_SCHEMA, RETRIEVE_BLOCK_CHILDREN_SCHEMA, UPDATE_BLOCK_SCHEMA, DELETE_BLOCK_SCHEMA, BATCH_APPEND_BLOCK_CHILDREN_SCHEMA, BATCH_UPDATE_BLOCKS_SCHEMA, BATCH_DELETE_BLOCKS_SCHEMA, BATCH_MIXED_OPERATIONS_SCHEMA, } from "../schema/blocks.js";
|
|
2
|
+
import { APPEND_BLOCK_CHILDREN_SCHEMA, RETRIEVE_BLOCK_SCHEMA, RETRIEVE_BLOCK_CHILDREN_SCHEMA, UPDATE_BLOCK_SCHEMA, DELETE_BLOCK_SCHEMA, BATCH_APPEND_BLOCK_CHILDREN_SCHEMA, BATCH_UPDATE_BLOCKS_SCHEMA, BATCH_DELETE_BLOCKS_SCHEMA, BATCH_MIXED_OPERATIONS_SCHEMA, BLOCKS_OPERATION_SCHEMA, } from "../schema/blocks.js";
|
|
3
3
|
export const appendBlockChildrenSchema = z.object(APPEND_BLOCK_CHILDREN_SCHEMA);
|
|
4
4
|
export const retrieveBlockSchema = z.object(RETRIEVE_BLOCK_SCHEMA);
|
|
5
5
|
export const retrieveBlockChildrenSchema = z.object(RETRIEVE_BLOCK_CHILDREN_SCHEMA);
|
|
@@ -9,3 +9,4 @@ export const batchAppendBlockChildrenSchema = z.object(BATCH_APPEND_BLOCK_CHILDR
|
|
|
9
9
|
export const batchUpdateBlocksSchema = z.object(BATCH_UPDATE_BLOCKS_SCHEMA);
|
|
10
10
|
export const batchDeleteBlocksSchema = z.object(BATCH_DELETE_BLOCKS_SCHEMA);
|
|
11
11
|
export const batchMixedOperationsSchema = z.object(BATCH_MIXED_OPERATIONS_SCHEMA);
|
|
12
|
+
export const blocksOperationSchema = z.object(BLOCKS_OPERATION_SCHEMA);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { GET_COMMENTS_SCHEMA, ADD_PAGE_COMMENT_SCHEMA, ADD_DISCUSSION_COMMENT_SCHEMA, COMMENTS_OPERATION_SCHEMA, } from "../schema/comments.js";
|
|
3
|
+
// Types inferred from the schemas
|
|
4
|
+
export const getCommentsSchema = z.object(GET_COMMENTS_SCHEMA);
|
|
5
|
+
export const addPageCommentSchema = z.object(ADD_PAGE_COMMENT_SCHEMA);
|
|
6
|
+
export const addDiscussionCommentSchema = z.object(ADD_DISCUSSION_COMMENT_SCHEMA);
|
|
7
|
+
export const commentsOperationSchema = z.object(COMMENTS_OPERATION_SCHEMA);
|
package/build/types/database.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { CREATE_DATABASE_SCHEMA, QUERY_DATABASE_SCHEMA, UPDATE_DATABASE_SCHEMA, } from "../schema/database.js";
|
|
2
|
+
import { CREATE_DATABASE_SCHEMA, QUERY_DATABASE_SCHEMA, UPDATE_DATABASE_SCHEMA, DATABASE_OPERATION_SCHEMA, } from "../schema/database.js";
|
|
3
3
|
export const createDatabaseSchema = z.object(CREATE_DATABASE_SCHEMA);
|
|
4
4
|
export const queryDatabaseSchema = z.object(QUERY_DATABASE_SCHEMA);
|
|
5
5
|
export const updateDatabaseSchema = z.object(UPDATE_DATABASE_SCHEMA);
|
|
6
|
+
export const databaseOperationSchema = z.object(DATABASE_OPERATION_SCHEMA);
|
package/build/types/page.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { ARCHIVE_PAGE_SCHEMA, CREATE_PAGE_SCHEMA, RESTORE_PAGE_SCHEMA, SEARCH_PAGES_SCHEMA, UPDATE_PAGE_PROPERTIES_SCHEMA, } from "../schema/page.js";
|
|
2
|
+
import { ARCHIVE_PAGE_SCHEMA, CREATE_PAGE_SCHEMA, RESTORE_PAGE_SCHEMA, SEARCH_PAGES_SCHEMA, UPDATE_PAGE_PROPERTIES_SCHEMA, PAGES_OPERATION_SCHEMA, } from "../schema/page.js";
|
|
3
3
|
export const createPageSchema = z.object(CREATE_PAGE_SCHEMA);
|
|
4
4
|
export const archivePageSchema = z.object(ARCHIVE_PAGE_SCHEMA);
|
|
5
5
|
export const restorePageSchema = z.object(RESTORE_PAGE_SCHEMA);
|
|
6
6
|
export const searchPagesSchema = z.object(SEARCH_PAGES_SCHEMA);
|
|
7
7
|
export const updatePagePropertiesSchema = z.object(UPDATE_PAGE_PROPERTIES_SCHEMA);
|
|
8
|
+
export const pagesOperationSchema = z.object(PAGES_OPERATION_SCHEMA);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { LIST_USERS_SCHEMA, GET_USER_SCHEMA, USERS_OPERATION_SCHEMA, } from "../schema/users.js";
|
|
3
|
+
// Types inferred from schemas
|
|
4
|
+
const listUsersSchema = z.object(LIST_USERS_SCHEMA);
|
|
5
|
+
const getUserSchema = z.object(GET_USER_SCHEMA);
|
|
6
|
+
const usersOperationSchema = z.object(USERS_OPERATION_SCHEMA);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "notion-mcp-server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"notion-mcp-server": "build/index.js"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"build"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.9.0",
|
|
29
29
|
"@notionhq/client": "^2.3.0",
|
|
30
30
|
"zod": "^3.24.2"
|
|
31
31
|
},
|