@nimbus-dev/connectors 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/LICENSE +662 -0
  2. package/NOTICE +40 -0
  3. package/README.md +111 -0
  4. package/connectors/airflow/nimbus.extension.json +16 -0
  5. package/connectors/airflow/src/search-filter.ts +38 -0
  6. package/connectors/airflow/src/server.ts +91 -0
  7. package/connectors/apple/nimbus.extension.json +40 -0
  8. package/connectors/apple/src/apple-mail-core.ts +43 -0
  9. package/connectors/apple/src/caldav-core.ts +116 -0
  10. package/connectors/apple/src/calendar-tools.ts +278 -0
  11. package/connectors/apple/src/server.ts +541 -0
  12. package/connectors/apple/src/tools.ts +138 -0
  13. package/connectors/argocd/nimbus.extension.json +16 -0
  14. package/connectors/argocd/src/search-filter.ts +24 -0
  15. package/connectors/argocd/src/server.ts +158 -0
  16. package/connectors/athena/nimbus.extension.json +15 -0
  17. package/connectors/athena/src/server.ts +6 -0
  18. package/connectors/athena/src/tools.ts +181 -0
  19. package/connectors/aws/nimbus.extension.json +21 -0
  20. package/connectors/aws/src/server.ts +191 -0
  21. package/connectors/azure/nimbus.extension.json +15 -0
  22. package/connectors/azure/src/server.ts +139 -0
  23. package/connectors/bigeye/nimbus.extension.json +16 -0
  24. package/connectors/bigeye/src/search-filter.ts +22 -0
  25. package/connectors/bigeye/src/server.ts +161 -0
  26. package/connectors/bigquery/nimbus.extension.json +15 -0
  27. package/connectors/bigquery/src/server.ts +6 -0
  28. package/connectors/bigquery/src/tools.ts +175 -0
  29. package/connectors/bitbucket/nimbus.extension.json +15 -0
  30. package/connectors/bitbucket/src/server.ts +252 -0
  31. package/connectors/bitrise/nimbus.extension.json +15 -0
  32. package/connectors/bitrise/src/search-filter.ts +11 -0
  33. package/connectors/bitrise/src/server.ts +83 -0
  34. package/connectors/canva/nimbus.extension.json +15 -0
  35. package/connectors/canva/src/search-filter.ts +23 -0
  36. package/connectors/canva/src/server.ts +77 -0
  37. package/connectors/circleci/nimbus.extension.json +15 -0
  38. package/connectors/circleci/src/server.ts +184 -0
  39. package/connectors/cloud-logging/nimbus.extension.json +15 -0
  40. package/connectors/cloud-logging/src/server.ts +6 -0
  41. package/connectors/cloud-logging/src/tools.ts +115 -0
  42. package/connectors/cloudwatch/nimbus.extension.json +15 -0
  43. package/connectors/cloudwatch/src/server.ts +6 -0
  44. package/connectors/cloudwatch/src/tools.ts +144 -0
  45. package/connectors/codemagic/nimbus.extension.json +15 -0
  46. package/connectors/codemagic/src/search-filter.ts +11 -0
  47. package/connectors/codemagic/src/server.ts +74 -0
  48. package/connectors/confluence/nimbus.extension.json +15 -0
  49. package/connectors/confluence/src/kb-append.ts +25 -0
  50. package/connectors/confluence/src/server.ts +309 -0
  51. package/connectors/dagster/nimbus.extension.json +16 -0
  52. package/connectors/dagster/src/search-filter.ts +53 -0
  53. package/connectors/dagster/src/server.ts +218 -0
  54. package/connectors/databricks/nimbus.extension.json +16 -0
  55. package/connectors/databricks/src/search-filter.ts +28 -0
  56. package/connectors/databricks/src/server.ts +81 -0
  57. package/connectors/datadog/nimbus.extension.json +15 -0
  58. package/connectors/datadog/src/server.ts +56 -0
  59. package/connectors/dataprofile/nimbus.extension.json +16 -0
  60. package/connectors/dataprofile/src/profile.ts +298 -0
  61. package/connectors/dataprofile/src/server.ts +6 -0
  62. package/connectors/dataprofile/src/tools.ts +69 -0
  63. package/connectors/dbt/nimbus.extension.json +16 -0
  64. package/connectors/dbt/src/search-filter.ts +28 -0
  65. package/connectors/dbt/src/server.ts +96 -0
  66. package/connectors/dependencytrack/nimbus.extension.json +16 -0
  67. package/connectors/dependencytrack/src/search-filter.ts +24 -0
  68. package/connectors/dependencytrack/src/server.ts +80 -0
  69. package/connectors/discord/nimbus.extension.json +15 -0
  70. package/connectors/discord/src/server.ts +93 -0
  71. package/connectors/elasticsearch/nimbus.extension.json +16 -0
  72. package/connectors/elasticsearch/src/server.ts +6 -0
  73. package/connectors/elasticsearch/src/tools.ts +110 -0
  74. package/connectors/fastmail/nimbus.extension.json +16 -0
  75. package/connectors/fastmail/src/jmap-core.ts +86 -0
  76. package/connectors/fastmail/src/server.ts +194 -0
  77. package/connectors/fastmail/src/tools.ts +143 -0
  78. package/connectors/figma/nimbus.extension.json +15 -0
  79. package/connectors/figma/src/search-filter.ts +24 -0
  80. package/connectors/figma/src/server.ts +117 -0
  81. package/connectors/firebase/nimbus.extension.json +15 -0
  82. package/connectors/firebase/src/search-filter.ts +30 -0
  83. package/connectors/firebase/src/server.ts +94 -0
  84. package/connectors/firebase/src/token.ts +41 -0
  85. package/connectors/flagsmith/nimbus.extension.json +15 -0
  86. package/connectors/flagsmith/src/search-filter.ts +29 -0
  87. package/connectors/flagsmith/src/server.ts +102 -0
  88. package/connectors/flux/nimbus.extension.json +16 -0
  89. package/connectors/flux/src/search-filter.ts +42 -0
  90. package/connectors/flux/src/server.ts +182 -0
  91. package/connectors/gcp/nimbus.extension.json +15 -0
  92. package/connectors/gcp/src/server.ts +140 -0
  93. package/connectors/github/nimbus.extension.json +15 -0
  94. package/connectors/github/src/server.ts +347 -0
  95. package/connectors/github-actions/nimbus.extension.json +15 -0
  96. package/connectors/github-actions/src/server.ts +213 -0
  97. package/connectors/gitlab/nimbus.extension.json +15 -0
  98. package/connectors/gitlab/src/server.ts +392 -0
  99. package/connectors/gmail/nimbus.extension.json +15 -0
  100. package/connectors/gmail/src/server.ts +277 -0
  101. package/connectors/google-drive/nimbus.extension.json +15 -0
  102. package/connectors/google-drive/src/drive-query.ts +3 -0
  103. package/connectors/google-drive/src/server.ts +531 -0
  104. package/connectors/google-meet/nimbus.extension.json +15 -0
  105. package/connectors/google-meet/src/server.ts +89 -0
  106. package/connectors/google-photos/nimbus.extension.json +15 -0
  107. package/connectors/google-photos/src/server.ts +139 -0
  108. package/connectors/grafana/nimbus.extension.json +15 -0
  109. package/connectors/grafana/src/server.ts +61 -0
  110. package/connectors/great-expectations/nimbus.extension.json +16 -0
  111. package/connectors/great-expectations/src/gx-parse.ts +292 -0
  112. package/connectors/great-expectations/src/server.ts +6 -0
  113. package/connectors/great-expectations/src/tools.ts +91 -0
  114. package/connectors/greenhouse/nimbus.extension.json +15 -0
  115. package/connectors/greenhouse/src/search-filter.ts +65 -0
  116. package/connectors/greenhouse/src/server.ts +67 -0
  117. package/connectors/hubspot/nimbus.extension.json +15 -0
  118. package/connectors/hubspot/src/search-filter.ts +28 -0
  119. package/connectors/hubspot/src/server.ts +81 -0
  120. package/connectors/iac/nimbus.extension.json +14 -0
  121. package/connectors/iac/src/server.ts +145 -0
  122. package/connectors/imap/nimbus.extension.json +16 -0
  123. package/connectors/imap/src/imap-core.ts +110 -0
  124. package/connectors/imap/src/server.ts +232 -0
  125. package/connectors/imap/src/tools.ts +40 -0
  126. package/connectors/intercom/nimbus.extension.json +15 -0
  127. package/connectors/intercom/src/search-filter.ts +46 -0
  128. package/connectors/intercom/src/server.ts +65 -0
  129. package/connectors/jenkins/nimbus.extension.json +15 -0
  130. package/connectors/jenkins/src/jenkins-api.ts +156 -0
  131. package/connectors/jenkins/src/server.ts +223 -0
  132. package/connectors/jira/nimbus.extension.json +15 -0
  133. package/connectors/jira/src/server.ts +309 -0
  134. package/connectors/kubernetes/nimbus.extension.json +15 -0
  135. package/connectors/kubernetes/src/server.ts +163 -0
  136. package/connectors/launchdarkly/nimbus.extension.json +15 -0
  137. package/connectors/launchdarkly/src/search-filter.ts +31 -0
  138. package/connectors/launchdarkly/src/server.ts +79 -0
  139. package/connectors/lever/nimbus.extension.json +15 -0
  140. package/connectors/lever/src/search-filter.ts +35 -0
  141. package/connectors/lever/src/server.ts +64 -0
  142. package/connectors/linear/nimbus.extension.json +15 -0
  143. package/connectors/linear/src/server.ts +467 -0
  144. package/connectors/localdb/nimbus.extension.json +16 -0
  145. package/connectors/localdb/src/server.ts +6 -0
  146. package/connectors/localdb/src/sql-scan.ts +158 -0
  147. package/connectors/localdb/src/tools.ts +67 -0
  148. package/connectors/looker/nimbus.extension.json +16 -0
  149. package/connectors/looker/src/search-filter.ts +22 -0
  150. package/connectors/looker/src/server.ts +254 -0
  151. package/connectors/mendeley/nimbus.extension.json +15 -0
  152. package/connectors/mendeley/src/search-filter.ts +68 -0
  153. package/connectors/mendeley/src/server.ts +59 -0
  154. package/connectors/mercury/nimbus.extension.json +15 -0
  155. package/connectors/mercury/src/search-filter.ts +11 -0
  156. package/connectors/mercury/src/server.ts +61 -0
  157. package/connectors/metabase/nimbus.extension.json +16 -0
  158. package/connectors/metabase/src/search-filter.ts +22 -0
  159. package/connectors/metabase/src/server.ts +83 -0
  160. package/connectors/miro/nimbus.extension.json +15 -0
  161. package/connectors/miro/src/search-filter.ts +24 -0
  162. package/connectors/miro/src/server.ts +76 -0
  163. package/connectors/mlflow/nimbus.extension.json +16 -0
  164. package/connectors/mlflow/src/search-filter.ts +38 -0
  165. package/connectors/mlflow/src/server.ts +167 -0
  166. package/connectors/monte-carlo/nimbus.extension.json +16 -0
  167. package/connectors/monte-carlo/src/search-filter.ts +11 -0
  168. package/connectors/monte-carlo/src/server.ts +241 -0
  169. package/connectors/netlify/nimbus.extension.json +15 -0
  170. package/connectors/netlify/src/search-filter.ts +37 -0
  171. package/connectors/netlify/src/server.ts +64 -0
  172. package/connectors/newrelic/nimbus.extension.json +15 -0
  173. package/connectors/newrelic/src/server.ts +48 -0
  174. package/connectors/notion/nimbus.extension.json +15 -0
  175. package/connectors/notion/src/kb-append.ts +23 -0
  176. package/connectors/notion/src/server.ts +343 -0
  177. package/connectors/obsidian/nimbus.extension.json +19 -0
  178. package/connectors/obsidian/src/server.ts +433 -0
  179. package/connectors/onedrive/nimbus.extension.json +15 -0
  180. package/connectors/onedrive/src/server.ts +256 -0
  181. package/connectors/outlook/nimbus.extension.json +15 -0
  182. package/connectors/outlook/src/server.ts +358 -0
  183. package/connectors/outlook/src/tool-scope-policy.ts +53 -0
  184. package/connectors/pagerduty/nimbus.extension.json +15 -0
  185. package/connectors/pagerduty/src/server.ts +140 -0
  186. package/connectors/pipedrive/nimbus.extension.json +15 -0
  187. package/connectors/pipedrive/src/search-filter.ts +11 -0
  188. package/connectors/pipedrive/src/server.ts +62 -0
  189. package/connectors/powerbi/nimbus.extension.json +16 -0
  190. package/connectors/powerbi/src/search-filter.ts +22 -0
  191. package/connectors/powerbi/src/server.ts +249 -0
  192. package/connectors/prefect/nimbus.extension.json +16 -0
  193. package/connectors/prefect/src/search-filter.ts +40 -0
  194. package/connectors/prefect/src/server.ts +94 -0
  195. package/connectors/protonmail/nimbus.extension.json +16 -0
  196. package/connectors/protonmail/src/mail-core.ts +96 -0
  197. package/connectors/protonmail/src/server.ts +231 -0
  198. package/connectors/protonmail/src/tools.ts +45 -0
  199. package/connectors/raindrop/nimbus.extension.json +15 -0
  200. package/connectors/raindrop/src/search-filter.ts +20 -0
  201. package/connectors/raindrop/src/server.ts +107 -0
  202. package/connectors/ramp/nimbus.extension.json +15 -0
  203. package/connectors/ramp/src/search-filter.ts +37 -0
  204. package/connectors/ramp/src/server.ts +109 -0
  205. package/connectors/readwise/nimbus.extension.json +15 -0
  206. package/connectors/readwise/src/search-filter.ts +64 -0
  207. package/connectors/readwise/src/server.ts +92 -0
  208. package/connectors/sagemaker/nimbus.extension.json +15 -0
  209. package/connectors/sagemaker/src/server.ts +6 -0
  210. package/connectors/sagemaker/src/tools.ts +121 -0
  211. package/connectors/salesforce/nimbus.extension.json +15 -0
  212. package/connectors/salesforce/src/search-filter.ts +23 -0
  213. package/connectors/salesforce/src/server.ts +94 -0
  214. package/connectors/semgrep/nimbus.extension.json +15 -0
  215. package/connectors/semgrep/src/search-filter.ts +31 -0
  216. package/connectors/semgrep/src/server.ts +108 -0
  217. package/connectors/sentry/nimbus.extension.json +15 -0
  218. package/connectors/sentry/src/server.ts +66 -0
  219. package/connectors/slack/nimbus.extension.json +15 -0
  220. package/connectors/slack/src/server.ts +360 -0
  221. package/connectors/snowflake/nimbus.extension.json +16 -0
  222. package/connectors/snowflake/src/search-filter.ts +26 -0
  223. package/connectors/snowflake/src/server.ts +236 -0
  224. package/connectors/snyk/nimbus.extension.json +15 -0
  225. package/connectors/snyk/src/search-filter.ts +28 -0
  226. package/connectors/snyk/src/server.ts +144 -0
  227. package/connectors/sonarqube/nimbus.extension.json +15 -0
  228. package/connectors/sonarqube/src/search-filter.ts +28 -0
  229. package/connectors/sonarqube/src/server.ts +115 -0
  230. package/connectors/stackoverflow/nimbus.extension.json +15 -0
  231. package/connectors/stackoverflow/src/search-filter.ts +52 -0
  232. package/connectors/stackoverflow/src/server.ts +81 -0
  233. package/connectors/storybook/nimbus.extension.json +16 -0
  234. package/connectors/storybook/src/server.ts +6 -0
  235. package/connectors/storybook/src/storybook-parse.ts +67 -0
  236. package/connectors/storybook/src/tools.ts +68 -0
  237. package/connectors/stripe/nimbus.extension.json +15 -0
  238. package/connectors/stripe/src/search-filter.ts +19 -0
  239. package/connectors/stripe/src/server.ts +65 -0
  240. package/connectors/superset/nimbus.extension.json +16 -0
  241. package/connectors/superset/src/search-filter.ts +22 -0
  242. package/connectors/superset/src/server.ts +119 -0
  243. package/connectors/tableau/nimbus.extension.json +16 -0
  244. package/connectors/tableau/src/search-filter.ts +22 -0
  245. package/connectors/tableau/src/server.ts +248 -0
  246. package/connectors/teams/nimbus.extension.json +20 -0
  247. package/connectors/teams/src/bot-send.ts +72 -0
  248. package/connectors/teams/src/server.ts +257 -0
  249. package/connectors/testflight/nimbus.extension.json +15 -0
  250. package/connectors/testflight/src/jwt.ts +27 -0
  251. package/connectors/testflight/src/search-filter.ts +30 -0
  252. package/connectors/testflight/src/server.ts +74 -0
  253. package/connectors/vercel/nimbus.extension.json +15 -0
  254. package/connectors/vercel/src/search-filter.ts +34 -0
  255. package/connectors/vercel/src/server.ts +79 -0
  256. package/connectors/vertex-ai/nimbus.extension.json +15 -0
  257. package/connectors/vertex-ai/src/server.ts +6 -0
  258. package/connectors/vertex-ai/src/tools.ts +145 -0
  259. package/connectors/wiz/nimbus.extension.json +15 -0
  260. package/connectors/wiz/src/search-filter.ts +50 -0
  261. package/connectors/wiz/src/server.ts +192 -0
  262. package/connectors/workday/nimbus.extension.json +19 -0
  263. package/connectors/workday/src/search-filter.ts +5 -0
  264. package/connectors/workday/src/server.ts +78 -0
  265. package/connectors/workday/src/tools.ts +1 -0
  266. package/connectors/zendesk/nimbus.extension.json +16 -0
  267. package/connectors/zendesk/src/search-filter.ts +11 -0
  268. package/connectors/zendesk/src/server.ts +77 -0
  269. package/connectors/zoom/nimbus.extension.json +15 -0
  270. package/connectors/zoom/src/encode-meeting-path.ts +5 -0
  271. package/connectors/zoom/src/recordings-window.ts +34 -0
  272. package/connectors/zoom/src/search-filter.ts +42 -0
  273. package/connectors/zoom/src/server.ts +98 -0
  274. package/connectors/zotero/nimbus.extension.json +15 -0
  275. package/connectors/zotero/src/search-filter.ts +81 -0
  276. package/connectors/zotero/src/server.ts +82 -0
  277. package/package.json +152 -0
  278. package/shared/atlassian-json-fetch.ts +42 -0
  279. package/shared/audit-chain.ts +133 -0
  280. package/shared/connector-mode.ts +60 -0
  281. package/shared/consent-kit.ts +323 -0
  282. package/shared/fetch-bearer-json.ts +18 -0
  283. package/shared/header-safe.ts +28 -0
  284. package/shared/imap-bodystructure.ts +113 -0
  285. package/shared/imap-mail-core.ts +57 -0
  286. package/shared/imap-tool-kit.ts +293 -0
  287. package/shared/join-api-path.ts +18 -0
  288. package/shared/kb-markdown.ts +142 -0
  289. package/shared/mcp-search-tool.ts +37 -0
  290. package/shared/mcp-tool-kit.ts +35 -0
  291. package/shared/nimbus-spawn.ts +128 -0
  292. package/shared/rest-tool-kit.ts +18 -0
  293. package/shared/run-cli-json.ts +55 -0
  294. package/shared/run-read-only-mcp-connector.ts +59 -0
  295. package/shared/safe-cli-arg.ts +55 -0
  296. package/shared/search-filter.ts +140 -0
  297. package/shared/strip-trailing-slashes.ts +7 -0
  298. package/shared/write-scope.ts +58 -0
  299. package/standalone/src/bin.ts +19 -0
  300. package/standalone/src/launcher.ts +186 -0
  301. package/standalone/tsconfig.json +8 -0
