@mcp-monorepo/notion-query 1.1.0 → 1.2.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/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/client.d.ts +9 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +19 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/id-utils.d.ts +8 -0
- package/dist/lib/id-utils.d.ts.map +1 -0
- package/dist/lib/id-utils.js +20 -0
- package/dist/lib/id-utils.js.map +1 -0
- package/dist/lib/markdown-converter.d.ts +8 -0
- package/dist/lib/markdown-converter.d.ts.map +1 -0
- package/dist/lib/markdown-converter.js +95 -0
- package/dist/lib/markdown-converter.js.map +1 -0
- package/dist/lib/parser.d.ts +13 -0
- package/dist/lib/parser.d.ts.map +1 -0
- package/dist/lib/parser.js +88 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/property-parser.d.ts +25 -0
- package/dist/lib/property-parser.d.ts.map +1 -0
- package/dist/lib/property-parser.js +113 -0
- package/dist/lib/property-parser.js.map +1 -0
- package/dist/lib/response-formatter.d.ts +16 -0
- package/dist/lib/response-formatter.d.ts.map +1 -0
- package/dist/lib/response-formatter.js +173 -0
- package/dist/lib/response-formatter.js.map +1 -0
- package/dist/tools/create-pages.d.ts +3 -0
- package/dist/tools/create-pages.d.ts.map +1 -0
- package/dist/tools/create-pages.js +183 -0
- package/dist/tools/create-pages.js.map +1 -0
- package/dist/tools/fetch.d.ts +3 -0
- package/dist/tools/fetch.d.ts.map +1 -0
- package/dist/tools/fetch.js +89 -0
- package/dist/tools/fetch.js.map +1 -0
- package/dist/tools/query-datasource.d.ts +3 -0
- package/dist/tools/query-datasource.d.ts.map +1 -0
- package/dist/tools/{notion-query.js → query-datasource.js} +30 -37
- package/dist/tools/query-datasource.js.map +1 -0
- package/package.json +9 -8
- package/dist/tools/notion-query.d.ts +0 -3
- package/dist/tools/notion-query.d.ts.map +0 -1
- package/dist/tools/notion-query.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createMcpServer } from '@mcp-monorepo/shared';
|
|
3
|
-
import {
|
|
3
|
+
import { registerCreatePagesTool } from './tools/create-pages.js';
|
|
4
|
+
import { registerFetchTool } from './tools/fetch.js';
|
|
5
|
+
import { registerQueryDatasourceTool } from './tools/query-datasource.js';
|
|
4
6
|
createMcpServer({
|
|
5
7
|
name: 'notion-query',
|
|
6
8
|
importMetaPath: import.meta.filename,
|
|
7
9
|
title: 'Notion Query MCP Server',
|
|
8
|
-
tools: [
|
|
10
|
+
tools: [registerQueryDatasourceTool, registerFetchTool, registerCreatePagesTool],
|
|
9
11
|
});
|
|
10
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAA;AAEzE,eAAe,CAAC;IACd,IAAI,EAAE,cAAc;IACpB,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ;IACpC,KAAK,EAAE,yBAAyB;IAChC,KAAK,EAAE,CAAC,2BAA2B,EAAE,iBAAiB,EAAE,uBAAuB,CAAC;CACjF,CAAC,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Client } from '@notionhq/client';
|
|
2
|
+
/**
|
|
3
|
+
* Initializes and returns a singleton instance of the Notion SDK Client.
|
|
4
|
+
* It retrieves the NOTION_API_KEY from the environment variables.
|
|
5
|
+
* @throws {Error} If the NOTION_API_KEY environment variable is not set.
|
|
6
|
+
* @returns {Client} The initialized Notion client.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getNotionClient(): Client;
|
|
9
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAIzC;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,MAAM,CASxC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Client } from '@notionhq/client';
|
|
2
|
+
let notionClient;
|
|
3
|
+
/**
|
|
4
|
+
* Initializes and returns a singleton instance of the Notion SDK Client.
|
|
5
|
+
* It retrieves the NOTION_API_KEY from the environment variables.
|
|
6
|
+
* @throws {Error} If the NOTION_API_KEY environment variable is not set.
|
|
7
|
+
* @returns {Client} The initialized Notion client.
|
|
8
|
+
*/
|
|
9
|
+
export function getNotionClient() {
|
|
10
|
+
if (!notionClient) {
|
|
11
|
+
const NOTION_API_KEY = process.env.NOTION_API_KEY;
|
|
12
|
+
if (!NOTION_API_KEY) {
|
|
13
|
+
throw new Error('NOTION_API_KEY environment variable is not set.');
|
|
14
|
+
}
|
|
15
|
+
notionClient = new Client({ auth: NOTION_API_KEY });
|
|
16
|
+
}
|
|
17
|
+
return notionClient;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,IAAI,YAAgC,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;QACjD,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;QACpE,CAAC;QACD,YAAY,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAA;IACrD,CAAC;IACD,OAAO,YAAY,CAAA;AACrB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts a Notion page, database, or block ID from a URL or a raw ID string.
|
|
3
|
+
* Normalizes the ID by removing dashes.
|
|
4
|
+
* @param idOrUrl - The Notion URL or ID string.
|
|
5
|
+
* @returns The normalized 32-character ID, or undefined if no valid ID is found.
|
|
6
|
+
*/
|
|
7
|
+
export declare function normalizeId(idOrUrl: string): string | undefined;
|
|
8
|
+
//# sourceMappingURL=id-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-utils.d.ts","sourceRoot":"","sources":["../../src/lib/id-utils.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO/D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A regex to extract a UUID v4 from a string.
|
|
3
|
+
* It matches UUIDs with or without dashes.
|
|
4
|
+
*/
|
|
5
|
+
const UUID_REGEX = /([0-9a-f]{8})-?([0-9a-f]{4})-?([0-9a-f]{4})-?([0-9a-f]{4})-?([0-9a-f]{12})/;
|
|
6
|
+
/**
|
|
7
|
+
* Extracts a Notion page, database, or block ID from a URL or a raw ID string.
|
|
8
|
+
* Normalizes the ID by removing dashes.
|
|
9
|
+
* @param idOrUrl - The Notion URL or ID string.
|
|
10
|
+
* @returns The normalized 32-character ID, or undefined if no valid ID is found.
|
|
11
|
+
*/
|
|
12
|
+
export function normalizeId(idOrUrl) {
|
|
13
|
+
const match = idOrUrl.match(UUID_REGEX);
|
|
14
|
+
if (!match) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
// Reconstruct the ID without dashes
|
|
18
|
+
return match.slice(1).join('');
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=id-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-utils.js","sourceRoot":"","sources":["../../src/lib/id-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,GAAG,4EAA4E,CAAA;AAE/F;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IACvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,oCAAoC;IACpC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAChC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type BlockObjectResponse } from '@notionhq/client/build/src/api-endpoints.js';
|
|
2
|
+
/**
|
|
3
|
+
* Converts a list of Notion blocks to a Notion-flavored Markdown string [9].
|
|
4
|
+
* @param blocks - The array of block objects.
|
|
5
|
+
* @returns A promise that resolves to the full Markdown string.
|
|
6
|
+
*/
|
|
7
|
+
export declare function notionToMarkdown(blocks: BlockObjectResponse[]): Promise<string>;
|
|
8
|
+
//# sourceMappingURL=markdown-converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-converter.d.ts","sourceRoot":"","sources":["../../src/lib/markdown-converter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EAGzB,MAAM,6CAA6C,CAAA;AAqGpD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAOrF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { NotionToMarkdown } from 'notion-to-md';
|
|
2
|
+
import { getNotionClient } from './client.js';
|
|
3
|
+
let n2m;
|
|
4
|
+
/**
|
|
5
|
+
* Renders an array of rich text items into a Notion-flavored Markdown string.
|
|
6
|
+
* Supports bold, italic, strikethrough, underline, code, and links [9].
|
|
7
|
+
* @param richTextItems - The array of rich text items.
|
|
8
|
+
* @returns A formatted markdown string.
|
|
9
|
+
*/
|
|
10
|
+
function renderRichText(richTextItems) {
|
|
11
|
+
return richTextItems
|
|
12
|
+
.map((item) => {
|
|
13
|
+
let text = item.plain_text;
|
|
14
|
+
if (item.href) {
|
|
15
|
+
// Handle citations [^URL] and regular links [text](URL)
|
|
16
|
+
if (text === item.href) {
|
|
17
|
+
return `[^${item.href}]`;
|
|
18
|
+
}
|
|
19
|
+
return `[${text}](${item.href})`;
|
|
20
|
+
}
|
|
21
|
+
// Handle annotations [6]
|
|
22
|
+
if (item.annotations.code)
|
|
23
|
+
text = `\`${text}\``;
|
|
24
|
+
if (item.annotations.bold)
|
|
25
|
+
text = `**${text}**`;
|
|
26
|
+
if (item.annotations.italic)
|
|
27
|
+
text = `*${text}*`;
|
|
28
|
+
if (item.annotations.strikethrough)
|
|
29
|
+
text = `~~${text}~~`;
|
|
30
|
+
if (item.annotations.underline)
|
|
31
|
+
text = `<span underline="true">${text}</span>`;
|
|
32
|
+
return text;
|
|
33
|
+
})
|
|
34
|
+
.join('');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Gets a pre-configured singleton instance of NotionToMarkdown.
|
|
38
|
+
* Sets up custom transformers for Notion-flavored Markdown [9].
|
|
39
|
+
* @returns An instance of NotionToMarkdown.
|
|
40
|
+
*/
|
|
41
|
+
function getMarkdownConverter() {
|
|
42
|
+
if (n2m) {
|
|
43
|
+
return n2m;
|
|
44
|
+
}
|
|
45
|
+
const notionClient = getNotionClient();
|
|
46
|
+
n2m = new NotionToMarkdown({ notionClient });
|
|
47
|
+
// A generic transformer for simple blocks with rich_text and color properties [1].
|
|
48
|
+
const createColorBlockTransformer = (prefix = '') => async (block) => {
|
|
49
|
+
const blockContent = 'type' in block &&
|
|
50
|
+
block[block.type];
|
|
51
|
+
if (!blockContent) {
|
|
52
|
+
return '';
|
|
53
|
+
}
|
|
54
|
+
const markdownContent = renderRichText(blockContent.rich_text);
|
|
55
|
+
let finalMarkdown = `${prefix}${markdownContent}`;
|
|
56
|
+
if (blockContent.color && blockContent.color !== 'default') {
|
|
57
|
+
finalMarkdown += ` {color="${blockContent.color}"}`;
|
|
58
|
+
}
|
|
59
|
+
return finalMarkdown;
|
|
60
|
+
};
|
|
61
|
+
// Register transformers for block types that support color [1, 9].
|
|
62
|
+
n2m.setCustomTransformer('paragraph', createColorBlockTransformer());
|
|
63
|
+
n2m.setCustomTransformer('heading_1', createColorBlockTransformer('# '));
|
|
64
|
+
n2m.setCustomTransformer('heading_2', createColorBlockTransformer('## '));
|
|
65
|
+
n2m.setCustomTransformer('heading_3', createColorBlockTransformer('### '));
|
|
66
|
+
n2m.setCustomTransformer('bulleted_list_item', createColorBlockTransformer('- '));
|
|
67
|
+
n2m.setCustomTransformer('numbered_list_item', createColorBlockTransformer('1. '));
|
|
68
|
+
n2m.setCustomTransformer('quote', createColorBlockTransformer('> '));
|
|
69
|
+
// Custom transformer for to-do blocks to handle the checked state [9].
|
|
70
|
+
n2m.setCustomTransformer('to_do', async (block) => {
|
|
71
|
+
const todoBlock = block;
|
|
72
|
+
const prefix = todoBlock.to_do.checked ? '- [x] ' : '- [ ] ';
|
|
73
|
+
const markdownContent = renderRichText(todoBlock.to_do.rich_text);
|
|
74
|
+
let finalMarkdown = `${prefix}${markdownContent}`;
|
|
75
|
+
if (todoBlock.to_do.color && todoBlock.to_do.color !== 'default') {
|
|
76
|
+
finalMarkdown += ` {color="${todoBlock.to_do.color}"}`;
|
|
77
|
+
}
|
|
78
|
+
return finalMarkdown;
|
|
79
|
+
});
|
|
80
|
+
return n2m;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Converts a list of Notion blocks to a Notion-flavored Markdown string [9].
|
|
84
|
+
* @param blocks - The array of block objects.
|
|
85
|
+
* @returns A promise that resolves to the full Markdown string.
|
|
86
|
+
*/
|
|
87
|
+
export async function notionToMarkdown(blocks) {
|
|
88
|
+
const converter = getMarkdownConverter();
|
|
89
|
+
// The 'blocks' parameter expects the 'results' from a 'listBlockChildren' call, which matches BlockObjectResponse[]
|
|
90
|
+
const mdBlocks = await converter.blocksToMarkdown(blocks);
|
|
91
|
+
const mdString = converter.toMarkdownString(mdBlocks);
|
|
92
|
+
// `toMarkdownString` returns an object where `parent` holds the main content [7]
|
|
93
|
+
return mdString.parent ?? '';
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=markdown-converter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-converter.js","sourceRoot":"","sources":["../../src/lib/markdown-converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type DataSourceObjectResponse, type PageObjectResponse, type PartialDataSourceObjectResponse, type PartialPageObjectResponse } from '@notionhq/client';
|
|
2
|
+
type SimplifiedPropertyValue = string | number | boolean | string[] | (string | number | boolean)[] | undefined;
|
|
3
|
+
type SimplifiedPage = Record<string, SimplifiedPropertyValue>;
|
|
4
|
+
type NotionPage = PageObjectResponse | PartialPageObjectResponse | PartialDataSourceObjectResponse | DataSourceObjectResponse;
|
|
5
|
+
/**
|
|
6
|
+
* Takes an array of Notion page objects from the API and converts them into
|
|
7
|
+
* a simplified, flat array of key-value objects.
|
|
8
|
+
* @param pages The array of page objects from the Notion API response.
|
|
9
|
+
* @returns An array of simplified page objects.
|
|
10
|
+
*/
|
|
11
|
+
export declare const simplifyNotionPages: (pages: NotionPage[]) => SimplifiedPage[];
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,+BAA+B,EACpC,KAAK,yBAAyB,EAC/B,MAAM,kBAAkB,CAAA;AAEzB,KAAK,uBAAuB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,GAAG,SAAS,CAAA;AAG/G,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;AAU7D,KAAK,UAAU,GACX,kBAAkB,GAClB,yBAAyB,GACzB,+BAA+B,GAC/B,wBAAwB,CAAA;AAsD5B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,UAAU,EAAE,KAAG,cAAc,EA8BvE,CAAA"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// notion-query/lib/parser.ts
|
|
2
|
+
/**
|
|
3
|
+
* Simplifies a single Notion property object into a more readable, simple value.
|
|
4
|
+
* @param prop The Notion property object.
|
|
5
|
+
* @returns A simplified value (string, number, boolean, array, etc.) or undefined.
|
|
6
|
+
*/
|
|
7
|
+
const simplifyPropertyValue = (prop) => {
|
|
8
|
+
switch (prop.type) {
|
|
9
|
+
case 'title':
|
|
10
|
+
return prop.title.map((t) => t.plain_text).join('');
|
|
11
|
+
case 'rich_text':
|
|
12
|
+
return prop.rich_text.map((t) => t.plain_text).join('');
|
|
13
|
+
case 'number':
|
|
14
|
+
return prop.number;
|
|
15
|
+
case 'checkbox':
|
|
16
|
+
return prop.checkbox;
|
|
17
|
+
case 'select':
|
|
18
|
+
return prop.select?.name;
|
|
19
|
+
case 'multi_select':
|
|
20
|
+
return prop.multi_select.map((s) => s.name);
|
|
21
|
+
case 'status':
|
|
22
|
+
return prop.status?.name;
|
|
23
|
+
case 'date': {
|
|
24
|
+
const date = prop.date;
|
|
25
|
+
if (!date)
|
|
26
|
+
return undefined;
|
|
27
|
+
return date.end ? `${date.start} to ${date.end}` : date.start;
|
|
28
|
+
}
|
|
29
|
+
case 'people':
|
|
30
|
+
return prop.people.map((p) => p.name ?? p.id);
|
|
31
|
+
case 'relation':
|
|
32
|
+
return prop.relation.map((r) => r.id);
|
|
33
|
+
case 'formula': {
|
|
34
|
+
const formula = prop.formula;
|
|
35
|
+
return formula[formula.type];
|
|
36
|
+
}
|
|
37
|
+
case 'rollup': {
|
|
38
|
+
const rollup = prop.rollup;
|
|
39
|
+
if (rollup.type === 'array' && rollup.array) {
|
|
40
|
+
return rollup.array.flatMap((item) => simplifyPropertyValue(item)).filter((p) => p !== undefined);
|
|
41
|
+
}
|
|
42
|
+
return rollup[rollup.type];
|
|
43
|
+
}
|
|
44
|
+
case 'url':
|
|
45
|
+
return prop.url;
|
|
46
|
+
case 'email':
|
|
47
|
+
return prop.email;
|
|
48
|
+
case 'phone_number':
|
|
49
|
+
return prop.phone_number;
|
|
50
|
+
default:
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Takes an array of Notion page objects from the API and converts them into
|
|
56
|
+
* a simplified, flat array of key-value objects.
|
|
57
|
+
* @param pages The array of page objects from the Notion API response.
|
|
58
|
+
* @returns An array of simplified page objects.
|
|
59
|
+
*/
|
|
60
|
+
export const simplifyNotionPages = (pages) => {
|
|
61
|
+
return pages.map((page) => {
|
|
62
|
+
const simplifiedPage = {};
|
|
63
|
+
if ('icon' in page) {
|
|
64
|
+
if (page.icon?.type === 'emoji') {
|
|
65
|
+
simplifiedPage.icon = page.icon.emoji;
|
|
66
|
+
}
|
|
67
|
+
else if (page.icon?.type === 'external') {
|
|
68
|
+
simplifiedPage.icon = page.icon.external.url;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if ('cover' in page) {
|
|
72
|
+
if (page.cover?.type === 'external') {
|
|
73
|
+
simplifiedPage.cover = page.cover.external.url;
|
|
74
|
+
}
|
|
75
|
+
else if (page.cover?.type === 'file') {
|
|
76
|
+
simplifiedPage.cover = page.cover.file.url;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
simplifiedPage.url = 'url' in page ? page.url : undefined;
|
|
80
|
+
if ('properties' in page && page.properties) {
|
|
81
|
+
for (const [propName, propValue] of Object.entries(page.properties)) {
|
|
82
|
+
simplifiedPage[propName] = simplifyPropertyValue(propValue);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return simplifiedPage;
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type CreatePageParameters, type UpdatePageParameters } from '@notionhq/client';
|
|
2
|
+
import { type DataSourceObjectResponse } from '@notionhq/client/build/src/api-endpoints.js';
|
|
3
|
+
type DataSourceSchema = DataSourceObjectResponse['properties'];
|
|
4
|
+
type NotionProperties = CreatePageParameters['properties'];
|
|
5
|
+
/**
|
|
6
|
+
* Parses a flat properties object from the 'create-pages' tool input
|
|
7
|
+
* into the format required by the Notion API.
|
|
8
|
+
*
|
|
9
|
+
* It uses the data source schema to correctly format each property
|
|
10
|
+
* according to its type (e.g., number, select, date) [11].
|
|
11
|
+
*
|
|
12
|
+
* @param properties - A flat key-value map of properties from the tool input [1].
|
|
13
|
+
* @param dataSourceSchema - The schema of the parent data source, used to determine property types [6].
|
|
14
|
+
* @returns A Notion `CreatePageParameters['properties']` object ready for the API [9].
|
|
15
|
+
*/
|
|
16
|
+
export declare function parsePropertiesForCreate(properties: Record<string, string | number | boolean | null>, dataSourceSchema?: DataSourceSchema): NotionProperties;
|
|
17
|
+
/**
|
|
18
|
+
* Parses a flat properties object with special keys (e.g., 'date:deadline:start')
|
|
19
|
+
* from the 'update-page' tool input into the format required by the Notion API.
|
|
20
|
+
* @param properties - A flat key-value map with special-cased keys.
|
|
21
|
+
* @returns A Notion `UpdatePageParameters['properties']` object.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parsePropertiesForUpdate(_properties: Record<string, string | number>): UpdatePageParameters['properties'];
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=property-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property-parser.d.ts","sourceRoot":"","sources":["../../src/lib/property-parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvF,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,6CAA6C,CAAA;AAE3F,KAAK,gBAAgB,GAAG,wBAAwB,CAAC,YAAY,CAAC,CAAA;AAC9D,KAAK,gBAAgB,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAA;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EAC5D,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,gBAAgB,CA2FlB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,oBAAoB,CAAC,YAAY,CAAC,CAMpC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { logger } from '@mcp-monorepo/shared';
|
|
2
|
+
/**
|
|
3
|
+
* Parses a flat properties object from the 'create-pages' tool input
|
|
4
|
+
* into the format required by the Notion API.
|
|
5
|
+
*
|
|
6
|
+
* It uses the data source schema to correctly format each property
|
|
7
|
+
* according to its type (e.g., number, select, date) [11].
|
|
8
|
+
*
|
|
9
|
+
* @param properties - A flat key-value map of properties from the tool input [1].
|
|
10
|
+
* @param dataSourceSchema - The schema of the parent data source, used to determine property types [6].
|
|
11
|
+
* @returns A Notion `CreatePageParameters['properties']` object ready for the API [9].
|
|
12
|
+
*/
|
|
13
|
+
export function parsePropertiesForCreate(properties, dataSourceSchema) {
|
|
14
|
+
const notionProperties = {};
|
|
15
|
+
// Find the name of the 'title' property from the schema, if it exists [11].
|
|
16
|
+
const titleSchemaKey = dataSourceSchema
|
|
17
|
+
? Object.keys(dataSourceSchema).find((key) => dataSourceSchema[key]?.type === 'title')
|
|
18
|
+
: 'title';
|
|
19
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
20
|
+
// eslint-disable-next-line no-restricted-syntax -- User input
|
|
21
|
+
if (value === null || value === undefined)
|
|
22
|
+
continue;
|
|
23
|
+
// For convenience, allow 'title' as a key and map it to the actual title property name [1].
|
|
24
|
+
if (key.toLowerCase() === 'title' && titleSchemaKey) {
|
|
25
|
+
notionProperties[titleSchemaKey] = {
|
|
26
|
+
title: [{ text: { content: String(value) } }],
|
|
27
|
+
};
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
// If no schema is available (e.g., for a workspace page), only the 'title' is valid [9].
|
|
31
|
+
if (!dataSourceSchema) {
|
|
32
|
+
if (key.toLowerCase() === 'title') {
|
|
33
|
+
notionProperties[key] = { title: [{ text: { content: String(value) } }] };
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
logger.warn(`Skipping property "${key}"; only 'title' is allowed for pages not in a database.`);
|
|
37
|
+
}
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const schema = dataSourceSchema[key];
|
|
41
|
+
if (!schema) {
|
|
42
|
+
logger.warn(`Skipping property "${key}" as it was not found in the data source schema.`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Format the property based on its type from the schema [11].
|
|
46
|
+
switch (schema.type) {
|
|
47
|
+
case 'title':
|
|
48
|
+
notionProperties[key] = { title: [{ text: { content: String(value) } }] };
|
|
49
|
+
break;
|
|
50
|
+
case 'rich_text':
|
|
51
|
+
notionProperties[key] = { rich_text: [{ text: { content: String(value) } }] };
|
|
52
|
+
break;
|
|
53
|
+
case 'number':
|
|
54
|
+
notionProperties[key] = { number: Number(value) };
|
|
55
|
+
break;
|
|
56
|
+
case 'select':
|
|
57
|
+
notionProperties[key] = { select: { name: String(value) } };
|
|
58
|
+
break;
|
|
59
|
+
case 'status':
|
|
60
|
+
notionProperties[key] = { status: { name: String(value) } };
|
|
61
|
+
break;
|
|
62
|
+
case 'multi_select':
|
|
63
|
+
notionProperties[key] = {
|
|
64
|
+
multi_select: String(value)
|
|
65
|
+
.split(',')
|
|
66
|
+
.map((name) => ({ name: name.trim() })),
|
|
67
|
+
};
|
|
68
|
+
break;
|
|
69
|
+
case 'date':
|
|
70
|
+
notionProperties[key] = { date: { start: String(value) } };
|
|
71
|
+
break;
|
|
72
|
+
case 'checkbox': {
|
|
73
|
+
const lowerValue = String(value).toLowerCase();
|
|
74
|
+
const boolValue = lowerValue === 'true' || lowerValue === 'yes' || value === 1 || value === true;
|
|
75
|
+
notionProperties[key] = { checkbox: boolValue };
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case 'url':
|
|
79
|
+
notionProperties[key] = { url: String(value) };
|
|
80
|
+
break;
|
|
81
|
+
case 'email':
|
|
82
|
+
notionProperties[key] = { email: String(value) };
|
|
83
|
+
break;
|
|
84
|
+
case 'phone_number':
|
|
85
|
+
notionProperties[key] = { phone_number: String(value) };
|
|
86
|
+
break;
|
|
87
|
+
// Advanced types like relation, people, and files are complex and would require
|
|
88
|
+
// more specific input formats than string/number, often needing IDs.
|
|
89
|
+
// They are omitted here but can be extended if the tool input is enhanced.
|
|
90
|
+
case 'relation':
|
|
91
|
+
case 'people':
|
|
92
|
+
case 'files':
|
|
93
|
+
default:
|
|
94
|
+
logger.warn(`Unsupported property type "${schema.type}" for key "${key}" during creation.`);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return notionProperties;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Parses a flat properties object with special keys (e.g., 'date:deadline:start')
|
|
102
|
+
* from the 'update-page' tool input into the format required by the Notion API.
|
|
103
|
+
* @param properties - A flat key-value map with special-cased keys.
|
|
104
|
+
* @returns A Notion `UpdatePageParameters['properties']` object.
|
|
105
|
+
*/
|
|
106
|
+
export function parsePropertiesForUpdate(_properties) {
|
|
107
|
+
// This function would contain the complex logic to handle formats like:
|
|
108
|
+
// "date:deadline:start", "place:office:name", "__YES__" for checkboxes etc.
|
|
109
|
+
// It is a placeholder for now.
|
|
110
|
+
logger.warn('parsePropertiesForUpdate is a skeleton and not fully implemented.');
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=property-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property-parser.js","sourceRoot":"","sources":["../../src/lib/property-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type BlockObjectResponse, type DatabaseObjectResponse, type DataSourceObjectResponse, type PageObjectResponse } from '@notionhq/client/build/src/api-endpoints.js';
|
|
2
|
+
/**
|
|
3
|
+
* Formats a Notion Page object and its content into a single Markdown string [5].
|
|
4
|
+
* @param page - The fetched Page object from the Notion API.
|
|
5
|
+
* @param blocks - The content blocks of the page.
|
|
6
|
+
* @returns A promise that resolves to a comprehensive Markdown string representing the page.
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatPageToMarkdown(page: PageObjectResponse, blocks: BlockObjectResponse[]): Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Formats a Notion Database object and its data sources into a Markdown string that describes its schemas [10].
|
|
11
|
+
* @param database - The fetched Database object from the Notion API.
|
|
12
|
+
* @param data_sources - An array of fetched Data Source objects belonging to the database.
|
|
13
|
+
* @returns A promise that resolves to a Markdown string representing the database and its data source schemas.
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatDatabaseToMarkdown(database: DatabaseObjectResponse, data_sources: DataSourceObjectResponse[]): Promise<string>;
|
|
16
|
+
//# sourceMappingURL=response-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-formatter.d.ts","sourceRoot":"","sources":["../../src/lib/response-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACxB,MAAM,6CAA6C,CAAA;AAoGpD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBnH;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,sBAAsB,EAChC,YAAY,EAAE,wBAAwB,EAAE,GACvC,OAAO,CAAC,MAAM,CAAC,CA8CjB"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { notionToMarkdown } from './markdown-converter.js';
|
|
2
|
+
/**
|
|
3
|
+
* Formats a single Notion page property into a readable string based on its type [2].
|
|
4
|
+
* @param name - The name of the property.
|
|
5
|
+
* @param prop - The property value object from the Notion API.
|
|
6
|
+
* @returns A formatted string representing the property's value.
|
|
7
|
+
*/
|
|
8
|
+
function formatPageProperty(name, prop) {
|
|
9
|
+
let value = 'Unsupported type';
|
|
10
|
+
switch (prop.type) {
|
|
11
|
+
case 'title':
|
|
12
|
+
value = prop.title.map((t) => t.plain_text).join('');
|
|
13
|
+
break;
|
|
14
|
+
case 'rich_text':
|
|
15
|
+
value = prop.rich_text.map((t) => t.plain_text).join('');
|
|
16
|
+
break;
|
|
17
|
+
case 'number':
|
|
18
|
+
value = prop.number;
|
|
19
|
+
break;
|
|
20
|
+
case 'select':
|
|
21
|
+
value = prop.select?.name;
|
|
22
|
+
break;
|
|
23
|
+
case 'multi_select':
|
|
24
|
+
value = prop.multi_select.map((s) => s.name).join(', ');
|
|
25
|
+
break;
|
|
26
|
+
case 'status':
|
|
27
|
+
value = prop.status?.name;
|
|
28
|
+
break;
|
|
29
|
+
case 'date':
|
|
30
|
+
if (prop.date) {
|
|
31
|
+
value = prop.date.end ? `${prop.date.start} -> ${prop.date.end}` : prop.date.start;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
value = undefined;
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
case 'people':
|
|
38
|
+
value = prop.people.map((p) => ('name' in p ? p.name : p.id)).join(', ');
|
|
39
|
+
break;
|
|
40
|
+
case 'files':
|
|
41
|
+
value = prop.files.map((f) => f.name).join(', ');
|
|
42
|
+
break;
|
|
43
|
+
case 'checkbox':
|
|
44
|
+
value = prop.checkbox ? 'Yes' : 'No';
|
|
45
|
+
break;
|
|
46
|
+
case 'url':
|
|
47
|
+
value = prop.url;
|
|
48
|
+
break;
|
|
49
|
+
case 'email':
|
|
50
|
+
value = prop.email;
|
|
51
|
+
break;
|
|
52
|
+
case 'phone_number':
|
|
53
|
+
value = prop.phone_number;
|
|
54
|
+
break;
|
|
55
|
+
case 'formula': {
|
|
56
|
+
const { formula } = prop;
|
|
57
|
+
if (formula.type === 'string')
|
|
58
|
+
value = formula.string;
|
|
59
|
+
if (formula.type === 'number')
|
|
60
|
+
value = formula.number;
|
|
61
|
+
if (formula.type === 'boolean')
|
|
62
|
+
value = formula.boolean ? 'Yes' : 'No';
|
|
63
|
+
if (formula.type === 'date')
|
|
64
|
+
value = formula.date?.start;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
case 'relation':
|
|
68
|
+
value = `${prop.relation.length} relation(s)`;
|
|
69
|
+
break;
|
|
70
|
+
case 'created_time':
|
|
71
|
+
value = new Date(prop.created_time).toLocaleString();
|
|
72
|
+
break;
|
|
73
|
+
case 'last_edited_time':
|
|
74
|
+
value = new Date(prop.last_edited_time).toLocaleString();
|
|
75
|
+
break;
|
|
76
|
+
case 'created_by':
|
|
77
|
+
value = 'id' in prop.created_by ? prop.created_by.id : '';
|
|
78
|
+
break;
|
|
79
|
+
case 'last_edited_by':
|
|
80
|
+
value = 'id' in prop.last_edited_by ? prop.last_edited_by.id : '';
|
|
81
|
+
break;
|
|
82
|
+
case 'rollup': {
|
|
83
|
+
const rollup = prop.rollup;
|
|
84
|
+
if (rollup.type === 'number')
|
|
85
|
+
value = rollup.number;
|
|
86
|
+
else if (rollup.type === 'date')
|
|
87
|
+
value = rollup.date?.start;
|
|
88
|
+
else if (rollup.type === 'array')
|
|
89
|
+
value = `${rollup.array.length} items`;
|
|
90
|
+
else
|
|
91
|
+
value = `Unsupported rollup type`;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case 'unique_id':
|
|
95
|
+
value = prop.unique_id.prefix ? `${prop.unique_id.prefix}-${prop.unique_id.number}` : `${prop.unique_id.number}`;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
99
|
+
return `- **${name}**: ${value ?? 'null'}`;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Formats a Notion Page object and its content into a single Markdown string [5].
|
|
103
|
+
* @param page - The fetched Page object from the Notion API.
|
|
104
|
+
* @param blocks - The content blocks of the page.
|
|
105
|
+
* @returns A promise that resolves to a comprehensive Markdown string representing the page.
|
|
106
|
+
*/
|
|
107
|
+
export async function formatPageToMarkdown(page, blocks) {
|
|
108
|
+
const contentMarkdown = await notionToMarkdown(blocks);
|
|
109
|
+
const propertiesMarkdown = Object.entries(page.properties)
|
|
110
|
+
.map(([name, prop]) => formatPageProperty(name, prop))
|
|
111
|
+
.join('\n');
|
|
112
|
+
const icon = page.icon?.type === 'emoji' ? `${page.icon.emoji} ` : '';
|
|
113
|
+
return `
|
|
114
|
+
# ${icon}Page: ${page.url}
|
|
115
|
+
|
|
116
|
+
## Properties
|
|
117
|
+
${propertiesMarkdown}
|
|
118
|
+
|
|
119
|
+
## Content
|
|
120
|
+
---
|
|
121
|
+
${contentMarkdown}
|
|
122
|
+
`.trim();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Formats a Notion Database object and its data sources into a Markdown string that describes its schemas [10].
|
|
126
|
+
* @param database - The fetched Database object from the Notion API.
|
|
127
|
+
* @param data_sources - An array of fetched Data Source objects belonging to the database.
|
|
128
|
+
* @returns A promise that resolves to a Markdown string representing the database and its data source schemas.
|
|
129
|
+
*/
|
|
130
|
+
export async function formatDatabaseToMarkdown(database, data_sources) {
|
|
131
|
+
const title = database.title.map((t) => t.plain_text).join('');
|
|
132
|
+
const icon = database.icon?.type === 'emoji' ? `${database.icon.emoji} ` : '';
|
|
133
|
+
const dataSourcesMarkdown = data_sources
|
|
134
|
+
.map((ds) => {
|
|
135
|
+
const dsTitle = ds.title.map((t) => t.plain_text).join('');
|
|
136
|
+
const propertiesMarkdown = Object.entries(ds.properties)
|
|
137
|
+
.map(([name, prop]) => {
|
|
138
|
+
let details = `(type: \`${prop.type}\`, id: \`${prop.id}\`)`;
|
|
139
|
+
let options = [];
|
|
140
|
+
// For select, multi_select, and status, list the available options [13].
|
|
141
|
+
if (prop.type === 'select') {
|
|
142
|
+
options = prop.select.options;
|
|
143
|
+
}
|
|
144
|
+
else if (prop.type === 'multi_select') {
|
|
145
|
+
options = prop.multi_select.options;
|
|
146
|
+
}
|
|
147
|
+
else if (prop.type === 'status') {
|
|
148
|
+
options = prop.status.options;
|
|
149
|
+
}
|
|
150
|
+
if (options.length > 0) {
|
|
151
|
+
const optionsString = options.map((o) => o.name).join(', ');
|
|
152
|
+
details += `\n - Options: ${optionsString}`;
|
|
153
|
+
}
|
|
154
|
+
return ` - **${name}** ${details}`;
|
|
155
|
+
})
|
|
156
|
+
.join('\n');
|
|
157
|
+
return `
|
|
158
|
+
### Data Source: ${dsTitle}
|
|
159
|
+
> To query this data source, use its URL: collection://${ds.id}
|
|
160
|
+
|
|
161
|
+
**Schema / Properties:**
|
|
162
|
+
${propertiesMarkdown}
|
|
163
|
+
`.trim();
|
|
164
|
+
})
|
|
165
|
+
.join('\n\n');
|
|
166
|
+
return `
|
|
167
|
+
# ${icon}Database: ${title}
|
|
168
|
+
> To query pages from this database, use one of the data source URLs below.
|
|
169
|
+
|
|
170
|
+
${dataSourcesMarkdown}
|
|
171
|
+
`.trim();
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=response-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-formatter.js","sourceRoot":"","sources":["../../src/lib/response-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-pages.d.ts","sourceRoot":"","sources":["../../src/tools/create-pages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAqExE,eAAO,MAAM,uBAAuB,GAAI,QAAQ,SAAS,SAwIrD,CAAA"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { registerTool } from '@mcp-monorepo/shared';
|
|
2
|
+
import { markdownToBlocks } from '@tryfabric/martian';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { getNotionClient } from '../lib/client.js';
|
|
5
|
+
import { normalizeId } from '../lib/id-utils.js';
|
|
6
|
+
import { parsePropertiesForCreate } from '../lib/property-parser.js';
|
|
7
|
+
// The description is an exact copy of the provided tool definition [1].
|
|
8
|
+
const description = `Creates one or more Notion pages with specified properties and content.
|
|
9
|
+
Use "create-pages" when you need to create one or more new pages that don't exist yet.
|
|
10
|
+
Always include a title property under \`properties\` in each entry of the \`pages\` array.
|
|
11
|
+
Otherwise, the page title will appear blank even if the page content is populated. Don't
|
|
12
|
+
duplicate the page title at the top of the page's \`content\`.
|
|
13
|
+
When creating pages under a Notion database, the property names must match the database's
|
|
14
|
+
schema. Use the "fetch" tool with a Notion database URL to get the database schema. Or, look
|
|
15
|
+
for existing pages under the database using the "search" tool then use the "fetch" tool to see
|
|
16
|
+
the names of the property keys. One exception is the "title" property, which all pages have,
|
|
17
|
+
but can be named differently in the schema of a database. For convenience, you can use the
|
|
18
|
+
generic property name "title" in the "properties" object, and it will automatically be
|
|
19
|
+
re-mapped to the actual name of the title property in the database schema when creating the
|
|
20
|
+
page.
|
|
21
|
+
All pages created with a single call to this tool will have the same parent.
|
|
22
|
+
The parent can be a Notion page or database. If the parent is omitted, the pages will be
|
|
23
|
+
created as standalone, workspace-level private pages and the person that created them
|
|
24
|
+
can organize them as they see fit later.
|
|
25
|
+
IMPORTANT: When specifying a parent database, use the appropriate ID format:
|
|
26
|
+
- Use "data_source_id" when you have a collection:// URL from the fetch tool (this is the most common case)
|
|
27
|
+
- Use "database_id" when you have a page URL for a database view (less common)
|
|
28
|
+
- Use "page_id" when the parent is a regular page
|
|
29
|
+
Examples of creating pages:
|
|
30
|
+
1. Create a standalone page with a title and content:
|
|
31
|
+
{
|
|
32
|
+
"pages": [
|
|
33
|
+
{
|
|
34
|
+
"properties": {"title":"Page title"},
|
|
35
|
+
"content": "# Section 1\\nSection 1 content\\n# Section 2\\nSection 2 content"
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
2. Create a page under a database's data source (collection), e.g. using an ID from a collection:// URL provided by the fetch tool:
|
|
40
|
+
{
|
|
41
|
+
"parent": {"data_source_id": "f336d0bc-b841-465b-8045-024475c079dd"},
|
|
42
|
+
"pages": [
|
|
43
|
+
{
|
|
44
|
+
"properties": {
|
|
45
|
+
"Task Name": "Task 123",
|
|
46
|
+
"Status": "In Progress",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
}
|
|
51
|
+
3. Create a page with an existing page as a parent:
|
|
52
|
+
{
|
|
53
|
+
"parent": {"page_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"},
|
|
54
|
+
"pages": [
|
|
55
|
+
{
|
|
56
|
+
"properties": {"title": "Page title"},
|
|
57
|
+
"content": "# Section 1\\nSection 1 content\\n# Section 2\\nSection 2 content"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}`;
|
|
61
|
+
export const registerCreatePagesTool = (server) => registerTool(server, {
|
|
62
|
+
name: 'notion-create-pages',
|
|
63
|
+
title: 'Create pages in Markdown',
|
|
64
|
+
description,
|
|
65
|
+
inputSchema: {
|
|
66
|
+
pages: z
|
|
67
|
+
.array(z
|
|
68
|
+
.object({
|
|
69
|
+
content: z.string().describe('The content of the new page, using Notion Markdown.').optional(),
|
|
70
|
+
properties: z
|
|
71
|
+
.record(z.union([z.string(), z.number(), z.null()]))
|
|
72
|
+
.describe('The properties of the new page, which is a JSON map of property names to SQLite values.\nFor pages in a database, use the SQLite schema definition shown in <database>.\nFor pages outside of a database, the only allowed property is "title", which is the title of the page and is automatically shown at the top of the page as a large heading.'),
|
|
73
|
+
})
|
|
74
|
+
.strict())
|
|
75
|
+
.max(100)
|
|
76
|
+
.describe('The pages to create.'),
|
|
77
|
+
parent: z
|
|
78
|
+
.union([
|
|
79
|
+
z
|
|
80
|
+
.object({
|
|
81
|
+
type: z.literal('page_id').optional(),
|
|
82
|
+
page_id: z
|
|
83
|
+
.string()
|
|
84
|
+
.describe('The ID of the parent page (with or without dashes), for example, 195de9221179449fab8075a27c979105'),
|
|
85
|
+
})
|
|
86
|
+
.strict(),
|
|
87
|
+
z
|
|
88
|
+
.object({
|
|
89
|
+
type: z.literal('database_id').optional(),
|
|
90
|
+
database_id: z
|
|
91
|
+
.string()
|
|
92
|
+
.describe('The ID of the parent database (with or without dashes), for example, 195de9221179449fab8075a27c979105'),
|
|
93
|
+
})
|
|
94
|
+
.strict(),
|
|
95
|
+
z
|
|
96
|
+
.object({
|
|
97
|
+
type: z.literal('data_source_id').optional(),
|
|
98
|
+
data_source_id: z
|
|
99
|
+
.string()
|
|
100
|
+
.describe('The ID of the parent data source (collection), with or without dashes. For example, f336d0bc-b841-465b-8045-024475c079dd'),
|
|
101
|
+
})
|
|
102
|
+
.strict(),
|
|
103
|
+
])
|
|
104
|
+
.optional()
|
|
105
|
+
.describe('The parent under which the new pages will be created. This can be a page (page_id), a database page (database_id), or a data source/collection under a database (data_source_id). If omitted, the new pages will be created as private pages at the workspace level. Use data_source_id when you have a collection:// URL from the fetch tool.'),
|
|
106
|
+
},
|
|
107
|
+
outputSchema: {
|
|
108
|
+
created_pages: z
|
|
109
|
+
.array(z.object({
|
|
110
|
+
page_id: z.string(),
|
|
111
|
+
url: z.string(),
|
|
112
|
+
title: z.string().optional(),
|
|
113
|
+
}))
|
|
114
|
+
.describe('A list of the pages that were successfully created.'),
|
|
115
|
+
},
|
|
116
|
+
async fetcher(args) {
|
|
117
|
+
const notion = getNotionClient();
|
|
118
|
+
const { pages, parent } = args;
|
|
119
|
+
let apiParent;
|
|
120
|
+
let dataSourceSchema;
|
|
121
|
+
if (!parent) {
|
|
122
|
+
// To create a page at the workspace level, the parent must be `{ workspace: true }` [2, 1].
|
|
123
|
+
apiParent = { workspace: true };
|
|
124
|
+
}
|
|
125
|
+
else if ('data_source_id' in parent && parent.data_source_id) {
|
|
126
|
+
const id = normalizeId(parent.data_source_id);
|
|
127
|
+
if (!id)
|
|
128
|
+
throw new Error(`Invalid data_source_id: ${parent.data_source_id}`);
|
|
129
|
+
const dataSource = (await notion.dataSources.retrieve({ data_source_id: id }));
|
|
130
|
+
apiParent = { database_id: dataSource.parent.database_id };
|
|
131
|
+
dataSourceSchema = dataSource.properties;
|
|
132
|
+
}
|
|
133
|
+
else if ('database_id' in parent && parent.database_id) {
|
|
134
|
+
const id = normalizeId(parent.database_id);
|
|
135
|
+
if (!id)
|
|
136
|
+
throw new Error(`Invalid database_id: ${parent.database_id}`);
|
|
137
|
+
const database = (await notion.databases.retrieve({ database_id: id }));
|
|
138
|
+
const firstDataSourceId = database.data_sources[0]?.id;
|
|
139
|
+
if (!firstDataSourceId)
|
|
140
|
+
throw new Error(`Database ${parent.database_id} has no data sources.`);
|
|
141
|
+
const dataSource = (await notion.dataSources.retrieve({
|
|
142
|
+
data_source_id: firstDataSourceId,
|
|
143
|
+
}));
|
|
144
|
+
apiParent = { database_id: dataSource.parent.database_id };
|
|
145
|
+
dataSourceSchema = dataSource.properties;
|
|
146
|
+
}
|
|
147
|
+
else if ('page_id' in parent && parent.page_id) {
|
|
148
|
+
const id = normalizeId(parent.page_id);
|
|
149
|
+
if (!id)
|
|
150
|
+
throw new Error(`Invalid page_id: ${parent.page_id}`);
|
|
151
|
+
apiParent = { page_id: id };
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
throw new Error('Invalid parent object provided.');
|
|
155
|
+
}
|
|
156
|
+
const createPagePromises = pages.map(async (page) => {
|
|
157
|
+
const children = page.content ? markdownToBlocks(page.content) : undefined;
|
|
158
|
+
const notionProperties = parsePropertiesForCreate(page.properties, dataSourceSchema);
|
|
159
|
+
const newPage = await notion.pages.create({
|
|
160
|
+
parent: apiParent,
|
|
161
|
+
properties: notionProperties,
|
|
162
|
+
children,
|
|
163
|
+
});
|
|
164
|
+
return newPage;
|
|
165
|
+
});
|
|
166
|
+
return Promise.all(createPagePromises);
|
|
167
|
+
},
|
|
168
|
+
async formatter(createdPages) {
|
|
169
|
+
const results = createdPages.map((page) => {
|
|
170
|
+
const titleProperty = Object.values(page.properties).find((p) => p.type === 'title');
|
|
171
|
+
const title = titleProperty && 'title' in titleProperty && titleProperty.title.length > 0
|
|
172
|
+
? titleProperty.title[0].plain_text
|
|
173
|
+
: 'Untitled';
|
|
174
|
+
return {
|
|
175
|
+
page_id: page.id,
|
|
176
|
+
url: page.url,
|
|
177
|
+
title,
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
return { created_pages: results };
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
//# sourceMappingURL=create-pages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-pages.js","sourceRoot":"","sources":["../../src/tools/create-pages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/tools/fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAuBxE,eAAO,MAAM,iBAAiB,GAAI,QAAQ,SAAS,SA4F/C,CAAA"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { registerTool } from '@mcp-monorepo/shared';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getNotionClient } from '../lib/client.js';
|
|
4
|
+
import { normalizeId } from '../lib/id-utils.js';
|
|
5
|
+
import { formatDatabaseToMarkdown, formatPageToMarkdown } from '../lib/response-formatter.js';
|
|
6
|
+
export const registerFetchTool = (server) => registerTool(server, {
|
|
7
|
+
name: 'fetch',
|
|
8
|
+
title: 'Fetch Notion entities',
|
|
9
|
+
description: `Retrieves details about a Notion entity by its URL or ID.
|
|
10
|
+
You can fetch the following types of entities:
|
|
11
|
+
- Page, i.e. from a <page> block or a <mention-page> mention
|
|
12
|
+
- Database, i.e. from a <database> block or a <mention-database> mention
|
|
13
|
+
Use the "fetch" tool when you need to see the details of a Notion entity you already know
|
|
14
|
+
exists and have its URL or ID.
|
|
15
|
+
Provide the Notion entity's URL or ID in the \`id\` parameter. You must make multiple calls
|
|
16
|
+
to the "fetch" tool if you want to fetch multiple entities.
|
|
17
|
+
Content for pages that are returned use the enhanced Markdown format, which is a superset of
|
|
18
|
+
the standard Markdown syntax. See the full spec in the description of the "create-pages"
|
|
19
|
+
tool.
|
|
20
|
+
Databases can have multiple data sources, which are collections of pages with the same schema.
|
|
21
|
+
When fetching a database, the tool will return information about all its data sources.
|
|
22
|
+
Examples of fetching entities:
|
|
23
|
+
1. Fetch a page by URL:
|
|
24
|
+
{
|
|
25
|
+
"id": "https://www.notion.so/workspace/Product-Requirements-1234567890abcdef"
|
|
26
|
+
}
|
|
27
|
+
2. Fetch a page by ID (UUIDv4 with dashes):
|
|
28
|
+
{
|
|
29
|
+
"id": "12345678-90ab-cdef-1234-567890abcdef"
|
|
30
|
+
}
|
|
31
|
+
3. Fetch a page by ID (UUIDv4 without dashes):
|
|
32
|
+
{
|
|
33
|
+
"id": "1234567890abcdef1234567890abcdef"
|
|
34
|
+
}
|
|
35
|
+
4. Fetch a database:
|
|
36
|
+
{
|
|
37
|
+
"id": "https://www.notion.so/workspace/Projects-Database-abcdef1234567890"
|
|
38
|
+
}
|
|
39
|
+
Common use cases:
|
|
40
|
+
- "What are the product requirements still need to be implemented from this ticket
|
|
41
|
+
https://notion.so/page-url?"
|
|
42
|
+
- "Show me the details of the project database at this URL"
|
|
43
|
+
- "Get the content of page 12345678-90ab-cdef-1234-567890abcdef"`,
|
|
44
|
+
isReadOnly: true,
|
|
45
|
+
inputSchema: {
|
|
46
|
+
id: z.string().describe('The ID or URL of the Notion page or database to fetch.'),
|
|
47
|
+
},
|
|
48
|
+
outputSchema: {
|
|
49
|
+
markdown: z.string(),
|
|
50
|
+
},
|
|
51
|
+
async fetcher(args) {
|
|
52
|
+
const notion = getNotionClient();
|
|
53
|
+
const entityId = normalizeId(args.id);
|
|
54
|
+
if (!entityId) {
|
|
55
|
+
throw new Error(`Invalid Notion ID or URL: ${args.id}`);
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const page = await notion.pages.retrieve({ page_id: entityId });
|
|
59
|
+
const blocks = await notion.blocks.children.list({ block_id: entityId });
|
|
60
|
+
return { type: 'page', page, blocks };
|
|
61
|
+
}
|
|
62
|
+
catch (pageError) {
|
|
63
|
+
try {
|
|
64
|
+
const databaseResponse = (await notion.databases.retrieve({
|
|
65
|
+
database_id: entityId,
|
|
66
|
+
}));
|
|
67
|
+
// A database contains references to its data sources. We need to fetch each one to get the schema.
|
|
68
|
+
const dataSourcePromises = (databaseResponse.data_sources || []).map((ds) => notion.dataSources.retrieve({ data_source_id: ds.id }));
|
|
69
|
+
const data_sources = await Promise.all(dataSourcePromises);
|
|
70
|
+
return { type: 'database', database: databaseResponse, data_sources };
|
|
71
|
+
}
|
|
72
|
+
catch (dbError) {
|
|
73
|
+
throw new Error(`Could not fetch '${entityId}' as a page or database.`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
async formatter(data) {
|
|
78
|
+
if (data.type === 'page') {
|
|
79
|
+
return {
|
|
80
|
+
markdown: await formatPageToMarkdown(data.page, data.blocks.results),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// Pass both the database and its full data_sources to the formatter.
|
|
84
|
+
return {
|
|
85
|
+
markdown: await formatDatabaseToMarkdown(data.database, data.data_sources),
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/tools/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAcnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAM7F,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAiB,EAAE,EAAE,CACrD,YAAY,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,uBAAuB;IAC9B,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iEAkCgD;IAC7D,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE;QACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;KAClF;IACD,YAAY,EAAE;QACZ,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;KACrB;IACD,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;QAChC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QACzD,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAA;YAC/D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAA;YACxE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;QACvC,CAAC;QAAC,OAAO,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,MAAM,gBAAgB,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC;oBACxD,WAAW,EAAE,QAAQ;iBACtB,CAAC,CAA2B,CAAA;gBAE7B,mGAAmG;gBACnG,MAAM,kBAAkB,GAAG,CAAC,gBAAgB,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAC1E,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CACvD,CAAA;gBACD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;gBAE1D,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,CAAA;YACvE,CAAC;YAAC,OAAO,OAAO,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,0BAA0B,CAAC,CAAA;YACzE,CAAC;QACH,CAAC;IACH,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,IAAI;QAClB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,OAAO;gBACL,QAAQ,EAAE,MAAM,oBAAoB,CAClC,IAAI,CAAC,IAA0B,EAC/B,IAAI,CAAC,MAAM,CAAC,OAAgC,CAC7C;aACF,CAAA;QACH,CAAC;QACD,qEAAqE;QACrE,OAAO;YACL,QAAQ,EAAE,MAAM,wBAAwB,CACtC,IAAI,CAAC,QAAkC,EACvC,IAAI,CAAC,YAA0C,CAChD;SACF,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-datasource.d.ts","sourceRoot":"","sources":["../../src/tools/query-datasource.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,eAAO,MAAM,2BAA2B,GAAI,QAAQ,SAAS,SA6EzD,CAAA"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { registerTool } from '@mcp-monorepo/shared';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { getNotionClient } from '../lib/client.js';
|
|
4
|
+
import { simplifyNotionPages } from '../lib/parser.js';
|
|
5
|
+
export const registerQueryDatasourceTool = (server) => registerTool(server, {
|
|
6
|
+
name: 'query-datasource',
|
|
5
7
|
title: 'Query a Notion Data Source',
|
|
6
|
-
description: `Gets a list of pages from a data source, identified by its URL (e.g., "collection://<uuid>"). Supports filtering and sorting. The response is paginated; use 'start_cursor' for subsequent requests if 'next_cursor' is returned. Filters operate on properties and can be simple or compound (using "and"/"or"). Sorts operate on properties or timestamps. For performance, use 'filter_properties' to retrieve only necessary page properties. Refer to Notion API documentation for the exact filter and sort object structures.`,
|
|
8
|
+
description: `Gets a list of pages from a data source, identified by its URL (e.g., "collection://<uuid>"). Supports filtering and sorting. The response is paginated; use 'start_cursor' for subsequent requests if 'next_cursor' is returned. Filters operate on properties and can be simple or compound (using "and"/"or"). Sorts operate on properties or timestamps. For performance, you can use 'filter_properties' to retrieve only necessary page properties. Refer to Notion API documentation for the exact filter and sort object structures.`,
|
|
7
9
|
inputSchema: {
|
|
8
10
|
data_source_url: z
|
|
9
11
|
.string()
|
|
@@ -13,7 +15,11 @@ export const registerNotionQueryTool = (server) => registerTool(server, {
|
|
|
13
15
|
.optional()
|
|
14
16
|
.describe('A JSON filter object to apply. Example: {"property": "Done", "checkbox": {"equals": true}} or {"and": [...]}.'),
|
|
15
17
|
sorts: z
|
|
16
|
-
.array(z.
|
|
18
|
+
.array(z.object({
|
|
19
|
+
property: z.string().optional(),
|
|
20
|
+
timestamp: z.string().optional(),
|
|
21
|
+
direction: z.enum(['ascending', 'descending']),
|
|
22
|
+
}))
|
|
17
23
|
.optional()
|
|
18
24
|
.describe('An array of JSON sort objects. Example: [{"property": "Name", "direction": "ascending"}].'),
|
|
19
25
|
start_cursor: z.string().optional().describe('If provided, starts the query at the specified cursor.'),
|
|
@@ -24,7 +30,9 @@ export const registerNotionQueryTool = (server) => registerTool(server, {
|
|
|
24
30
|
.describe('An array of property IDs or names to return. If not provided, all properties are returned.'),
|
|
25
31
|
},
|
|
26
32
|
outputSchema: {
|
|
27
|
-
results: z
|
|
33
|
+
results: z
|
|
34
|
+
.array(z.record(z.string(), z.any()))
|
|
35
|
+
.describe('An array of simplified page objects. Each object is a flat key-value map of its properties.'),
|
|
28
36
|
next_cursor: z
|
|
29
37
|
.string()
|
|
30
38
|
.nullable()
|
|
@@ -37,47 +45,32 @@ export const registerNotionQueryTool = (server) => registerTool(server, {
|
|
|
37
45
|
if (!data_source_url?.startsWith('collection://')) {
|
|
38
46
|
throw new Error('Invalid data_source_url format. Must start with "collection://".');
|
|
39
47
|
}
|
|
48
|
+
const notion = getNotionClient();
|
|
40
49
|
const dataSourceId = data_source_url.substring('collection://'.length);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
try {
|
|
51
|
+
return await notion.dataSources.query({
|
|
52
|
+
data_source_id: dataSourceId,
|
|
53
|
+
filter: filter,
|
|
54
|
+
sorts: sorts,
|
|
55
|
+
start_cursor,
|
|
56
|
+
page_size,
|
|
57
|
+
filter_properties,
|
|
49
58
|
});
|
|
50
59
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (start_cursor)
|
|
57
|
-
body.start_cursor = start_cursor;
|
|
58
|
-
if (page_size)
|
|
59
|
-
body.page_size = page_size;
|
|
60
|
-
const response = await fetch(apiUrl.toString(), {
|
|
61
|
-
method: 'POST',
|
|
62
|
-
headers: {
|
|
63
|
-
Authorization: `Bearer ${NOTION_API_KEY}`,
|
|
64
|
-
'Notion-Version': '2025-09-03',
|
|
65
|
-
'Content-Type': 'application/json',
|
|
66
|
-
},
|
|
67
|
-
body: Object.keys(body).length > 0 ? JSON.stringify(body) : undefined,
|
|
68
|
-
});
|
|
69
|
-
if (!response.ok) {
|
|
70
|
-
const errorText = await response.text();
|
|
71
|
-
throw new Error(`Notion API request failed with status ${response.status}: ${errorText}`);
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof Error) {
|
|
62
|
+
throw new Error(`Notion API request failed: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
throw new Error('An unknown Notion API error occurred.');
|
|
72
65
|
}
|
|
73
|
-
return (await response.json());
|
|
74
66
|
},
|
|
67
|
+
// The formatter is now extremely clean, just calling the new parser.
|
|
75
68
|
formatter(data) {
|
|
76
69
|
return {
|
|
77
|
-
results: data.results,
|
|
70
|
+
results: simplifyNotionPages(data.results),
|
|
78
71
|
next_cursor: data.next_cursor,
|
|
79
72
|
has_more: data.has_more,
|
|
80
73
|
};
|
|
81
74
|
},
|
|
82
75
|
});
|
|
83
|
-
//# sourceMappingURL=
|
|
76
|
+
//# sourceMappingURL=query-datasource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-datasource.js","sourceRoot":"","sources":["../../src/tools/query-datasource.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-monorepo/notion-query",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCP server for querying Notion data sources.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
-
"bin":
|
|
9
|
-
"@mcp-monorepo/notion-query": "./dist/index.js"
|
|
10
|
-
},
|
|
8
|
+
"bin": "./dist/index.js",
|
|
11
9
|
"files": [
|
|
12
10
|
"dist"
|
|
13
11
|
],
|
|
@@ -25,14 +23,17 @@
|
|
|
25
23
|
"clean": "rimraf dist tsconfig.tsbuildinfo"
|
|
26
24
|
},
|
|
27
25
|
"dependencies": {
|
|
26
|
+
"@mcp-monorepo/shared": "workspace:*",
|
|
28
27
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
29
|
-
"
|
|
30
|
-
"@
|
|
28
|
+
"@notionhq/client": "^5.6.0",
|
|
29
|
+
"@tryfabric/martian": "^1.2.4",
|
|
30
|
+
"notion-to-md": "^3.1.9",
|
|
31
|
+
"zod": "^3.25.76"
|
|
31
32
|
},
|
|
32
33
|
"devDependencies": {
|
|
33
34
|
"@types/node": "^22.14.1",
|
|
35
|
+
"rimraf": "^6.0.1",
|
|
34
36
|
"typescript": "^5.8.3",
|
|
35
|
-
"vitest": "^3.2.4"
|
|
36
|
-
"rimraf": "^6.0.1"
|
|
37
|
+
"vitest": "^3.2.4"
|
|
37
38
|
}
|
|
38
39
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"notion-query.d.ts","sourceRoot":"","sources":["../../src/tools/notion-query.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,eAAO,MAAM,uBAAuB,GAAI,QAAQ,SAAS,SAuFrD,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"notion-query.js","sourceRoot":"","sources":["../../src/tools/notion-query.ts"],"names":[],"mappings":"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"}
|