@nimbus-dev/connectors 0.2.0 → 0.2.2

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 (215) hide show
  1. package/README.md +18 -4
  2. package/connectors/airflow/src/search-filter.ts +2 -15
  3. package/connectors/airflow/src/server.ts +2 -87
  4. package/connectors/airflow/src/tools.ts +74 -0
  5. package/connectors/apple/src/adapters.ts +326 -0
  6. package/connectors/apple/src/apple-mail-core.ts +4 -8
  7. package/connectors/apple/src/calendar-tools.ts +28 -8
  8. package/connectors/apple/src/server.ts +23 -512
  9. package/connectors/apple/src/tools.ts +18 -44
  10. package/connectors/argocd/src/server.ts +25 -38
  11. package/connectors/athena/src/tools.ts +15 -34
  12. package/connectors/aws/src/server.ts +2 -183
  13. package/connectors/aws/src/tools.ts +197 -0
  14. package/connectors/azure/src/server.ts +2 -131
  15. package/connectors/azure/src/tools.ts +133 -0
  16. package/connectors/bigeye/src/search-filter.ts +4 -15
  17. package/connectors/bigeye/src/server.ts +38 -38
  18. package/connectors/bigquery/src/tools.ts +1 -26
  19. package/connectors/bitbucket/src/server.ts +2 -244
  20. package/connectors/bitbucket/src/tools.ts +241 -0
  21. package/connectors/bitrise/src/server.ts +2 -79
  22. package/connectors/bitrise/src/tools.ts +76 -0
  23. package/connectors/canva/src/search-filter.ts +2 -11
  24. package/connectors/canva/src/server.ts +2 -73
  25. package/connectors/canva/src/tools.ts +66 -0
  26. package/connectors/circleci/src/server.ts +2 -176
  27. package/connectors/circleci/src/tools.ts +193 -0
  28. package/connectors/cloud-logging/src/tools.ts +14 -27
  29. package/connectors/cloudwatch/src/tools.ts +15 -34
  30. package/connectors/codemagic/src/server.ts +2 -70
  31. package/connectors/codemagic/src/tools.ts +71 -0
  32. package/connectors/confluence/src/server.ts +2 -301
  33. package/connectors/confluence/src/tools.ts +320 -0
  34. package/connectors/dagster/src/server.ts +2 -214
  35. package/connectors/dagster/src/tools.ts +187 -0
  36. package/connectors/databricks/src/search-filter.ts +7 -7
  37. package/connectors/databricks/src/server.ts +2 -77
  38. package/connectors/databricks/src/tools.ts +66 -0
  39. package/connectors/datadog/src/server.ts +2 -48
  40. package/connectors/datadog/src/tools.ts +48 -0
  41. package/connectors/dataprofile/src/profile.ts +16 -46
  42. package/connectors/dbt/src/server.ts +2 -92
  43. package/connectors/dbt/src/tools.ts +80 -0
  44. package/connectors/dependencytrack/src/server.ts +2 -76
  45. package/connectors/dependencytrack/src/tools.ts +65 -0
  46. package/connectors/discord/src/server.ts +2 -85
  47. package/connectors/discord/src/tools.ts +82 -0
  48. package/connectors/elasticsearch/src/tools.ts +7 -37
  49. package/connectors/fastmail/src/jmap-client.ts +202 -0
  50. package/connectors/fastmail/src/jmap-core.ts +8 -21
  51. package/connectors/fastmail/src/server.ts +2 -187
  52. package/connectors/fastmail/src/tools.ts +4 -23
  53. package/connectors/figma/src/search-filter.ts +2 -11
  54. package/connectors/figma/src/server.ts +2 -113
  55. package/connectors/figma/src/tools.ts +99 -0
  56. package/connectors/firebase/src/server.ts +2 -90
  57. package/connectors/firebase/src/token.ts +2 -5
  58. package/connectors/firebase/src/tools.ts +106 -0
  59. package/connectors/flagsmith/src/server.ts +2 -98
  60. package/connectors/flagsmith/src/tools.ts +95 -0
  61. package/connectors/flux/src/server.ts +52 -53
  62. package/connectors/gcp/src/server.ts +2 -132
  63. package/connectors/gcp/src/tools.ts +123 -0
  64. package/connectors/github/src/server.ts +2 -328
  65. package/connectors/github/src/tools.ts +311 -0
  66. package/connectors/github-actions/src/server.ts +2 -205
  67. package/connectors/github-actions/src/tools.ts +209 -0
  68. package/connectors/gitlab/src/server.ts +2 -384
  69. package/connectors/gitlab/src/tools.ts +392 -0
  70. package/connectors/gmail/src/server.ts +2 -270
  71. package/connectors/gmail/src/tools.ts +209 -0
  72. package/connectors/google-drive/src/server.ts +2 -524
  73. package/connectors/google-drive/src/tools.ts +529 -0
  74. package/connectors/google-meet/src/server.ts +2 -82
  75. package/connectors/google-meet/src/tools.ts +87 -0
  76. package/connectors/google-photos/src/server.ts +2 -132
  77. package/connectors/google-photos/src/tools.ts +138 -0
  78. package/connectors/grafana/src/server.ts +2 -53
  79. package/connectors/grafana/src/tools.ts +53 -0
  80. package/connectors/great-expectations/src/gx-parse.ts +14 -45
  81. package/connectors/greenhouse/src/server.ts +2 -63
  82. package/connectors/greenhouse/src/tools.ts +68 -0
  83. package/connectors/hubspot/src/server.ts +2 -77
  84. package/connectors/hubspot/src/tools.ts +70 -0
  85. package/connectors/iac/src/server.ts +2 -137
  86. package/connectors/iac/src/tools.ts +152 -0
  87. package/connectors/imap/src/imap-core.ts +29 -82
  88. package/connectors/imap/src/server.ts +33 -220
  89. package/connectors/intercom/src/server.ts +2 -61
  90. package/connectors/intercom/src/tools.ts +58 -0
  91. package/connectors/jenkins/src/jenkins-api.ts +2 -6
  92. package/connectors/jenkins/src/server.ts +2 -215
  93. package/connectors/jenkins/src/tools.ts +240 -0
  94. package/connectors/jira/src/server.ts +2 -301
  95. package/connectors/jira/src/tools.ts +325 -0
  96. package/connectors/kubernetes/src/server.ts +2 -155
  97. package/connectors/kubernetes/src/tools.ts +159 -0
  98. package/connectors/launchdarkly/src/server.ts +2 -75
  99. package/connectors/launchdarkly/src/tools.ts +72 -0
  100. package/connectors/lever/src/search-filter.ts +4 -12
  101. package/connectors/lever/src/server.ts +2 -60
  102. package/connectors/lever/src/tools.ts +61 -0
  103. package/connectors/linear/src/server.ts +2 -459
  104. package/connectors/linear/src/tools.ts +482 -0
  105. package/connectors/localdb/src/sql-scan.ts +13 -41
  106. package/connectors/localdb/src/tools.ts +1 -1
  107. package/connectors/looker/src/search-filter.ts +2 -15
  108. package/connectors/looker/src/server.ts +35 -70
  109. package/connectors/mendeley/src/server.ts +2 -55
  110. package/connectors/mendeley/src/tools.ts +54 -0
  111. package/connectors/mercury/src/server.ts +2 -57
  112. package/connectors/mercury/src/tools.ts +50 -0
  113. package/connectors/metabase/src/search-filter.ts +4 -15
  114. package/connectors/metabase/src/server.ts +2 -79
  115. package/connectors/metabase/src/tools.ts +64 -0
  116. package/connectors/miro/src/server.ts +2 -72
  117. package/connectors/miro/src/tools.ts +65 -0
  118. package/connectors/mlflow/src/search-filter.ts +3 -7
  119. package/connectors/mlflow/src/server.ts +20 -40
  120. package/connectors/monte-carlo/src/server.ts +50 -57
  121. package/connectors/netlify/src/search-filter.ts +6 -14
  122. package/connectors/netlify/src/server.ts +2 -60
  123. package/connectors/netlify/src/tools.ts +53 -0
  124. package/connectors/newrelic/src/server.ts +2 -40
  125. package/connectors/newrelic/src/tools.ts +37 -0
  126. package/connectors/notion/src/server.ts +2 -335
  127. package/connectors/notion/src/tools.ts +344 -0
  128. package/connectors/obsidian/src/server.ts +2 -425
  129. package/connectors/obsidian/src/tools.ts +466 -0
  130. package/connectors/onedrive/src/server.ts +2 -249
  131. package/connectors/onedrive/src/tools.ts +253 -0
  132. package/connectors/outlook/src/server.ts +2 -351
  133. package/connectors/outlook/src/tools.ts +357 -0
  134. package/connectors/pagerduty/src/server.ts +2 -132
  135. package/connectors/pagerduty/src/tools.ts +126 -0
  136. package/connectors/pipedrive/src/server.ts +2 -58
  137. package/connectors/pipedrive/src/tools.ts +63 -0
  138. package/connectors/powerbi/src/search-filter.ts +2 -15
  139. package/connectors/powerbi/src/server.ts +43 -68
  140. package/connectors/prefect/src/search-filter.ts +3 -16
  141. package/connectors/prefect/src/server.ts +2 -90
  142. package/connectors/prefect/src/tools.ts +83 -0
  143. package/connectors/protonmail/src/mail-core.ts +16 -75
  144. package/connectors/protonmail/src/server.ts +34 -214
  145. package/connectors/raindrop/src/server.ts +2 -103
  146. package/connectors/raindrop/src/tools.ts +103 -0
  147. package/connectors/ramp/src/server.ts +2 -105
  148. package/connectors/ramp/src/tools.ts +98 -0
  149. package/connectors/readwise/src/server.ts +2 -88
  150. package/connectors/readwise/src/tools.ts +81 -0
  151. package/connectors/sagemaker/src/tools.ts +19 -38
  152. package/connectors/salesforce/src/search-filter.ts +4 -11
  153. package/connectors/salesforce/src/server.ts +2 -90
  154. package/connectors/salesforce/src/tools.ts +75 -0
  155. package/connectors/semgrep/src/search-filter.ts +3 -10
  156. package/connectors/semgrep/src/server.ts +2 -104
  157. package/connectors/semgrep/src/tools.ts +92 -0
  158. package/connectors/sentry/src/server.ts +2 -58
  159. package/connectors/sentry/src/tools.ts +53 -0
  160. package/connectors/slack/src/server.ts +2 -352
  161. package/connectors/slack/src/tools.ts +376 -0
  162. package/connectors/snowflake/src/search-filter.ts +4 -19
  163. package/connectors/snowflake/src/server.ts +6 -25
  164. package/connectors/snyk/src/server.ts +2 -140
  165. package/connectors/snyk/src/tools.ts +136 -0
  166. package/connectors/sonarqube/src/server.ts +2 -111
  167. package/connectors/sonarqube/src/tools.ts +98 -0
  168. package/connectors/stackoverflow/src/server.ts +2 -77
  169. package/connectors/stackoverflow/src/tools.ts +66 -0
  170. package/connectors/storybook/src/storybook-parse.ts +3 -6
  171. package/connectors/stripe/src/server.ts +2 -61
  172. package/connectors/stripe/src/tools.ts +54 -0
  173. package/connectors/superset/src/search-filter.ts +4 -15
  174. package/connectors/superset/src/server.ts +2 -115
  175. package/connectors/superset/src/tools.ts +98 -0
  176. package/connectors/tableau/src/search-filter.ts +2 -15
  177. package/connectors/tableau/src/server.ts +13 -65
  178. package/connectors/teams/src/server.ts +2 -249
  179. package/connectors/teams/src/tools.ts +283 -0
  180. package/connectors/testflight/src/server.ts +2 -70
  181. package/connectors/testflight/src/tools.ts +79 -0
  182. package/connectors/vercel/src/search-filter.ts +2 -10
  183. package/connectors/vercel/src/server.ts +2 -75
  184. package/connectors/vercel/src/tools.ts +73 -0
  185. package/connectors/vertex-ai/src/tools.ts +23 -33
  186. package/connectors/wiz/src/search-filter.ts +6 -30
  187. package/connectors/wiz/src/server.ts +2 -188
  188. package/connectors/wiz/src/tools.ts +168 -0
  189. package/connectors/zendesk/src/server.ts +2 -73
  190. package/connectors/zendesk/src/tools.ts +60 -0
  191. package/connectors/zoom/src/search-filter.ts +1 -7
  192. package/connectors/zoom/src/server.ts +2 -94
  193. package/connectors/zoom/src/tools.ts +93 -0
  194. package/connectors/zotero/src/server.ts +2 -78
  195. package/connectors/zotero/src/tools.ts +67 -0
  196. package/package.json +15 -12
  197. package/shared/access-token-cache.ts +123 -0
  198. package/shared/atlassian-json-fetch.ts +6 -16
  199. package/shared/audit-chain.ts +13 -6
  200. package/shared/cli-json-kit.ts +150 -0
  201. package/shared/collection-tool-kit.ts +143 -0
  202. package/shared/connector-mode.ts +3 -2
  203. package/shared/cursor-list-tool.ts +29 -0
  204. package/shared/env-json-api.ts +209 -0
  205. package/shared/fetch-json-text.ts +27 -0
  206. package/shared/github-rest.ts +62 -0
  207. package/shared/graphql-json.ts +60 -0
  208. package/shared/imap-mail-core.ts +91 -0
  209. package/shared/imap-tool-kit.ts +57 -23
  210. package/shared/imapflow-adapter.ts +417 -0
  211. package/shared/rest-tool-kit.ts +77 -7
  212. package/shared/run-cli-json.ts +38 -16
  213. package/shared/search-filter.ts +58 -18
  214. package/shared/walk-files.ts +118 -0
  215. package/standalone/src/launcher.ts +19 -7
