@vineethnkrishnan/notion-mcp 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/common/types.d.ts +11 -0
- package/build/common/types.js +3 -0
- package/build/common/types.js.map +1 -0
- package/build/common/utils.d.ts +30 -0
- package/build/common/utils.js +264 -0
- package/build/common/utils.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +101 -0
- package/build/index.js.map +1 -0
- package/build/services/notion.service.d.ts +17 -0
- package/build/services/notion.service.js +103 -0
- package/build/services/notion.service.js.map +1 -0
- package/build/tools/database.tools.d.ts +25 -0
- package/build/tools/database.tools.js +44 -0
- package/build/tools/database.tools.js.map +1 -0
- package/build/tools/page.tools.d.ts +28 -0
- package/build/tools/page.tools.js +44 -0
- package/build/tools/page.tools.js.map +1 -0
- package/build/tools/search.tools.d.ts +20 -0
- package/build/tools/search.tools.js +31 -0
- package/build/tools/search.tools.js.map +1 -0
- package/build/tools/user.tools.d.ts +15 -0
- package/build/tools/user.tools.js +25 -0
- package/build/tools/user.tools.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { McpToolResponse } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Converts Notion's rich text array to a single plain text string.
|
|
4
|
+
* Handles text, mention, and equation types.
|
|
5
|
+
*/
|
|
6
|
+
export declare function flattenRichText(richText: unknown[]): string;
|
|
7
|
+
/**
|
|
8
|
+
* Converts an array of Notion block objects to readable text lines.
|
|
9
|
+
*/
|
|
10
|
+
export declare function flattenBlocks(blocks: unknown[]): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Recursively removes specified keys from an object.
|
|
13
|
+
*/
|
|
14
|
+
export declare function stripNotionMetadata(obj: unknown, keys?: string[]): unknown;
|
|
15
|
+
/**
|
|
16
|
+
* Limits block count, appending a truncation marker if exceeded.
|
|
17
|
+
*/
|
|
18
|
+
export declare function truncateBlocks(blocks: unknown[], max?: number): unknown[];
|
|
19
|
+
/**
|
|
20
|
+
* Composes all Notion-specific transformations for LLM optimization.
|
|
21
|
+
*/
|
|
22
|
+
export declare function transformNotionResponse(data: unknown): unknown;
|
|
23
|
+
/**
|
|
24
|
+
* Transforms Notion data and wraps it in the MCP tool response format.
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatMcpResponse(data: unknown): McpToolResponse;
|
|
27
|
+
/**
|
|
28
|
+
* Wraps an error in the MCP tool error response format.
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatMcpError(error: unknown): McpToolResponse;
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.flattenRichText = flattenRichText;
|
|
4
|
+
exports.flattenBlocks = flattenBlocks;
|
|
5
|
+
exports.stripNotionMetadata = stripNotionMetadata;
|
|
6
|
+
exports.truncateBlocks = truncateBlocks;
|
|
7
|
+
exports.transformNotionResponse = transformNotionResponse;
|
|
8
|
+
exports.formatMcpResponse = formatMcpResponse;
|
|
9
|
+
exports.formatMcpError = formatMcpError;
|
|
10
|
+
const NOTION_STRIP_KEYS = ["object", "request_id", "developer_survey", "public_url"];
|
|
11
|
+
// ===========================================================================
|
|
12
|
+
// Rich text flattening
|
|
13
|
+
// ===========================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Converts Notion's rich text array to a single plain text string.
|
|
16
|
+
* Handles text, mention, and equation types.
|
|
17
|
+
*/
|
|
18
|
+
function flattenRichText(richText) {
|
|
19
|
+
if (!Array.isArray(richText))
|
|
20
|
+
return "";
|
|
21
|
+
return richText
|
|
22
|
+
.map((segment) => {
|
|
23
|
+
if (!segment || typeof segment !== "object")
|
|
24
|
+
return "";
|
|
25
|
+
const record = segment;
|
|
26
|
+
if (record.plain_text && typeof record.plain_text === "string") {
|
|
27
|
+
return record.plain_text;
|
|
28
|
+
}
|
|
29
|
+
const type = record.type;
|
|
30
|
+
if (type === "text") {
|
|
31
|
+
const text = record.text;
|
|
32
|
+
return text?.content ?? "";
|
|
33
|
+
}
|
|
34
|
+
if (type === "mention") {
|
|
35
|
+
const mention = record.mention;
|
|
36
|
+
if (!mention)
|
|
37
|
+
return "@unknown";
|
|
38
|
+
const mentionType = mention.type;
|
|
39
|
+
if (mentionType === "user") {
|
|
40
|
+
const user = mention.user;
|
|
41
|
+
return `@${user?.name ?? "unknown"}`;
|
|
42
|
+
}
|
|
43
|
+
if (mentionType === "page") {
|
|
44
|
+
return "[page mention]";
|
|
45
|
+
}
|
|
46
|
+
if (mentionType === "database") {
|
|
47
|
+
return "[database mention]";
|
|
48
|
+
}
|
|
49
|
+
if (mentionType === "date") {
|
|
50
|
+
const date = mention.date;
|
|
51
|
+
return date?.start ? String(date.start) : "[date]";
|
|
52
|
+
}
|
|
53
|
+
return `@${mentionType}`;
|
|
54
|
+
}
|
|
55
|
+
if (type === "equation") {
|
|
56
|
+
const equation = record.equation;
|
|
57
|
+
return equation?.expression ?? "";
|
|
58
|
+
}
|
|
59
|
+
return "";
|
|
60
|
+
})
|
|
61
|
+
.join("");
|
|
62
|
+
}
|
|
63
|
+
// ===========================================================================
|
|
64
|
+
// Block rendering
|
|
65
|
+
// ===========================================================================
|
|
66
|
+
/**
|
|
67
|
+
* Extracts text content from a block by looking at its type-specific data.
|
|
68
|
+
*/
|
|
69
|
+
function getBlockText(block) {
|
|
70
|
+
const type = block.type;
|
|
71
|
+
if (!type)
|
|
72
|
+
return "";
|
|
73
|
+
const data = block[type];
|
|
74
|
+
if (!data)
|
|
75
|
+
return "";
|
|
76
|
+
const richText = data.rich_text;
|
|
77
|
+
if (richText)
|
|
78
|
+
return flattenRichText(richText);
|
|
79
|
+
return "";
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Renders a single Notion block to a markdown-like plain text line.
|
|
83
|
+
*/
|
|
84
|
+
function renderBlock(block, depth) {
|
|
85
|
+
const type = block.type;
|
|
86
|
+
if (!type)
|
|
87
|
+
return "";
|
|
88
|
+
const indent = " ".repeat(depth);
|
|
89
|
+
const text = getBlockText(block);
|
|
90
|
+
switch (type) {
|
|
91
|
+
case "paragraph":
|
|
92
|
+
return `${indent}${text}`;
|
|
93
|
+
case "heading_1":
|
|
94
|
+
return `${indent}# ${text}`;
|
|
95
|
+
case "heading_2":
|
|
96
|
+
return `${indent}## ${text}`;
|
|
97
|
+
case "heading_3":
|
|
98
|
+
return `${indent}### ${text}`;
|
|
99
|
+
case "bulleted_list_item":
|
|
100
|
+
return `${indent}- ${text}`;
|
|
101
|
+
case "numbered_list_item":
|
|
102
|
+
return `${indent}1. ${text}`;
|
|
103
|
+
case "to_do": {
|
|
104
|
+
const data = block[type];
|
|
105
|
+
const isChecked = data?.checked === true;
|
|
106
|
+
return `${indent}${isChecked ? "[x]" : "[ ]"} ${text}`;
|
|
107
|
+
}
|
|
108
|
+
case "toggle":
|
|
109
|
+
return `${indent}> ${text}`;
|
|
110
|
+
case "code": {
|
|
111
|
+
const data = block[type];
|
|
112
|
+
const language = data?.language ?? "";
|
|
113
|
+
return `${indent}\`\`\`${language}\n${indent}${text}\n${indent}\`\`\``;
|
|
114
|
+
}
|
|
115
|
+
case "quote":
|
|
116
|
+
return `${indent}> ${text}`;
|
|
117
|
+
case "divider":
|
|
118
|
+
return `${indent}---`;
|
|
119
|
+
case "callout": {
|
|
120
|
+
const data = block[type];
|
|
121
|
+
const icon = data?.icon;
|
|
122
|
+
const emoji = icon?.type === "emoji" ? icon.emoji : "";
|
|
123
|
+
return `${indent}${emoji ? emoji + " " : ""}${text}`;
|
|
124
|
+
}
|
|
125
|
+
case "image": {
|
|
126
|
+
const data = block[type];
|
|
127
|
+
const caption = data?.caption;
|
|
128
|
+
const captionText = caption ? flattenRichText(caption) : "";
|
|
129
|
+
let url = "";
|
|
130
|
+
if (data?.type === "external") {
|
|
131
|
+
const external = data.external;
|
|
132
|
+
url = external?.url ?? "";
|
|
133
|
+
}
|
|
134
|
+
else if (data?.type === "file") {
|
|
135
|
+
const file = data.file;
|
|
136
|
+
url = file?.url ?? "";
|
|
137
|
+
}
|
|
138
|
+
return `${indent}[Image: ${captionText || url}]`;
|
|
139
|
+
}
|
|
140
|
+
case "bookmark": {
|
|
141
|
+
const data = block[type];
|
|
142
|
+
const url = data?.url ?? "";
|
|
143
|
+
return `${indent}[Bookmark: ${url}]`;
|
|
144
|
+
}
|
|
145
|
+
case "table_row": {
|
|
146
|
+
const data = block[type];
|
|
147
|
+
const cells = data?.cells;
|
|
148
|
+
if (!cells)
|
|
149
|
+
return `${indent}| |`;
|
|
150
|
+
const cellTexts = cells.map((cell) => flattenRichText(cell));
|
|
151
|
+
return `${indent}| ${cellTexts.join(" | ")} |`;
|
|
152
|
+
}
|
|
153
|
+
case "child_page": {
|
|
154
|
+
const data = block[type];
|
|
155
|
+
const title = data?.title ?? "";
|
|
156
|
+
return `${indent}[Child page: ${title}]`;
|
|
157
|
+
}
|
|
158
|
+
case "child_database": {
|
|
159
|
+
const data = block[type];
|
|
160
|
+
const title = data?.title ?? "";
|
|
161
|
+
return `${indent}[Child database: ${title}]`;
|
|
162
|
+
}
|
|
163
|
+
case "embed": {
|
|
164
|
+
const data = block[type];
|
|
165
|
+
const url = data?.url ?? "";
|
|
166
|
+
return `${indent}[Embed: ${url}]`;
|
|
167
|
+
}
|
|
168
|
+
case "synced_block":
|
|
169
|
+
return `${indent}[Synced block]`;
|
|
170
|
+
case "column_list":
|
|
171
|
+
case "column":
|
|
172
|
+
return "";
|
|
173
|
+
default:
|
|
174
|
+
return text ? `${indent}${text}` : `${indent}[${type} block]`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Converts an array of Notion block objects to readable text lines.
|
|
179
|
+
*/
|
|
180
|
+
function flattenBlocks(blocks) {
|
|
181
|
+
if (!Array.isArray(blocks))
|
|
182
|
+
return [];
|
|
183
|
+
const lines = [];
|
|
184
|
+
for (const block of blocks) {
|
|
185
|
+
if (!block || typeof block !== "object")
|
|
186
|
+
continue;
|
|
187
|
+
const record = block;
|
|
188
|
+
const depth = record._depth ?? 0;
|
|
189
|
+
const line = renderBlock(record, depth);
|
|
190
|
+
if (line !== "") {
|
|
191
|
+
lines.push(line);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return lines;
|
|
195
|
+
}
|
|
196
|
+
// ===========================================================================
|
|
197
|
+
// Metadata stripping
|
|
198
|
+
// ===========================================================================
|
|
199
|
+
/**
|
|
200
|
+
* Recursively removes specified keys from an object.
|
|
201
|
+
*/
|
|
202
|
+
function stripNotionMetadata(obj, keys = NOTION_STRIP_KEYS) {
|
|
203
|
+
if (obj === null || obj === undefined)
|
|
204
|
+
return obj;
|
|
205
|
+
if (Array.isArray(obj))
|
|
206
|
+
return obj.map((item) => stripNotionMetadata(item, keys));
|
|
207
|
+
if (typeof obj !== "object")
|
|
208
|
+
return obj;
|
|
209
|
+
const result = {};
|
|
210
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
211
|
+
if (keys.includes(key))
|
|
212
|
+
continue;
|
|
213
|
+
result[key] = stripNotionMetadata(value, keys);
|
|
214
|
+
}
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
// ===========================================================================
|
|
218
|
+
// Block truncation
|
|
219
|
+
// ===========================================================================
|
|
220
|
+
/**
|
|
221
|
+
* Limits block count, appending a truncation marker if exceeded.
|
|
222
|
+
*/
|
|
223
|
+
function truncateBlocks(blocks, max = 100) {
|
|
224
|
+
if (!Array.isArray(blocks) || blocks.length <= max)
|
|
225
|
+
return blocks;
|
|
226
|
+
const truncated = blocks.slice(0, max);
|
|
227
|
+
truncated.push({
|
|
228
|
+
_truncated: true,
|
|
229
|
+
message: `[Truncated: showing ${max} of ${blocks.length} total blocks]`,
|
|
230
|
+
});
|
|
231
|
+
return truncated;
|
|
232
|
+
}
|
|
233
|
+
// ===========================================================================
|
|
234
|
+
// Composed transform
|
|
235
|
+
// ===========================================================================
|
|
236
|
+
/**
|
|
237
|
+
* Composes all Notion-specific transformations for LLM optimization.
|
|
238
|
+
*/
|
|
239
|
+
function transformNotionResponse(data) {
|
|
240
|
+
return stripNotionMetadata(data);
|
|
241
|
+
}
|
|
242
|
+
// ===========================================================================
|
|
243
|
+
// MCP response formatting
|
|
244
|
+
// ===========================================================================
|
|
245
|
+
/**
|
|
246
|
+
* Transforms Notion data and wraps it in the MCP tool response format.
|
|
247
|
+
*/
|
|
248
|
+
function formatMcpResponse(data) {
|
|
249
|
+
const transformed = transformNotionResponse(data);
|
|
250
|
+
return {
|
|
251
|
+
content: [{ type: "text", text: JSON.stringify(transformed, null, 2) }],
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Wraps an error in the MCP tool error response format.
|
|
256
|
+
*/
|
|
257
|
+
function formatMcpError(error) {
|
|
258
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
259
|
+
return {
|
|
260
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
261
|
+
isError: true,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
7
|
+
const zod_1 = require("zod");
|
|
8
|
+
const notion_service_1 = require("./services/notion.service");
|
|
9
|
+
const search_tools_1 = require("./tools/search.tools");
|
|
10
|
+
const page_tools_1 = require("./tools/page.tools");
|
|
11
|
+
const database_tools_1 = require("./tools/database.tools");
|
|
12
|
+
const user_tools_1 = require("./tools/user.tools");
|
|
13
|
+
// Validate required config
|
|
14
|
+
const NOTION_API_KEY = process.env.NOTION_API_KEY;
|
|
15
|
+
if (!NOTION_API_KEY) {
|
|
16
|
+
console.error("NOTION_API_KEY environment variable is required.");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const notionService = new notion_service_1.NotionService({
|
|
20
|
+
apiKey: NOTION_API_KEY,
|
|
21
|
+
notionVersion: process.env.NOTION_VERSION ?? "2022-06-28",
|
|
22
|
+
});
|
|
23
|
+
// Initialize tool classes
|
|
24
|
+
const tools = {
|
|
25
|
+
search: new search_tools_1.SearchTools(notionService),
|
|
26
|
+
pages: new page_tools_1.PageTools(notionService),
|
|
27
|
+
databases: new database_tools_1.DatabaseTools(notionService),
|
|
28
|
+
users: new user_tools_1.UserTools(notionService),
|
|
29
|
+
};
|
|
30
|
+
// Combine all schemas
|
|
31
|
+
const AllToolSchemas = {
|
|
32
|
+
...search_tools_1.SearchToolSchemas,
|
|
33
|
+
...page_tools_1.PageToolSchemas,
|
|
34
|
+
...database_tools_1.DatabaseToolSchemas,
|
|
35
|
+
...user_tools_1.UserToolSchemas,
|
|
36
|
+
};
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
|
+
const { version } = require("../package.json");
|
|
39
|
+
const server = new index_js_1.Server({
|
|
40
|
+
name: "notion-mcp",
|
|
41
|
+
version,
|
|
42
|
+
}, {
|
|
43
|
+
capabilities: {
|
|
44
|
+
tools: {},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Handler for listing available tools.
|
|
49
|
+
*/
|
|
50
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
51
|
+
return {
|
|
52
|
+
tools: Object.entries(AllToolSchemas).map(([name, config]) => ({
|
|
53
|
+
name,
|
|
54
|
+
description: config.description,
|
|
55
|
+
inputSchema: zod_1.z.toJSONSchema(config.schema),
|
|
56
|
+
})),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
const toolRegistry = {};
|
|
60
|
+
for (const name of Object.keys(search_tools_1.SearchToolSchemas)) {
|
|
61
|
+
toolRegistry[name] = (args) => tools.search[name](args);
|
|
62
|
+
}
|
|
63
|
+
for (const name of Object.keys(page_tools_1.PageToolSchemas)) {
|
|
64
|
+
toolRegistry[name] = (args) => tools.pages[name](args);
|
|
65
|
+
}
|
|
66
|
+
for (const name of Object.keys(database_tools_1.DatabaseToolSchemas)) {
|
|
67
|
+
toolRegistry[name] = (args) => tools.databases[name](args);
|
|
68
|
+
}
|
|
69
|
+
for (const name of Object.keys(user_tools_1.UserToolSchemas)) {
|
|
70
|
+
toolRegistry[name] = (args) => tools.users[name](args);
|
|
71
|
+
}
|
|
72
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
73
|
+
try {
|
|
74
|
+
const { name, arguments: args } = request.params;
|
|
75
|
+
const handler = toolRegistry[name];
|
|
76
|
+
if (!handler) {
|
|
77
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Tool not found: ${name}`);
|
|
78
|
+
}
|
|
79
|
+
return await handler(args ?? {});
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
return {
|
|
84
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
85
|
+
isError: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* Start the server using Stdio transport.
|
|
91
|
+
*/
|
|
92
|
+
async function main() {
|
|
93
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
94
|
+
await server.connect(transport);
|
|
95
|
+
console.error("Notion MCP Server running on stdio");
|
|
96
|
+
}
|
|
97
|
+
main().catch((error) => {
|
|
98
|
+
console.error("Server error:", error);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,wEAAmE;AACnE,wEAAiF;AACjF,iEAK4C;AAC5C,6BAAwB;AACxB,8DAA0D;AAC1D,uDAAsE;AACtE,mDAAgE;AAChE,2DAA4E;AAC5E,mDAAgE;AAEhE,2BAA2B;AAC3B,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;AAElD,IAAI,CAAC,cAAc,EAAE,CAAC;IACpB,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,aAAa,GAAG,IAAI,8BAAa,CAAC;IACtC,MAAM,EAAE,cAAc;IACtB,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,YAAY;CAC1D,CAAC,CAAC;AAEH,0BAA0B;AAC1B,MAAM,KAAK,GAAG;IACZ,MAAM,EAAE,IAAI,0BAAW,CAAC,aAAa,CAAC;IACtC,KAAK,EAAE,IAAI,sBAAS,CAAC,aAAa,CAAC;IACnC,SAAS,EAAE,IAAI,8BAAa,CAAC,aAAa,CAAC;IAC3C,KAAK,EAAE,IAAI,sBAAS,CAAC,aAAa,CAAC;CACpC,CAAC;AAEF,sBAAsB;AACtB,MAAM,cAAc,GAAG;IACrB,GAAG,gCAAiB;IACpB,GAAG,4BAAe;IAClB,GAAG,oCAAmB;IACtB,GAAG,4BAAe;CACV,CAAC;AAEX,iEAAiE;AACjE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE/C,MAAM,MAAM,GAAG,IAAI,iBAAM,CACvB;IACE,IAAI,EAAE,YAAY;IAClB,OAAO;CACR,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7D,IAAI;YACJ,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,WAAW,EAAE,OAAC,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC;SAC3C,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC,CAAC,CAAC;AAUH,MAAM,YAAY,GAAgC,EAAE,CAAC;AAErD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,gCAAiB,CAAC,EAAE,CAAC;IAClD,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAE,KAAK,CAAC,MAAM,CAAC,IAAyB,CAAiB,CAAC,IAAI,CAAC,CAAC;AAChG,CAAC;AACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,4BAAe,CAAC,EAAE,CAAC;IAChD,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAE,KAAK,CAAC,KAAK,CAAC,IAAuB,CAAiB,CAAC,IAAI,CAAC,CAAC;AAC7F,CAAC;AACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,oCAAmB,CAAC,EAAE,CAAC;IACpD,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAC3B,KAAK,CAAC,SAAS,CAAC,IAA2B,CAAiB,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC;AACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,4BAAe,CAAC,EAAE,CAAC;IAChD,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAE,KAAK,CAAC,KAAK,CAAC,IAAuB,CAAiB,CAAC,IAAI,CAAC,CAAC;AAC7F,CAAC;AAED,MAAM,CAAC,iBAAiB,CAAC,gCAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAEnC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,mBAAQ,CAAC,oBAAS,CAAC,cAAc,EAAE,mBAAmB,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,OAAO,MAAM,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;YACtD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;AACtD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NotionConfig } from "../common/types";
|
|
2
|
+
export declare class NotionService {
|
|
3
|
+
private baseUrl;
|
|
4
|
+
private apiKey;
|
|
5
|
+
private notionVersion;
|
|
6
|
+
constructor(config: NotionConfig);
|
|
7
|
+
private request;
|
|
8
|
+
search(query?: string, filter?: {
|
|
9
|
+
property: "object";
|
|
10
|
+
value: "page" | "database";
|
|
11
|
+
}, limit?: number): Promise<unknown>;
|
|
12
|
+
getPage(pageId: string): Promise<unknown>;
|
|
13
|
+
getPageContent(blockId: string, maxDepth?: number, maxBlocks?: number): Promise<unknown[]>;
|
|
14
|
+
getDatabase(databaseId: string): Promise<unknown>;
|
|
15
|
+
queryDatabase(databaseId: string, filter?: unknown, sorts?: unknown, limit?: number): Promise<unknown>;
|
|
16
|
+
listUsers(limit?: number): Promise<unknown>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NotionService = void 0;
|
|
4
|
+
class NotionService {
|
|
5
|
+
baseUrl;
|
|
6
|
+
apiKey;
|
|
7
|
+
notionVersion;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.baseUrl = "https://api.notion.com/v1";
|
|
10
|
+
this.apiKey = config.apiKey;
|
|
11
|
+
this.notionVersion = config.notionVersion;
|
|
12
|
+
}
|
|
13
|
+
async request(method, path, body) {
|
|
14
|
+
const url = `${this.baseUrl}${path}`;
|
|
15
|
+
const options = {
|
|
16
|
+
method,
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
19
|
+
"Notion-Version": this.notionVersion,
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
if (body && method === "POST") {
|
|
24
|
+
options.body = JSON.stringify(body);
|
|
25
|
+
}
|
|
26
|
+
const response = await fetch(url, options);
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
const errorBody = await response.text().catch(() => "");
|
|
29
|
+
switch (response.status) {
|
|
30
|
+
case 401:
|
|
31
|
+
throw new Error("Authentication failed. Check your NOTION_API_KEY.");
|
|
32
|
+
case 403:
|
|
33
|
+
throw new Error("Access denied. Ensure the Notion integration is connected to this page/database via the 'Connect to' menu.");
|
|
34
|
+
case 404:
|
|
35
|
+
throw new Error("Not found. The page/database may not exist or may not be shared with your integration.");
|
|
36
|
+
case 429: {
|
|
37
|
+
const retryAfter = response.headers.get("Retry-After") ?? "unknown";
|
|
38
|
+
throw new Error(`Rate limited by Notion. Retry after ${retryAfter} seconds.`);
|
|
39
|
+
}
|
|
40
|
+
default:
|
|
41
|
+
throw new Error(`Notion API error (${response.status}): ${errorBody || response.statusText}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return response.json();
|
|
45
|
+
}
|
|
46
|
+
// ===========================================================================
|
|
47
|
+
// Search
|
|
48
|
+
// ===========================================================================
|
|
49
|
+
async search(query, filter, limit = 10) {
|
|
50
|
+
const body = { page_size: Math.min(limit, 100) };
|
|
51
|
+
if (query)
|
|
52
|
+
body.query = query;
|
|
53
|
+
if (filter)
|
|
54
|
+
body.filter = filter;
|
|
55
|
+
return this.request("POST", "/search", body);
|
|
56
|
+
}
|
|
57
|
+
// ===========================================================================
|
|
58
|
+
// Pages
|
|
59
|
+
// ===========================================================================
|
|
60
|
+
async getPage(pageId) {
|
|
61
|
+
return this.request("GET", `/pages/${pageId}`);
|
|
62
|
+
}
|
|
63
|
+
async getPageContent(blockId, maxDepth = 3, maxBlocks = 100) {
|
|
64
|
+
const allBlocks = [];
|
|
65
|
+
const fetchChildren = async (parentId, depth) => {
|
|
66
|
+
if (depth > maxDepth || allBlocks.length >= maxBlocks)
|
|
67
|
+
return;
|
|
68
|
+
const result = await this.request("GET", `/blocks/${parentId}/children?page_size=100`);
|
|
69
|
+
for (const block of result.results) {
|
|
70
|
+
if (allBlocks.length >= maxBlocks)
|
|
71
|
+
break;
|
|
72
|
+
allBlocks.push({ ...block, _depth: depth });
|
|
73
|
+
if (block.has_children === true) {
|
|
74
|
+
await fetchChildren(block.id, depth + 1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
await fetchChildren(blockId, 0);
|
|
79
|
+
return allBlocks;
|
|
80
|
+
}
|
|
81
|
+
// ===========================================================================
|
|
82
|
+
// Databases
|
|
83
|
+
// ===========================================================================
|
|
84
|
+
async getDatabase(databaseId) {
|
|
85
|
+
return this.request("GET", `/databases/${databaseId}`);
|
|
86
|
+
}
|
|
87
|
+
async queryDatabase(databaseId, filter, sorts, limit = 25) {
|
|
88
|
+
const body = { page_size: Math.min(limit, 100) };
|
|
89
|
+
if (filter)
|
|
90
|
+
body.filter = filter;
|
|
91
|
+
if (sorts)
|
|
92
|
+
body.sorts = sorts;
|
|
93
|
+
return this.request("POST", `/databases/${databaseId}/query`, body);
|
|
94
|
+
}
|
|
95
|
+
// ===========================================================================
|
|
96
|
+
// Users
|
|
97
|
+
// ===========================================================================
|
|
98
|
+
async listUsers(limit = 25) {
|
|
99
|
+
return this.request("GET", `/users?page_size=${Math.min(limit, 100)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.NotionService = NotionService;
|
|
103
|
+
//# sourceMappingURL=notion.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notion.service.js","sourceRoot":"","sources":["../../src/services/notion.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { NotionService } from "../services/notion.service";
|
|
3
|
+
export declare const DatabaseToolSchemas: {
|
|
4
|
+
get_database: {
|
|
5
|
+
description: string;
|
|
6
|
+
schema: z.ZodObject<{
|
|
7
|
+
database_id: z.ZodString;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
};
|
|
10
|
+
query_database: {
|
|
11
|
+
description: string;
|
|
12
|
+
schema: z.ZodObject<{
|
|
13
|
+
database_id: z.ZodString;
|
|
14
|
+
filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
15
|
+
sorts: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
16
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export declare class DatabaseTools {
|
|
21
|
+
private notionService;
|
|
22
|
+
constructor(notionService: NotionService);
|
|
23
|
+
get_database(args: z.infer<typeof DatabaseToolSchemas.get_database.schema>): Promise<import("../common/types").McpToolResponse>;
|
|
24
|
+
query_database(args: z.infer<typeof DatabaseToolSchemas.query_database.schema>): Promise<import("../common/types").McpToolResponse>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseTools = exports.DatabaseToolSchemas = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const utils_1 = require("../common/utils");
|
|
6
|
+
exports.DatabaseToolSchemas = {
|
|
7
|
+
get_database: {
|
|
8
|
+
description: "Retrieves database metadata including title, description, and property schema (column definitions). Use this to understand the structure of a database before querying it.",
|
|
9
|
+
schema: zod_1.z.object({
|
|
10
|
+
database_id: zod_1.z.string().describe("The Notion database ID (UUID or 32-char hex)."),
|
|
11
|
+
}),
|
|
12
|
+
},
|
|
13
|
+
query_database: {
|
|
14
|
+
description: "Queries a Notion database with optional filter and sort objects. Returns matching entries with all property values. Use Notion's native filter syntax.",
|
|
15
|
+
schema: zod_1.z.object({
|
|
16
|
+
database_id: zod_1.z.string().describe("The Notion database ID (UUID or 32-char hex)."),
|
|
17
|
+
filter: zod_1.z
|
|
18
|
+
.record(zod_1.z.string(), zod_1.z.unknown())
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Notion filter object (see Notion API docs for filter syntax)."),
|
|
21
|
+
sorts: zod_1.z
|
|
22
|
+
.array(zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()))
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Array of Notion sort objects."),
|
|
25
|
+
limit: zod_1.z.number().optional().default(25).describe("Max results (max 100)."),
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
class DatabaseTools {
|
|
30
|
+
notionService;
|
|
31
|
+
constructor(notionService) {
|
|
32
|
+
this.notionService = notionService;
|
|
33
|
+
}
|
|
34
|
+
async get_database(args) {
|
|
35
|
+
const database = await this.notionService.getDatabase(args.database_id);
|
|
36
|
+
return (0, utils_1.formatMcpResponse)(database);
|
|
37
|
+
}
|
|
38
|
+
async query_database(args) {
|
|
39
|
+
const result = await this.notionService.queryDatabase(args.database_id, args.filter, args.sorts, args.limit);
|
|
40
|
+
return (0, utils_1.formatMcpResponse)(result);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.DatabaseTools = DatabaseTools;
|
|
44
|
+
//# sourceMappingURL=database.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.tools.js","sourceRoot":"","sources":["../../src/tools/database.tools.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,2CAAoD;AAEvC,QAAA,mBAAmB,GAAG;IACjC,YAAY,EAAE;QACZ,WAAW,EACT,4KAA4K;QAC9K,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;SAClF,CAAC;KACH;IACD,cAAc,EAAE;QACd,WAAW,EACT,wJAAwJ;QAC1J,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;YACjF,MAAM,EAAE,OAAC;iBACN,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC;iBAC/B,QAAQ,EAAE;iBACV,QAAQ,CAAC,+DAA+D,CAAC;YAC5E,KAAK,EAAE,OAAC;iBACL,KAAK,CAAC,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC;iBACxC,QAAQ,EAAE;iBACV,QAAQ,CAAC,+BAA+B,CAAC;YAC5C,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SAC5E,CAAC;KACH;CACF,CAAC;AAEF,MAAa,aAAa;IACJ;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,KAAK,CAAC,YAAY,CAAC,IAA6D;QAC9E,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxE,OAAO,IAAA,yBAAiB,EAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAA+D;QAClF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,CACnD,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,KAAK,CACX,CAAC;QACF,OAAO,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC;IACnC,CAAC;CACF;AAjBD,sCAiBC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { NotionService } from "../services/notion.service";
|
|
3
|
+
export declare const PageToolSchemas: {
|
|
4
|
+
get_page: {
|
|
5
|
+
description: string;
|
|
6
|
+
schema: z.ZodObject<{
|
|
7
|
+
page_id: z.ZodString;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
};
|
|
10
|
+
get_page_content: {
|
|
11
|
+
description: string;
|
|
12
|
+
schema: z.ZodObject<{
|
|
13
|
+
page_id: z.ZodString;
|
|
14
|
+
max_depth: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare class PageTools {
|
|
19
|
+
private notionService;
|
|
20
|
+
constructor(notionService: NotionService);
|
|
21
|
+
get_page(args: z.infer<typeof PageToolSchemas.get_page.schema>): Promise<import("../common/types").McpToolResponse>;
|
|
22
|
+
get_page_content(args: z.infer<typeof PageToolSchemas.get_page_content.schema>): Promise<{
|
|
23
|
+
content: {
|
|
24
|
+
type: string;
|
|
25
|
+
text: string;
|
|
26
|
+
}[];
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PageTools = exports.PageToolSchemas = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const utils_1 = require("../common/utils");
|
|
6
|
+
exports.PageToolSchemas = {
|
|
7
|
+
get_page: {
|
|
8
|
+
description: "Retrieves page properties including title, created time, last edited time, parent, and all property values. Use when you have a specific page ID.",
|
|
9
|
+
schema: zod_1.z.object({
|
|
10
|
+
page_id: zod_1.z.string().describe("The Notion page ID (UUID or 32-char hex)."),
|
|
11
|
+
}),
|
|
12
|
+
},
|
|
13
|
+
get_page_content: {
|
|
14
|
+
description: "Retrieves the full content of a page as readable text blocks. Recursively fetches nested blocks (toggles, columns, etc.) up to a configurable depth. Returns flattened plain text optimized for LLM consumption.",
|
|
15
|
+
schema: zod_1.z.object({
|
|
16
|
+
page_id: zod_1.z.string().describe("The Notion page ID (UUID or 32-char hex)."),
|
|
17
|
+
max_depth: zod_1.z
|
|
18
|
+
.number()
|
|
19
|
+
.optional()
|
|
20
|
+
.default(3)
|
|
21
|
+
.describe("Maximum recursion depth for nested blocks (default: 3)."),
|
|
22
|
+
}),
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
class PageTools {
|
|
26
|
+
notionService;
|
|
27
|
+
constructor(notionService) {
|
|
28
|
+
this.notionService = notionService;
|
|
29
|
+
}
|
|
30
|
+
async get_page(args) {
|
|
31
|
+
const page = await this.notionService.getPage(args.page_id);
|
|
32
|
+
return (0, utils_1.formatMcpResponse)(page);
|
|
33
|
+
}
|
|
34
|
+
async get_page_content(args) {
|
|
35
|
+
const blocks = await this.notionService.getPageContent(args.page_id, args.max_depth);
|
|
36
|
+
const truncated = (0, utils_1.truncateBlocks)(blocks);
|
|
37
|
+
const lines = (0, utils_1.flattenBlocks)(truncated);
|
|
38
|
+
return {
|
|
39
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.PageTools = PageTools;
|
|
44
|
+
//# sourceMappingURL=page.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.tools.js","sourceRoot":"","sources":["../../src/tools/page.tools.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,2CAAmF;AAEtE,QAAA,eAAe,GAAG;IAC7B,QAAQ,EAAE;QACR,WAAW,EACT,mJAAmJ;QACrJ,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;SAC1E,CAAC;KACH;IACD,gBAAgB,EAAE;QAChB,WAAW,EACT,kNAAkN;QACpN,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YACzE,SAAS,EAAE,OAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,OAAO,CAAC,CAAC,CAAC;iBACV,QAAQ,CAAC,yDAAyD,CAAC;SACvE,CAAC;KACH;CACF,CAAC;AAEF,MAAa,SAAS;IACA;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,KAAK,CAAC,QAAQ,CAAC,IAAqD;QAClE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5D,OAAO,IAAA,yBAAiB,EAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAA6D;QAClF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACrF,MAAM,SAAS,GAAG,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAA,qBAAa,EAAC,SAAS,CAAC,CAAC;QACvC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;SACpD,CAAC;IACJ,CAAC;CACF;AAhBD,8BAgBC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { NotionService } from "../services/notion.service";
|
|
3
|
+
export declare const SearchToolSchemas: {
|
|
4
|
+
search: {
|
|
5
|
+
description: string;
|
|
6
|
+
schema: z.ZodObject<{
|
|
7
|
+
query: z.ZodOptional<z.ZodString>;
|
|
8
|
+
filter: z.ZodOptional<z.ZodEnum<{
|
|
9
|
+
page: "page";
|
|
10
|
+
database: "database";
|
|
11
|
+
}>>;
|
|
12
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare class SearchTools {
|
|
17
|
+
private notionService;
|
|
18
|
+
constructor(notionService: NotionService);
|
|
19
|
+
search(args: z.infer<typeof SearchToolSchemas.search.schema>): Promise<import("../common/types").McpToolResponse>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SearchTools = exports.SearchToolSchemas = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const utils_1 = require("../common/utils");
|
|
6
|
+
exports.SearchToolSchemas = {
|
|
7
|
+
search: {
|
|
8
|
+
description: "Searches across all pages and databases in the Notion workspace. Use this to find content by title or text. Only returns content shared with the integration.",
|
|
9
|
+
schema: zod_1.z.object({
|
|
10
|
+
query: zod_1.z.string().optional().describe("Search query text."),
|
|
11
|
+
filter: zod_1.z
|
|
12
|
+
.enum(["page", "database"])
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Filter results to only pages or only databases."),
|
|
15
|
+
limit: zod_1.z.number().optional().default(10).describe("Max results (max 100)."),
|
|
16
|
+
}),
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
class SearchTools {
|
|
20
|
+
notionService;
|
|
21
|
+
constructor(notionService) {
|
|
22
|
+
this.notionService = notionService;
|
|
23
|
+
}
|
|
24
|
+
async search(args) {
|
|
25
|
+
const filter = args.filter ? { property: "object", value: args.filter } : undefined;
|
|
26
|
+
const result = await this.notionService.search(args.query, filter, args.limit);
|
|
27
|
+
return (0, utils_1.formatMcpResponse)(result);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.SearchTools = SearchTools;
|
|
31
|
+
//# sourceMappingURL=search.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.tools.js","sourceRoot":"","sources":["../../src/tools/search.tools.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,2CAAoD;AAEvC,QAAA,iBAAiB,GAAG;IAC/B,MAAM,EAAE;QACN,WAAW,EACT,+JAA+J;QACjK,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAC3D,MAAM,EAAE,OAAC;iBACN,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;iBAC1B,QAAQ,EAAE;iBACV,QAAQ,CAAC,iDAAiD,CAAC;YAC9D,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SAC5E,CAAC;KACH;CACF,CAAC;AAEF,MAAa,WAAW;IACF;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,KAAK,CAAC,MAAM,CAAC,IAAqD;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAiB,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7F,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/E,OAAO,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC;IACnC,CAAC;CACF;AARD,kCAQC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { NotionService } from "../services/notion.service";
|
|
3
|
+
export declare const UserToolSchemas: {
|
|
4
|
+
list_users: {
|
|
5
|
+
description: string;
|
|
6
|
+
schema: z.ZodObject<{
|
|
7
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare class UserTools {
|
|
12
|
+
private notionService;
|
|
13
|
+
constructor(notionService: NotionService);
|
|
14
|
+
list_users(args: z.infer<typeof UserToolSchemas.list_users.schema>): Promise<import("../common/types").McpToolResponse>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UserTools = exports.UserToolSchemas = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const utils_1 = require("../common/utils");
|
|
6
|
+
exports.UserToolSchemas = {
|
|
7
|
+
list_users: {
|
|
8
|
+
description: "Lists all users in the Notion workspace including name, email, type (person/bot), and avatar URL.",
|
|
9
|
+
schema: zod_1.z.object({
|
|
10
|
+
limit: zod_1.z.number().optional().default(25).describe("Max results (max 100)."),
|
|
11
|
+
}),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
class UserTools {
|
|
15
|
+
notionService;
|
|
16
|
+
constructor(notionService) {
|
|
17
|
+
this.notionService = notionService;
|
|
18
|
+
}
|
|
19
|
+
async list_users(args) {
|
|
20
|
+
const users = await this.notionService.listUsers(args.limit);
|
|
21
|
+
return (0, utils_1.formatMcpResponse)(users);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.UserTools = UserTools;
|
|
25
|
+
//# sourceMappingURL=user.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.tools.js","sourceRoot":"","sources":["../../src/tools/user.tools.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,2CAAoD;AAEvC,QAAA,eAAe,GAAG;IAC7B,UAAU,EAAE;QACV,WAAW,EACT,mGAAmG;QACrG,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SAC5E,CAAC;KACH;CACF,CAAC;AAEF,MAAa,SAAS;IACA;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,KAAK,CAAC,UAAU,CAAC,IAAuD;QACtE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7D,OAAO,IAAA,yBAAiB,EAAC,KAAK,CAAC,CAAC;IAClC,CAAC;CACF;AAPD,8BAOC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vineethnkrishnan/notion-mcp",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A read-only MCP server for the Notion API, enabling AI assistants to search, read pages, query databases, and list users.",
|
|
5
|
+
"main": "build/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"notion-mcp": "build/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"build/"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"start": "node build/index.js",
|
|
15
|
+
"test": "jest --coverage"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mcp",
|
|
22
|
+
"notion",
|
|
23
|
+
"ai",
|
|
24
|
+
"model-context-protocol",
|
|
25
|
+
"knowledge-base",
|
|
26
|
+
"wiki",
|
|
27
|
+
"databases"
|
|
28
|
+
],
|
|
29
|
+
"author": "Vineeth Krishnan",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"type": "commonjs",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
37
|
+
"zod": "^4.3.6"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/jest": "^30.0.0",
|
|
41
|
+
"@types/node": "^25.5.0",
|
|
42
|
+
"jest": "^30.3.0",
|
|
43
|
+
"ts-jest": "^29.4.6",
|
|
44
|
+
"typescript": "^5.7.0"
|
|
45
|
+
}
|
|
46
|
+
}
|