@jbctechsolutions/mcp-office365 2.5.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.
Files changed (339) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +667 -0
  3. package/dist/applescript/account-repository.d.ts +30 -0
  4. package/dist/applescript/account-repository.d.ts.map +1 -0
  5. package/dist/applescript/account-repository.js +38 -0
  6. package/dist/applescript/account-repository.js.map +1 -0
  7. package/dist/applescript/account-scripts.d.ts +21 -0
  8. package/dist/applescript/account-scripts.d.ts.map +1 -0
  9. package/dist/applescript/account-scripts.js +180 -0
  10. package/dist/applescript/account-scripts.js.map +1 -0
  11. package/dist/applescript/calendar-manager.d.ts +44 -0
  12. package/dist/applescript/calendar-manager.d.ts.map +1 -0
  13. package/dist/applescript/calendar-manager.js +92 -0
  14. package/dist/applescript/calendar-manager.js.map +1 -0
  15. package/dist/applescript/calendar-writer.d.ts +36 -0
  16. package/dist/applescript/calendar-writer.d.ts.map +1 -0
  17. package/dist/applescript/calendar-writer.js +94 -0
  18. package/dist/applescript/calendar-writer.js.map +1 -0
  19. package/dist/applescript/content-readers.d.ts +114 -0
  20. package/dist/applescript/content-readers.d.ts.map +1 -0
  21. package/dist/applescript/content-readers.js +328 -0
  22. package/dist/applescript/content-readers.js.map +1 -0
  23. package/dist/applescript/executor.d.ts +60 -0
  24. package/dist/applescript/executor.d.ts.map +1 -0
  25. package/dist/applescript/executor.js +173 -0
  26. package/dist/applescript/executor.js.map +1 -0
  27. package/dist/applescript/index.d.ts +20 -0
  28. package/dist/applescript/index.d.ts.map +1 -0
  29. package/dist/applescript/index.js +29 -0
  30. package/dist/applescript/index.js.map +1 -0
  31. package/dist/applescript/mail-sender.d.ts +38 -0
  32. package/dist/applescript/mail-sender.d.ts.map +1 -0
  33. package/dist/applescript/mail-sender.js +67 -0
  34. package/dist/applescript/mail-sender.js.map +1 -0
  35. package/dist/applescript/parser.d.ts +235 -0
  36. package/dist/applescript/parser.d.ts.map +1 -0
  37. package/dist/applescript/parser.js +496 -0
  38. package/dist/applescript/parser.js.map +1 -0
  39. package/dist/applescript/repository.d.ts +64 -0
  40. package/dist/applescript/repository.d.ts.map +1 -0
  41. package/dist/applescript/repository.js +444 -0
  42. package/dist/applescript/repository.js.map +1 -0
  43. package/dist/applescript/scripts.d.ts +265 -0
  44. package/dist/applescript/scripts.d.ts.map +1 -0
  45. package/dist/applescript/scripts.js +1483 -0
  46. package/dist/applescript/scripts.js.map +1 -0
  47. package/dist/approval/hash.d.ts +87 -0
  48. package/dist/approval/hash.d.ts.map +1 -0
  49. package/dist/approval/hash.js +102 -0
  50. package/dist/approval/hash.js.map +1 -0
  51. package/dist/approval/index.d.ts +13 -0
  52. package/dist/approval/index.d.ts.map +1 -0
  53. package/dist/approval/index.js +7 -0
  54. package/dist/approval/index.js.map +1 -0
  55. package/dist/approval/token-manager.d.ts +51 -0
  56. package/dist/approval/token-manager.d.ts.map +1 -0
  57. package/dist/approval/token-manager.js +111 -0
  58. package/dist/approval/token-manager.js.map +1 -0
  59. package/dist/approval/types.d.ts +44 -0
  60. package/dist/approval/types.d.ts.map +1 -0
  61. package/dist/approval/types.js +6 -0
  62. package/dist/approval/types.js.map +1 -0
  63. package/dist/cli.d.ts +30 -0
  64. package/dist/cli.d.ts.map +1 -0
  65. package/dist/cli.js +143 -0
  66. package/dist/cli.js.map +1 -0
  67. package/dist/config.d.ts +27 -0
  68. package/dist/config.d.ts.map +1 -0
  69. package/dist/config.js +42 -0
  70. package/dist/config.js.map +1 -0
  71. package/dist/database/connection.d.ts +77 -0
  72. package/dist/database/connection.d.ts.map +1 -0
  73. package/dist/database/connection.js +130 -0
  74. package/dist/database/connection.js.map +1 -0
  75. package/dist/database/index.d.ts +11 -0
  76. package/dist/database/index.d.ts.map +1 -0
  77. package/dist/database/index.js +11 -0
  78. package/dist/database/index.js.map +1 -0
  79. package/dist/database/queries.d.ts +93 -0
  80. package/dist/database/queries.d.ts.map +1 -0
  81. package/dist/database/queries.js +430 -0
  82. package/dist/database/queries.js.map +1 -0
  83. package/dist/database/repository.d.ts +198 -0
  84. package/dist/database/repository.d.ts.map +1 -0
  85. package/dist/database/repository.js +199 -0
  86. package/dist/database/repository.js.map +1 -0
  87. package/dist/graph/attachments.d.ts +72 -0
  88. package/dist/graph/attachments.d.ts.map +1 -0
  89. package/dist/graph/attachments.js +207 -0
  90. package/dist/graph/attachments.js.map +1 -0
  91. package/dist/graph/auth/config.d.ts +34 -0
  92. package/dist/graph/auth/config.d.ts.map +1 -0
  93. package/dist/graph/auth/config.js +78 -0
  94. package/dist/graph/auth/config.js.map +1 -0
  95. package/dist/graph/auth/device-code-flow.d.ts +55 -0
  96. package/dist/graph/auth/device-code-flow.d.ts.map +1 -0
  97. package/dist/graph/auth/device-code-flow.js +180 -0
  98. package/dist/graph/auth/device-code-flow.js.map +1 -0
  99. package/dist/graph/auth/index.d.ts +13 -0
  100. package/dist/graph/auth/index.d.ts.map +1 -0
  101. package/dist/graph/auth/index.js +13 -0
  102. package/dist/graph/auth/index.js.map +1 -0
  103. package/dist/graph/auth/token-cache.d.ts +41 -0
  104. package/dist/graph/auth/token-cache.d.ts.map +1 -0
  105. package/dist/graph/auth/token-cache.js +105 -0
  106. package/dist/graph/auth/token-cache.js.map +1 -0
  107. package/dist/graph/client/batch.d.ts +38 -0
  108. package/dist/graph/client/batch.d.ts.map +1 -0
  109. package/dist/graph/client/batch.js +33 -0
  110. package/dist/graph/client/batch.js.map +1 -0
  111. package/dist/graph/client/cache.d.ts +64 -0
  112. package/dist/graph/client/cache.d.ts.map +1 -0
  113. package/dist/graph/client/cache.js +108 -0
  114. package/dist/graph/client/cache.js.map +1 -0
  115. package/dist/graph/client/graph-client.d.ts +630 -0
  116. package/dist/graph/client/graph-client.d.ts.map +1 -0
  117. package/dist/graph/client/graph-client.js +1771 -0
  118. package/dist/graph/client/graph-client.js.map +1 -0
  119. package/dist/graph/client/index.d.ts +12 -0
  120. package/dist/graph/client/index.d.ts.map +1 -0
  121. package/dist/graph/client/index.js +12 -0
  122. package/dist/graph/client/index.js.map +1 -0
  123. package/dist/graph/content-readers.d.ts +106 -0
  124. package/dist/graph/content-readers.d.ts.map +1 -0
  125. package/dist/graph/content-readers.js +321 -0
  126. package/dist/graph/content-readers.js.map +1 -0
  127. package/dist/graph/index.d.ts +18 -0
  128. package/dist/graph/index.d.ts.map +1 -0
  129. package/dist/graph/index.js +23 -0
  130. package/dist/graph/index.js.map +1 -0
  131. package/dist/graph/mailbox-adapter.d.ts +30 -0
  132. package/dist/graph/mailbox-adapter.d.ts.map +1 -0
  133. package/dist/graph/mailbox-adapter.js +59 -0
  134. package/dist/graph/mailbox-adapter.js.map +1 -0
  135. package/dist/graph/mappers/contact-mapper.d.ts +14 -0
  136. package/dist/graph/mappers/contact-mapper.d.ts.map +1 -0
  137. package/dist/graph/mappers/contact-mapper.js +20 -0
  138. package/dist/graph/mappers/contact-mapper.js.map +1 -0
  139. package/dist/graph/mappers/email-mapper.d.ts +14 -0
  140. package/dist/graph/mappers/email-mapper.d.ts.map +1 -0
  141. package/dist/graph/mappers/email-mapper.js +44 -0
  142. package/dist/graph/mappers/email-mapper.js.map +1 -0
  143. package/dist/graph/mappers/event-mapper.d.ts +14 -0
  144. package/dist/graph/mappers/event-mapper.d.ts.map +1 -0
  145. package/dist/graph/mappers/event-mapper.js +31 -0
  146. package/dist/graph/mappers/event-mapper.js.map +1 -0
  147. package/dist/graph/mappers/folder-mapper.d.ts +22 -0
  148. package/dist/graph/mappers/folder-mapper.d.ts.map +1 -0
  149. package/dist/graph/mappers/folder-mapper.js +51 -0
  150. package/dist/graph/mappers/folder-mapper.js.map +1 -0
  151. package/dist/graph/mappers/index.d.ts +16 -0
  152. package/dist/graph/mappers/index.d.ts.map +1 -0
  153. package/dist/graph/mappers/index.js +16 -0
  154. package/dist/graph/mappers/index.js.map +1 -0
  155. package/dist/graph/mappers/task-mapper.d.ts +20 -0
  156. package/dist/graph/mappers/task-mapper.d.ts.map +1 -0
  157. package/dist/graph/mappers/task-mapper.js +27 -0
  158. package/dist/graph/mappers/task-mapper.js.map +1 -0
  159. package/dist/graph/mappers/utils.d.ts +97 -0
  160. package/dist/graph/mappers/utils.d.ts.map +1 -0
  161. package/dist/graph/mappers/utils.js +186 -0
  162. package/dist/graph/mappers/utils.js.map +1 -0
  163. package/dist/graph/repository.d.ts +1104 -0
  164. package/dist/graph/repository.d.ts.map +1 -0
  165. package/dist/graph/repository.js +2999 -0
  166. package/dist/graph/repository.js.map +1 -0
  167. package/dist/index.d.ts +21 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +6052 -0
  170. package/dist/index.js.map +1 -0
  171. package/dist/parsers/html-stripper.d.ts +41 -0
  172. package/dist/parsers/html-stripper.d.ts.map +1 -0
  173. package/dist/parsers/html-stripper.js +179 -0
  174. package/dist/parsers/html-stripper.js.map +1 -0
  175. package/dist/parsers/index.d.ts +12 -0
  176. package/dist/parsers/index.d.ts.map +1 -0
  177. package/dist/parsers/index.js +12 -0
  178. package/dist/parsers/index.js.map +1 -0
  179. package/dist/parsers/olk15.d.ts +87 -0
  180. package/dist/parsers/olk15.d.ts.map +1 -0
  181. package/dist/parsers/olk15.js +368 -0
  182. package/dist/parsers/olk15.js.map +1 -0
  183. package/dist/signature.d.ts +22 -0
  184. package/dist/signature.d.ts.map +1 -0
  185. package/dist/signature.js +89 -0
  186. package/dist/signature.js.map +1 -0
  187. package/dist/tools/calendar-permissions.d.ts +79 -0
  188. package/dist/tools/calendar-permissions.d.ts.map +1 -0
  189. package/dist/tools/calendar-permissions.js +121 -0
  190. package/dist/tools/calendar-permissions.js.map +1 -0
  191. package/dist/tools/calendar.d.ts +208 -0
  192. package/dist/tools/calendar.d.ts.map +1 -0
  193. package/dist/tools/calendar.js +247 -0
  194. package/dist/tools/calendar.js.map +1 -0
  195. package/dist/tools/categories.d.ts +94 -0
  196. package/dist/tools/categories.d.ts.map +1 -0
  197. package/dist/tools/categories.js +117 -0
  198. package/dist/tools/categories.js.map +1 -0
  199. package/dist/tools/checklist-items.d.ts +89 -0
  200. package/dist/tools/checklist-items.d.ts.map +1 -0
  201. package/dist/tools/checklist-items.js +140 -0
  202. package/dist/tools/checklist-items.js.map +1 -0
  203. package/dist/tools/contacts.d.ts +94 -0
  204. package/dist/tools/contacts.d.ts.map +1 -0
  205. package/dist/tools/contacts.js +134 -0
  206. package/dist/tools/contacts.js.map +1 -0
  207. package/dist/tools/excel.d.ts +96 -0
  208. package/dist/tools/excel.d.ts.map +1 -0
  209. package/dist/tools/excel.js +165 -0
  210. package/dist/tools/excel.js.map +1 -0
  211. package/dist/tools/focused-overrides.d.ts +70 -0
  212. package/dist/tools/focused-overrides.d.ts.map +1 -0
  213. package/dist/tools/focused-overrides.js +117 -0
  214. package/dist/tools/focused-overrides.js.map +1 -0
  215. package/dist/tools/index.d.ts +22 -0
  216. package/dist/tools/index.d.ts.map +1 -0
  217. package/dist/tools/index.js +34 -0
  218. package/dist/tools/index.js.map +1 -0
  219. package/dist/tools/linked-resources.d.ts +74 -0
  220. package/dist/tools/linked-resources.d.ts.map +1 -0
  221. package/dist/tools/linked-resources.js +122 -0
  222. package/dist/tools/linked-resources.js.map +1 -0
  223. package/dist/tools/mail-rules.d.ts +98 -0
  224. package/dist/tools/mail-rules.d.ts.map +1 -0
  225. package/dist/tools/mail-rules.js +169 -0
  226. package/dist/tools/mail-rules.js.map +1 -0
  227. package/dist/tools/mail-send.d.ts +314 -0
  228. package/dist/tools/mail-send.d.ts.map +1 -0
  229. package/dist/tools/mail-send.js +555 -0
  230. package/dist/tools/mail-send.js.map +1 -0
  231. package/dist/tools/mail.d.ts +127 -0
  232. package/dist/tools/mail.d.ts.map +1 -0
  233. package/dist/tools/mail.js +311 -0
  234. package/dist/tools/mail.js.map +1 -0
  235. package/dist/tools/mailbox-organization.d.ts +301 -0
  236. package/dist/tools/mailbox-organization.d.ts.map +1 -0
  237. package/dist/tools/mailbox-organization.js +541 -0
  238. package/dist/tools/mailbox-organization.js.map +1 -0
  239. package/dist/tools/meetings.d.ts +114 -0
  240. package/dist/tools/meetings.d.ts.map +1 -0
  241. package/dist/tools/meetings.js +110 -0
  242. package/dist/tools/meetings.js.map +1 -0
  243. package/dist/tools/notes.d.ts +74 -0
  244. package/dist/tools/notes.d.ts.map +1 -0
  245. package/dist/tools/notes.js +136 -0
  246. package/dist/tools/notes.js.map +1 -0
  247. package/dist/tools/onedrive.d.ts +194 -0
  248. package/dist/tools/onedrive.d.ts.map +1 -0
  249. package/dist/tools/onedrive.js +257 -0
  250. package/dist/tools/onedrive.js.map +1 -0
  251. package/dist/tools/people.d.ts +129 -0
  252. package/dist/tools/people.d.ts.map +1 -0
  253. package/dist/tools/people.js +195 -0
  254. package/dist/tools/people.js.map +1 -0
  255. package/dist/tools/planner-visualization.d.ts +91 -0
  256. package/dist/tools/planner-visualization.d.ts.map +1 -0
  257. package/dist/tools/planner-visualization.js +192 -0
  258. package/dist/tools/planner-visualization.js.map +1 -0
  259. package/dist/tools/planner.d.ts +288 -0
  260. package/dist/tools/planner.d.ts.map +1 -0
  261. package/dist/tools/planner.js +368 -0
  262. package/dist/tools/planner.js.map +1 -0
  263. package/dist/tools/scheduling.d.ts +49 -0
  264. package/dist/tools/scheduling.d.ts.map +1 -0
  265. package/dist/tools/scheduling.js +115 -0
  266. package/dist/tools/scheduling.js.map +1 -0
  267. package/dist/tools/sharepoint.d.ts +115 -0
  268. package/dist/tools/sharepoint.d.ts.map +1 -0
  269. package/dist/tools/sharepoint.js +99 -0
  270. package/dist/tools/sharepoint.js.map +1 -0
  271. package/dist/tools/task-attachments.d.ts +74 -0
  272. package/dist/tools/task-attachments.d.ts.map +1 -0
  273. package/dist/tools/task-attachments.js +122 -0
  274. package/dist/tools/task-attachments.js.map +1 -0
  275. package/dist/tools/tasks.d.ts +74 -0
  276. package/dist/tools/tasks.d.ts.map +1 -0
  277. package/dist/tools/tasks.js +126 -0
  278. package/dist/tools/tasks.js.map +1 -0
  279. package/dist/tools/teams.d.ts +389 -0
  280. package/dist/tools/teams.d.ts.map +1 -0
  281. package/dist/tools/teams.js +546 -0
  282. package/dist/tools/teams.js.map +1 -0
  283. package/dist/types/calendar.d.ts +60 -0
  284. package/dist/types/calendar.d.ts.map +1 -0
  285. package/dist/types/calendar.js +15 -0
  286. package/dist/types/calendar.js.map +1 -0
  287. package/dist/types/contacts.d.ts +96 -0
  288. package/dist/types/contacts.d.ts.map +1 -0
  289. package/dist/types/contacts.js +41 -0
  290. package/dist/types/contacts.js.map +1 -0
  291. package/dist/types/index.d.ts +15 -0
  292. package/dist/types/index.d.ts.map +1 -0
  293. package/dist/types/index.js +16 -0
  294. package/dist/types/index.js.map +1 -0
  295. package/dist/types/mail.d.ts +108 -0
  296. package/dist/types/mail.d.ts.map +1 -0
  297. package/dist/types/mail.js +40 -0
  298. package/dist/types/mail.js.map +1 -0
  299. package/dist/types/notes.d.ts +26 -0
  300. package/dist/types/notes.d.ts.map +1 -0
  301. package/dist/types/notes.js +6 -0
  302. package/dist/types/notes.js.map +1 -0
  303. package/dist/types/tasks.d.ts +31 -0
  304. package/dist/types/tasks.d.ts.map +1 -0
  305. package/dist/types/tasks.js +6 -0
  306. package/dist/types/tasks.js.map +1 -0
  307. package/dist/utils/dates.d.ts +66 -0
  308. package/dist/utils/dates.d.ts.map +1 -0
  309. package/dist/utils/dates.js +94 -0
  310. package/dist/utils/dates.js.map +1 -0
  311. package/dist/utils/errors.d.ts +218 -0
  312. package/dist/utils/errors.d.ts.map +1 -0
  313. package/dist/utils/errors.js +306 -0
  314. package/dist/utils/errors.js.map +1 -0
  315. package/dist/utils/index.d.ts +10 -0
  316. package/dist/utils/index.d.ts.map +1 -0
  317. package/dist/utils/index.js +10 -0
  318. package/dist/utils/index.js.map +1 -0
  319. package/dist/visualization/html.d.ts +26 -0
  320. package/dist/visualization/html.d.ts.map +1 -0
  321. package/dist/visualization/html.js +306 -0
  322. package/dist/visualization/html.js.map +1 -0
  323. package/dist/visualization/markdown.d.ts +25 -0
  324. package/dist/visualization/markdown.d.ts.map +1 -0
  325. package/dist/visualization/markdown.js +186 -0
  326. package/dist/visualization/markdown.js.map +1 -0
  327. package/dist/visualization/mermaid.d.ts +25 -0
  328. package/dist/visualization/mermaid.d.ts.map +1 -0
  329. package/dist/visualization/mermaid.js +158 -0
  330. package/dist/visualization/mermaid.js.map +1 -0
  331. package/dist/visualization/svg.d.ts +25 -0
  332. package/dist/visualization/svg.d.ts.map +1 -0
  333. package/dist/visualization/svg.js +282 -0
  334. package/dist/visualization/svg.js.map +1 -0
  335. package/dist/visualization/types.d.ts +43 -0
  336. package/dist/visualization/types.d.ts.map +1 -0
  337. package/dist/visualization/types.js +34 -0
  338. package/dist/visualization/types.js.map +1 -0
  339. package/package.json +88 -0
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Copyright (c) 2026 JBC Tech Solutions, LLC
3
+ * Licensed under the MIT License. See LICENSE file in the project root.
4
+ */
5
+ import * as queries from './queries.js';
6
+ import { isoToAppleTimestamp } from '../utils/dates.js';
7
+ // =============================================================================
8
+ // Repository Implementation
9
+ // =============================================================================
10
+ /**
11
+ * Repository implementation using better-sqlite3.
12
+ */
13
+ export class OutlookRepository {
14
+ connection;
15
+ constructor(connection) {
16
+ this.connection = connection;
17
+ }
18
+ // ---------------------------------------------------------------------------
19
+ // Folders
20
+ // ---------------------------------------------------------------------------
21
+ listFolders() {
22
+ return this.connection.execute((db) => {
23
+ const stmt = db.prepare(queries.LIST_FOLDERS);
24
+ return stmt.all();
25
+ });
26
+ }
27
+ getFolder(id) {
28
+ return this.connection.execute((db) => {
29
+ const stmt = db.prepare(queries.GET_FOLDER);
30
+ return stmt.get(id);
31
+ });
32
+ }
33
+ // ---------------------------------------------------------------------------
34
+ // Emails
35
+ // ---------------------------------------------------------------------------
36
+ listEmails(folderId, limit, offset) {
37
+ return this.connection.execute((db) => {
38
+ const stmt = db.prepare(queries.LIST_EMAILS);
39
+ return stmt.all(folderId, limit, offset);
40
+ });
41
+ }
42
+ listUnreadEmails(folderId, limit, offset) {
43
+ return this.connection.execute((db) => {
44
+ const stmt = db.prepare(queries.LIST_UNREAD_EMAILS);
45
+ return stmt.all(folderId, limit, offset);
46
+ });
47
+ }
48
+ searchEmails(query, limit) {
49
+ return this.connection.execute((db) => {
50
+ const pattern = `%${query}%`;
51
+ const stmt = db.prepare(queries.SEARCH_EMAILS);
52
+ return stmt.all(pattern, pattern, pattern, limit);
53
+ });
54
+ }
55
+ searchEmailsInFolder(folderId, query, limit) {
56
+ return this.connection.execute((db) => {
57
+ const pattern = `%${query}%`;
58
+ const stmt = db.prepare(queries.SEARCH_EMAILS_IN_FOLDER);
59
+ return stmt.all(folderId, pattern, pattern, pattern, limit);
60
+ });
61
+ }
62
+ getEmail(id) {
63
+ return this.connection.execute((db) => {
64
+ const stmt = db.prepare(queries.GET_EMAIL);
65
+ return stmt.get(id);
66
+ });
67
+ }
68
+ getUnreadCount() {
69
+ return this.connection.execute((db) => {
70
+ const stmt = db.prepare(queries.GET_UNREAD_COUNT);
71
+ const row = stmt.get();
72
+ return row?.count ?? 0;
73
+ });
74
+ }
75
+ getUnreadCountByFolder(folderId) {
76
+ return this.connection.execute((db) => {
77
+ const stmt = db.prepare(queries.GET_UNREAD_COUNT_BY_FOLDER);
78
+ const row = stmt.get(folderId);
79
+ return row?.count ?? 0;
80
+ });
81
+ }
82
+ // ---------------------------------------------------------------------------
83
+ // Calendar
84
+ // ---------------------------------------------------------------------------
85
+ listCalendars() {
86
+ return this.connection.execute((db) => {
87
+ const stmt = db.prepare(queries.LIST_CALENDARS);
88
+ return stmt.all();
89
+ });
90
+ }
91
+ listEvents(limit) {
92
+ return this.connection.execute((db) => {
93
+ const stmt = db.prepare(queries.LIST_EVENTS);
94
+ return stmt.all(limit);
95
+ });
96
+ }
97
+ listEventsByFolder(folderId, limit) {
98
+ return this.connection.execute((db) => {
99
+ const stmt = db.prepare(queries.LIST_EVENTS_BY_FOLDER);
100
+ return stmt.all(folderId, limit);
101
+ });
102
+ }
103
+ listEventsByDateRange(startDate, endDate, limit) {
104
+ return this.connection.execute((db) => {
105
+ const stmt = db.prepare(queries.LIST_EVENTS_BY_DATE_RANGE);
106
+ return stmt.all(startDate, endDate, limit);
107
+ });
108
+ }
109
+ searchEvents(query, startDate, endDate, limit) {
110
+ // SQLite doesn't have event titles in the database, so we can only filter by date range here.
111
+ // Title filtering must be done at a higher layer using content readers.
112
+ if (startDate != null && endDate != null) {
113
+ const startTs = isoToAppleTimestamp(startDate);
114
+ const endTs = isoToAppleTimestamp(endDate);
115
+ if (startTs != null && endTs != null) {
116
+ return this.listEventsByDateRange(startTs, endTs, limit);
117
+ }
118
+ }
119
+ return this.listEvents(limit);
120
+ }
121
+ getEvent(id) {
122
+ return this.connection.execute((db) => {
123
+ const stmt = db.prepare(queries.GET_EVENT);
124
+ return stmt.get(id);
125
+ });
126
+ }
127
+ // ---------------------------------------------------------------------------
128
+ // Contacts
129
+ // ---------------------------------------------------------------------------
130
+ listContacts(limit, offset) {
131
+ return this.connection.execute((db) => {
132
+ const stmt = db.prepare(queries.LIST_CONTACTS);
133
+ return stmt.all(limit, offset);
134
+ });
135
+ }
136
+ searchContacts(query, limit) {
137
+ return this.connection.execute((db) => {
138
+ const pattern = `%${query}%`;
139
+ const stmt = db.prepare(queries.SEARCH_CONTACTS);
140
+ return stmt.all(pattern, pattern, limit);
141
+ });
142
+ }
143
+ getContact(id) {
144
+ return this.connection.execute((db) => {
145
+ const stmt = db.prepare(queries.GET_CONTACT);
146
+ return stmt.get(id);
147
+ });
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Tasks
151
+ // ---------------------------------------------------------------------------
152
+ listTasks(limit, offset) {
153
+ return this.connection.execute((db) => {
154
+ const stmt = db.prepare(queries.LIST_TASKS);
155
+ return stmt.all(limit, offset);
156
+ });
157
+ }
158
+ listIncompleteTasks(limit, offset) {
159
+ return this.connection.execute((db) => {
160
+ const stmt = db.prepare(queries.LIST_INCOMPLETE_TASKS);
161
+ return stmt.all(limit, offset);
162
+ });
163
+ }
164
+ searchTasks(query, limit) {
165
+ return this.connection.execute((db) => {
166
+ const pattern = `%${query}%`;
167
+ const stmt = db.prepare(queries.SEARCH_TASKS);
168
+ return stmt.all(pattern, limit);
169
+ });
170
+ }
171
+ getTask(id) {
172
+ return this.connection.execute((db) => {
173
+ const stmt = db.prepare(queries.GET_TASK);
174
+ return stmt.get(id);
175
+ });
176
+ }
177
+ // ---------------------------------------------------------------------------
178
+ // Notes
179
+ // ---------------------------------------------------------------------------
180
+ listNotes(limit, offset) {
181
+ return this.connection.execute((db) => {
182
+ const stmt = db.prepare(queries.LIST_NOTES);
183
+ return stmt.all(limit, offset);
184
+ });
185
+ }
186
+ getNote(id) {
187
+ return this.connection.execute((db) => {
188
+ const stmt = db.prepare(queries.GET_NOTE);
189
+ return stmt.get(id);
190
+ });
191
+ }
192
+ }
193
+ /**
194
+ * Creates a repository with the given connection.
195
+ */
196
+ export function createRepository(connection) {
197
+ return new OutlookRepository(connection);
198
+ }
199
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/database/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Copyright (c) 2026 JBC Tech Solutions, LLC
3
+ * Licensed under the MIT License. See LICENSE file in the project root.
4
+ */
5
+ import type { GraphClient } from './client/index.js';
6
+ /**
7
+ * Returns the download directory for attachments.
8
+ *
9
+ * Reads `MCP_OUTLOOK_DOWNLOAD_DIR` env var, falls back to `os.tmpdir()`.
10
+ * Creates a subdirectory `mcp-outlook-attachments` inside it.
11
+ */
12
+ export declare function getDownloadDir(): string;
13
+ /**
14
+ * Sanitizes a filename to prevent path traversal attacks.
15
+ *
16
+ * Strips directory separators (`/`, `\`), strips `..` segments,
17
+ * and trims whitespace. Falls back to `'attachment'` if result is empty.
18
+ */
19
+ export declare function sanitizeFilename(name: string): string;
20
+ /**
21
+ * Generates a unique file path in the given directory.
22
+ *
23
+ * Sanitizes the filename, then checks if it already exists.
24
+ * If it does, appends a numeric suffix (e.g., `file(1).txt`, `file(2).txt`).
25
+ */
26
+ export declare function resolveFilePath(downloadDir: string, filename: string): string;
27
+ /**
28
+ * Uploads a file as an attachment to a message.
29
+ *
30
+ * Routes based on file size:
31
+ * - <= 3MB: Inline base64 upload via `client.addAttachment`
32
+ * - > 3MB: Chunked upload session via `client.createUploadSession` + raw fetch
33
+ *
34
+ * @param client - The Graph API client
35
+ * @param messageId - The message to attach the file to
36
+ * @param filePath - Local path to the file to upload
37
+ * @param name - Optional display name (defaults to basename of filePath)
38
+ * @param contentType - Optional MIME type (defaults to 'application/octet-stream')
39
+ */
40
+ export declare function uploadAttachment(client: GraphClient, messageId: string, filePath: string, name?: string, contentType?: string): Promise<void>;
41
+ /**
42
+ * Uploads a file as an inline attachment (e.g. for cid: references in HTML body).
43
+ *
44
+ * Use this when the HTML body references the image via <img src="cid:contentId">.
45
+ * Keeps the body small by not embedding base64 in the MCP payload.
46
+ *
47
+ * Only supports files <= 3MB (same as regular inline upload).
48
+ *
49
+ * @param client - The Graph API client
50
+ * @param messageId - The message to attach the file to
51
+ * @param filePath - Local path to the image file
52
+ * @param contentId - Content-ID used in HTML (e.g. "logo" for cid:logo)
53
+ * @param contentType - Optional MIME type (defaults from file extension or image/png)
54
+ */
55
+ export declare function uploadInlineAttachment(client: GraphClient, messageId: string, filePath: string, contentId: string, contentType?: string): Promise<void>;
56
+ /**
57
+ * Downloads an attachment from a message and saves it to disk.
58
+ *
59
+ * Decodes `contentBytes` from base64 and writes the file to the download directory.
60
+ *
61
+ * @param client - The Graph API client
62
+ * @param messageId - The message containing the attachment
63
+ * @param attachmentId - The attachment to download
64
+ * @returns Metadata about the downloaded file including its local path
65
+ */
66
+ export declare function downloadAttachment(client: GraphClient, messageId: string, attachmentId: string): Promise<{
67
+ filePath: string;
68
+ name: string;
69
+ size: number;
70
+ contentType: string;
71
+ }>;
72
+ //# sourceMappingURL=attachments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/graph/attachments.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQrD;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAKvC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmB7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAsDf;AAWD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBhF"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Copyright (c) 2026 JBC Tech Solutions, LLC
3
+ * Licensed under the MIT License. See LICENSE file in the project root.
4
+ */
5
+ /**
6
+ * Attachment upload and download helpers for Microsoft Graph API.
7
+ *
8
+ * Handles:
9
+ * - File I/O for reading/writing attachments
10
+ * - Size-based routing (inline vs chunked upload)
11
+ * - Chunked upload sessions for large files (> 3MB)
12
+ * - Safe filename resolution with path traversal prevention
13
+ */
14
+ import * as fs from 'fs';
15
+ import * as os from 'os';
16
+ import * as path from 'path';
17
+ /** 3MB threshold for inline vs chunked upload. */
18
+ const INLINE_MAX_BYTES = 3 * 1024 * 1024;
19
+ /** Microsoft's recommended chunk size (~3.75MB). */
20
+ const CHUNK_SIZE = 3932160;
21
+ /**
22
+ * Returns the download directory for attachments.
23
+ *
24
+ * Reads `MCP_OUTLOOK_DOWNLOAD_DIR` env var, falls back to `os.tmpdir()`.
25
+ * Creates a subdirectory `mcp-outlook-attachments` inside it.
26
+ */
27
+ export function getDownloadDir() {
28
+ const base = process.env['MCP_OUTLOOK_DOWNLOAD_DIR'] ?? os.tmpdir();
29
+ const dir = path.join(base, 'mcp-outlook-attachments');
30
+ fs.mkdirSync(dir, { recursive: true });
31
+ return dir;
32
+ }
33
+ /**
34
+ * Sanitizes a filename to prevent path traversal attacks.
35
+ *
36
+ * Strips directory separators (`/`, `\`), strips `..` segments,
37
+ * and trims whitespace. Falls back to `'attachment'` if result is empty.
38
+ */
39
+ export function sanitizeFilename(name) {
40
+ // Strip .. segments
41
+ let sanitized = name.replace(/\.\./g, '');
42
+ // Take only the last component after any path separator
43
+ const forwardSlashIdx = sanitized.lastIndexOf('/');
44
+ if (forwardSlashIdx >= 0) {
45
+ sanitized = sanitized.substring(forwardSlashIdx + 1);
46
+ }
47
+ const backslashIdx = sanitized.lastIndexOf('\\');
48
+ if (backslashIdx >= 0) {
49
+ sanitized = sanitized.substring(backslashIdx + 1);
50
+ }
51
+ sanitized = sanitized.trim();
52
+ return sanitized.length > 0 ? sanitized : 'attachment';
53
+ }
54
+ /**
55
+ * Generates a unique file path in the given directory.
56
+ *
57
+ * Sanitizes the filename, then checks if it already exists.
58
+ * If it does, appends a numeric suffix (e.g., `file(1).txt`, `file(2).txt`).
59
+ */
60
+ export function resolveFilePath(downloadDir, filename) {
61
+ const safeName = sanitizeFilename(filename);
62
+ let candidate = path.join(downloadDir, safeName);
63
+ if (!fs.existsSync(candidate)) {
64
+ return candidate;
65
+ }
66
+ const ext = path.extname(safeName);
67
+ const base = safeName.substring(0, safeName.length - ext.length);
68
+ let counter = 1;
69
+ for (;;) { // eslint-disable-line no-constant-condition
70
+ candidate = path.join(downloadDir, `${base}(${counter})${ext}`);
71
+ if (!fs.existsSync(candidate)) {
72
+ return candidate;
73
+ }
74
+ counter++;
75
+ }
76
+ }
77
+ /**
78
+ * Uploads a file as an attachment to a message.
79
+ *
80
+ * Routes based on file size:
81
+ * - <= 3MB: Inline base64 upload via `client.addAttachment`
82
+ * - > 3MB: Chunked upload session via `client.createUploadSession` + raw fetch
83
+ *
84
+ * @param client - The Graph API client
85
+ * @param messageId - The message to attach the file to
86
+ * @param filePath - Local path to the file to upload
87
+ * @param name - Optional display name (defaults to basename of filePath)
88
+ * @param contentType - Optional MIME type (defaults to 'application/octet-stream')
89
+ */
90
+ export async function uploadAttachment(client, messageId, filePath, name, contentType) {
91
+ const fileName = name ?? path.basename(filePath);
92
+ const mimeType = contentType ?? 'application/octet-stream';
93
+ const stat = fs.statSync(filePath);
94
+ const fileSize = stat.size;
95
+ if (fileSize <= INLINE_MAX_BYTES) {
96
+ // Inline upload: read file, base64 encode, POST as attachment
97
+ const fileContent = fs.readFileSync(filePath);
98
+ const base64 = fileContent.toString('base64');
99
+ await client.addAttachment(messageId, {
100
+ '@odata.type': '#microsoft.graph.fileAttachment',
101
+ name: fileName,
102
+ contentBytes: base64,
103
+ contentType: mimeType,
104
+ });
105
+ }
106
+ else {
107
+ // Chunked upload session for large files
108
+ const session = await client.createUploadSession(messageId, {
109
+ AttachmentItem: {
110
+ attachmentType: 'file',
111
+ name: fileName,
112
+ size: fileSize,
113
+ },
114
+ });
115
+ const uploadUrl = session.uploadUrl;
116
+ const fileContent = fs.readFileSync(filePath);
117
+ let offset = 0;
118
+ while (offset < fileSize) {
119
+ const end = Math.min(offset + CHUNK_SIZE, fileSize);
120
+ const chunk = fileContent.subarray(offset, end);
121
+ const contentRange = `bytes ${offset}-${end - 1}/${fileSize}`;
122
+ const response = await fetch(uploadUrl, {
123
+ method: 'PUT',
124
+ headers: {
125
+ 'Content-Range': contentRange,
126
+ 'Content-Length': String(chunk.length),
127
+ },
128
+ body: chunk,
129
+ });
130
+ if (!response.ok) {
131
+ throw new Error(`Upload chunk failed: ${response.status} ${response.statusText}`);
132
+ }
133
+ offset = end;
134
+ }
135
+ }
136
+ }
137
+ /** MIME type by extension for inline images. */
138
+ const IMAGE_EXT_TO_MIME = {
139
+ '.png': 'image/png',
140
+ '.jpg': 'image/jpeg',
141
+ '.jpeg': 'image/jpeg',
142
+ '.gif': 'image/gif',
143
+ '.webp': 'image/webp',
144
+ };
145
+ /**
146
+ * Uploads a file as an inline attachment (e.g. for cid: references in HTML body).
147
+ *
148
+ * Use this when the HTML body references the image via <img src="cid:contentId">.
149
+ * Keeps the body small by not embedding base64 in the MCP payload.
150
+ *
151
+ * Only supports files <= 3MB (same as regular inline upload).
152
+ *
153
+ * @param client - The Graph API client
154
+ * @param messageId - The message to attach the file to
155
+ * @param filePath - Local path to the image file
156
+ * @param contentId - Content-ID used in HTML (e.g. "logo" for cid:logo)
157
+ * @param contentType - Optional MIME type (defaults from file extension or image/png)
158
+ */
159
+ export async function uploadInlineAttachment(client, messageId, filePath, contentId, contentType) {
160
+ const fileName = path.basename(filePath);
161
+ const ext = path.extname(filePath).toLowerCase();
162
+ const mimeType = contentType ?? IMAGE_EXT_TO_MIME[ext] ?? 'image/png';
163
+ const stat = fs.statSync(filePath);
164
+ const fileSize = stat.size;
165
+ if (fileSize > INLINE_MAX_BYTES) {
166
+ throw new Error(`Inline image too large (${fileSize} bytes). Max ${INLINE_MAX_BYTES} bytes. Use a smaller image or attach as regular attachment.`);
167
+ }
168
+ const fileContent = fs.readFileSync(filePath);
169
+ const base64 = fileContent.toString('base64');
170
+ await client.addAttachment(messageId, {
171
+ '@odata.type': '#microsoft.graph.fileAttachment',
172
+ name: fileName,
173
+ contentBytes: base64,
174
+ contentType: mimeType,
175
+ isInline: true,
176
+ contentId,
177
+ });
178
+ }
179
+ /**
180
+ * Downloads an attachment from a message and saves it to disk.
181
+ *
182
+ * Decodes `contentBytes` from base64 and writes the file to the download directory.
183
+ *
184
+ * @param client - The Graph API client
185
+ * @param messageId - The message containing the attachment
186
+ * @param attachmentId - The attachment to download
187
+ * @returns Metadata about the downloaded file including its local path
188
+ */
189
+ export async function downloadAttachment(client, messageId, attachmentId) {
190
+ const attachment = await client.getAttachment(messageId, attachmentId);
191
+ const rawName = attachment.name ?? '';
192
+ const safeName = sanitizeFilename(rawName);
193
+ const size = attachment.size ?? 0;
194
+ const attachmentContentType = attachment.contentType ?? 'application/octet-stream';
195
+ const downloadDir = getDownloadDir();
196
+ const filePath = resolveFilePath(downloadDir, safeName);
197
+ const contentBytes = attachment.contentBytes ?? '';
198
+ const buffer = Buffer.from(contentBytes, 'base64');
199
+ fs.writeFileSync(filePath, buffer);
200
+ return {
201
+ filePath,
202
+ name: safeName,
203
+ size,
204
+ contentType: attachmentContentType,
205
+ };
206
+ }
207
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/graph/attachments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Copyright (c) 2026 JBC Tech Solutions, LLC
3
+ * Licensed under the MIT License. See LICENSE file in the project root.
4
+ */
5
+ /**
6
+ * Microsoft Graph API scopes required for Outlook access.
7
+ *
8
+ * Includes read/write permissions for mail and calendars to support
9
+ * future implementation of email sending and event management features.
10
+ */
11
+ export declare const GRAPH_SCOPES: readonly ["Mail.ReadWrite", "Calendars.ReadWrite", "Contacts.ReadWrite", "Tasks.ReadWrite", "User.Read", "offline_access", "ChannelMessage.Read.All", "ChannelMessage.Send", "Channel.ReadBasic.All", "Team.ReadBasic.All", "Chat.ReadWrite", "ChatMessage.Send", "People.Read", "User.ReadBasic.All", "Presence.Read.All", "Group.Read.All"];
12
+ /**
13
+ * Microsoft Graph API configuration.
14
+ */
15
+ export interface GraphAuthConfig {
16
+ /** Azure AD application (client) ID */
17
+ readonly clientId: string;
18
+ /** Azure AD tenant ID (default: 'common' for multi-tenant) */
19
+ readonly tenantId: string;
20
+ /** OAuth2 scopes to request */
21
+ readonly scopes: readonly string[];
22
+ }
23
+ /**
24
+ * Loads the Graph API configuration.
25
+ *
26
+ * Uses embedded defaults but allows override via environment variables
27
+ * for users who want to use their own Azure AD app registration.
28
+ */
29
+ export declare function loadGraphConfig(): GraphAuthConfig;
30
+ /**
31
+ * Gets the Azure AD authority URL for the configured tenant.
32
+ */
33
+ export declare function getAuthorityUrl(config: GraphAuthConfig): string;
34
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/graph/auth/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,+UAqBf,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,eAAe,CAiBjD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAE/D"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Copyright (c) 2026 JBC Tech Solutions, LLC
3
+ * Licensed under the MIT License. See LICENSE file in the project root.
4
+ */
5
+ /**
6
+ * Microsoft Graph API configuration.
7
+ *
8
+ * Contains Azure AD app registration settings for the device code flow.
9
+ * The client ID is embedded in the package - users don't need to configure anything.
10
+ */
11
+ /**
12
+ * Default client ID for the Outlook MCP Server Azure AD app.
13
+ *
14
+ * This is a public client application registered in Azure AD by JBC Tech Solutions.
15
+ * Multi-tenant configuration supports both personal and work/school Microsoft accounts.
16
+ *
17
+ * Users can override this with their own app registration by setting:
18
+ * - OUTLOOK_MCP_CLIENT_ID environment variable
19
+ * - OUTLOOK_MCP_TENANT_ID environment variable (default: 'common')
20
+ *
21
+ * For setup instructions: https://github.com/jbctechsolutions/mcp-office365#custom-azure-ad-setup
22
+ */
23
+ const DEFAULT_CLIENT_ID = '681fbb29-5afa-47b1-9c16-0cd2be01754d';
24
+ /**
25
+ * Microsoft Graph API scopes required for Outlook access.
26
+ *
27
+ * Includes read/write permissions for mail and calendars to support
28
+ * future implementation of email sending and event management features.
29
+ */
30
+ export const GRAPH_SCOPES = [
31
+ // Outlook
32
+ 'Mail.ReadWrite',
33
+ 'Calendars.ReadWrite',
34
+ 'Contacts.ReadWrite',
35
+ 'Tasks.ReadWrite',
36
+ 'User.Read',
37
+ 'offline_access',
38
+ // Teams
39
+ 'ChannelMessage.Read.All',
40
+ 'ChannelMessage.Send',
41
+ 'Channel.ReadBasic.All',
42
+ 'Team.ReadBasic.All',
43
+ 'Chat.ReadWrite',
44
+ 'ChatMessage.Send',
45
+ // People & Presence
46
+ 'People.Read',
47
+ 'User.ReadBasic.All',
48
+ 'Presence.Read.All',
49
+ // Planner
50
+ 'Group.Read.All',
51
+ ];
52
+ /**
53
+ * Loads the Graph API configuration.
54
+ *
55
+ * Uses embedded defaults but allows override via environment variables
56
+ * for users who want to use their own Azure AD app registration.
57
+ */
58
+ export function loadGraphConfig() {
59
+ const clientId = process.env['OUTLOOK_MCP_CLIENT_ID'] ?? DEFAULT_CLIENT_ID;
60
+ const tenantId = process.env['OUTLOOK_MCP_TENANT_ID'] ?? 'common';
61
+ if (clientId === 'YOUR_AZURE_APP_CLIENT_ID') {
62
+ throw new Error('Azure AD app not configured. Either:\n' +
63
+ '1. Set OUTLOOK_MCP_CLIENT_ID environment variable, or\n' +
64
+ '2. The package maintainer needs to embed the client ID in config.ts');
65
+ }
66
+ return {
67
+ clientId,
68
+ tenantId,
69
+ scopes: [...GRAPH_SCOPES],
70
+ };
71
+ }
72
+ /**
73
+ * Gets the Azure AD authority URL for the configured tenant.
74
+ */
75
+ export function getAuthorityUrl(config) {
76
+ return `https://login.microsoftonline.com/${config.tenantId}`;
77
+ }
78
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/graph/auth/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,iBAAiB,GAAG,sCAAsC,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,UAAU;IACV,gBAAgB;IAChB,qBAAqB;IACrB,oBAAoB;IACpB,iBAAiB;IACjB,WAAW;IACX,gBAAgB;IAChB,QAAQ;IACR,yBAAyB;IACzB,qBAAqB;IACrB,uBAAuB;IACvB,oBAAoB;IACpB,gBAAgB;IAChB,kBAAkB;IAClB,oBAAoB;IACpB,aAAa;IACb,oBAAoB;IACpB,mBAAmB;IACnB,UAAU;IACV,gBAAgB;CACR,CAAC;AAcX;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,iBAAiB,CAAC;IAC3E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,QAAQ,CAAC;IAElE,IAAI,QAAQ,KAAK,0BAA0B,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,wCAAwC;YACtC,yDAAyD;YACzD,qEAAqE,CACxE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,MAAM,EAAE,CAAC,GAAG,YAAY,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAAuB;IACrD,OAAO,qCAAqC,MAAM,CAAC,QAAQ,EAAE,CAAC;AAChE,CAAC"}