@@ -0,0 +1,343 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { z } from "zod";
4
+ import { joinApiPath } from "../../../shared/join-api-path.ts";
5
+ import { parseCitationsJson } from "../../../shared/kb-markdown.ts";
6
+ import {
7
+ createRegisterSimpleTool,
8
+ createZodToolRegistrar,
9
+ mcpJsonResult as jsonResult,
10
+ mcpJsonResultFromTextIfOk,
11
+ parseJsonTextIfOk,
12
+ putOptionalNonEmptyString,
13
+ requireProcessEnv,
14
+ } from "../../../shared/mcp-tool-kit.ts";
15
+ import { buildNotionKbPageBody } from "./kb-append.ts";
16
+
17
+ const NOTION_VERSION = "2022-06-28";
18
+ const API = "https://api.notion.com/v1";
19
+
20
+ async function notionFetch(
21
+ path: string,
22
+ init?: RequestInit,
23
+ ): Promise<{ ok: boolean; status: number; text: string }> {
24
+ const token = requireProcessEnv("NOTION_ACCESS_TOKEN");
25
+ const url = joinApiPath(API, path);
26
+ const headers: Record<string, string> = {
27
+ Authorization: `Bearer ${token}`,
28
+ "Notion-Version": NOTION_VERSION,
29
+ };
30
+ if (init?.body !== undefined) {
31
+ headers["Content-Type"] = "application/json";
32
+ }
33
+ const res = await fetch(url, {
34
+ ...init,
35
+ headers: {
36
+ ...headers,
37
+ ...(init?.headers as Record<string, string> | undefined),
38
+ },
39
+ });
40
+ const text = await res.text();
41
+ return { ok: res.ok, status: res.status, text };
42
+ }
43
+
44
+ function richText(content: string): ReadonlyArray<Record<string, unknown>> {
45
+ return [{ type: "text", text: { content: content.slice(0, 2000) } }];
46
+ }
47
+
48
+ const server = new McpServer({ name: "nimbus-notion", version: "0.1.0" });
49
+
50
+ const registerSimpleTool = createRegisterSimpleTool(server);
51
+
52
+ import { createWriteToolRegistrar } from "../../../shared/consent-kit.ts";
53
+
54
+ const reg = createZodToolRegistrar(registerSimpleTool);
55
+
56
+ /**
57
+ * Every MUTATING notion tool goes through here. Outside the gateway this adds the
58
+ * consent gate, the write-scope allow-list, the mutation budget and the audit record; inside
59
+ * the gateway it is a pass-through, because executor.ts (I2) is the gate there.
60
+ */
61
+ const registerWriteTool = createWriteToolRegistrar(server, {
62
+ connector: "notion",
63
+ scopeEnv: "NIMBUS_MCP_NOTION_WRITE_SCOPE",
64
+ scopeKinds: ["page", "database", "block"],
65
+ });
66
+
67
+ const notionSearchSchema = z.object({
68
+ query: z.string().optional(),
69
+ pageSize: z.number().int().min(1).max(100).optional(),
70
+ startCursor: z.string().optional(),
71
+ });
72
+
73
+ function notionSearchPostBody(
74
+ objectValue: "page" | "database",
75
+ parsed: z.infer<typeof notionSearchSchema>,
76
+ ): Record<string, unknown> {
77
+ const body: Record<string, unknown> = {
78
+ filter: { property: "object", value: objectValue },
79
+ page_size: parsed.pageSize ?? 50,
80
+ };
81
+ putOptionalNonEmptyString(body, "query", parsed.query);
82
+ putOptionalNonEmptyString(body, "start_cursor", parsed.startCursor);
83
+ return body;
84
+ }
85
+
86
+ reg(
87
+ "notion_page_list",
88
+ "Search Notion pages the integration can access (POST /v1/search, object filter page).",
89
+ notionSearchSchema,
90
+ async (parsed) => {
91
+ const body = notionSearchPostBody("page", parsed);
92
+ const res = await notionFetch("/search", { method: "POST", body: JSON.stringify(body) });
93
+ return mcpJsonResultFromTextIfOk("Notion", res);
94
+ },
95
+ );
96
+
97
+ const notionPageIdSchema = z.object({ pageId: z.string().min(1) });
98
+
99
+ reg(
100
+ "notion_page_get",
101
+ "Retrieve a Notion page and its direct child blocks.",
102
+ notionPageIdSchema,
103
+ async (parsed) => {
104
+ const id = encodeURIComponent(parsed.pageId);
105
+ const page = await notionFetch(`/pages/${id}`);
106
+ const blocks = await notionFetch(`/blocks/${id}/children?page_size=100`);
107
+ return jsonResult({
108
+ page: parseJsonTextIfOk("Notion", page),
109
+ blockChildren: parseJsonTextIfOk("Notion blocks", blocks),
110
+ });
111
+ },
112
+ );
113
+
114
+ reg(
115
+ "notion_database_list",
116
+ "Search Notion databases (POST /v1/search, object filter database).",
117
+ notionSearchSchema,
118
+ async (parsed) => {
119
+ const body = notionSearchPostBody("database", parsed);
120
+ const res = await notionFetch("/search", { method: "POST", body: JSON.stringify(body) });
121
+ return mcpJsonResultFromTextIfOk("Notion", res);
122
+ },
123
+ );
124
+
125
+ const notionDatabaseQuerySchema = z.object({
126
+ databaseId: z.string().min(1),
127
+ pageSize: z.number().int().min(1).max(100).optional(),
128
+ startCursor: z.string().optional(),
129
+ });
130
+
131
+ reg(
132
+ "notion_database_query",
133
+ "Query a Notion database (POST /v1/databases/{id}/query).",
134
+ notionDatabaseQuerySchema,
135
+ async (parsed) => {
136
+ const id = encodeURIComponent(parsed.databaseId);
137
+ const body: Record<string, unknown> = {
138
+ page_size: parsed.pageSize ?? 50,
139
+ };
140
+ putOptionalNonEmptyString(body, "start_cursor", parsed.startCursor);
141
+ const res = await notionFetch(`/databases/${id}/query`, {
142
+ method: "POST",
143
+ body: JSON.stringify(body),
144
+ });
145
+ return mcpJsonResultFromTextIfOk("Notion", res);
146
+ },
147
+ );
148
+
149
+ const notionBlockPagedSchema = z.object({
150
+ blockId: z.string().min(1),
151
+ pageSize: z.number().int().min(1).max(100).optional(),
152
+ startCursor: z.string().optional(),
153
+ });
154
+
155
+ reg(
156
+ "notion_block_children",
157
+ "List child blocks of a block or page (GET /v1/blocks/{id}/children).",
158
+ notionBlockPagedSchema,
159
+ async (parsed) => {
160
+ const id = encodeURIComponent(parsed.blockId);
161
+ const qs = new URLSearchParams({
162
+ page_size: String(parsed.pageSize ?? 50),
163
+ });
164
+ if (parsed.startCursor !== undefined && parsed.startCursor !== "") {
165
+ qs.set("start_cursor", parsed.startCursor);
166
+ }
167
+ const res = await notionFetch(`/blocks/${id}/children?${qs.toString()}`);
168
+ return mcpJsonResultFromTextIfOk("Notion", res);
169
+ },
170
+ );
171
+
172
+ reg(
173
+ "notion_comment_list",
174
+ "List comments for a block or page (GET /v1/comments).",
175
+ notionBlockPagedSchema,
176
+ async (parsed) => {
177
+ const qs = new URLSearchParams({
178
+ block_id: parsed.blockId,
179
+ page_size: String(parsed.pageSize ?? 50),
180
+ });
181
+ if (parsed.startCursor !== undefined && parsed.startCursor !== "") {
182
+ qs.set("start_cursor", parsed.startCursor);
183
+ }
184
+ const res = await notionFetch(`/comments?${qs.toString()}`);
185
+ return mcpJsonResultFromTextIfOk("Notion", res);
186
+ },
187
+ );
188
+
189
+ const notionPageCreateSchema = z.object({
190
+ parentPageId: z.string().min(1),
191
+ title: z.string().min(1),
192
+ titlePropertyName: z.string().min(1).optional(),
193
+ });
194
+
195
+ registerWriteTool(
196
+ "notion_page_create",
197
+ {
198
+ mutates: "notion.page.create",
199
+ recoverable: true,
200
+ scopeTargetOf: (p) => ({ kind: "page", value: p.parentPageId }),
201
+ },
202
+ "Create a page under a parent page (POST /v1/pages).",
203
+ notionPageCreateSchema,
204
+ async (parsed) => {
205
+ const prop = parsed.titlePropertyName ?? "title";
206
+ const body = {
207
+ parent: { page_id: parsed.parentPageId },
208
+ properties: {
209
+ [prop]: {
210
+ title: richText(parsed.title),
211
+ },
212
+ },
213
+ };
214
+ const res = await notionFetch("/pages", { method: "POST", body: JSON.stringify(body) });
215
+ return mcpJsonResultFromTextIfOk("Notion", res);
216
+ },
217
+ );
218
+
219
+ const notionKbAppendSchema = z.object({
220
+ databaseId: z.string().min(1),
221
+ title: z.string().min(1),
222
+ bodyMarkdown: z.string().min(1),
223
+ citationsJson: z.string().optional(),
224
+ titlePropertyName: z.string().min(1).optional(),
225
+ });
226
+
227
+ registerWriteTool(
228
+ "notion_kb_append",
229
+ {
230
+ mutates: "notion.knowledge.write",
231
+ recoverable: true,
232
+ scopeTargetOf: (p) => ({ kind: "database", value: p.databaseId }),
233
+ },
234
+ "Create a knowledge-base page in a database from simple markdown + citations (POST /v1/pages). " +
235
+ "Used by Nimbus tribal-knowledge capture; the destination database is supplied by the gateway from local config only.",
236
+ notionKbAppendSchema,
237
+ async (parsed) => {
238
+ const body = buildNotionKbPageBody({
239
+ databaseId: parsed.databaseId,
240
+ title: parsed.title,
241
+ bodyMarkdown: parsed.bodyMarkdown,
242
+ citations: parseCitationsJson(parsed.citationsJson ?? "[]"),
243
+ ...(parsed.titlePropertyName === undefined
244
+ ? {}
245
+ : { titlePropertyName: parsed.titlePropertyName }),
246
+ });
247
+ const res = await notionFetch("/pages", { method: "POST", body: JSON.stringify(body) });
248
+ return mcpJsonResultFromTextIfOk("Notion", res);
249
+ },
250
+ );
251
+
252
+ const notionPageUpdateSchema = z.object({
253
+ pageId: z.string().min(1),
254
+ propertiesJson: z.string().min(1),
255
+ });
256
+
257
+ registerWriteTool(
258
+ "notion_page_update",
259
+ {
260
+ mutates: "notion.page.update",
261
+ recoverable: true,
262
+ scopeTargetOf: (p) => ({ kind: "page", value: p.pageId }),
263
+ },
264
+ "Update page properties (PATCH /v1/pages/{id}). Pass properties JSON as string.",
265
+ notionPageUpdateSchema,
266
+ async (parsed) => {
267
+ let props: unknown;
268
+ try {
269
+ props = JSON.parse(parsed.propertiesJson) as unknown;
270
+ } catch {
271
+ throw new Error("propertiesJson must be valid JSON");
272
+ }
273
+ if (props === null || typeof props !== "object" || Array.isArray(props)) {
274
+ throw new Error("propertiesJson must be a JSON object");
275
+ }
276
+ const id = encodeURIComponent(parsed.pageId);
277
+ const res = await notionFetch(`/pages/${id}`, {
278
+ method: "PATCH",
279
+ body: JSON.stringify({ properties: props }),
280
+ });
281
+ return mcpJsonResultFromTextIfOk("Notion", res);
282
+ },
283
+ );
284
+
285
+ const notionBlockAppendSchema = z.object({
286
+ parentBlockId: z.string().min(1),
287
+ childrenJson: z.string().min(1),
288
+ });
289
+
290
+ registerWriteTool(
291
+ "notion_block_append",
292
+ {
293
+ mutates: "notion.block.append",
294
+ recoverable: true,
295
+ scopeTargetOf: (p) => ({ kind: "block", value: p.parentBlockId }),
296
+ },
297
+ "Append blocks to a parent block (PATCH /v1/blocks/{id}/children). childrenJson is a JSON array of block objects.",
298
+ notionBlockAppendSchema,
299
+ async (parsed) => {
300
+ let children: unknown;
301
+ try {
302
+ children = JSON.parse(parsed.childrenJson) as unknown;
303
+ } catch {
304
+ throw new Error("childrenJson must be valid JSON");
305
+ }
306
+ if (!Array.isArray(children)) {
307
+ throw new TypeError("childrenJson must be a JSON array");
308
+ }
309
+ const id = encodeURIComponent(parsed.parentBlockId);
310
+ const res = await notionFetch(`/blocks/${id}/children`, {
311
+ method: "PATCH",
312
+ body: JSON.stringify({ children }),
313
+ });
314
+ return mcpJsonResultFromTextIfOk("Notion", res);
315
+ },
316
+ );
317
+
318
+ const notionCommentCreateSchema = z.object({
319
+ pageId: z.string().min(1),
320
+ text: z.string().min(1),
321
+ });
322
+
323
+ registerWriteTool(
324
+ "notion_comment_create",
325
+ {
326
+ mutates: "notion.comment.create",
327
+ recoverable: true,
328
+ scopeTargetOf: (p) => ({ kind: "page", value: p.pageId }),
329
+ },
330
+ "Create a comment thread on a page (POST /v1/comments).",
331
+ notionCommentCreateSchema,
332
+ async (parsed) => {
333
+ const body = {
334
+ parent: { page_id: parsed.pageId },
335
+ rich_text: richText(parsed.text),
336
+ };
337
+ const res = await notionFetch("/comments", { method: "POST", body: JSON.stringify(body) });
338
+ return mcpJsonResultFromTextIfOk("Notion", res);
339
+ },
340
+ );
341
+
342
+ const transport = new StdioServerTransport();
343
+ await server.connect(transport);
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "com.nimbus.obsidian",
3
+ "displayName": "Obsidian",
4
+ "version": "0.1.0",
5
+ "description": "Local Obsidian vault connector (notes, backlinks). No network. Vault paths come from [[filesystem.roots]] and are merged into permissions.filesystem at spawn time by the Gateway. obsidian_append_to_daily_note requires HITL.",
6
+ "author": "Nimbus",
7
+ "entrypoint": "dist/server.js",
8
+ "runtime": "bun",
9
+ "permissions": {
10
+ "network": [],
11
+ "filesystem": {
12
+ "read": [],
13
+ "write": []
14
+ }
15
+ },
16
+ "hitlRequired": ["write"],
17
+ "syncInterval": 300,
18
+ "minNimbusVersion": "0.2.0"
19
+ }