@atikk-co-jp/notion-mcp-server 0.6.0 → 0.7.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.
Files changed (31) hide show
  1. package/README.md +19 -2
  2. package/dist/src/tools/archive-database.d.ts.map +1 -1
  3. package/dist/src/tools/archive-database.js +1 -2
  4. package/dist/src/tools/archive-page.d.ts.map +1 -1
  5. package/dist/src/tools/archive-page.js +1 -2
  6. package/dist/src/tools/create-comment-simple.d.ts +4 -0
  7. package/dist/src/tools/create-comment-simple.d.ts.map +1 -0
  8. package/dist/src/tools/create-comment-simple.js +50 -0
  9. package/dist/src/tools/create-comment.d.ts.map +1 -1
  10. package/dist/src/tools/create-comment.js +22 -5
  11. package/dist/src/tools/create-page-simple.d.ts.map +1 -1
  12. package/dist/src/tools/create-page-simple.js +24 -8
  13. package/dist/src/tools/create-page.js +2 -2
  14. package/dist/src/tools/get-block-children.js +1 -1
  15. package/dist/src/tools/index.d.ts +2 -1
  16. package/dist/src/tools/index.d.ts.map +1 -1
  17. package/dist/src/tools/index.js +3 -1
  18. package/dist/src/tools/query-data-source.d.ts.map +1 -1
  19. package/dist/src/tools/query-data-source.js +8 -2
  20. package/dist/src/tools/retrieve-page-property.d.ts.map +1 -1
  21. package/dist/src/tools/retrieve-page-property.js +1 -2
  22. package/dist/src/tools/update-data-source.js +2 -2
  23. package/dist/src/tools/update-page.d.ts.map +1 -1
  24. package/dist/src/tools/update-page.js +4 -2
  25. package/dist/src/utils/error-handler.d.ts +11 -0
  26. package/dist/src/utils/error-handler.d.ts.map +1 -1
  27. package/dist/src/utils/error-handler.js +36 -0
  28. package/dist/src/utils/index.d.ts +1 -1
  29. package/dist/src/utils/index.d.ts.map +1 -1
  30. package/dist/src/utils/index.js +1 -1
  31. package/package.json +1 -1
package/README.md CHANGED
@@ -21,6 +21,8 @@ MCP (Model Context Protocol) server for Notion API. Enables AI assistants to int
21
21
 
22
22
  ## API Coverage
23
23
 
24
+ > ⭐ = Markdown input supported (reduces input tokens by ~80%)
25
+
24
26
  | Category | Notion API | MCP Tool | Format |
25
27
  |----------|-----------|----------|--------|
26
28
  | **Pages** | | | |
@@ -50,6 +52,7 @@ MCP (Model Context Protocol) server for Notion API. Enables AI assistants to int
50
52
  | | | `append-blocks-simple` ⭐ | Markdown |
51
53
  | **Comments** | | | |
