@mcp-z/mcp-outlook 1.0.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 (300) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/bin/server.js +5 -0
  4. package/dist/cjs/constants.d.cts +10 -0
  5. package/dist/cjs/constants.d.ts +10 -0
  6. package/dist/cjs/constants.js +35 -0
  7. package/dist/cjs/constants.js.map +1 -0
  8. package/dist/cjs/email/composition/outlook-message-builder.d.cts +36 -0
  9. package/dist/cjs/email/composition/outlook-message-builder.d.ts +36 -0
  10. package/dist/cjs/email/composition/outlook-message-builder.js +56 -0
  11. package/dist/cjs/email/composition/outlook-message-builder.js.map +1 -0
  12. package/dist/cjs/email/messages/messages.d.cts +7 -0
  13. package/dist/cjs/email/messages/messages.d.ts +7 -0
  14. package/dist/cjs/email/messages/messages.js +61 -0
  15. package/dist/cjs/email/messages/messages.js.map +1 -0
  16. package/dist/cjs/email/parsing/header-parsing.d.cts +18 -0
  17. package/dist/cjs/email/parsing/header-parsing.d.ts +18 -0
  18. package/dist/cjs/email/parsing/header-parsing.js +42 -0
  19. package/dist/cjs/email/parsing/header-parsing.js.map +1 -0
  20. package/dist/cjs/email/parsing/message-extraction.d.cts +4 -0
  21. package/dist/cjs/email/parsing/message-extraction.d.ts +4 -0
  22. package/dist/cjs/email/parsing/message-extraction.js +192 -0
  23. package/dist/cjs/email/parsing/message-extraction.js.map +1 -0
  24. package/dist/cjs/email/parsing/message-mapping.d.cts +21 -0
  25. package/dist/cjs/email/parsing/message-mapping.d.ts +21 -0
  26. package/dist/cjs/email/parsing/message-mapping.js +47 -0
  27. package/dist/cjs/email/parsing/message-mapping.js.map +1 -0
  28. package/dist/cjs/email/querying/execute-query.d.cts +20 -0
  29. package/dist/cjs/email/querying/execute-query.d.ts +20 -0
  30. package/dist/cjs/email/querying/execute-query.js +268 -0
  31. package/dist/cjs/email/querying/execute-query.js.map +1 -0
  32. package/dist/cjs/email/querying/query-builder.d.cts +32 -0
  33. package/dist/cjs/email/querying/query-builder.d.ts +32 -0
  34. package/dist/cjs/email/querying/query-builder.js +528 -0
  35. package/dist/cjs/email/querying/query-builder.js.map +1 -0
  36. package/dist/cjs/email/querying/search-execution.d.cts +24 -0
  37. package/dist/cjs/email/querying/search-execution.d.ts +24 -0
  38. package/dist/cjs/email/querying/search-execution.js +261 -0
  39. package/dist/cjs/email/querying/search-execution.js.map +1 -0
  40. package/dist/cjs/index.d.cts +8 -0
  41. package/dist/cjs/index.d.ts +8 -0
  42. package/dist/cjs/index.js +314 -0
  43. package/dist/cjs/index.js.map +1 -0
  44. package/dist/cjs/lib/create-store.d.cts +2 -0
  45. package/dist/cjs/lib/create-store.d.ts +2 -0
  46. package/dist/cjs/lib/create-store.js +166 -0
  47. package/dist/cjs/lib/create-store.js.map +1 -0
  48. package/dist/cjs/lib/messages-to-row.d.cts +39 -0
  49. package/dist/cjs/lib/messages-to-row.d.ts +39 -0
  50. package/dist/cjs/lib/messages-to-row.js +177 -0
  51. package/dist/cjs/lib/messages-to-row.js.map +1 -0
  52. package/dist/cjs/lib/outlook/index.d.cts +7 -0
  53. package/dist/cjs/lib/outlook/index.d.ts +7 -0
  54. package/dist/cjs/lib/outlook/index.js +56 -0
  55. package/dist/cjs/lib/outlook/index.js.map +1 -0
  56. package/dist/cjs/lib/outlook/types.d.cts +22 -0
  57. package/dist/cjs/lib/outlook/types.d.ts +22 -0
  58. package/dist/cjs/lib/outlook/types.js +6 -0
  59. package/dist/cjs/lib/outlook/types.js.map +1 -0
  60. package/dist/cjs/mcp/index.d.cts +3 -0
  61. package/dist/cjs/mcp/index.d.ts +3 -0
  62. package/dist/cjs/mcp/index.js +66 -0
  63. package/dist/cjs/mcp/index.js.map +1 -0
  64. package/dist/cjs/mcp/prompts/draft-email.d.cts +30 -0
  65. package/dist/cjs/mcp/prompts/draft-email.d.ts +30 -0
  66. package/dist/cjs/mcp/prompts/draft-email.js +184 -0
  67. package/dist/cjs/mcp/prompts/draft-email.js.map +1 -0
  68. package/dist/cjs/mcp/prompts/index.d.cts +2 -0
  69. package/dist/cjs/mcp/prompts/index.d.ts +2 -0
  70. package/dist/cjs/mcp/prompts/index.js +26 -0
  71. package/dist/cjs/mcp/prompts/index.js.map +1 -0
  72. package/dist/cjs/mcp/prompts/query-syntax.d.cts +19 -0
  73. package/dist/cjs/mcp/prompts/query-syntax.d.ts +19 -0
  74. package/dist/cjs/mcp/prompts/query-syntax.js +169 -0
  75. package/dist/cjs/mcp/prompts/query-syntax.js.map +1 -0
  76. package/dist/cjs/mcp/resources/email.d.cts +11 -0
  77. package/dist/cjs/mcp/resources/email.d.ts +11 -0
  78. package/dist/cjs/mcp/resources/email.js +233 -0
  79. package/dist/cjs/mcp/resources/email.js.map +1 -0
  80. package/dist/cjs/mcp/resources/index.d.cts +1 -0
  81. package/dist/cjs/mcp/resources/index.d.ts +1 -0
  82. package/dist/cjs/mcp/resources/index.js +17 -0
  83. package/dist/cjs/mcp/resources/index.js.map +1 -0
  84. package/dist/cjs/mcp/tools/categories-list.d.cts +96 -0
  85. package/dist/cjs/mcp/tools/categories-list.d.ts +96 -0
  86. package/dist/cjs/mcp/tools/categories-list.js +252 -0
  87. package/dist/cjs/mcp/tools/categories-list.js.map +1 -0
  88. package/dist/cjs/mcp/tools/index.d.cts +11 -0
  89. package/dist/cjs/mcp/tools/index.d.ts +11 -0
  90. package/dist/cjs/mcp/tools/index.js +62 -0
  91. package/dist/cjs/mcp/tools/index.js.map +1 -0
  92. package/dist/cjs/mcp/tools/label-add.d.cts +44 -0
  93. package/dist/cjs/mcp/tools/label-add.d.ts +44 -0
  94. package/dist/cjs/mcp/tools/label-add.js +249 -0
  95. package/dist/cjs/mcp/tools/label-add.js.map +1 -0
  96. package/dist/cjs/mcp/tools/label-delete.d.cts +54 -0
  97. package/dist/cjs/mcp/tools/label-delete.d.ts +54 -0
  98. package/dist/cjs/mcp/tools/label-delete.js +497 -0
  99. package/dist/cjs/mcp/tools/label-delete.js.map +1 -0
  100. package/dist/cjs/mcp/tools/labels-list.d.cts +96 -0
  101. package/dist/cjs/mcp/tools/labels-list.d.ts +96 -0
  102. package/dist/cjs/mcp/tools/labels-list.js +252 -0
  103. package/dist/cjs/mcp/tools/labels-list.js.map +1 -0
  104. package/dist/cjs/mcp/tools/message-get.d.cts +110 -0
  105. package/dist/cjs/mcp/tools/message-get.d.ts +110 -0
  106. package/dist/cjs/mcp/tools/message-get.js +289 -0
  107. package/dist/cjs/mcp/tools/message-get.js.map +1 -0
  108. package/dist/cjs/mcp/tools/message-mark-read.d.cts +42 -0
  109. package/dist/cjs/mcp/tools/message-mark-read.d.ts +42 -0
  110. package/dist/cjs/mcp/tools/message-mark-read.js +254 -0
  111. package/dist/cjs/mcp/tools/message-mark-read.js.map +1 -0
  112. package/dist/cjs/mcp/tools/message-move-to-trash.d.cts +54 -0
  113. package/dist/cjs/mcp/tools/message-move-to-trash.d.ts +54 -0
  114. package/dist/cjs/mcp/tools/message-move-to-trash.js +460 -0
  115. package/dist/cjs/mcp/tools/message-move-to-trash.js.map +1 -0
  116. package/dist/cjs/mcp/tools/message-respond.d.cts +52 -0
  117. package/dist/cjs/mcp/tools/message-respond.d.ts +52 -0
  118. package/dist/cjs/mcp/tools/message-respond.js +263 -0
  119. package/dist/cjs/mcp/tools/message-respond.js.map +1 -0
  120. package/dist/cjs/mcp/tools/message-search.d.cts +138 -0
  121. package/dist/cjs/mcp/tools/message-search.d.ts +138 -0
  122. package/dist/cjs/mcp/tools/message-search.js +408 -0
  123. package/dist/cjs/mcp/tools/message-search.js.map +1 -0
  124. package/dist/cjs/mcp/tools/message-send.d.cts +66 -0
  125. package/dist/cjs/mcp/tools/message-send.d.ts +66 -0
  126. package/dist/cjs/mcp/tools/message-send.js +298 -0
  127. package/dist/cjs/mcp/tools/message-send.js.map +1 -0
  128. package/dist/cjs/mcp/tools/messages-export-csv.d.cts +72 -0
  129. package/dist/cjs/mcp/tools/messages-export-csv.d.ts +72 -0
  130. package/dist/cjs/mcp/tools/messages-export-csv.js +540 -0
  131. package/dist/cjs/mcp/tools/messages-export-csv.js.map +1 -0
  132. package/dist/cjs/package.json +1 -0
  133. package/dist/cjs/schemas/index.d.cts +2 -0
  134. package/dist/cjs/schemas/index.d.ts +2 -0
  135. package/dist/cjs/schemas/index.js +20 -0
  136. package/dist/cjs/schemas/index.js.map +1 -0
  137. package/dist/cjs/schemas/outlook-query-schema.d.cts +53 -0
  138. package/dist/cjs/schemas/outlook-query-schema.d.ts +53 -0
  139. package/dist/cjs/schemas/outlook-query-schema.js +115 -0
  140. package/dist/cjs/schemas/outlook-query-schema.js.map +1 -0
  141. package/dist/cjs/schemas/outlook-validation.d.cts +428 -0
  142. package/dist/cjs/schemas/outlook-validation.d.ts +428 -0
  143. package/dist/cjs/schemas/outlook-validation.js +420 -0
  144. package/dist/cjs/schemas/outlook-validation.js.map +1 -0
  145. package/dist/cjs/setup/config.d.cts +50 -0
  146. package/dist/cjs/setup/config.d.ts +50 -0
  147. package/dist/cjs/setup/config.js +217 -0
  148. package/dist/cjs/setup/config.js.map +1 -0
  149. package/dist/cjs/setup/http.d.cts +8 -0
  150. package/dist/cjs/setup/http.d.ts +8 -0
  151. package/dist/cjs/setup/http.js +267 -0
  152. package/dist/cjs/setup/http.js.map +1 -0
  153. package/dist/cjs/setup/index.d.cts +5 -0
  154. package/dist/cjs/setup/index.d.ts +5 -0
  155. package/dist/cjs/setup/index.js +46 -0
  156. package/dist/cjs/setup/index.js.map +1 -0
  157. package/dist/cjs/setup/oauth-microsoft.d.cts +43 -0
  158. package/dist/cjs/setup/oauth-microsoft.d.ts +43 -0
  159. package/dist/cjs/setup/oauth-microsoft.js +366 -0
  160. package/dist/cjs/setup/oauth-microsoft.js.map +1 -0
  161. package/dist/cjs/setup/runtime.d.cts +11 -0
  162. package/dist/cjs/setup/runtime.d.ts +11 -0
  163. package/dist/cjs/setup/runtime.js +489 -0
  164. package/dist/cjs/setup/runtime.js.map +1 -0
  165. package/dist/cjs/setup/stdio.d.cts +7 -0
  166. package/dist/cjs/setup/stdio.d.ts +7 -0
  167. package/dist/cjs/setup/stdio.js +239 -0
  168. package/dist/cjs/setup/stdio.js.map +1 -0
  169. package/dist/cjs/types.d.cts +54 -0
  170. package/dist/cjs/types.d.ts +54 -0
  171. package/dist/cjs/types.js +5 -0
  172. package/dist/cjs/types.js.map +1 -0
  173. package/dist/esm/constants.d.ts +10 -0
  174. package/dist/esm/constants.js +13 -0
  175. package/dist/esm/constants.js.map +1 -0
  176. package/dist/esm/email/composition/outlook-message-builder.d.ts +36 -0
  177. package/dist/esm/email/composition/outlook-message-builder.js +46 -0
  178. package/dist/esm/email/composition/outlook-message-builder.js.map +1 -0
  179. package/dist/esm/email/messages/messages.d.ts +7 -0
  180. package/dist/esm/email/messages/messages.js +42 -0
  181. package/dist/esm/email/messages/messages.js.map +1 -0
  182. package/dist/esm/email/parsing/header-parsing.d.ts +18 -0
  183. package/dist/esm/email/parsing/header-parsing.js +18 -0
  184. package/dist/esm/email/parsing/header-parsing.js.map +1 -0
  185. package/dist/esm/email/parsing/message-extraction.d.ts +4 -0
  186. package/dist/esm/email/parsing/message-extraction.js +26 -0
  187. package/dist/esm/email/parsing/message-extraction.js.map +1 -0
  188. package/dist/esm/email/parsing/message-mapping.d.ts +21 -0
  189. package/dist/esm/email/parsing/message-mapping.js +35 -0
  190. package/dist/esm/email/parsing/message-mapping.js.map +1 -0
  191. package/dist/esm/email/querying/execute-query.d.ts +20 -0
  192. package/dist/esm/email/querying/execute-query.js +48 -0
  193. package/dist/esm/email/querying/execute-query.js.map +1 -0
  194. package/dist/esm/email/querying/query-builder.d.ts +32 -0
  195. package/dist/esm/email/querying/query-builder.js +424 -0
  196. package/dist/esm/email/querying/query-builder.js.map +1 -0
  197. package/dist/esm/email/querying/search-execution.d.ts +24 -0
  198. package/dist/esm/email/querying/search-execution.js +96 -0
  199. package/dist/esm/email/querying/search-execution.js.map +1 -0
  200. package/dist/esm/index.d.ts +8 -0
  201. package/dist/esm/index.js +34 -0
  202. package/dist/esm/index.js.map +1 -0
  203. package/dist/esm/lib/create-store.d.ts +2 -0
  204. package/dist/esm/lib/create-store.js +6 -0
  205. package/dist/esm/lib/create-store.js.map +1 -0
  206. package/dist/esm/lib/messages-to-row.d.ts +39 -0
  207. package/dist/esm/lib/messages-to-row.js +141 -0
  208. package/dist/esm/lib/messages-to-row.js.map +1 -0
  209. package/dist/esm/lib/outlook/index.d.ts +7 -0
  210. package/dist/esm/lib/outlook/index.js +7 -0
  211. package/dist/esm/lib/outlook/index.js.map +1 -0
  212. package/dist/esm/lib/outlook/types.d.ts +22 -0
  213. package/dist/esm/lib/outlook/types.js +2 -0
  214. package/dist/esm/lib/outlook/types.js.map +1 -0
  215. package/dist/esm/mcp/index.d.ts +3 -0
  216. package/dist/esm/mcp/index.js +6 -0
  217. package/dist/esm/mcp/index.js.map +1 -0
  218. package/dist/esm/mcp/prompts/draft-email.d.ts +30 -0
  219. package/dist/esm/mcp/prompts/draft-email.js +37 -0
  220. package/dist/esm/mcp/prompts/draft-email.js.map +1 -0
  221. package/dist/esm/mcp/prompts/index.d.ts +2 -0
  222. package/dist/esm/mcp/prompts/index.js +2 -0
  223. package/dist/esm/mcp/prompts/index.js.map +1 -0
  224. package/dist/esm/mcp/prompts/query-syntax.d.ts +19 -0
  225. package/dist/esm/mcp/prompts/query-syntax.js +75 -0
  226. package/dist/esm/mcp/prompts/query-syntax.js.map +1 -0
  227. package/dist/esm/mcp/resources/email.d.ts +11 -0
  228. package/dist/esm/mcp/resources/email.js +69 -0
  229. package/dist/esm/mcp/resources/email.js.map +1 -0
  230. package/dist/esm/mcp/resources/index.d.ts +1 -0
  231. package/dist/esm/mcp/resources/index.js +1 -0
  232. package/dist/esm/mcp/resources/index.js.map +1 -0
  233. package/dist/esm/mcp/tools/categories-list.d.ts +96 -0
  234. package/dist/esm/mcp/tools/categories-list.js +78 -0
  235. package/dist/esm/mcp/tools/categories-list.js.map +1 -0
  236. package/dist/esm/mcp/tools/index.d.ts +11 -0
  237. package/dist/esm/mcp/tools/index.js +11 -0
  238. package/dist/esm/mcp/tools/index.js.map +1 -0
  239. package/dist/esm/mcp/tools/label-add.d.ts +44 -0
  240. package/dist/esm/mcp/tools/label-add.js +75 -0
  241. package/dist/esm/mcp/tools/label-add.js.map +1 -0
  242. package/dist/esm/mcp/tools/label-delete.d.ts +54 -0
  243. package/dist/esm/mcp/tools/label-delete.js +166 -0
  244. package/dist/esm/mcp/tools/label-delete.js.map +1 -0
  245. package/dist/esm/mcp/tools/labels-list.d.ts +96 -0
  246. package/dist/esm/mcp/tools/labels-list.js +78 -0
  247. package/dist/esm/mcp/tools/labels-list.js.map +1 -0
  248. package/dist/esm/mcp/tools/message-get.d.ts +110 -0
  249. package/dist/esm/mcp/tools/message-get.js +117 -0
  250. package/dist/esm/mcp/tools/message-get.js.map +1 -0
  251. package/dist/esm/mcp/tools/message-mark-read.d.ts +42 -0
  252. package/dist/esm/mcp/tools/message-mark-read.js +80 -0
  253. package/dist/esm/mcp/tools/message-mark-read.js.map +1 -0
  254. package/dist/esm/mcp/tools/message-move-to-trash.d.ts +54 -0
  255. package/dist/esm/mcp/tools/message-move-to-trash.js +177 -0
  256. package/dist/esm/mcp/tools/message-move-to-trash.js.map +1 -0
  257. package/dist/esm/mcp/tools/message-respond.d.ts +52 -0
  258. package/dist/esm/mcp/tools/message-respond.js +89 -0
  259. package/dist/esm/mcp/tools/message-respond.js.map +1 -0
  260. package/dist/esm/mcp/tools/message-search.d.ts +138 -0
  261. package/dist/esm/mcp/tools/message-search.js +184 -0
  262. package/dist/esm/mcp/tools/message-search.js.map +1 -0
  263. package/dist/esm/mcp/tools/message-send.d.ts +66 -0
  264. package/dist/esm/mcp/tools/message-send.js +111 -0
  265. package/dist/esm/mcp/tools/message-send.js.map +1 -0
  266. package/dist/esm/mcp/tools/messages-export-csv.d.ts +72 -0
  267. package/dist/esm/mcp/tools/messages-export-csv.js +273 -0
  268. package/dist/esm/mcp/tools/messages-export-csv.js.map +1 -0
  269. package/dist/esm/package.json +1 -0
  270. package/dist/esm/schemas/index.d.ts +2 -0
  271. package/dist/esm/schemas/index.js +2 -0
  272. package/dist/esm/schemas/index.js.map +1 -0
  273. package/dist/esm/schemas/outlook-query-schema.d.ts +53 -0
  274. package/dist/esm/schemas/outlook-query-schema.js +63 -0
  275. package/dist/esm/schemas/outlook-query-schema.js.map +1 -0
  276. package/dist/esm/schemas/outlook-validation.d.ts +428 -0
  277. package/dist/esm/schemas/outlook-validation.js +388 -0
  278. package/dist/esm/schemas/outlook-validation.js.map +1 -0
  279. package/dist/esm/setup/config.d.ts +50 -0
  280. package/dist/esm/setup/config.js +180 -0
  281. package/dist/esm/setup/config.js.map +1 -0
  282. package/dist/esm/setup/http.d.ts +8 -0
  283. package/dist/esm/setup/http.js +61 -0
  284. package/dist/esm/setup/http.js.map +1 -0
  285. package/dist/esm/setup/index.d.ts +5 -0
  286. package/dist/esm/setup/index.js +5 -0
  287. package/dist/esm/setup/index.js.map +1 -0
  288. package/dist/esm/setup/oauth-microsoft.d.ts +43 -0
  289. package/dist/esm/setup/oauth-microsoft.js +169 -0
  290. package/dist/esm/setup/oauth-microsoft.js.map +1 -0
  291. package/dist/esm/setup/runtime.d.ts +11 -0
  292. package/dist/esm/setup/runtime.js +115 -0
  293. package/dist/esm/setup/runtime.js.map +1 -0
  294. package/dist/esm/setup/stdio.d.ts +7 -0
  295. package/dist/esm/setup/stdio.js +38 -0
  296. package/dist/esm/setup/stdio.js.map +1 -0
  297. package/dist/esm/types.d.ts +54 -0
  298. package/dist/esm/types.js +1 -0
  299. package/dist/esm/types.js.map +1 -0
  300. package/package.json +111 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/message-get.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText, normalizeDateToISO as toIsoUtc } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { createFieldsSchema, filterFields, parseFields, type ToolModule } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nconst inputSchema = z.object({\n id: z.coerce.string().trim().min(1).describe('Outlook message ID to retrieve'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schema - uses item: wrapper for consistency with standard vocabulary\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n item: EmailDetailSchema,\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Get an Outlook message by ID with flexible field selection',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ id, fields, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n\n logger.info('outlook.message.get called', { id, fields: fields || 'all' });\n\n if (!id) {\n logger.info('outlook.message.get missing id');\n throw new McpError(ErrorCode.InvalidParams, 'Missing id');\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n const message = (await graph.api(`/me/messages/${encodeURIComponent(id)}`).get()) as MicrosoftGraph.Message;\n\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent = message.body?.content ?? '';\n const isHtml = message.body?.contentType?.toLowerCase() === 'html';\n\n if (isHtml && excludeThreadHistory) {\n // Remove thread history from HTML\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n // Convert HTML to plain text (thread extraction happens inside if excludeThreadHistory was true)\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body?.content ?? '');\n }\n\n // Build full message data\n const payload = {\n id: message.id,\n subject: message.subject,\n from: message.from?.emailAddress?.address,\n date: toIsoUtc(message.receivedDateTime) || message.receivedDateTime,\n snippet: message.bodyPreview,\n body: bodyContent,\n bodyContentType: contentType,\n };\n\n // Filter based on requested fields\n const filteredPayload = filterFields(payload, requestedFields);\n\n logger.info('outlook.message.get success', { id: payload.id, subject: payload.subject, from: payload.from, date: payload.date, fields: fields || 'all' });\n\n const result: Output = {\n type: 'success' as const,\n item: filteredPayload as z.infer<typeof EmailDetailSchema>,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.message.get error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error getting message: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-get',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EMAIL_COMMON_PATTERNS","EMAIL_FIELD_DESCRIPTIONS","EMAIL_FIELDS","EmailContentTypeSchema","EmailDetailSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","normalizeDateToISO","toIsoUtc","schemas","AuthRequiredBranchSchema","createFieldsSchema","filterFields","parseFields","Client","ErrorCode","McpError","z","inputSchema","object","id","coerce","string","trim","min","describe","fields","availableFields","fieldDescriptions","commonPatterns","resourceName","contentType","excludeThreadHistory","successBranchSchema","type","literal","item","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","requestedFields","info","InvalidParams","message","graph","initWithMiddleware","authProvider","authContext","auth","api","encodeURIComponent","get","bodyContent","body","content","isHtml","toLowerCase","payload","subject","from","emailAddress","address","date","receivedDateTime","snippet","bodyPreview","bodyContentType","filteredPayload","text","JSON","stringify","structuredContent","error","Error","String","InternalError","stack","undefined","createTool","name"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';
2
+ import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js';
3
+ import { z } from 'zod';
4
+ declare const inputSchema: z.ZodObject<{
5
+ id: z.ZodCoercedString<unknown>;
6
+ }, z.core.$strip>;
7
+ declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
8
+ success: z.ZodBoolean;
9
+ id: z.ZodOptional<z.ZodString>;
10
+ type: z.ZodLiteral<"success">;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ type: z.ZodLiteral<"auth_required">;
13
+ provider: z.ZodString;
14
+ message: z.ZodString;
15
+ url: z.ZodOptional<z.ZodString>;
16
+ }, z.core.$strip>], "type">;
17
+ export type Input = z.infer<typeof inputSchema>;
18
+ export type Output = z.infer<typeof outputSchema>;
19
+ declare function handler({ id }: Input, extra: EnrichedExtra): Promise<CallToolResult>;
20
+ export default function createTool(): {
21
+ name: string;
22
+ config: {
23
+ readonly description: "Mark an Outlook message as read";
24
+ readonly inputSchema: z.ZodObject<{
25
+ id: z.ZodCoercedString<unknown>;
26
+ }, z.core.$strip>;
27
+ readonly outputSchema: z.ZodObject<{
28
+ result: z.ZodDiscriminatedUnion<[z.ZodObject<{
29
+ success: z.ZodBoolean;
30
+ id: z.ZodOptional<z.ZodString>;
31
+ type: z.ZodLiteral<"success">;
32
+ }, z.core.$strip>, z.ZodObject<{
33
+ type: z.ZodLiteral<"auth_required">;
34
+ provider: z.ZodString;
35
+ message: z.ZodString;
36
+ url: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>], "type">;
38
+ }, z.core.$strip>;
39
+ };
40
+ handler: typeof handler;
41
+ };
42
+ export {};
@@ -0,0 +1,80 @@
1
+ import { schemas } from '@mcp-z/oauth-microsoft';
2
+ const { AuthRequiredBranchSchema } = schemas;
3
+ import { Client } from '@microsoft/microsoft-graph-client';
4
+ import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
5
+ import { z } from 'zod';
6
+ const SuccessSchema = z.object({
7
+ success: z.boolean().describe('Whether the operation completed successfully'),
8
+ id: z.string().optional().describe('Message ID that was marked as read')
9
+ });
10
+ const inputSchema = z.object({
11
+ id: z.coerce.string().trim().min(1).describe('Outlook message ID to mark as read')
12
+ });
13
+ // Success branch schema
14
+ const successBranchSchema = SuccessSchema.extend({
15
+ type: z.literal('success')
16
+ });
17
+ // Output schema with auth_required support
18
+ const outputSchema = z.discriminatedUnion('type', [
19
+ successBranchSchema,
20
+ AuthRequiredBranchSchema
21
+ ]);
22
+ const config = {
23
+ description: 'Mark an Outlook message as read',
24
+ inputSchema: inputSchema,
25
+ outputSchema: z.object({
26
+ result: outputSchema
27
+ })
28
+ };
29
+ async function handler({ id }, extra) {
30
+ const logger = extra.logger;
31
+ logger.info('outlook-message-mark-read called', {
32
+ id
33
+ });
34
+ if (!id) {
35
+ logger.info('outlook-message-mark-read missing id');
36
+ throw new McpError(ErrorCode.InvalidParams, 'Missing id');
37
+ }
38
+ try {
39
+ const graph = Client.initWithMiddleware({
40
+ authProvider: extra.authContext.auth
41
+ });
42
+ await graph.api(`/me/messages/${encodeURIComponent(id)}`).update({
43
+ isRead: true
44
+ });
45
+ logger.info('outlook-message-mark-read success', {
46
+ id
47
+ });
48
+ const result = {
49
+ type: 'success',
50
+ success: true,
51
+ id
52
+ };
53
+ return {
54
+ content: [
55
+ {
56
+ type: 'text',
57
+ text: JSON.stringify(result)
58
+ }
59
+ ],
60
+ structuredContent: {
61
+ result
62
+ }
63
+ };
64
+ } catch (error) {
65
+ const message = error instanceof Error ? error.message : String(error);
66
+ logger.error('outlook-message-mark-read error', {
67
+ error: message
68
+ });
69
+ throw new McpError(ErrorCode.InternalError, `Error marking message as read: ${message}`, {
70
+ stack: error instanceof Error ? error.stack : undefined
71
+ });
72
+ }
73
+ }
74
+ export default function createTool() {
75
+ return {
76
+ name: 'message-mark-read',
77
+ config,
78
+ handler
79
+ };
80
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/message-mark-read.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nconst SuccessSchema = z.object({\n success: z.boolean().describe('Whether the operation completed successfully'),\n id: z.string().optional().describe('Message ID that was marked as read'),\n});\n\nconst inputSchema = z.object({\n id: z.coerce.string().trim().min(1).describe('Outlook message ID to mark as read'),\n});\n\n// Success branch schema\nconst successBranchSchema = SuccessSchema.extend({\n type: z.literal('success'),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Mark an Outlook message as read',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ id }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n logger.info('outlook-message-mark-read called', { id });\n\n if (!id) {\n logger.info('outlook-message-mark-read missing id');\n throw new McpError(ErrorCode.InvalidParams, 'Missing id');\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n await graph.api(`/me/messages/${encodeURIComponent(id)}`).update({ isRead: true });\n\n logger.info('outlook-message-mark-read success', { id });\n\n const result: Output = {\n type: 'success' as const,\n success: true,\n id,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook-message-mark-read error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error marking message as read: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-mark-read',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","Client","ErrorCode","McpError","z","SuccessSchema","object","success","boolean","describe","id","string","optional","inputSchema","coerce","trim","min","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","InvalidParams","graph","initWithMiddleware","authProvider","authContext","auth","api","encodeURIComponent","update","isRead","content","text","JSON","stringify","structuredContent","error","message","Error","String","InternalError","stack","undefined","createTool","name"],"mappings":"AACA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAGrC,SAASE,MAAM,QAAQ,oCAAoC;AAC3D,SAA8BC,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AAC9F,SAASC,CAAC,QAAQ,MAAM;AAExB,MAAMC,gBAAgBD,EAAEE,MAAM,CAAC;IAC7BC,SAASH,EAAEI,OAAO,GAAGC,QAAQ,CAAC;IAC9BC,IAAIN,EAAEO,MAAM,GAAGC,QAAQ,GAAGH,QAAQ,CAAC;AACrC;AAEA,MAAMI,cAAcT,EAAEE,MAAM,CAAC;IAC3BI,IAAIN,EAAEU,MAAM,CAACH,MAAM,GAAGI,IAAI,GAAGC,GAAG,CAAC,GAAGP,QAAQ,CAAC;AAC/C;AAEA,wBAAwB;AACxB,MAAMQ,sBAAsBZ,cAAca,MAAM,CAAC;IAC/CC,MAAMf,EAAEgB,OAAO,CAAC;AAClB;AAEA,2CAA2C;AAC3C,MAAMC,eAAejB,EAAEkB,kBAAkB,CAAC,QAAQ;IAACL;IAAqBjB;CAAyB;AAEjG,MAAMuB,SAAS;IACbC,aAAa;IACbX,aAAaA;IACbQ,cAAcjB,EAAEE,MAAM,CAAC;QACrBmB,QAAQJ;IACV;AACF;AAKA,eAAeK,QAAQ,EAAEhB,EAAE,EAAS,EAAEiB,KAAoB;IACxD,MAAMC,SAASD,MAAMC,MAAM;IAC3BA,OAAOC,IAAI,CAAC,oCAAoC;QAAEnB;IAAG;IAErD,IAAI,CAACA,IAAI;QACPkB,OAAOC,IAAI,CAAC;QACZ,MAAM,IAAI1B,SAASD,UAAU4B,aAAa,EAAE;IAC9C;IAEA,IAAI;QACF,MAAMC,QAAQ9B,OAAO+B,kBAAkB,CAAC;YAAEC,cAAcN,MAAMO,WAAW,CAACC,IAAI;QAAC;QAC/E,MAAMJ,MAAMK,GAAG,CAAC,CAAC,aAAa,EAAEC,mBAAmB3B,KAAK,EAAE4B,MAAM,CAAC;YAAEC,QAAQ;QAAK;QAEhFX,OAAOC,IAAI,CAAC,qCAAqC;YAAEnB;QAAG;QAEtD,MAAMe,SAAiB;YACrBN,MAAM;YACNZ,SAAS;YACTG;QACF;QAEA,OAAO;YACL8B,SAAS;gBACP;oBACErB,MAAM;oBACNsB,MAAMC,KAAKC,SAAS,CAAClB;gBACvB;aACD;YACDmB,mBAAmB;gBAAEnB;YAAO;QAC9B;IACF,EAAE,OAAOoB,OAAO;QACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;QAChEjB,OAAOiB,KAAK,CAAC,mCAAmC;YAAEA,OAAOC;QAAQ;QAEjE,MAAM,IAAI3C,SAASD,UAAU+C,aAAa,EAAE,CAAC,+BAA+B,EAAEH,SAAS,EAAE;YACvFI,OAAOL,iBAAiBE,QAAQF,MAAMK,KAAK,GAAGC;QAChD;IACF;AACF;AAEA,eAAe,SAASC;IACtB,OAAO;QACLC,MAAM;QACN9B;QACAG;IACF;AACF"}
@@ -0,0 +1,54 @@
1
+ import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';
2
+ import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js';
3
+ import { z } from 'zod';
4
+ declare const inputSchema: z.ZodObject<{
5
+ ids: z.ZodArray<z.ZodCoercedString<unknown>>;
6
+ }, z.core.$strip>;
7
+ declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
8
+ totalRequested: z.ZodNumber;
9
+ successCount: z.ZodNumber;
10
+ failureCount: z.ZodNumber;
11
+ results: z.ZodArray<z.ZodObject<{
12
+ id: z.ZodString;
13
+ success: z.ZodBoolean;
14
+ error: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>>;
16
+ type: z.ZodLiteral<"success">;
17
+ }, z.core.$strip>, z.ZodObject<{
18
+ type: z.ZodLiteral<"auth_required">;
19
+ provider: z.ZodString;
20
+ message: z.ZodString;
21
+ url: z.ZodOptional<z.ZodString>;
22
+ }, z.core.$strip>], "type">;
23
+ export type Input = z.infer<typeof inputSchema>;
24
+ export type Output = z.infer<typeof outputSchema>;
25
+ declare function handler({ ids }: Input, extra: EnrichedExtra): Promise<CallToolResult>;
26
+ export default function createTool(): {
27
+ name: string;
28
+ config: {
29
+ readonly description: "Move Outlook messages to trash (recoverable).";
30
+ readonly inputSchema: z.ZodObject<{
31
+ ids: z.ZodArray<z.ZodCoercedString<unknown>>;
32
+ }, z.core.$strip>;
33
+ readonly outputSchema: z.ZodObject<{
34
+ result: z.ZodDiscriminatedUnion<[z.ZodObject<{
35
+ totalRequested: z.ZodNumber;
36
+ successCount: z.ZodNumber;
37
+ failureCount: z.ZodNumber;
38
+ results: z.ZodArray<z.ZodObject<{
39
+ id: z.ZodString;
40
+ success: z.ZodBoolean;
41
+ error: z.ZodOptional<z.ZodString>;
42
+ }, z.core.$strip>>;
43
+ type: z.ZodLiteral<"success">;
44
+ }, z.core.$strip>, z.ZodObject<{
45
+ type: z.ZodLiteral<"auth_required">;
46
+ provider: z.ZodString;
47
+ message: z.ZodString;
48
+ url: z.ZodOptional<z.ZodString>;
49
+ }, z.core.$strip>], "type">;
50
+ }, z.core.$strip>;
51
+ };
52
+ handler: typeof handler;
53
+ };
54
+ export {};
@@ -0,0 +1,177 @@
1
+ import { schemas } from '@mcp-z/oauth-microsoft';
2
+ const { AuthRequiredBranchSchema } = schemas;
3
+ import { Client } from '@microsoft/microsoft-graph-client';
4
+ import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
5
+ import { z } from 'zod';
6
+ import { CHUNK_SIZE, MAX_BATCH_SIZE } from '../../constants.js';
7
+ const BatchResultSchema = z.object({
8
+ totalRequested: z.number().describe('Total number of messages requested to trash'),
9
+ successCount: z.number().describe('Number of messages successfully moved to trash'),
10
+ failureCount: z.number().describe('Number of messages that failed to move'),
11
+ results: z.array(z.object({
12
+ id: z.string().describe('Message ID'),
13
+ success: z.boolean().describe('Whether the operation succeeded'),
14
+ error: z.string().optional().describe('Error message if operation failed')
15
+ })).describe('Individual results for each message')
16
+ });
17
+ const inputSchema = z.object({
18
+ ids: z.array(z.coerce.string().trim().min(1)).min(1).describe('Outlook message IDs to move to trash')
19
+ });
20
+ // Success branch schema
21
+ const successBranchSchema = BatchResultSchema.extend({
22
+ type: z.literal('success')
23
+ });
24
+ // Output schema with auth_required support
25
+ const outputSchema = z.discriminatedUnion('type', [
26
+ successBranchSchema,
27
+ AuthRequiredBranchSchema
28
+ ]);
29
+ const config = {
30
+ description: 'Move Outlook messages to trash (recoverable).',
31
+ inputSchema: inputSchema,
32
+ outputSchema: z.object({
33
+ result: outputSchema
34
+ })
35
+ };
36
+ async function handler({ ids }, extra) {
37
+ const logger = extra.logger;
38
+ logger.info('outlook-message-move-to-trash called', {
39
+ count: ids.length
40
+ });
41
+ if (!ids || ids.length === 0) {
42
+ logger.info('outlook-message-move-to-trash missing ids');
43
+ throw new McpError(ErrorCode.InvalidParams, 'Missing ids');
44
+ }
45
+ // Validate batch size to prevent memory exhaustion
46
+ if (ids.length > MAX_BATCH_SIZE) {
47
+ logger.info('outlook-message-move-to-trash batch size exceeded', {
48
+ requested: ids.length,
49
+ max: MAX_BATCH_SIZE
50
+ });
51
+ throw new McpError(ErrorCode.InvalidParams, `Batch size ${ids.length} exceeds maximum allowed size of ${MAX_BATCH_SIZE}`);
52
+ }
53
+ // Validate and sanitize IDs
54
+ const validatedIds = [];
55
+ const invalidIds = [];
56
+ for (const id of ids){
57
+ const trimmedId = id.trim();
58
+ if (!trimmedId) {
59
+ invalidIds.push(id);
60
+ continue;
61
+ }
62
+ // Basic Outlook message ID validation - should not contain certain characters
63
+ if (trimmedId.includes('/') || trimmedId.includes('\\') || trimmedId.includes('<') || trimmedId.includes('>')) {
64
+ invalidIds.push(id);
65
+ continue;
66
+ }
67
+ validatedIds.push(trimmedId);
68
+ }
69
+ if (invalidIds.length > 0) {
70
+ logger.info('outlook-message-move-to-trash found invalid ids', {
71
+ invalidIds,
72
+ count: invalidIds.length
73
+ });
74
+ throw new McpError(ErrorCode.InvalidParams, `Found ${invalidIds.length} invalid IDs: ${invalidIds.join(', ')}`);
75
+ }
76
+ if (validatedIds.length === 0) {
77
+ logger.info('outlook-message-move-to-trash no valid ids after validation');
78
+ throw new McpError(ErrorCode.InvalidParams, 'No valid IDs found after validation');
79
+ }
80
+ try {
81
+ const graph = Client.initWithMiddleware({
82
+ authProvider: extra.authContext.auth
83
+ });
84
+ // Process operations in chunks to prevent memory exhaustion
85
+ const allResults = [];
86
+ for(let i = 0; i < validatedIds.length; i += CHUNK_SIZE){
87
+ const chunk = validatedIds.slice(i, i + CHUNK_SIZE);
88
+ logger.info('Processing chunk', {
89
+ chunkIndex: i / CHUNK_SIZE + 1,
90
+ chunkSize: chunk.length,
91
+ totalChunks: Math.ceil(validatedIds.length / CHUNK_SIZE)
92
+ });
93
+ const chunkResults = await Promise.allSettled(chunk.map(async (id)=>{
94
+ await graph.api(`/me/messages/${encodeURIComponent(id)}`).delete();
95
+ return {
96
+ id,
97
+ success: true
98
+ };
99
+ }));
100
+ // Process chunk results
101
+ const processedChunkResults = chunkResults.map((result, chunkIndex)=>{
102
+ const id = chunk[chunkIndex];
103
+ if (!id) {
104
+ throw new Error(`Chunk index ${chunkIndex} is out of bounds for chunk of size ${chunk.length}`);
105
+ }
106
+ if (result.status === 'fulfilled') {
107
+ return {
108
+ id,
109
+ success: true
110
+ };
111
+ }
112
+ // Extract error message more robustly
113
+ let errorMessage = 'Unknown error';
114
+ if (result.reason) {
115
+ if (typeof result.reason === 'string') {
116
+ errorMessage = result.reason;
117
+ } else if (result.reason instanceof Error) {
118
+ errorMessage = result.reason.message;
119
+ } else if (result.reason && typeof result.reason === 'object' && 'message' in result.reason) {
120
+ errorMessage = String(result.reason.message);
121
+ } else if (result.reason && typeof result.reason === 'object' && 'error' in result.reason) {
122
+ errorMessage = String(result.reason.error);
123
+ } else {
124
+ errorMessage = String(result.reason);
125
+ }
126
+ }
127
+ return {
128
+ id,
129
+ success: false,
130
+ error: errorMessage
131
+ };
132
+ });
133
+ allResults.push(...processedChunkResults);
134
+ }
135
+ const successCount = allResults.filter((r)=>r.success).length;
136
+ const failureCount = allResults.filter((r)=>!r.success).length;
137
+ const result = {
138
+ type: 'success',
139
+ totalRequested: validatedIds.length,
140
+ successCount,
141
+ failureCount,
142
+ results: allResults
143
+ };
144
+ logger.info('outlook-message-move-to-trash completed', {
145
+ totalRequested: validatedIds.length,
146
+ successCount,
147
+ failureCount,
148
+ chunksProcessed: Math.ceil(validatedIds.length / CHUNK_SIZE)
149
+ });
150
+ return {
151
+ content: [
152
+ {
153
+ type: 'text',
154
+ text: JSON.stringify(result)
155
+ }
156
+ ],
157
+ structuredContent: {
158
+ result
159
+ }
160
+ };
161
+ } catch (error) {
162
+ const message = error instanceof Error ? error.message : String(error);
163
+ logger.error('outlook-message-move-to-trash error', {
164
+ error: message
165
+ });
166
+ throw new McpError(ErrorCode.InternalError, `Error moving messages to trash: ${message}`, {
167
+ stack: error instanceof Error ? error.stack : undefined
168
+ });
169
+ }
170
+ }
171
+ export default function createTool() {
172
+ return {
173
+ name: 'message-move-to-trash',
174
+ config,
175
+ handler
176
+ };
177
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/message-move-to-trash.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { CHUNK_SIZE, MAX_BATCH_SIZE } from '../../constants.ts';\n\nconst BatchResultSchema = z.object({\n totalRequested: z.number().describe('Total number of messages requested to trash'),\n successCount: z.number().describe('Number of messages successfully moved to trash'),\n failureCount: z.number().describe('Number of messages that failed to move'),\n results: z\n .array(\n z.object({\n id: z.string().describe('Message ID'),\n success: z.boolean().describe('Whether the operation succeeded'),\n error: z.string().optional().describe('Error message if operation failed'),\n })\n )\n .describe('Individual results for each message'),\n});\n\nconst inputSchema = z.object({\n ids: z.array(z.coerce.string().trim().min(1)).min(1).describe('Outlook message IDs to move to trash'),\n});\n\n// Success branch schema\nconst successBranchSchema = BatchResultSchema.extend({\n type: z.literal('success'),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Move Outlook messages to trash (recoverable).',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ ids }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n logger.info('outlook-message-move-to-trash called', { count: ids.length });\n\n if (!ids || ids.length === 0) {\n logger.info('outlook-message-move-to-trash missing ids');\n throw new McpError(ErrorCode.InvalidParams, 'Missing ids');\n }\n\n // Validate batch size to prevent memory exhaustion\n if (ids.length > MAX_BATCH_SIZE) {\n logger.info('outlook-message-move-to-trash batch size exceeded', { requested: ids.length, max: MAX_BATCH_SIZE });\n throw new McpError(ErrorCode.InvalidParams, `Batch size ${ids.length} exceeds maximum allowed size of ${MAX_BATCH_SIZE}`);\n }\n\n // Validate and sanitize IDs\n const validatedIds: string[] = [];\n const invalidIds: string[] = [];\n\n for (const id of ids) {\n const trimmedId = id.trim();\n if (!trimmedId) {\n invalidIds.push(id);\n continue;\n }\n // Basic Outlook message ID validation - should not contain certain characters\n if (trimmedId.includes('/') || trimmedId.includes('\\\\') || trimmedId.includes('<') || trimmedId.includes('>')) {\n invalidIds.push(id);\n continue;\n }\n validatedIds.push(trimmedId);\n }\n\n if (invalidIds.length > 0) {\n logger.info('outlook-message-move-to-trash found invalid ids', { invalidIds, count: invalidIds.length });\n throw new McpError(ErrorCode.InvalidParams, `Found ${invalidIds.length} invalid IDs: ${invalidIds.join(', ')}`);\n }\n\n if (validatedIds.length === 0) {\n logger.info('outlook-message-move-to-trash no valid ids after validation');\n throw new McpError(ErrorCode.InvalidParams, 'No valid IDs found after validation');\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n // Process operations in chunks to prevent memory exhaustion\n const allResults: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (let i = 0; i < validatedIds.length; i += CHUNK_SIZE) {\n const chunk = validatedIds.slice(i, i + CHUNK_SIZE);\n logger.info('Processing chunk', { chunkIndex: i / CHUNK_SIZE + 1, chunkSize: chunk.length, totalChunks: Math.ceil(validatedIds.length / CHUNK_SIZE) });\n\n const chunkResults = await Promise.allSettled(\n chunk.map(async (id) => {\n await graph.api(`/me/messages/${encodeURIComponent(id)}`).delete();\n return { id, success: true };\n })\n );\n\n // Process chunk results\n const processedChunkResults = chunkResults.map((result, chunkIndex) => {\n const id = chunk[chunkIndex];\n if (!id) {\n throw new Error(`Chunk index ${chunkIndex} is out of bounds for chunk of size ${chunk.length}`);\n }\n if (result.status === 'fulfilled') {\n return { id, success: true };\n }\n\n // Extract error message more robustly\n let errorMessage = 'Unknown error';\n if (result.reason) {\n if (typeof result.reason === 'string') {\n errorMessage = result.reason;\n } else if (result.reason instanceof Error) {\n errorMessage = result.reason.message;\n } else if (result.reason && typeof result.reason === 'object' && 'message' in result.reason) {\n errorMessage = String(result.reason.message);\n } else if (result.reason && typeof result.reason === 'object' && 'error' in result.reason) {\n errorMessage = String(result.reason.error);\n } else {\n errorMessage = String(result.reason);\n }\n }\n\n return { id, success: false, error: errorMessage };\n });\n\n allResults.push(...processedChunkResults);\n }\n\n const successCount = allResults.filter((r) => r.success).length;\n const failureCount = allResults.filter((r) => !r.success).length;\n\n const result: Output = {\n type: 'success' as const,\n totalRequested: validatedIds.length,\n successCount,\n failureCount,\n results: allResults,\n };\n\n logger.info('outlook-message-move-to-trash completed', {\n totalRequested: validatedIds.length,\n successCount,\n failureCount,\n chunksProcessed: Math.ceil(validatedIds.length / CHUNK_SIZE),\n });\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook-message-move-to-trash error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error moving messages to trash: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-move-to-trash',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","Client","ErrorCode","McpError","z","CHUNK_SIZE","MAX_BATCH_SIZE","BatchResultSchema","object","totalRequested","number","describe","successCount","failureCount","results","array","id","string","success","boolean","error","optional","inputSchema","ids","coerce","trim","min","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","count","length","InvalidParams","requested","max","validatedIds","invalidIds","trimmedId","push","includes","join","graph","initWithMiddleware","authProvider","authContext","auth","allResults","i","chunk","slice","chunkIndex","chunkSize","totalChunks","Math","ceil","chunkResults","Promise","allSettled","map","api","encodeURIComponent","delete","processedChunkResults","Error","status","errorMessage","reason","message","String","filter","r","chunksProcessed","content","text","JSON","stringify","structuredContent","InternalError","stack","undefined","createTool","name"],"mappings":"AACA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAGrC,SAASE,MAAM,QAAQ,oCAAoC;AAC3D,SAA8BC,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AAC9F,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,UAAU,EAAEC,cAAc,QAAQ,qBAAqB;AAEhE,MAAMC,oBAAoBH,EAAEI,MAAM,CAAC;IACjCC,gBAAgBL,EAAEM,MAAM,GAAGC,QAAQ,CAAC;IACpCC,cAAcR,EAAEM,MAAM,GAAGC,QAAQ,CAAC;IAClCE,cAAcT,EAAEM,MAAM,GAAGC,QAAQ,CAAC;IAClCG,SAASV,EACNW,KAAK,CACJX,EAAEI,MAAM,CAAC;QACPQ,IAAIZ,EAAEa,MAAM,GAAGN,QAAQ,CAAC;QACxBO,SAASd,EAAEe,OAAO,GAAGR,QAAQ,CAAC;QAC9BS,OAAOhB,EAAEa,MAAM,GAAGI,QAAQ,GAAGV,QAAQ,CAAC;IACxC,IAEDA,QAAQ,CAAC;AACd;AAEA,MAAMW,cAAclB,EAAEI,MAAM,CAAC;IAC3Be,KAAKnB,EAAEW,KAAK,CAACX,EAAEoB,MAAM,CAACP,MAAM,GAAGQ,IAAI,GAAGC,GAAG,CAAC,IAAIA,GAAG,CAAC,GAAGf,QAAQ,CAAC;AAChE;AAEA,wBAAwB;AACxB,MAAMgB,sBAAsBpB,kBAAkBqB,MAAM,CAAC;IACnDC,MAAMzB,EAAE0B,OAAO,CAAC;AAClB;AAEA,2CAA2C;AAC3C,MAAMC,eAAe3B,EAAE4B,kBAAkB,CAAC,QAAQ;IAACL;IAAqB3B;CAAyB;AAEjG,MAAMiC,SAAS;IACbC,aAAa;IACbZ,aAAaA;IACbS,cAAc3B,EAAEI,MAAM,CAAC;QACrB2B,QAAQJ;IACV;AACF;AAKA,eAAeK,QAAQ,EAAEb,GAAG,EAAS,EAAEc,KAAoB;IACzD,MAAMC,SAASD,MAAMC,MAAM;IAC3BA,OAAOC,IAAI,CAAC,wCAAwC;QAAEC,OAAOjB,IAAIkB,MAAM;IAAC;IAExE,IAAI,CAAClB,OAAOA,IAAIkB,MAAM,KAAK,GAAG;QAC5BH,OAAOC,IAAI,CAAC;QACZ,MAAM,IAAIpC,SAASD,UAAUwC,aAAa,EAAE;IAC9C;IAEA,mDAAmD;IACnD,IAAInB,IAAIkB,MAAM,GAAGnC,gBAAgB;QAC/BgC,OAAOC,IAAI,CAAC,qDAAqD;YAAEI,WAAWpB,IAAIkB,MAAM;YAAEG,KAAKtC;QAAe;QAC9G,MAAM,IAAIH,SAASD,UAAUwC,aAAa,EAAE,CAAC,WAAW,EAAEnB,IAAIkB,MAAM,CAAC,iCAAiC,EAAEnC,gBAAgB;IAC1H;IAEA,4BAA4B;IAC5B,MAAMuC,eAAyB,EAAE;IACjC,MAAMC,aAAuB,EAAE;IAE/B,KAAK,MAAM9B,MAAMO,IAAK;QACpB,MAAMwB,YAAY/B,GAAGS,IAAI;QACzB,IAAI,CAACsB,WAAW;YACdD,WAAWE,IAAI,CAAChC;YAChB;QACF;QACA,8EAA8E;QAC9E,IAAI+B,UAAUE,QAAQ,CAAC,QAAQF,UAAUE,QAAQ,CAAC,SAASF,UAAUE,QAAQ,CAAC,QAAQF,UAAUE,QAAQ,CAAC,MAAM;YAC7GH,WAAWE,IAAI,CAAChC;YAChB;QACF;QACA6B,aAAaG,IAAI,CAACD;IACpB;IAEA,IAAID,WAAWL,MAAM,GAAG,GAAG;QACzBH,OAAOC,IAAI,CAAC,mDAAmD;YAAEO;YAAYN,OAAOM,WAAWL,MAAM;QAAC;QACtG,MAAM,IAAItC,SAASD,UAAUwC,aAAa,EAAE,CAAC,MAAM,EAAEI,WAAWL,MAAM,CAAC,cAAc,EAAEK,WAAWI,IAAI,CAAC,OAAO;IAChH;IAEA,IAAIL,aAAaJ,MAAM,KAAK,GAAG;QAC7BH,OAAOC,IAAI,CAAC;QACZ,MAAM,IAAIpC,SAASD,UAAUwC,aAAa,EAAE;IAC9C;IAEA,IAAI;QACF,MAAMS,QAAQlD,OAAOmD,kBAAkB,CAAC;YAAEC,cAAchB,MAAMiB,WAAW,CAACC,IAAI;QAAC;QAC/E,4DAA4D;QAC5D,MAAMC,aAAsE,EAAE;QAE9E,IAAK,IAAIC,IAAI,GAAGA,IAAIZ,aAAaJ,MAAM,EAAEgB,KAAKpD,WAAY;YACxD,MAAMqD,QAAQb,aAAac,KAAK,CAACF,GAAGA,IAAIpD;YACxCiC,OAAOC,IAAI,CAAC,oBAAoB;gBAAEqB,YAAYH,IAAIpD,aAAa;gBAAGwD,WAAWH,MAAMjB,MAAM;gBAAEqB,aAAaC,KAAKC,IAAI,CAACnB,aAAaJ,MAAM,GAAGpC;YAAY;YAEpJ,MAAM4D,eAAe,MAAMC,QAAQC,UAAU,CAC3CT,MAAMU,GAAG,CAAC,OAAOpD;gBACf,MAAMmC,MAAMkB,GAAG,CAAC,CAAC,aAAa,EAAEC,mBAAmBtD,KAAK,EAAEuD,MAAM;gBAChE,OAAO;oBAAEvD;oBAAIE,SAAS;gBAAK;YAC7B;YAGF,wBAAwB;YACxB,MAAMsD,wBAAwBP,aAAaG,GAAG,CAAC,CAACjC,QAAQyB;gBACtD,MAAM5C,KAAK0C,KAAK,CAACE,WAAW;gBAC5B,IAAI,CAAC5C,IAAI;oBACP,MAAM,IAAIyD,MAAM,CAAC,YAAY,EAAEb,WAAW,oCAAoC,EAAEF,MAAMjB,MAAM,EAAE;gBAChG;gBACA,IAAIN,OAAOuC,MAAM,KAAK,aAAa;oBACjC,OAAO;wBAAE1D;wBAAIE,SAAS;oBAAK;gBAC7B;gBAEA,sCAAsC;gBACtC,IAAIyD,eAAe;gBACnB,IAAIxC,OAAOyC,MAAM,EAAE;oBACjB,IAAI,OAAOzC,OAAOyC,MAAM,KAAK,UAAU;wBACrCD,eAAexC,OAAOyC,MAAM;oBAC9B,OAAO,IAAIzC,OAAOyC,MAAM,YAAYH,OAAO;wBACzCE,eAAexC,OAAOyC,MAAM,CAACC,OAAO;oBACtC,OAAO,IAAI1C,OAAOyC,MAAM,IAAI,OAAOzC,OAAOyC,MAAM,KAAK,YAAY,aAAazC,OAAOyC,MAAM,EAAE;wBAC3FD,eAAeG,OAAO3C,OAAOyC,MAAM,CAACC,OAAO;oBAC7C,OAAO,IAAI1C,OAAOyC,MAAM,IAAI,OAAOzC,OAAOyC,MAAM,KAAK,YAAY,WAAWzC,OAAOyC,MAAM,EAAE;wBACzFD,eAAeG,OAAO3C,OAAOyC,MAAM,CAACxD,KAAK;oBAC3C,OAAO;wBACLuD,eAAeG,OAAO3C,OAAOyC,MAAM;oBACrC;gBACF;gBAEA,OAAO;oBAAE5D;oBAAIE,SAAS;oBAAOE,OAAOuD;gBAAa;YACnD;YAEAnB,WAAWR,IAAI,IAAIwB;QACrB;QAEA,MAAM5D,eAAe4C,WAAWuB,MAAM,CAAC,CAACC,IAAMA,EAAE9D,OAAO,EAAEuB,MAAM;QAC/D,MAAM5B,eAAe2C,WAAWuB,MAAM,CAAC,CAACC,IAAM,CAACA,EAAE9D,OAAO,EAAEuB,MAAM;QAEhE,MAAMN,SAAiB;YACrBN,MAAM;YACNpB,gBAAgBoC,aAAaJ,MAAM;YACnC7B;YACAC;YACAC,SAAS0C;QACX;QAEAlB,OAAOC,IAAI,CAAC,2CAA2C;YACrD9B,gBAAgBoC,aAAaJ,MAAM;YACnC7B;YACAC;YACAoE,iBAAiBlB,KAAKC,IAAI,CAACnB,aAAaJ,MAAM,GAAGpC;QACnD;QAEA,OAAO;YACL6E,SAAS;gBACP;oBACErD,MAAM;oBACNsD,MAAMC,KAAKC,SAAS,CAAClD;gBACvB;aACD;YACDmD,mBAAmB;gBAAEnD;YAAO;QAC9B;IACF,EAAE,OAAOf,OAAO;QACd,MAAMyD,UAAUzD,iBAAiBqD,QAAQrD,MAAMyD,OAAO,GAAGC,OAAO1D;QAChEkB,OAAOlB,KAAK,CAAC,uCAAuC;YAAEA,OAAOyD;QAAQ;QAErE,MAAM,IAAI1E,SAASD,UAAUqF,aAAa,EAAE,CAAC,gCAAgC,EAAEV,SAAS,EAAE;YACxFW,OAAOpE,iBAAiBqD,QAAQrD,MAAMoE,KAAK,GAAGC;QAChD;IACF;AACF;AAEA,eAAe,SAASC;IACtB,OAAO;QACLC,MAAM;QACN1D;QACAG;IACF;AACF"}
@@ -0,0 +1,52 @@
1
+ import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';
2
+ import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js';
3
+ import { z } from 'zod';
4
+ declare const inputSchema: z.ZodObject<{
5
+ id: z.ZodCoercedString<unknown>;
6
+ body: z.ZodCoercedString<unknown>;
7
+ contentType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
8
+ text: "text";
9
+ html: "html";
10
+ }>>>;
11
+ }, z.core.$strip>;
12
+ declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
13
+ success: z.ZodBoolean;
14
+ id: z.ZodOptional<z.ZodString>;
15
+ type: z.ZodLiteral<"success">;
16
+ }, z.core.$strip>, z.ZodObject<{
17
+ type: z.ZodLiteral<"auth_required">;
18
+ provider: z.ZodString;
19
+ message: z.ZodString;
20
+ url: z.ZodOptional<z.ZodString>;
21
+ }, z.core.$strip>], "type">;
22
+ export type Input = z.infer<typeof inputSchema>;
23
+ export type Output = z.infer<typeof outputSchema>;
24
+ declare function handler({ id, body, contentType }: Input, extra: EnrichedExtra): Promise<CallToolResult>;
25
+ export default function createTool(): {
26
+ name: string;
27
+ config: {
28
+ readonly description: "Reply to an Outlook message";
29
+ readonly inputSchema: z.ZodObject<{
30
+ id: z.ZodCoercedString<unknown>;
31
+ body: z.ZodCoercedString<unknown>;
32
+ contentType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
33
+ text: "text";
34
+ html: "html";
35
+ }>>>;
36
+ }, z.core.$strip>;
37
+ readonly outputSchema: z.ZodObject<{
38
+ result: z.ZodDiscriminatedUnion<[z.ZodObject<{
39
+ success: z.ZodBoolean;
40
+ id: z.ZodOptional<z.ZodString>;
41
+ type: z.ZodLiteral<"success">;
42
+ }, z.core.$strip>, z.ZodObject<{
43
+ type: z.ZodLiteral<"auth_required">;
44
+ provider: z.ZodString;
45
+ message: z.ZodString;
46
+ url: z.ZodOptional<z.ZodString>;
47
+ }, z.core.$strip>], "type">;
48
+ }, z.core.$strip>;
49
+ };
50
+ handler: typeof handler;
51
+ };
52
+ export {};
@@ -0,0 +1,89 @@
1
+ import { ComposeContentTypeSchema } from '@mcp-z/email';
2
+ import { schemas } from '@mcp-z/oauth-microsoft';
3
+ const { AuthRequiredBranchSchema } = schemas;
4
+ import { Client } from '@microsoft/microsoft-graph-client';
5
+ import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
6
+ import { z } from 'zod';
7
+ const SuccessSchema = z.object({
8
+ success: z.boolean().describe('Whether the reply was sent successfully'),
9
+ id: z.string().optional().describe('Original message ID that was replied to')
10
+ });
11
+ const inputSchema = z.object({
12
+ id: z.coerce.string().trim().min(1).describe('Outlook message ID to reply to'),
13
+ body: z.coerce.string().trim().min(1).describe('Reply body content (plain text or HTML)'),
14
+ contentType: ComposeContentTypeSchema
15
+ });
16
+ // Success branch schema
17
+ const successBranchSchema = SuccessSchema.extend({
18
+ type: z.literal('success')
19
+ });
20
+ // Output schema with auth_required support
21
+ const outputSchema = z.discriminatedUnion('type', [
22
+ successBranchSchema,
23
+ AuthRequiredBranchSchema
24
+ ]);
25
+ const config = {
26
+ description: 'Reply to an Outlook message',
27
+ inputSchema: inputSchema,
28
+ outputSchema: z.object({
29
+ result: outputSchema
30
+ })
31
+ };
32
+ async function handler({ id, body, contentType }, extra) {
33
+ const logger = extra.logger;
34
+ logger.info('outlook.respond called', {
35
+ id,
36
+ hasBody: !!body
37
+ });
38
+ if (!id || !body) {
39
+ logger.info('outlook.respond missing id or body');
40
+ throw new McpError(ErrorCode.InvalidParams, 'Missing id or body');
41
+ }
42
+ try {
43
+ const graph = Client.initWithMiddleware({
44
+ authProvider: extra.authContext.auth
45
+ });
46
+ await graph.api(`/me/messages/${encodeURIComponent(id)}/reply`).post({
47
+ message: {
48
+ body: {
49
+ contentType: contentType === 'html' ? 'HTML' : 'Text',
50
+ content: body
51
+ }
52
+ }
53
+ });
54
+ logger.info('outlook.respond success', {
55
+ id
56
+ });
57
+ const result = {
58
+ type: 'success',
59
+ success: true,
60
+ id
61
+ };
62
+ return {
63
+ content: [
64
+ {
65
+ type: 'text',
66
+ text: JSON.stringify(result)
67
+ }
68
+ ],
69
+ structuredContent: {
70
+ result
71
+ }
72
+ };
73
+ } catch (error) {
74
+ const message = error instanceof Error ? error.message : String(error);
75
+ logger.error('outlook.respond error', {
76
+ error: message
77
+ });
78
+ throw new McpError(ErrorCode.InternalError, `Error replying to message: ${message}`, {
79
+ stack: error instanceof Error ? error.stack : undefined
80
+ });
81
+ }
82
+ }
83
+ export default function createTool() {
84
+ return {
85
+ name: 'message-respond',
86
+ config,
87
+ handler
88
+ };
89
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/message-respond.ts"],"sourcesContent":["import { ComposeContentTypeSchema } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nconst SuccessSchema = z.object({\n success: z.boolean().describe('Whether the reply was sent successfully'),\n id: z.string().optional().describe('Original message ID that was replied to'),\n});\n\nconst inputSchema = z.object({\n id: z.coerce.string().trim().min(1).describe('Outlook message ID to reply to'),\n body: z.coerce.string().trim().min(1).describe('Reply body content (plain text or HTML)'),\n contentType: ComposeContentTypeSchema,\n});\n\n// Success branch schema\nconst successBranchSchema = SuccessSchema.extend({\n type: z.literal('success'),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Reply to an Outlook message',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ id, body, contentType }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n logger.info('outlook.respond called', { id, hasBody: !!body });\n\n if (!id || !body) {\n logger.info('outlook.respond missing id or body');\n throw new McpError(ErrorCode.InvalidParams, 'Missing id or body');\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n await graph.api(`/me/messages/${encodeURIComponent(id)}/reply`).post({ message: { body: { contentType: contentType === 'html' ? 'HTML' : 'Text', content: body } } });\n\n logger.info('outlook.respond success', { id });\n\n const result: Output = {\n type: 'success' as const,\n success: true,\n id,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.respond error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error replying to message: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-respond',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["ComposeContentTypeSchema","schemas","AuthRequiredBranchSchema","Client","ErrorCode","McpError","z","SuccessSchema","object","success","boolean","describe","id","string","optional","inputSchema","coerce","trim","min","body","contentType","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","hasBody","InvalidParams","graph","initWithMiddleware","authProvider","authContext","auth","api","encodeURIComponent","post","message","content","text","JSON","stringify","structuredContent","error","Error","String","InternalError","stack","undefined","createTool","name"],"mappings":"AAAA,SAASA,wBAAwB,QAAQ,eAAe;AAExD,SAASC,OAAO,QAAQ,yBAAyB;AAEjD,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAGrC,SAASE,MAAM,QAAQ,oCAAoC;AAC3D,SAA8BC,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AAC9F,SAASC,CAAC,QAAQ,MAAM;AAExB,MAAMC,gBAAgBD,EAAEE,MAAM,CAAC;IAC7BC,SAASH,EAAEI,OAAO,GAAGC,QAAQ,CAAC;IAC9BC,IAAIN,EAAEO,MAAM,GAAGC,QAAQ,GAAGH,QAAQ,CAAC;AACrC;AAEA,MAAMI,cAAcT,EAAEE,MAAM,CAAC;IAC3BI,IAAIN,EAAEU,MAAM,CAACH,MAAM,GAAGI,IAAI,GAAGC,GAAG,CAAC,GAAGP,QAAQ,CAAC;IAC7CQ,MAAMb,EAAEU,MAAM,CAACH,MAAM,GAAGI,IAAI,GAAGC,GAAG,CAAC,GAAGP,QAAQ,CAAC;IAC/CS,aAAapB;AACf;AAEA,wBAAwB;AACxB,MAAMqB,sBAAsBd,cAAce,MAAM,CAAC;IAC/CC,MAAMjB,EAAEkB,OAAO,CAAC;AAClB;AAEA,2CAA2C;AAC3C,MAAMC,eAAenB,EAAEoB,kBAAkB,CAAC,QAAQ;IAACL;IAAqBnB;CAAyB;AAEjG,MAAMyB,SAAS;IACbC,aAAa;IACbb,aAAaA;IACbU,cAAcnB,EAAEE,MAAM,CAAC;QACrBqB,QAAQJ;IACV;AACF;AAKA,eAAeK,QAAQ,EAAElB,EAAE,EAAEO,IAAI,EAAEC,WAAW,EAAS,EAAEW,KAAoB;IAC3E,MAAMC,SAASD,MAAMC,MAAM;IAC3BA,OAAOC,IAAI,CAAC,0BAA0B;QAAErB;QAAIsB,SAAS,CAAC,CAACf;IAAK;IAE5D,IAAI,CAACP,MAAM,CAACO,MAAM;QAChBa,OAAOC,IAAI,CAAC;QACZ,MAAM,IAAI5B,SAASD,UAAU+B,aAAa,EAAE;IAC9C;IAEA,IAAI;QACF,MAAMC,QAAQjC,OAAOkC,kBAAkB,CAAC;YAAEC,cAAcP,MAAMQ,WAAW,CAACC,IAAI;QAAC;QAC/E,MAAMJ,MAAMK,GAAG,CAAC,CAAC,aAAa,EAAEC,mBAAmB9B,IAAI,MAAM,CAAC,EAAE+B,IAAI,CAAC;YAAEC,SAAS;gBAAEzB,MAAM;oBAAEC,aAAaA,gBAAgB,SAAS,SAAS;oBAAQyB,SAAS1B;gBAAK;YAAE;QAAE;QAEnKa,OAAOC,IAAI,CAAC,2BAA2B;YAAErB;QAAG;QAE5C,MAAMiB,SAAiB;YACrBN,MAAM;YACNd,SAAS;YACTG;QACF;QAEA,OAAO;YACLiC,SAAS;gBACP;oBACEtB,MAAM;oBACNuB,MAAMC,KAAKC,SAAS,CAACnB;gBACvB;aACD;YACDoB,mBAAmB;gBAAEpB;YAAO;QAC9B;IACF,EAAE,OAAOqB,OAAO;QACd,MAAMN,UAAUM,iBAAiBC,QAAQD,MAAMN,OAAO,GAAGQ,OAAOF;QAChElB,OAAOkB,KAAK,CAAC,yBAAyB;YAAEA,OAAON;QAAQ;QAEvD,MAAM,IAAIvC,SAASD,UAAUiD,aAAa,EAAE,CAAC,2BAA2B,EAAET,SAAS,EAAE;YACnFU,OAAOJ,iBAAiBC,QAAQD,MAAMI,KAAK,GAAGC;QAChD;IACF;AACF;AAEA,eAAe,SAASC;IACtB,OAAO;QACLC,MAAM;QACN9B;QACAG;IACF;AACF"}