@@ -1,358 +1,9 @@
1
- /**
2
- * nimbus-connector outlook — Microsoft Graph mail, calendar, contacts (read + guarded writes).
3
- * Access token is injected as MICROSOFT_OAUTH_ACCESS_TOKEN (never logged).
4
- * Optional `MICROSOFT_OAUTH_SCOPES` (space-separated) gates which tools register; the Gateway
5
- * audit-ignore-next-line D11-vault-key (JSDoc reference, not vault-key construction)
6
- * sets it from `microsoft.oauth` JSON when `scopes` is present.
7
- * Send / calendar mutations require Gateway HITL (email.send, calendar.event.create | delete).
8
- */
9
-
10
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
11
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
12
- import { z } from "zod";
13
- import { headerLine } from "../../../shared/header-safe.ts";
14
- import {
15
- createRegisterSimpleTool,
16
- createZodToolRegistrar,
17
- mcpJsonResult,
18
- mcpJsonResultIfOk,
19
- requireProcessEnv,
20
- type ZodObjectSchema,
21
- } from "../../../shared/mcp-tool-kit.ts";
22
- import { makeRestFetcher, makeRestToolRegistrar } from "../../../shared/rest-tool-kit.ts";
23
- import {
24
- outlookToolShouldRegister,
25
- parseMicrosoftOAuthScopesFromEnv,
26
- } from "./tool-scope-policy.ts";
27
-
28
- const GRAPH = "https://graph.microsoft.com/v1.0";
29
-
30
- function graphRequest(
31
- token: string,
32
- pathOrUrl: string,
33
- init?: RequestInit,
34
- ): Promise<{ ok: boolean; status: number; json: unknown; text: string }> {
35
- return makeRestFetcher({ apiBase: GRAPH, token })(pathOrUrl, init);
36
- }
3
+ import { registerOutlookTools } from "./tools.ts";
37
4
 
