notion.ts•3.93 kB
import { BaseApiClient } from "../../core/base-api.js";
import { loadConfig } from "../../core/config.js";
import { ToolRegistration } from "../../core/types.js";
class NotionClient extends BaseApiClient {
private readonly token: string;
constructor(token: string) {
super("https://api.notion.com", {
Authorization: `Bearer ${token}`,
"Notion-Version": "2022-06-28",
Accept: "application/json",
});
this.token = token;
}
queryDatabase(databaseId: string, filter?: unknown) {
return this.request(`/v1/databases/${databaseId}/query`, {
method: "POST",
body: filter ? { filter } : {},
});
}
createPage(parentId: string, properties: unknown) {
return this.request(`/v1/pages`, {
method: "POST",
body: { parent: { page_id: parentId, database_id: undefined }, properties },
});
}
updatePage(pageId: string, properties: unknown) {
return this.request(`/v1/pages/${pageId}`, {
method: "PATCH",
body: { properties },
});
}
search(query: string) {
return this.request(`/v1/search`, {
method: "POST",
body: { query },
});
}
}
export function registerNotion(): ToolRegistration {
const cfg = loadConfig();
const client = new NotionClient(cfg.notionToken || "");
return {
tools: [
{
name: "query_database",
description: "Query a Notion database with optional filter",
inputSchema: {
type: "object",
properties: {
database_id: { type: "string" },
filter: { type: "object" },
},
required: ["database_id"],
},
},
{
name: "create_page",
description: "Create a Notion page under a parent page or database",
inputSchema: {
type: "object",
properties: {
parent_id: { type: "string" },
properties: { type: "object" },
},
required: ["parent_id", "properties"],
},
},
{
name: "update_page",
description: "Update a Notion page properties",
inputSchema: {
type: "object",
properties: {
page_id: { type: "string" },
properties: { type: "object" },
},
required: ["page_id", "properties"],
},
},
{
name: "search_pages",
description: "Search Notion pages by query string",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
},
required: ["query"],
},
},
],
handlers: {
async query_database(args: Record<string, unknown>) {
if (!cfg.notionToken) throw new Error("NOTION_TOKEN is not configured");
const databaseId = String(args.database_id || "");
if (!databaseId) throw new Error("database_id is required");
return client.queryDatabase(databaseId, args.filter);
},
async create_page(args: Record<string, unknown>) {
if (!cfg.notionToken) throw new Error("NOTION_TOKEN is not configured");
const parentId = String(args.parent_id || "");
if (!parentId) throw new Error("parent_id is required");
return client.createPage(parentId, args.properties);
},
async update_page(args: Record<string, unknown>) {
if (!cfg.notionToken) throw new Error("NOTION_TOKEN is not configured");
const pageId = String(args.page_id || "");
if (!pageId) throw new Error("page_id is required");
return client.updatePage(pageId, args.properties);
},
async search_pages(args: Record<string, unknown>) {
if (!cfg.notionToken) throw new Error("NOTION_TOKEN is not configured");
const query = String(args.query || "");
if (!query) throw new Error("query is required");
return client.search(query);
},
},
};
}