52
54
  | | [Create comment](https://developers.notion.com/reference/create-a-comment) | `create-comment` | JSON |
55
+ | | | `create-comment-simple` ⭐ | Markdown |
53
56
  | | [List comments](https://developers.notion.com/reference/retrieve-comments) | `list-comments` | JSON |
54
57
  | **Users** | | | |
55
58
  | | [List users](https://developers.notion.com/reference/get-users) | `list-users` | JSON |
@@ -58,8 +61,6 @@ MCP (Model Context Protocol) server for Notion API. Enables AI assistants to int
58
61
  | **Search** | | | |
59
62
  | | [Search](https://developers.notion.com/reference/post-search) | `search` | JSON |
60
63
 
61
- ⭐ = Markdown input supported (reduces input tokens by ~80%)
62
-
63
64
  ## Installation
64
65
 
65
66
  ```bash
@@ -414,6 +415,22 @@ Add a comment to a page.
414
415
  }
415
416
  ```
416
417
 
418
+ ### create-comment-simple ⭐
419
+
420
+ Add a comment using Markdown. Simpler than `create-comment`.
421
+
422
+ **Parameters:**
423
+ - `page_id` (required): The ID of the page
424
+ - `content` (required): Comment in Markdown
425
+ - `discussion_id` (optional): Reply to existing thread
426
+
427
+ ```json
428
+ {
429
+ "page_id": "page-uuid-here",
430
+ "content": "This is **important** with a [link](https://example.com)"
431
+ }
432
+ ```
433
+
417
434
  ## Development
418
435
 
419
436
  ```bash
@@ -1 +1 @@
1
- {"version":3,"file":"archive-database.d.ts","sourceRoot":"","sources":["../../../src/tools/archive-database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAOvD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAqBrF"}
1
+ {"version":3,"file":"archive-database.d.ts","sourceRoot":"","sources":["../../../src/tools/archive-database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAOvD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAoBrF"}
@@ -5,8 +5,7 @@ const inputSchema = {
5
5
  };
6
6
  export function registerArchiveDatabase(server, notion) {
7
7
  server.registerTool('archive-database', {
8
- description: 'Archive (delete) a Notion database by moving it to trash. ' +
9
- 'This is equivalent to update-database with archived: true.',
8
+ description: 'Move a database to trash. Recoverable for 30 days via Notion UI.',
10
9
  inputSchema,
11
10
  }, async ({ database_id }) => {
12
11
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"archive-page.d.ts","sourceRoot":"","sources":["../../../src/tools/archive-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAOvD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAqBjF"}
1
+ {"version":3,"file":"archive-page.d.ts","sourceRoot":"","sources":["../../../src/tools/archive-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAOvD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAoBjF"}
@@ -5,8 +5,7 @@ const inputSchema = {
5
5
  };
6
6
  export function registerArchivePage(server, notion) {
7
7
  server.registerTool('archive-page', {
8
- description: 'Archive (delete) a Notion page by moving it to trash. ' +
9
- 'This is equivalent to update-page with archived: true.',
8
+ description: 'Move a page to trash. Recoverable for 30 days via Notion UI.',
10
9
  inputSchema,
11
10
  }, async ({ page_id }) => {
12
11
  try {
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { NotionClient } from '../notion-client.js';
3
+ export declare function registerCreateCommentSimple(server: McpServer, notion: NotionClient): void;
4
+ //# sourceMappingURL=create-comment-simple.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-comment-simple.d.ts","sourceRoot":"","sources":["../../../src/tools/create-comment-simple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAUvD,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAmDzF"}
@@ -0,0 +1,50 @@
1
+ import { z } from 'zod';
2
+ import { parseInlineMarkdown } from '../converters/index.js';
3
+ import { formatResponse, handleError } from '../utils/index.js';
4
+ const inputSchema = {
5
+ page_id: z.string().optional().describe('Page ID (for page comments)'),
6
+ block_id: z.string().optional().describe('Block ID (for block comments)'),
7
+ discussion_id: z.string().optional().describe('Discussion ID (for replies)'),
8
+ content: z.string().describe('Comment in Markdown (**bold**, *italic*, [link](url), `code`)'),
9
+ };
10
+ export function registerCreateCommentSimple(server, notion) {
11
+ server.registerTool('create-comment-simple', {
12
+ description: 'Add a comment using Markdown. Simpler than create-comment.',
13
+ inputSchema,
14
+ }, async ({ page_id, block_id, discussion_id, content }) => {
15
+ try {
16
+ // Validate: exactly one of page_id, block_id, or discussion_id must be provided
17
+ const providedCount = [page_id, block_id, discussion_id].filter(Boolean).length;
18
+ if (providedCount !== 1) {
19
+ return {
20
+ content: [
21
+ {
22
+ type: 'text',
23
+ text: 'Error: Provide exactly one of page_id, block_id, or discussion_id.',
24
+ },
25
+ ],
26
+ isError: true,
27
+ };
28
+ }
29
+ const rich_text = parseInlineMarkdown(content);
30
+ // Build params based on which ID was provided
31
+ const params = {
32
+ rich_text,
33
+ };
34
+ if (discussion_id) {
35
+ params.discussion_id = discussion_id;
36
+ }
37
+ else if (page_id) {
38
+ params.parent = { page_id };
39
+ }
40
+ else if (block_id) {
41
+ params.parent = { block_id };
42
+ }
43
+ const response = await notion.comments.create(params);
44
+ return formatResponse(response);
45
+ }
46
+ catch (error) {
47
+ return handleError(error);
48
+ }
49
+ });
50
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"create-comment.d.ts","sourceRoot":"","sources":["../../../src/tools/create-comment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAUvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAqCnF"}
1
+ {"version":3,"file":"create-comment.d.ts","sourceRoot":"","sources":["../../../src/tools/create-comment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAWvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAqDnF"}
@@ -2,9 +2,10 @@ import { z } from 'zod';
2
2
  import { formatResponse, handleError } from '../utils/index.js';
3
3
  // Minimal schema for MCP (full validation by Notion API)
4
4
  const inputSchema = {
5
- page_id: z.string().describe('Page ID'),
5
+ page_id: z.string().optional().describe('Page ID (for page comments)'),
6
+ block_id: z.string().optional().describe('Block ID (for block comments)'),
7
+ discussion_id: z.string().optional().describe('Discussion ID (for replies)'),
6
8
  rich_text: z.array(z.any()).describe('Comment content as rich text'),
7
- discussion_id: z.string().optional().describe('Reply to existing discussion'),
8
9
  };
9
10
  export function registerCreateComment(server, notion) {
10
11
  server.registerTool('create-comment', {
@@ -13,18 +14,34 @@ export function registerCreateComment(server, notion) {
13
14
  'Use discussion_id to reply to an existing comment thread. ' +
14
15
  'Returns the created comment with its ID.',
15
16
  inputSchema,
16
- }, async ({ page_id, rich_text, discussion_id }) => {
17
+ }, async ({ page_id, block_id, discussion_id, rich_text }) => {
17
18
  try {
18
- // The Notion API requires either parent or discussion_id
19
+ // Validate: exactly one of page_id, block_id, or discussion_id must be provided
20
+ const providedCount = [page_id, block_id, discussion_id].filter(Boolean).length;
21
+ if (providedCount !== 1) {
22
+ return {
23
+ content: [
24
+ {
25
+ type: 'text',
26
+ text: 'Error: Provide exactly one of page_id, block_id, or discussion_id.',
27
+ },
28
+ ],
29
+ isError: true,
30
+ };
31
+ }
32
+ // Build params based on which ID was provided
19
33
  const params = {
20
34
  rich_text,
21
35
  };
22
36
  if (discussion_id) {
23
37
  params.discussion_id = discussion_id;
24
38
  }
25
- else {
39
+ else if (page_id) {
26
40
  params.parent = { page_id };
27
41
  }
42
+ else if (block_id) {
43
+ params.parent = { block_id };
44
+ }
28
45
  const response = await notion.comments.create(params);
29
46
  return formatResponse(response);
30
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-page-simple.d.ts","sourceRoot":"","sources":["../../../src/tools/create-page-simple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAYvD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA4DtF"}
1
+ {"version":3,"file":"create-page-simple.d.ts","sourceRoot":"","sources":["../../../src/tools/create-page-simple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAqBvD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA+EtF"}
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { markdownToBlocks } from '../converters/index.js';
3
- import { formatResponse, handleError } from '../utils/index.js';
3
+ import { formatResponse, handleErrorWithContext } from '../utils/index.js';
4
4
  // Minimal schema for MCP
5
5
  const inputSchema = {
6
6
  data_source_id: z.string().describe('Data source ID (required in API 2025-09-03)'),
@@ -11,13 +11,26 @@ const inputSchema = {
11
11
  };
12
12
  export function registerCreatePageSimple(server, notion) {
13
13
  server.registerTool('create-page-simple', {
14
- description: 'Create a Notion page with Markdown content. ' +
15
- 'Simpler than create-page: just provide title and markdown text. ' +
16
- 'Supports: headings (#), lists (- or 1.), checkboxes (- [ ]), code blocks (```), quotes (>), images (![]()), bold (**), italic (*), links ([]()), etc. ' +
17
- '(API version 2025-09-03)',
14
+ description: 'Create a page with Markdown. Title is auto-mapped to the database title property. ' +
15
+ 'Supports: # headings, - lists, - [ ] checkboxes, ``` code, > quotes, **bold**, *italic*, [links]().',
18
16
  inputSchema,
19
17
  }, async ({ data_source_id, title, content, properties, icon }) => {
20
18
  try {
19
+ // Try to fetch data source schema to find the title property name
20
+ let titlePropertyName = 'Name'; // Default fallback
21
+ try {
22
+ const schema = await notion.dataSources.retrieve({
23
+ data_source_id,
24
+ });
25
+ // Find the title property name from schema
26
+ const foundTitleProp = Object.entries(schema.properties).find(([, prop]) => prop.type === 'title');
27
+ if (foundTitleProp) {
28
+ titlePropertyName = foundTitleProp[0];
29
+ }
30
+ }
31
+ catch {
32
+ // If schema fetch fails, fall back to 'Name'
33
+ }
21
34
  // Build properties with title
22
35
  const pageProperties = {
23
36
  ...properties,
@@ -25,9 +38,9 @@ export function registerCreatePageSimple(server, notion) {
25
38
  // Check if any title property is already provided
26
39
  // Title properties have the structure: { title: [...] }
27
40
  const hasTitleProperty = Object.values(pageProperties).some((prop) => prop && typeof prop === 'object' && 'title' in prop);
28
- // Only add Name if no title property exists
41
+ // Add title property if not already provided
29
42
  if (!hasTitleProperty) {
30
- pageProperties.Name = {
43
+ pageProperties[titlePropertyName] = {
31
44
  title: [{ type: 'text', text: { content: title } }],
32
45
  };
33
46
  }
@@ -49,7 +62,10 @@ export function registerCreatePageSimple(server, notion) {
49
62
  return formatResponse(response);
50
63
  }
51
64
  catch (error) {
52
- return handleError(error);
65
+ return handleErrorWithContext(error, notion, data_source_id, {
66
+ hint: 'Hint: The "title" parameter automatically sets the title property. ' +
67
+ 'Use "properties" for other fields like select or multi_select.',
68
+ });
53
69
  }
54
70
  });
55
71
  }
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { formatResponse, handleError } from '../utils/index.js';
2
+ import { formatResponse, handleErrorWithContext } from '../utils/index.js';
3
3
  // Minimal schema for MCP (full validation by Notion API)
4
4
  const inputSchema = {
5
5
  data_source_id: z.string().describe('Data source ID (required in API 2025-09-03)'),
@@ -33,7 +33,7 @@ export function registerCreatePage(server, notion) {
33
33
  return formatResponse(response);
34
34
  }
35
35
  catch (error) {
36
- return handleError(error);
36
+ return handleErrorWithContext(error, notion, data_source_id);
37
37
  }
38
38
  });
39
39
  }
@@ -22,7 +22,7 @@ const inputSchema = {
22
22
  .boolean()
23
23
  .optional()
24
24
  .default(false)
25
- .describe("When format='markdown', fetch nested children blocks recursively (toggle, list items with children, etc.). Default is false."),
25
+ .describe('Fetch nested children recursively. Default false. WARNING: causes many API calls for deep structures.'),
26
26
  };
27
27
  export function registerGetBlockChildren(server, notion) {
28
28
  server.registerTool('get-block-children', {
@@ -5,6 +5,7 @@ import { registerAppendBlocksSimple } from './append-blocks-simple.js';
5
5
  import { registerArchiveDatabase } from './archive-database.js';
6
6
  import { registerArchivePage } from './archive-page.js';
7
7
  import { registerCreateComment } from './create-comment.js';
8
+ import { registerCreateCommentSimple } from './create-comment-simple.js';
8
9
  import { registerCreateDatabase } from './create-database.js';
9
10
  import { registerCreatePage } from './create-page.js';
10
11
  import { registerCreatePageSimple } from './create-page-simple.js';
@@ -28,5 +29,5 @@ import { registerUpdateDatabase } from './update-database.js';
28
29
  import { registerUpdateDataSource } from './update-data-source.js';
29
30
  import { registerUpdatePage } from './update-page.js';
30
31
  export declare function registerAllTools(server: McpServer, notion: NotionClient): void;
31
- export { registerRetrievePage, registerCreatePage, registerCreatePageSimple, registerUpdatePage, registerArchivePage, registerRetrievePageProperty, registerMovePage, registerCreateDatabase, registerUpdateDatabase, registerArchiveDatabase, registerRetrieveDatabase, registerRetrieveDataSource, registerQueryDataSource, registerUpdateDataSource, registerSearch, registerGetBlockChildren, registerAppendBlockChildren, registerAppendBlocksSimple, registerRetrieveBlock, registerUpdateBlock, registerUpdateBlockSimple, registerDeleteBlock, registerCreateComment, registerListComments, registerListUsers, registerRetrieveUser, registerRetrieveBotUser, };
32
+ export { registerRetrievePage, registerCreatePage, registerCreatePageSimple, registerUpdatePage, registerArchivePage, registerRetrievePageProperty, registerMovePage, registerCreateDatabase, registerUpdateDatabase, registerArchiveDatabase, registerRetrieveDatabase, registerRetrieveDataSource, registerQueryDataSource, registerUpdateDataSource, registerSearch, registerGetBlockChildren, registerAppendBlockChildren, registerAppendBlocksSimple, registerRetrieveBlock, registerUpdateBlock, registerUpdateBlockSimple, registerDeleteBlock, registerCreateComment, registerCreateCommentSimple, registerListComments, registerListUsers, registerRetrieveUser, registerRetrieveBotUser, };
32
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAA;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAA;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAA;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAErD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAyC9E;AAED,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,GACxB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAA;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAA;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAA;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAErD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA0C9E;AAED,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACrB,2BAA2B,EAC3B,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,GACxB,CAAA"}
@@ -3,6 +3,7 @@ import { registerAppendBlocksSimple } from './append-blocks-simple.js';
3
3
  import { registerArchiveDatabase } from './archive-database.js';
4
4
  import { registerArchivePage } from './archive-page.js';
5
5
  import { registerCreateComment } from './create-comment.js';
6
+ import { registerCreateCommentSimple } from './create-comment-simple.js';
6
7
  import { registerCreateDatabase } from './create-database.js';
7
8
  import { registerCreatePage } from './create-page.js';
8
9
  import { registerCreatePageSimple } from './create-page-simple.js';
@@ -55,10 +56,11 @@ export function registerAllTools(server, notion) {
55
56
  registerDeleteBlock(server, notion);
56
57
  // Comment operations
57
58
  registerCreateComment(server, notion);
59
+ registerCreateCommentSimple(server, notion);
58
60
  registerListComments(server, notion);
59
61
  // User operations
60
62
  registerListUsers(server, notion);
61
63
  registerRetrieveUser(server, notion);
62
64
  registerRetrieveBotUser(server, notion);
63
65
  }
64
- export { registerRetrievePage, registerCreatePage, registerCreatePageSimple, registerUpdatePage, registerArchivePage, registerRetrievePageProperty, registerMovePage, registerCreateDatabase, registerUpdateDatabase, registerArchiveDatabase, registerRetrieveDatabase, registerRetrieveDataSource, registerQueryDataSource, registerUpdateDataSource, registerSearch, registerGetBlockChildren, registerAppendBlockChildren, registerAppendBlocksSimple, registerRetrieveBlock, registerUpdateBlock, registerUpdateBlockSimple, registerDeleteBlock, registerCreateComment, registerListComments, registerListUsers, registerRetrieveUser, registerRetrieveBotUser, };
66
+ export { registerRetrievePage, registerCreatePage, registerCreatePageSimple, registerUpdatePage, registerArchivePage, registerRetrievePageProperty, registerMovePage, registerCreateDatabase, registerUpdateDatabase, registerArchiveDatabase, registerRetrieveDatabase, registerRetrieveDataSource, registerQueryDataSource, registerUpdateDataSource, registerSearch, registerGetBlockChildren, registerAppendBlockChildren, registerAppendBlocksSimple, registerRetrieveBlock, registerUpdateBlock, registerUpdateBlockSimple, registerDeleteBlock, registerCreateComment, registerCreateCommentSimple, registerListComments, registerListUsers, registerRetrieveUser, registerRetrieveBotUser, };
@@ -1 +1 @@
1
- {"version":3,"file":"query-data-source.d.ts","sourceRoot":"","sources":["../../../src/tools/query-data-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AA8BvD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAsDrF"}
1
+ {"version":3,"file":"query-data-source.d.ts","sourceRoot":"","sources":["../../../src/tools/query-data-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAoCvD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAsDrF"}
@@ -4,8 +4,14 @@ import { formatPaginatedResponse, formatSimplePaginatedResponse, handleError, }
4
4
  // Minimal schema for MCP (full validation by Notion API)
5
5
  const inputSchema = {
6
6
  data_source_id: z.string().describe('Data source ID'),
7
- filter: z.any().optional().describe('Filter conditions'),
8
- sorts: z.array(z.any()).optional().describe('Sort conditions'),
7
+ filter: z
8
+ .any()
9
+ .optional()
10
+ .describe('Filter object. Example: {"property":"Status","select":{"equals":"Done"}}'),
11
+ sorts: z
12
+ .array(z.any())
13
+ .optional()
14
+ .describe('Sort array. Example: [{"property":"Date","direction":"descending"}]'),
9
15
  start_cursor: z.string().optional().describe('Pagination cursor'),
10
16
  page_size: z.number().optional().describe('Results per page (1-100)'),
11
17
  format: z.enum(['json', 'simple']).optional().describe('Output format (default: simple)'),
@@ -1 +1 @@
1
- {"version":3,"file":"retrieve-page-property.d.ts","sourceRoot":"","sources":["../../../src/tools/retrieve-page-property.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAmBvD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAkC1F"}
1
+ {"version":3,"file":"retrieve-page-property.d.ts","sourceRoot":"","sources":["../../../src/tools/retrieve-page-property.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAmBvD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAiC1F"}
@@ -8,8 +8,7 @@ const inputSchema = {
8
8
  };
9
9
  export function registerRetrievePageProperty(server, notion) {
10
10
  server.registerTool('retrieve-page-property', {
11
- description: 'Retrieve a specific property value from a page. Supports pagination for properties with many values (e.g., rollup, relation). ' +
12
- 'Use the property_id from the page properties object.',
11
+ description: 'Get a property with pagination (for relation/rollup with many items). For simple properties, use retrieve-page instead.',
13
12
  inputSchema,
14
13
  }, async ({ page_id, property_id, start_cursor, page_size }) => {
15
14
  try {
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { formatResponse, handleError } from '../utils/index.js';
2
+ import { formatResponse, handleErrorWithContext } from '../utils/index.js';
3
3
  // Minimal schema for MCP (full validation by Notion API)
4
4
  const inputSchema = {
5
5
  data_source_id: z.string().describe('Data source ID'),
@@ -25,7 +25,7 @@ export function registerUpdateDataSource(server, notion) {
25
25
  return formatResponse(response);
26
26
  }
27
27
  catch (error) {
28
- return handleError(error);
28
+ return handleErrorWithContext(error, notion, data_source_id);
29
29
  }
30
30
  });
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"update-page.d.ts","sourceRoot":"","sources":["../../../src/tools/update-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAkBvD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAkDhF"}
1
+ {"version":3,"file":"update-page.d.ts","sourceRoot":"","sources":["../../../src/tools/update-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAkBvD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAoDhF"}
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { formatResponse, handleError } from '../utils/index.js';
2
+ import { formatResponse, handleErrorWithContext } from '../utils/index.js';
3
3
  // Minimal schema for MCP (full validation by Notion API)
4
4
  const inputSchema = {
5
5
  page_id: z.string().describe('Page ID'),
@@ -39,7 +39,9 @@ export function registerUpdatePage(server, notion) {
39
39
  return formatResponse(response);
40
40
  }
41
41
  catch (error) {
42
- return handleError(error);
42
+ // Note: update-page uses page_id, not data_source_id,
43
+ // so we can't show available properties without additional API call
44
+ return handleErrorWithContext(error, notion);
43
45
  }
44
46
  });
45
47
  }
@@ -1,3 +1,4 @@
1
+ import type { NotionClient } from '../notion-client.js';
1
2
  export interface McpTextContent {
2
3
  type: 'text';
3
4
  text: string;
@@ -8,4 +9,14 @@ export interface McpResponse {
8
9
  isError?: boolean;
9
10
  }
10
11
  export declare function handleError(error: unknown): McpResponse;
12
+ interface HandleErrorOptions {
13
+ /** Additional hint to append after property list (e.g., usage examples) */
14
+ hint?: string;
15
+ }
16
+ /**
17
+ * Enhanced error handler that includes available properties for validation errors.
18
+ * Use this for tools that operate on data sources (create-page, update-page, etc.)
19
+ */
20
+ export declare function handleErrorWithContext(error: unknown, notion: NotionClient, dataSourceId?: string, options?: HandleErrorOptions): Promise<McpResponse>;
21
+ export {};
11
22
  //# sourceMappingURL=error-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/utils/error-handler.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAaD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAoBvD"}
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/utils/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAEvD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAkBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAoBvD;AA2DD,UAAU,kBAAkB;IAC1B,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,YAAY,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,CAAC,CAsBtB"}
@@ -62,3 +62,39 @@ function formatNotionError(error) {
62
62
  return error.message;
63
63
  }
64
64
  }
65
+ function isValidationError(error) {
66
+ if (!(error instanceof Error))
67
+ return false;
68
+ // Check if error message contains validation_error code
69
+ return error.message.includes('validation_error');
70
+ }
71
+ function formatPropertyList(properties) {
72
+ return Object.entries(properties)
73
+ .map(([name, prop]) => ` - ${name} (${prop.type})`)
74
+ .join('\n');
75
+ }
76
+ /**
77
+ * Enhanced error handler that includes available properties for validation errors.
78
+ * Use this for tools that operate on data sources (create-page, update-page, etc.)
79
+ */
80
+ export async function handleErrorWithContext(error, notion, dataSourceId, options) {
81
+ const baseResponse = handleError(error);
82
+ // For validation errors with a data source ID, append available properties
83
+ if (isValidationError(error) && dataSourceId) {
84
+ try {
85
+ const schema = await notion.dataSources.retrieve({
86
+ data_source_id: dataSourceId,
87
+ });
88
+ const propList = formatPropertyList(schema.properties);
89
+ baseResponse.content[0].text += `\n\nAvailable properties:\n${propList}`;
90
+ // Add optional hint
91
+ if (options?.hint) {
92
+ baseResponse.content[0].text += `\n\n${options.hint}`;
93
+ }
94
+ }
95
+ catch {
96
+ // Ignore schema fetch errors - keep the original error message
97
+ }
98
+ }
99
+ return baseResponse;
100
+ }
@@ -1,3 +1,3 @@
1
- export { handleError, type McpResponse, type McpTextContent } from './error-handler.js';
1
+ export { handleError, handleErrorWithContext, type McpResponse, type McpTextContent } from './error-handler.js';
2
2
  export { formatMarkdownResponse, formatPaginatedResponse, formatResponse, formatSimplePaginatedResponse, formatSimpleResponse, formatSuccessMessage, } from './response-formatter.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACvF,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACd,6BAA6B,EAC7B,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,yBAAyB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAC/G,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACd,6BAA6B,EAC7B,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,yBAAyB,CAAA"}
@@ -1,2 +1,2 @@
1
- export { handleError } from './error-handler.js';
1
+ export { handleError, handleErrorWithContext } from './error-handler.js';
2
2
  export { formatMarkdownResponse, formatPaginatedResponse, formatResponse, formatSimplePaginatedResponse, formatSimpleResponse, formatSuccessMessage, } from './response-formatter.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atikk-co-jp/notion-mcp-server",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "MCP server for Notion API - Create, read, update pages and databases",
5
5
  "type": "module",
6
6
  "license": "MIT",