Notion MCP Server
by SAhmadUmass
"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Client_auth, _Client_logLevel, _Client_logger, _Client_prefixUrl, _Client_timeoutMs, _Client_notionVersion, _Client_fetch, _Client_agent, _Client_userAgent;
Object.defineProperty(exports, "__esModule", { value: true });
const logging_1 = require("./logging");
const errors_1 = require("./errors");
const utils_1 = require("./utils");
const api_endpoints_1 = require("./api-endpoints");
const node_fetch_1 = require("node-fetch");
const package_json_1 = require("../package.json");
class Client {
constructor(options) {
var _a, _b, _c, _d, _e, _f;
_Client_auth.set(this, void 0);
_Client_logLevel.set(this, void 0);
_Client_logger.set(this, void 0);
_Client_prefixUrl.set(this, void 0);
_Client_timeoutMs.set(this, void 0);
_Client_notionVersion.set(this, void 0);
_Client_fetch.set(this, void 0);
_Client_agent.set(this, void 0);
_Client_userAgent.set(this, void 0);
/*
* Notion API endpoints
*/
this.blocks = {
/**
* Retrieve block
*/
retrieve: (args) => {
return this.request({
path: api_endpoints_1.getBlock.path(args),
method: api_endpoints_1.getBlock.method,
query: (0, utils_1.pick)(args, api_endpoints_1.getBlock.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.getBlock.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Update block
*/
update: (args) => {
return this.request({
path: api_endpoints_1.updateBlock.path(args),
method: api_endpoints_1.updateBlock.method,
query: (0, utils_1.pick)(args, api_endpoints_1.updateBlock.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.updateBlock.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Delete block
*/
delete: (args) => {
return this.request({
path: api_endpoints_1.deleteBlock.path(args),
method: api_endpoints_1.deleteBlock.method,
query: (0, utils_1.pick)(args, api_endpoints_1.deleteBlock.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.deleteBlock.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
children: {
/**
* Append block children
*/
append: (args) => {
return this.request({
path: api_endpoints_1.appendBlockChildren.path(args),
method: api_endpoints_1.appendBlockChildren.method,
query: (0, utils_1.pick)(args, api_endpoints_1.appendBlockChildren.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.appendBlockChildren.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Retrieve block children
*/
list: (args) => {
return this.request({
path: api_endpoints_1.listBlockChildren.path(args),
method: api_endpoints_1.listBlockChildren.method,
query: (0, utils_1.pick)(args, api_endpoints_1.listBlockChildren.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.listBlockChildren.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
},
};
this.databases = {
/**
* List databases
*
* @deprecated Please use `search`
*/
list: (args) => {
return this.request({
path: api_endpoints_1.listDatabases.path(),
method: api_endpoints_1.listDatabases.method,
query: (0, utils_1.pick)(args, api_endpoints_1.listDatabases.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.listDatabases.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Retrieve a database
*/
retrieve: (args) => {
return this.request({
path: api_endpoints_1.getDatabase.path(args),
method: api_endpoints_1.getDatabase.method,
query: (0, utils_1.pick)(args, api_endpoints_1.getDatabase.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.getDatabase.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Query a database
*/
query: (args) => {
return this.request({
path: api_endpoints_1.queryDatabase.path(args),
method: api_endpoints_1.queryDatabase.method,
query: (0, utils_1.pick)(args, api_endpoints_1.queryDatabase.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.queryDatabase.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Create a database
*/
create: (args) => {
return this.request({
path: api_endpoints_1.createDatabase.path(),
method: api_endpoints_1.createDatabase.method,
query: (0, utils_1.pick)(args, api_endpoints_1.createDatabase.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.createDatabase.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Update a database
*/
update: (args) => {
return this.request({
path: api_endpoints_1.updateDatabase.path(args),
method: api_endpoints_1.updateDatabase.method,
query: (0, utils_1.pick)(args, api_endpoints_1.updateDatabase.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.updateDatabase.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
};
this.pages = {
/**
* Create a page
*/
create: (args) => {
return this.request({
path: api_endpoints_1.createPage.path(),
method: api_endpoints_1.createPage.method,
query: (0, utils_1.pick)(args, api_endpoints_1.createPage.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.createPage.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Retrieve a page
*/
retrieve: (args) => {
return this.request({
path: api_endpoints_1.getPage.path(args),
method: api_endpoints_1.getPage.method,
query: (0, utils_1.pick)(args, api_endpoints_1.getPage.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.getPage.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Update page properties
*/
update: (args) => {
return this.request({
path: api_endpoints_1.updatePage.path(args),
method: api_endpoints_1.updatePage.method,
query: (0, utils_1.pick)(args, api_endpoints_1.updatePage.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.updatePage.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
properties: {
/**
* Retrieve page property
*/
retrieve: (args) => {
return this.request({
path: api_endpoints_1.getPageProperty.path(args),
method: api_endpoints_1.getPageProperty.method,
query: (0, utils_1.pick)(args, api_endpoints_1.getPageProperty.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.getPageProperty.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
},
};
this.users = {
/**
* Retrieve a user
*/
retrieve: (args) => {
return this.request({
path: api_endpoints_1.getUser.path(args),
method: api_endpoints_1.getUser.method,
query: (0, utils_1.pick)(args, api_endpoints_1.getUser.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.getUser.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* List all users
*/
list: (args) => {
return this.request({
path: api_endpoints_1.listUsers.path(),
method: api_endpoints_1.listUsers.method,
query: (0, utils_1.pick)(args, api_endpoints_1.listUsers.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.listUsers.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* Get details about bot
*/
me: (args) => {
return this.request({
path: api_endpoints_1.getSelf.path(),
method: api_endpoints_1.getSelf.method,
query: (0, utils_1.pick)(args, api_endpoints_1.getSelf.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.getSelf.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
};
this.comments = {
/**
* Create a comment
*/
create: (args) => {
return this.request({
path: api_endpoints_1.createComment.path(),
method: api_endpoints_1.createComment.method,
query: (0, utils_1.pick)(args, api_endpoints_1.createComment.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.createComment.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
/**
* List comments
*/
list: (args) => {
return this.request({
path: api_endpoints_1.listComments.path(),
method: api_endpoints_1.listComments.method,
query: (0, utils_1.pick)(args, api_endpoints_1.listComments.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.listComments.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
},
};
/**
* Search
*/
this.search = (args) => {
return this.request({
path: api_endpoints_1.search.path(),
method: api_endpoints_1.search.method,
query: (0, utils_1.pick)(args, api_endpoints_1.search.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.search.bodyParams),
auth: args === null || args === void 0 ? void 0 : args.auth,
});
};
this.oauth = {
/**
* Get token
*/
token: (args) => {
return this.request({
path: api_endpoints_1.oauthToken.path(),
method: api_endpoints_1.oauthToken.method,
query: (0, utils_1.pick)(args, api_endpoints_1.oauthToken.queryParams),
body: (0, utils_1.pick)(args, api_endpoints_1.oauthToken.bodyParams),
auth: {
client_id: args.client_id,
client_secret: args.client_secret,
},
});
},
};
__classPrivateFieldSet(this, _Client_auth, options === null || options === void 0 ? void 0 : options.auth, "f");
__classPrivateFieldSet(this, _Client_logLevel, (_a = options === null || options === void 0 ? void 0 : options.logLevel) !== null && _a !== void 0 ? _a : logging_1.LogLevel.WARN, "f");
__classPrivateFieldSet(this, _Client_logger, (_b = options === null || options === void 0 ? void 0 : options.logger) !== null && _b !== void 0 ? _b : (0, logging_1.makeConsoleLogger)(package_json_1.name), "f");
__classPrivateFieldSet(this, _Client_prefixUrl, ((_c = options === null || options === void 0 ? void 0 : options.baseUrl) !== null && _c !== void 0 ? _c : "https://api.notion.com") + "/v1/", "f");
__classPrivateFieldSet(this, _Client_timeoutMs, (_d = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _d !== void 0 ? _d : 60000, "f");
__classPrivateFieldSet(this, _Client_notionVersion, (_e = options === null || options === void 0 ? void 0 : options.notionVersion) !== null && _e !== void 0 ? _e : Client.defaultNotionVersion, "f");
__classPrivateFieldSet(this, _Client_fetch, (_f = options === null || options === void 0 ? void 0 : options.fetch) !== null && _f !== void 0 ? _f : node_fetch_1.default, "f");
__classPrivateFieldSet(this, _Client_agent, options === null || options === void 0 ? void 0 : options.agent, "f");
__classPrivateFieldSet(this, _Client_userAgent, `notionhq-client/${package_json_1.version}`, "f");
}
/**
* Sends a request.
*
* @param path
* @param method
* @param query
* @param body
* @returns
*/
async request({ path, method, query, body, auth, }) {
this.log(logging_1.LogLevel.INFO, "request start", { method, path });
// If the body is empty, don't send the body in the HTTP request
const bodyAsJsonString = !body || Object.entries(body).length === 0
? undefined
: JSON.stringify(body);
const url = new URL(`${__classPrivateFieldGet(this, _Client_prefixUrl, "f")}${path}`);
if (query) {
for (const [key, value] of Object.entries(query)) {
if (value !== undefined) {
if (Array.isArray(value)) {
value.forEach(val => url.searchParams.append(key, decodeURIComponent(val)));
}
else {
url.searchParams.append(key, String(value));
}
}
}
}
// Allow both client ID / client secret based auth as well as token based auth.
let authorizationHeader;
if (typeof auth === "object") {
// Client ID and secret based auth is **ONLY** supported when using the
// `/oauth/token` endpoint. If this is the case, handle formatting the
// authorization header as required by `Basic` auth.
const unencodedCredential = `${auth.client_id}:${auth.client_secret}`;
const encodedCredential = Buffer.from(unencodedCredential).toString("base64");
authorizationHeader = { authorization: `Basic ${encodedCredential}` };
}
else {
// Otherwise format authorization header as `Bearer` token auth.
authorizationHeader = this.authAsHeaders(auth);
}
const headers = {
...authorizationHeader,
"Notion-Version": __classPrivateFieldGet(this, _Client_notionVersion, "f"),
"user-agent": __classPrivateFieldGet(this, _Client_userAgent, "f"),
};
if (bodyAsJsonString !== undefined) {
headers["content-type"] = "application/json";
}
try {
const response = await errors_1.RequestTimeoutError.rejectAfterTimeout(__classPrivateFieldGet(this, _Client_fetch, "f").call(this, url.toString(), {
method: method.toUpperCase(),
headers,
body: bodyAsJsonString,
agent: __classPrivateFieldGet(this, _Client_agent, "f"),
}), __classPrivateFieldGet(this, _Client_timeoutMs, "f"));
const responseText = await response.text();
if (!response.ok) {
throw (0, errors_1.buildRequestError)(response, responseText);
}
const responseJson = JSON.parse(responseText);
this.log(logging_1.LogLevel.INFO, `request success`, { method, path });
return responseJson;
}
catch (error) {
if (!(0, errors_1.isNotionClientError)(error)) {
throw error;
}
// Log the error if it's one of our known error types
this.log(logging_1.LogLevel.WARN, `request fail`, {
code: error.code,
message: error.message,
});
if ((0, errors_1.isHTTPResponseError)(error)) {
// The response body may contain sensitive information so it is logged separately at the DEBUG level
this.log(logging_1.LogLevel.DEBUG, `failed response body`, {
body: error.body,
});
}
throw error;
}
}
/**
* Emits a log message to the console.
*
* @param level The level for this message
* @param args Arguments to send to the console
*/
log(level, message, extraInfo) {
if ((0, logging_1.logLevelSeverity)(level) >= (0, logging_1.logLevelSeverity)(__classPrivateFieldGet(this, _Client_logLevel, "f"))) {
__classPrivateFieldGet(this, _Client_logger, "f").call(this, level, message, extraInfo);
}
}
/**
* Transforms an API key or access token into a headers object suitable for an HTTP request.
*
* This method uses the instance's value as the default when the input is undefined. If neither are defined, it returns
* an empty object
*
* @param auth API key or access token
* @returns headers key-value object
*/
authAsHeaders(auth) {
const headers = {};
const authHeaderValue = auth !== null && auth !== void 0 ? auth : __classPrivateFieldGet(this, _Client_auth, "f");
if (authHeaderValue !== undefined) {
headers["authorization"] = `Bearer ${authHeaderValue}`;
}
return headers;
}
}
exports.default = Client;
_Client_auth = new WeakMap(), _Client_logLevel = new WeakMap(), _Client_logger = new WeakMap(), _Client_prefixUrl = new WeakMap(), _Client_timeoutMs = new WeakMap(), _Client_notionVersion = new WeakMap(), _Client_fetch = new WeakMap(), _Client_agent = new WeakMap(), _Client_userAgent = new WeakMap();
Client.defaultNotionVersion = "2022-06-28";
//# sourceMappingURL=Client.js.map