38
5
  const server = new McpServer({ name: "nimbus-outlook", version: "0.1.0" });
39
6
 
40
- const reg = createZodToolRegistrar(createRegisterSimpleTool(server));
41
- const grantedOutlookScopes = parseMicrosoftOAuthScopesFromEnv();
42
-
43
- /** Standard Graph read tool: token → graphRequest(buildPath[, buildInit]) → mcpJsonResultIfOk("Graph", …, 200). */
44
- import { createWriteToolRegistrar, type WriteToolConfig } from "../../../shared/consent-kit.ts";
45
-
46
- /**
47
- * Every MUTATING outlook tool goes through here. Outside the gateway this adds the
48
- * consent gate, the write-scope allow-list, the mutation budget and the audit record; inside
49
- * the gateway it is a pass-through, because executor.ts (I2) is the gate there.
50
- */
51
- const registerWriteTool = createWriteToolRegistrar(server, {
52
- connector: "outlook",
53
- scopeEnv: "NIMBUS_MCP_OUTLOOK_WRITE_SCOPE",
54
- scopeKinds: ["recipient", "calendar"],
55
- });
56
-
57
- /**
58
- * The write-tool equivalent of `registerOutlookTool`: identical fetch and result handling, routed
59
- * through the write registrar.
60
- */
61
- function registerOutlookWriteTool<T>(
62
- name: string,
63
- cfg: WriteToolConfig<T>,
64
- description: string,
65
- schema: ZodObjectSchema<T>,
66
- buildPath: (p: T) => string,
67
- buildInit?: (p: T) => RequestInit,
68
- ): void {
69
- registerWriteTool(name, cfg, description, schema, async (parsed) => {
70
- const token = requireProcessEnv("MICROSOFT_OAUTH_ACCESS_TOKEN");
71
- const res = await graphRequest(token, buildPath(parsed), buildInit?.(parsed));
72
- return mcpJsonResultIfOk("Graph", res, 200);
73
- });
74
- }
75
-
76
- const registerOutlookTool = makeRestToolRegistrar({
77
- registrar: reg,
78
- tokenEnv: "MICROSOFT_OAUTH_ACCESS_TOKEN",
79
- serviceLabel: "Graph",
80
- fetch: graphRequest,
81
- snippetMax: 200,
82
- });
83
-
84
- const outlookMailFoldersArgs = z.object({
85
- top: z.number().int().min(1).max(200).optional(),
86
- nextLink: z.url().optional(),
87
- });
88
-
89
- if (outlookToolShouldRegister("outlook_mail_folders", grantedOutlookScopes)) {
90
- registerOutlookTool(
91
- "outlook_mail_folders",
92
- "List mail folders (pagination via nextLink).",
93
- outlookMailFoldersArgs,
94
- (data) => {
95
- if (data.nextLink !== undefined && data.nextLink !== "") {
96
- return data.nextLink;
97
- }
98
- const top = data.top ?? 50;
99
- return `/me/mailFolders?$top=${String(top)}`;
100
- },
101
- );
102
- }
103
-
104
- const outlookMailListArgs = z.object({
105
- folderId: z.string().min(1).optional(),
106
- top: z.number().int().min(1).max(100).optional(),
107
- skip: z.number().int().min(0).optional(),
108
- nextLink: z.url().optional(),
109
- filter: z.string().max(500).optional(),
110
- });
111
-
112
- if (outlookToolShouldRegister("outlook_mail_list", grantedOutlookScopes)) {
113
- registerOutlookTool(
114
- "outlook_mail_list",
115
- "List mail messages (default folder inbox if folderId omitted). Pagination via nextLink.",
116
- outlookMailListArgs,
117
- (data) => {
118
- if (data.nextLink !== undefined && data.nextLink !== "") {
119
- return data.nextLink;
120
- }
121
- const top = data.top ?? 25;
122
- const fid = data.folderId !== undefined && data.folderId !== "" ? data.folderId : "inbox";
123
- const skip = data.skip ?? 0;
124
- const u = new URL(`${GRAPH}/me/mailFolders/${encodeURIComponent(fid)}/messages`);
125
- u.searchParams.set("$top", String(top));
126
- u.searchParams.set("$skip", String(skip));
127
- u.searchParams.set(
128
- "$select",
129
- "id,subject,bodyPreview,receivedDateTime,lastModifiedDateTime,hasAttachments,webLink",
130
- );
131
- if (data.filter !== undefined && data.filter !== "") {
132
- u.searchParams.set("$filter", data.filter);
133
- }
134
- return `${u.pathname}${u.search}`;
135
- },
136
- );
137
- }
138
-
139
- const outlookMailReadArgs = z.object({
140
- messageId: z.string().min(1),
141
- });
142
-
143
- if (outlookToolShouldRegister("outlook_mail_read", grantedOutlookScopes)) {
144
- registerOutlookTool(
145
- "outlook_mail_read",
146
- "Read a single message (body, headers, attachments metadata).",
147
- outlookMailReadArgs,
148
- (data) => `/me/messages/${encodeURIComponent(data.messageId)}?$expand=attachments`,
149
- );
150
- }
151
-
152
- const outlookMailSendArgs = z.object({
153
- to: headerLine({ min: 1, max: 2000 }),
154
- subject: headerLine({ min: 1, max: 500 }),
155
- body: z.string().min(1).max(1_000_000),
156
- contentType: z.enum(["text", "html"]).optional(),
157
- cc: headerLine({ max: 2000 }).optional(),
158
- });
159
-
160
- if (outlookToolShouldRegister("outlook_mail_send", grantedOutlookScopes)) {
161
- registerWriteTool(
162
- "outlook_mail_send",
163
- {
164
- mutates: "outlook.mail.send",
165
- recoverable: false,
166
- capturePreState: (p) => Promise.resolve({ to: p.to, subject: p.subject }),
167
- scopeTargetOf: (p) => ({ kind: "recipient", value: p.to }),
168
- },
169
- "Send an email via Microsoft Graph. Requires Gateway HITL email.send.",
170
- outlookMailSendArgs,
171
- async (data) => {
172
- const token = requireProcessEnv("MICROSOFT_OAUTH_ACCESS_TOKEN");
173
- const toList = data.to
174
- .split(",")
175
- .map((s) => s.trim())
176
- .filter((s) => s.length > 0);
177
- const message: Record<string, unknown> = {
178
- subject: data.subject,
179
- body: {
180
- contentType: (data.contentType ?? "text") === "html" ? "HTML" : "Text",
181
- content: data.body,
182
- },
183
- toRecipients: toList.map((addr) => ({
184
- emailAddress: { address: addr },
185
- })),
186
- };
187
- if (data.cc !== undefined && data.cc !== "") {
188
- const ccList = data.cc
189
- .split(",")
190
- .map((s) => s.trim())
191
- .filter((s) => s.length > 0);
192
- message["ccRecipients"] = ccList.map((addr) => ({
193
- emailAddress: { address: addr },
194
- }));
195
- }
196
- const r = await graphRequest(token, "/me/sendMail", {
197
- method: "POST",
198
- headers: { "Content-Type": "application/json" },
199
- body: JSON.stringify({ message, saveToSentItems: true }),
200
- });
201
- if (!r.ok) {
202
- throw new Error(`Graph ${String(r.status)}: ${r.text.slice(0, 200)}`);
203
- }
204
- return mcpJsonResult({ ok: true });
205
- },
206
- );
207
- }
208
-
209
- const outlookCalendarListArgs = z.object({
210
- startDateTime: z.string().min(1),
211
- endDateTime: z.string().min(1),
212
- top: z.number().int().min(1).max(200).optional(),
213
- nextLink: z.url().optional(),
214
- });
215
-
216
- if (outlookToolShouldRegister("outlook_calendar_list", grantedOutlookScopes)) {
217
- registerOutlookTool(
218
- "outlook_calendar_list",
219
- "List calendar events in a time window (ISO 8601 startDateTime / endDateTime).",
220
- outlookCalendarListArgs,
221
- (data) => {
222
- if (data.nextLink !== undefined && data.nextLink !== "") {
223
- return data.nextLink;
224
- }
225
- const top = data.top ?? 50;
226
- const s = encodeURIComponent(data.startDateTime);
227
- const e = encodeURIComponent(data.endDateTime);
228
- return `/me/calendarView?startDateTime=${s}&endDateTime=${e}&$top=${String(top)}`;
229
- },
230
- );
231
- }
232
-
233
- const outlookCalendarGetArgs = z.object({
234
- eventId: z.string().min(1),
235
- });
236
-
237
- if (outlookToolShouldRegister("outlook_calendar_get", grantedOutlookScopes)) {
238
- registerOutlookTool(
239
- "outlook_calendar_get",
240
- "Get a single calendar event by id.",
241
- outlookCalendarGetArgs,
242
- (data) => `/me/events/${encodeURIComponent(data.eventId)}`,
243
- );
244
- }
245
-
246
- const outlookCalendarCreateArgs = z.object({
247
- subject: headerLine({ min: 1, max: 500 }),
248
- startDateTime: z.string().min(1),
249
- endDateTime: z.string().min(1),
250
- timeZone: z.string().min(1).max(100).optional(),
251
- body: z.string().max(50_000).optional(),
252
- attendees: headerLine({ max: 4000 }).optional(),
253
- });
254
-
255
- if (outlookToolShouldRegister("outlook_calendar_create", grantedOutlookScopes)) {
256
- registerOutlookWriteTool(
257
- "outlook_calendar_create",
258
- {
259
- mutates: "outlook.calendar.create",
260
- recoverable: true,
261
- scopeTargetOf: (p) => ({ kind: "calendar", value: p.subject }),
262
- },
263
- "Create a calendar event. Requires Gateway HITL calendar.event.create.",
264
- outlookCalendarCreateArgs,
265
- () => "/me/events",
266
- (data) => {
267
- const tz = data.timeZone ?? "UTC";
268
- const body: Record<string, unknown> = {
269
- subject: data.subject,
270
- start: { dateTime: data.startDateTime, timeZone: tz },
271
- end: { dateTime: data.endDateTime, timeZone: tz },
272
- };
273
- if (data.body !== undefined && data.body !== "") {
274
- body["body"] = { contentType: "Text", content: data.body };
275
- }
276
- if (data.attendees !== undefined && data.attendees !== "") {
277
- const addrs = data.attendees
278
- .split(",")
279
- .map((s) => s.trim())
280
- .filter((s) => s.length > 0);
281
- body["attendees"] = addrs.map((a) => ({
282
- emailAddress: { address: a },
283
- type: "required",
284
- }));
285
- }
286
- return {
287
- method: "POST",
288
- headers: { "Content-Type": "application/json" },
289
- body: JSON.stringify(body),
290
- };
291
- },
292
- );
293
- }
294
-
295
- const outlookCalendarDeleteArgs = z.object({
296
- eventId: z.string().min(1),
297
- });
298
-
299
- if (outlookToolShouldRegister("outlook_calendar_delete", grantedOutlookScopes)) {
300
- registerWriteTool(
301
- "outlook_calendar_delete",
302
- {
303
- mutates: "outlook.calendar.delete",
304
- recoverable: false,
305
- capturePreState: (p) => Promise.resolve({ eventId: p.eventId }),
306
- scopeTargetOf: (p) => ({ kind: "calendar", value: p.eventId }),
307
- },
308
- "Delete a calendar event. Requires Gateway HITL calendar.event.delete.",
309
- outlookCalendarDeleteArgs,
310
- async (data) => {
311
- const token = requireProcessEnv("MICROSOFT_OAUTH_ACCESS_TOKEN");
312
- const r = await graphRequest(token, `/me/events/${encodeURIComponent(data.eventId)}`, {
313
- method: "DELETE",
314
- });
315
- if (!r.ok && r.status !== 204) {
316
- throw new Error(`Graph ${String(r.status)}: ${r.text.slice(0, 200)}`);
317
- }
318
- return mcpJsonResult({ ok: true });
319
- },
320
- );
321
- }
322
-
323
- const outlookContactListArgs = z.object({
324
- top: z.number().int().min(1).max(200).optional(),
325
- skip: z.number().int().min(0).optional(),
326
- nextLink: z.url().optional(),
327
- });
328
-
329
- if (outlookToolShouldRegister("outlook_contact_list", grantedOutlookScopes)) {
330
- registerOutlookTool(
331
- "outlook_contact_list",
332
- "List contacts from the default folder.",
333
- outlookContactListArgs,
334
- (data) => {
335
- if (data.nextLink !== undefined && data.nextLink !== "") {
336
- return data.nextLink;
337
- }
338
- const top = data.top ?? 50;
339
- const skip = data.skip ?? 0;
340
- return `/me/contacts?$top=${String(top)}&$skip=${String(skip)}`;
341
- },
342
- );
343
- }
344
-
345
- const outlookContactGetArgs = z.object({
346
- contactId: z.string().min(1),
347
- });
348
-
349
- if (outlookToolShouldRegister("outlook_contact_get", grantedOutlookScopes)) {
350
- registerOutlookTool(
351
- "outlook_contact_get",
352
- "Get a single contact by id.",
353
- outlookContactGetArgs,
354
- (data) => `/me/contacts/${encodeURIComponent(data.contactId)}`,
355
- );
356
- }
7
+ registerOutlookTools(server);
357
8
 
358
9
  await server.connect(new StdioServerTransport());