@mcp-z/mcp-outlook 1.0.9 → 1.0.11

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.
@@ -80,6 +80,13 @@ function _unsupported_iterable_to_array(o, minLen) {
80
80
  return systemCategory;
81
81
  }
82
82
  function toGraphFilter(query) {
83
+ if (query.kqlQuery) {
84
+ return {
85
+ search: query.kqlQuery,
86
+ filter: null,
87
+ requireBodyClientFilter: false
88
+ };
89
+ }
83
90
  var requireBodyClientFilter = false;
84
91
  function L(s) {
85
92
  // Microsoft Graph does NOT support toLower() function in OData filters
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/querying/query-builder.ts"],"sourcesContent":["import type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\n\ntype FieldOperator = {\n $any?: string[];\n $all?: string[];\n $none?: string[];\n};\n\ntype DateOperator = {\n $gte?: string;\n $lt?: string;\n};\n\ntype FieldQuery = {\n from?: FieldOperator | string;\n to?: FieldOperator | string;\n cc?: FieldOperator | string;\n bcc?: FieldOperator | string;\n subject?: FieldOperator | string;\n text?: FieldOperator | string;\n body?: FieldOperator | string;\n categories?: FieldOperator | string;\n label?: FieldOperator | string;\n};\n\n/**\n * Outlook category mappings - case insensitive input to exact system categories\n * Note: These are user-defined categories in Outlook, not system categories like Gmail\n */\nconst OUTLOOK_CATEGORIES = {\n personal: 'Personal',\n work: 'Work',\n family: 'Family',\n travel: 'Travel',\n important: 'Important',\n urgent: 'Urgent',\n} as const;\n\n/**\n * Validate and map category name to Outlook system category\n * Throws error for invalid categories (fail fast principle)\n */\nfunction mapOutlookCategory(category: string): string {\n // Input validation - fail fast on invalid input\n if (!category || typeof category !== 'string') {\n throw new Error(`Invalid category: expected non-empty string, got ${typeof category}`);\n }\n\n const trimmed = category.trim();\n if (trimmed === '') {\n throw new Error('Invalid category: empty string after trimming');\n }\n\n // Fail fast on unknown categories\n const normalizedCategory = trimmed.toLowerCase();\n const systemCategory = OUTLOOK_CATEGORIES[normalizedCategory as keyof typeof OUTLOOK_CATEGORIES];\n\n if (!systemCategory) {\n throw new Error(`Invalid Outlook category: \"${category}\". Valid categories: ${Object.keys(OUTLOOK_CATEGORIES).join(', ')}`);\n }\n\n return systemCategory;\n}\n\nexport interface ODataFilterResult {\n search: string | null;\n filter: string | null;\n requireBodyClientFilter: boolean;\n}\n\nexport function toGraphFilter(query: QueryNode): ODataFilterResult {\n let requireBodyClientFilter = false;\n\n function L(s: string) {\n // Microsoft Graph does NOT support toLower() function in OData filters\n // Case-insensitive matching must be done client-side or via $search\n return s;\n }\n function p(s: string) {\n return `(${s})`;\n }\n\n function recip(coll: string, V: string) {\n // Graph may reject functions on nested properties; use equality on nested address/name fields.\n const left = `r/emailAddress/address eq ${V}`;\n const right = `r/emailAddress/name eq ${V}`;\n return `${coll}/any(r: ${left} or ${right})`;\n }\n\n function fv(field: string, raw: string | number | boolean | null | undefined): string {\n if (raw == null) return '';\n const rawStr = String(raw);\n\n // For text and body fields, skip OData filtering entirely (uses KQL search instead)\n // Do this BEFORE validation so we don't throw on valid text/body queries\n if (field === 'text' || field === 'body') {\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n requireBodyClientFilter = true;\n return '';\n }\n\n // For all other fields, validate non-empty AFTER checking for null\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n\n const V = `'${rawStr.toLowerCase().replace(/'/g, \"''\")}'`;\n switch (field) {\n case 'from': {\n // For email addresses emit equality checks on nested address/name;\n // for name-only tokens, skip server-side filter (handled client-side or via $search).\n if (rawStr.includes('@')) {\n const addrEq = `${L('from/emailAddress/address')} eq ${V}`;\n const nameEq = `${L('from/emailAddress/name')} eq ${V}`;\n return p(`${addrEq} or ${nameEq}`);\n }\n // Don't emit a server-side filter for name-only 'from' tokens.\n return '';\n }\n case 'to':\n return recip('toRecipients', V);\n case 'cc':\n return recip('ccRecipients', V);\n case 'bcc':\n return recip('bccRecipients', V);\n case 'subject':\n // Microsoft Graph does NOT support contains() function in OData filters\n // Use startswith as a partial alternative or rely on $search\n if (rawStr.includes('-') || rawStr.length < 3) return '';\n return `startswith(subject, ${V})`;\n case 'categories': {\n // mapOutlookCategory will throw on invalid input (fail fast)\n const systemCategory = mapOutlookCategory(rawStr);\n // Use the categories OData property with exact case-sensitive match\n return `categories/any(c: c eq '${systemCategory}')`;\n }\n case 'label': {\n // Direct passthrough to categories for Outlook (case-sensitive)\n return `categories/any(c: c eq '${rawStr.replace(/'/g, \"''\")}')`;\n }\n default:\n // Microsoft Graph does NOT support contains() function\n // For unknown fields, skip server-side filtering\n return '';\n }\n }\n\n function chain(op: 'and' | 'or', arr: Array<string | undefined>) {\n if (!arr || arr.length === 0) {\n throw new Error(`chain: empty array for ${op} operation`);\n }\n if (arr.length === 1) {\n const first = arr[0] ?? '';\n return String(first);\n }\n const joined = arr.join(` ${op} `);\n return p(joined);\n }\n function fieldExpr(field: string, op: FieldOperator | string): string {\n if (typeof op === 'string') {\n return fv(field, op);\n }\n\n if (Array.isArray(op.$any)) {\n const results = op.$any.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('or', validResults);\n }\n if (Array.isArray(op.$all)) {\n const results = op.$all.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('and', validResults);\n }\n if (Array.isArray(op.$none)) {\n const results = op.$none.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return `not ${p(chain('or', validResults))}`;\n }\n throw new Error(`Unknown field operator ${JSON.stringify(op)}`);\n }\n\n function dateExpr(d: DateOperator): string {\n const parts: string[] = [];\n if (d.$gte) parts.push(`receivedDateTime ge ${d.$gte}T00:00:00Z`);\n if (d.$lt) parts.push(`receivedDateTime lt ${d.$lt}T00:00:00Z`);\n return parts.length > 1 ? p(parts.join(' and ')) : (parts[0] ?? '');\n }\n\n function emit(n: QueryNode): string {\n if (!n || typeof n !== 'object') return '';\n\n if ('$and' in n && n.$and) {\n const andParts = n.$and.map(emit).filter((part: string): part is string => Boolean(part));\n if (andParts.length === 0) return '';\n if (andParts.length === 1) {\n const firstPart = andParts[0];\n return firstPart ?? '';\n }\n return p(andParts.join(' and '));\n }\n if ('$or' in n && n.$or) {\n const orParts = n.$or.map(emit).filter((part: string): part is string => Boolean(part));\n if (orParts.length === 0) return '';\n if (orParts.length === 1) {\n const firstPart = orParts[0];\n return firstPart ?? '';\n }\n return p(orParts.join(' or '));\n }\n if ('$not' in n && n.$not) {\n const notExpr = emit(n.$not);\n return notExpr ? `not (${notExpr})` : '';\n }\n if ('hasAttachment' in n && n.hasAttachment) return 'hasAttachments eq true';\n if ('date' in n && n.date) return dateExpr(n.date);\n\n const keys = Object.keys(n);\n if (keys.length === 1) {\n const k0 = String(keys[0] ?? '');\n if (k0 && ['from', 'to', 'cc', 'bcc', 'subject', 'text', 'body', 'categories', 'label'].includes(k0)) {\n const fieldValue = (n as FieldQuery)[k0 as keyof FieldQuery];\n if (fieldValue) return fieldExpr(k0, fieldValue);\n }\n }\n return '';\n }\n\n const filterStr = emit(query);\n\n const terms: string[] = [];\n function pushTerms(arr?: string[]) {\n if (Array.isArray(arr)) for (const t of arr) if ((t ?? '').toString().trim()) terms.push(String(t).trim());\n }\n\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('exactPhrase' in node && node.exactPhrase) {\n // KQL uses double quotes for exact phrase matching\n pushTerms([`\"${String(node.exactPhrase).replace(/\"/g, '\\\\\"')}\"`]);\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n pushTerms([node.subject]);\n } else {\n pushTerms(node.subject.$any);\n pushTerms(node.subject.$all);\n pushTerms(node.subject.$none);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n pushTerms([node.body]);\n } else {\n pushTerms(node.body.$any);\n pushTerms(node.body.$all);\n pushTerms(node.body.$none);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n pushTerms([node.text]);\n } else {\n pushTerms(node.text.$any);\n pushTerms(node.text.$all);\n pushTerms(node.text.$none);\n }\n }\n }\n walk(query);\n\n /**\n * Escape KQL (Keyword Query Language) special characters in search terms.\n * KQL special characters that need escaping: \\ : ( ) { } [ ] \" * ? < > - _\n * According to Microsoft Graph KQL syntax, these must be escaped with backslash.\n */\n function escapeKQL(term: string): string {\n if (!term) return term;\n // Escape backslash first, then other special characters\n return term\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/:/g, '\\\\:')\n .replace(/\\(/g, '\\\\(')\n .replace(/\\)/g, '\\\\)')\n .replace(/\\{/g, '\\\\{')\n .replace(/\\}/g, '\\\\}')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\*/g, '\\\\*')\n .replace(/\\?/g, '\\\\?')\n .replace(/</g, '\\\\<')\n .replace(/>/g, '\\\\>')\n .replace(/-/g, '\\\\-')\n .replace(/_/g, '\\\\_');\n }\n\n const mapped = terms.map((t) => {\n const escaped = escapeKQL(String(t));\n return escaped;\n });\n const search = mapped.length ? mapped.join(' OR ') : null;\n\n return { search, filter: filterStr && typeof filterStr === 'string' && filterStr.length ? filterStr : null, requireBodyClientFilter };\n}\n\nexport function toOutlookFilter(parsed: QueryNode, _options?: { includeBodyContent?: boolean; useCaseInsensitiveWrap?: boolean }) {\n const graphResult = toGraphFilter(parsed);\n const filters = extractOutlookFilters(parsed);\n return {\n filter: graphResult.filter,\n search: graphResult.search,\n requireBodyClientFilter: graphResult.requireBodyClientFilter,\n filters,\n };\n}\n\ninterface ExtractedFilters {\n subjectIncludes: string[];\n bodyIncludes: string[];\n textIncludes: string[];\n fromIncludes: string[];\n toIncludes: string[];\n ccIncludes: string[];\n bccIncludes: string[];\n categoriesIncludes: string[];\n labelIncludes: string[];\n hasAttachment?: boolean;\n since?: string;\n before?: string;\n}\n\nexport function extractOutlookFilters(parsed: QueryNode): ExtractedFilters {\n const filters: ExtractedFilters = {\n subjectIncludes: [],\n bodyIncludes: [],\n textIncludes: [],\n fromIncludes: [],\n toIncludes: [],\n ccIncludes: [],\n bccIncludes: [],\n categoriesIncludes: [],\n labelIncludes: [],\n };\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('hasAttachment' in node && node.hasAttachment !== undefined) {\n filters.hasAttachment = node.hasAttachment === true;\n return;\n }\n if ('date' in node && node.date) {\n if (node.date.$gte) filters.since = node.date.$gte;\n if (node.date.$lt) filters.before = node.date.$lt;\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n filters.subjectIncludes.push(node.subject);\n } else {\n if (node.subject.$any) filters.subjectIncludes.push(...node.subject.$any);\n if (node.subject.$all) filters.subjectIncludes.push(...node.subject.$all);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n filters.bodyIncludes.push(node.body);\n } else {\n if (node.body.$any) filters.bodyIncludes.push(...node.body.$any);\n if (node.body.$all) filters.bodyIncludes.push(...node.body.$all);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n filters.textIncludes.push(node.text);\n filters.bodyIncludes.push(node.text);\n } else {\n if (node.text.$any) {\n filters.textIncludes.push(...node.text.$any);\n filters.bodyIncludes.push(...node.text.$any);\n }\n if (node.text.$all) {\n filters.textIncludes.push(...node.text.$all);\n filters.bodyIncludes.push(...node.text.$all);\n }\n }\n }\n if ('from' in node && node.from) {\n if (typeof node.from === 'string') {\n filters.fromIncludes.push(node.from);\n } else {\n if (node.from.$any) filters.fromIncludes.push(...node.from.$any);\n if (node.from.$all) filters.fromIncludes.push(...node.from.$all);\n }\n }\n if ('to' in node && node.to) {\n if (typeof node.to === 'string') {\n filters.toIncludes.push(node.to);\n } else {\n if (node.to.$any) filters.toIncludes.push(...node.to.$any);\n if (node.to.$all) filters.toIncludes.push(...node.to.$all);\n }\n }\n if ('cc' in node && node.cc) {\n if (typeof node.cc === 'string') {\n filters.ccIncludes.push(node.cc);\n } else {\n if (node.cc.$any) filters.ccIncludes.push(...node.cc.$any);\n if (node.cc.$all) filters.ccIncludes.push(...node.cc.$all);\n }\n }\n if ('bcc' in node && node.bcc) {\n if (typeof node.bcc === 'string') {\n filters.bccIncludes.push(node.bcc);\n } else {\n if (node.bcc.$any) filters.bccIncludes.push(...node.bcc.$any);\n if (node.bcc.$all) filters.bccIncludes.push(...node.bcc.$all);\n }\n }\n if ('categories' in node && node.categories) {\n if (typeof node.categories === 'string') {\n if (mapOutlookCategory(node.categories) !== null) {\n filters.categoriesIncludes.push(node.categories);\n }\n } else {\n // Filter out invalid categories to prevent memory leaks and maintain clean state\n if (node.categories.$any) {\n const validCategories = node.categories.$any.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$all) {\n const validCategories = node.categories.$all.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$none) {\n const validCategories = node.categories.$none.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n }\n }\n if ('label' in node && node.label) {\n if (typeof node.label === 'string') {\n filters.labelIncludes.push(node.label);\n } else {\n if (node.label.$any) filters.labelIncludes.push(...node.label.$any);\n if (node.label.$all) filters.labelIncludes.push(...node.label.$all);\n if (node.label.$none) filters.labelIncludes.push(...node.label.$none);\n }\n }\n }\n walk(parsed);\n return filters;\n}\n"],"names":["extractOutlookFilters","toGraphFilter","toOutlookFilter","OUTLOOK_CATEGORIES","personal","work","family","travel","important","urgent","mapOutlookCategory","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemCategory","Object","keys","join","query","requireBodyClientFilter","L","s","p","recip","coll","V","left","right","fv","field","raw","rawStr","String","replace","includes","addrEq","nameEq","length","chain","op","arr","first","joined","fieldExpr","Array","isArray","$any","results","map","v","validResults","filter","$all","$none","JSON","stringify","dateExpr","d","parts","$gte","push","$lt","emit","n","$and","andParts","part","Boolean","firstPart","$or","orParts","$not","notExpr","hasAttachment","date","k0","fieldValue","filterStr","terms","pushTerms","t","toString","walk","node","forEach","exactPhrase","subject","body","text","escapeKQL","term","mapped","escaped","search","parsed","_options","graphResult","filters","subjectIncludes","bodyIncludes","textIncludes","fromIncludes","toIncludes","ccIncludes","bccIncludes","categoriesIncludes","labelIncludes","undefined","since","before","from","to","cc","bcc","categories","validCategories","cat","label"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/querying/query-builder.ts"],"sourcesContent":["import type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\n\ntype FieldOperator = {\n $any?: string[];\n $all?: string[];\n $none?: string[];\n};\n\ntype DateOperator = {\n $gte?: string;\n $lt?: string;\n};\n\ntype FieldQuery = {\n from?: FieldOperator | string;\n to?: FieldOperator | string;\n cc?: FieldOperator | string;\n bcc?: FieldOperator | string;\n subject?: FieldOperator | string;\n text?: FieldOperator | string;\n body?: FieldOperator | string;\n categories?: FieldOperator | string;\n label?: FieldOperator | string;\n};\n\n/**\n * Outlook category mappings - case insensitive input to exact system categories\n * Note: These are user-defined categories in Outlook, not system categories like Gmail\n */\nconst OUTLOOK_CATEGORIES = {\n personal: 'Personal',\n work: 'Work',\n family: 'Family',\n travel: 'Travel',\n important: 'Important',\n urgent: 'Urgent',\n} as const;\n\n/**\n * Validate and map category name to Outlook system category\n * Throws error for invalid categories (fail fast principle)\n */\nfunction mapOutlookCategory(category: string): string {\n // Input validation - fail fast on invalid input\n if (!category || typeof category !== 'string') {\n throw new Error(`Invalid category: expected non-empty string, got ${typeof category}`);\n }\n\n const trimmed = category.trim();\n if (trimmed === '') {\n throw new Error('Invalid category: empty string after trimming');\n }\n\n // Fail fast on unknown categories\n const normalizedCategory = trimmed.toLowerCase();\n const systemCategory = OUTLOOK_CATEGORIES[normalizedCategory as keyof typeof OUTLOOK_CATEGORIES];\n\n if (!systemCategory) {\n throw new Error(`Invalid Outlook category: \"${category}\". Valid categories: ${Object.keys(OUTLOOK_CATEGORIES).join(', ')}`);\n }\n\n return systemCategory;\n}\n\nexport interface ODataFilterResult {\n search: string | null;\n filter: string | null;\n requireBodyClientFilter: boolean;\n}\n\nexport function toGraphFilter(query: QueryNode): ODataFilterResult {\n if (query.kqlQuery) {\n return { search: query.kqlQuery, filter: null, requireBodyClientFilter: false };\n }\n let requireBodyClientFilter = false;\n\n function L(s: string) {\n // Microsoft Graph does NOT support toLower() function in OData filters\n // Case-insensitive matching must be done client-side or via $search\n return s;\n }\n function p(s: string) {\n return `(${s})`;\n }\n\n function recip(coll: string, V: string) {\n // Graph may reject functions on nested properties; use equality on nested address/name fields.\n const left = `r/emailAddress/address eq ${V}`;\n const right = `r/emailAddress/name eq ${V}`;\n return `${coll}/any(r: ${left} or ${right})`;\n }\n\n function fv(field: string, raw: string | number | boolean | null | undefined): string {\n if (raw == null) return '';\n const rawStr = String(raw);\n\n // For text and body fields, skip OData filtering entirely (uses KQL search instead)\n // Do this BEFORE validation so we don't throw on valid text/body queries\n if (field === 'text' || field === 'body') {\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n requireBodyClientFilter = true;\n return '';\n }\n\n // For all other fields, validate non-empty AFTER checking for null\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n\n const V = `'${rawStr.toLowerCase().replace(/'/g, \"''\")}'`;\n switch (field) {\n case 'from': {\n // For email addresses emit equality checks on nested address/name;\n // for name-only tokens, skip server-side filter (handled client-side or via $search).\n if (rawStr.includes('@')) {\n const addrEq = `${L('from/emailAddress/address')} eq ${V}`;\n const nameEq = `${L('from/emailAddress/name')} eq ${V}`;\n return p(`${addrEq} or ${nameEq}`);\n }\n // Don't emit a server-side filter for name-only 'from' tokens.\n return '';\n }\n case 'to':\n return recip('toRecipients', V);\n case 'cc':\n return recip('ccRecipients', V);\n case 'bcc':\n return recip('bccRecipients', V);\n case 'subject':\n // Microsoft Graph does NOT support contains() function in OData filters\n // Use startswith as a partial alternative or rely on $search\n if (rawStr.includes('-') || rawStr.length < 3) return '';\n return `startswith(subject, ${V})`;\n case 'categories': {\n // mapOutlookCategory will throw on invalid input (fail fast)\n const systemCategory = mapOutlookCategory(rawStr);\n // Use the categories OData property with exact case-sensitive match\n return `categories/any(c: c eq '${systemCategory}')`;\n }\n case 'label': {\n // Direct passthrough to categories for Outlook (case-sensitive)\n return `categories/any(c: c eq '${rawStr.replace(/'/g, \"''\")}')`;\n }\n default:\n // Microsoft Graph does NOT support contains() function\n // For unknown fields, skip server-side filtering\n return '';\n }\n }\n\n function chain(op: 'and' | 'or', arr: Array<string | undefined>) {\n if (!arr || arr.length === 0) {\n throw new Error(`chain: empty array for ${op} operation`);\n }\n if (arr.length === 1) {\n const first = arr[0] ?? '';\n return String(first);\n }\n const joined = arr.join(` ${op} `);\n return p(joined);\n }\n function fieldExpr(field: string, op: FieldOperator | string): string {\n if (typeof op === 'string') {\n return fv(field, op);\n }\n\n if (Array.isArray(op.$any)) {\n const results = op.$any.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('or', validResults);\n }\n if (Array.isArray(op.$all)) {\n const results = op.$all.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('and', validResults);\n }\n if (Array.isArray(op.$none)) {\n const results = op.$none.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return `not ${p(chain('or', validResults))}`;\n }\n throw new Error(`Unknown field operator ${JSON.stringify(op)}`);\n }\n\n function dateExpr(d: DateOperator): string {\n const parts: string[] = [];\n if (d.$gte) parts.push(`receivedDateTime ge ${d.$gte}T00:00:00Z`);\n if (d.$lt) parts.push(`receivedDateTime lt ${d.$lt}T00:00:00Z`);\n return parts.length > 1 ? p(parts.join(' and ')) : (parts[0] ?? '');\n }\n\n function emit(n: QueryNode): string {\n if (!n || typeof n !== 'object') return '';\n\n if ('$and' in n && n.$and) {\n const andParts = n.$and.map(emit).filter((part: string): part is string => Boolean(part));\n if (andParts.length === 0) return '';\n if (andParts.length === 1) {\n const firstPart = andParts[0];\n return firstPart ?? '';\n }\n return p(andParts.join(' and '));\n }\n if ('$or' in n && n.$or) {\n const orParts = n.$or.map(emit).filter((part: string): part is string => Boolean(part));\n if (orParts.length === 0) return '';\n if (orParts.length === 1) {\n const firstPart = orParts[0];\n return firstPart ?? '';\n }\n return p(orParts.join(' or '));\n }\n if ('$not' in n && n.$not) {\n const notExpr = emit(n.$not);\n return notExpr ? `not (${notExpr})` : '';\n }\n if ('hasAttachment' in n && n.hasAttachment) return 'hasAttachments eq true';\n if ('date' in n && n.date) return dateExpr(n.date);\n\n const keys = Object.keys(n);\n if (keys.length === 1) {\n const k0 = String(keys[0] ?? '');\n if (k0 && ['from', 'to', 'cc', 'bcc', 'subject', 'text', 'body', 'categories', 'label'].includes(k0)) {\n const fieldValue = (n as FieldQuery)[k0 as keyof FieldQuery];\n if (fieldValue) return fieldExpr(k0, fieldValue);\n }\n }\n return '';\n }\n\n const filterStr = emit(query);\n\n const terms: string[] = [];\n function pushTerms(arr?: string[]) {\n if (Array.isArray(arr)) for (const t of arr) if ((t ?? '').toString().trim()) terms.push(String(t).trim());\n }\n\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('exactPhrase' in node && node.exactPhrase) {\n // KQL uses double quotes for exact phrase matching\n pushTerms([`\"${String(node.exactPhrase).replace(/\"/g, '\\\\\"')}\"`]);\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n pushTerms([node.subject]);\n } else {\n pushTerms(node.subject.$any);\n pushTerms(node.subject.$all);\n pushTerms(node.subject.$none);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n pushTerms([node.body]);\n } else {\n pushTerms(node.body.$any);\n pushTerms(node.body.$all);\n pushTerms(node.body.$none);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n pushTerms([node.text]);\n } else {\n pushTerms(node.text.$any);\n pushTerms(node.text.$all);\n pushTerms(node.text.$none);\n }\n }\n }\n walk(query);\n\n /**\n * Escape KQL (Keyword Query Language) special characters in search terms.\n * KQL special characters that need escaping: \\ : ( ) { } [ ] \" * ? < > - _\n * According to Microsoft Graph KQL syntax, these must be escaped with backslash.\n */\n function escapeKQL(term: string): string {\n if (!term) return term;\n // Escape backslash first, then other special characters\n return term\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/:/g, '\\\\:')\n .replace(/\\(/g, '\\\\(')\n .replace(/\\)/g, '\\\\)')\n .replace(/\\{/g, '\\\\{')\n .replace(/\\}/g, '\\\\}')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\*/g, '\\\\*')\n .replace(/\\?/g, '\\\\?')\n .replace(/</g, '\\\\<')\n .replace(/>/g, '\\\\>')\n .replace(/-/g, '\\\\-')\n .replace(/_/g, '\\\\_');\n }\n\n const mapped = terms.map((t) => {\n const escaped = escapeKQL(String(t));\n return escaped;\n });\n const search = mapped.length ? mapped.join(' OR ') : null;\n\n return { search, filter: filterStr && typeof filterStr === 'string' && filterStr.length ? filterStr : null, requireBodyClientFilter };\n}\n\nexport function toOutlookFilter(parsed: QueryNode, _options?: { includeBodyContent?: boolean; useCaseInsensitiveWrap?: boolean }) {\n const graphResult = toGraphFilter(parsed);\n const filters = extractOutlookFilters(parsed);\n return {\n filter: graphResult.filter,\n search: graphResult.search,\n requireBodyClientFilter: graphResult.requireBodyClientFilter,\n filters,\n };\n}\n\ninterface ExtractedFilters {\n subjectIncludes: string[];\n bodyIncludes: string[];\n textIncludes: string[];\n fromIncludes: string[];\n toIncludes: string[];\n ccIncludes: string[];\n bccIncludes: string[];\n categoriesIncludes: string[];\n labelIncludes: string[];\n hasAttachment?: boolean;\n since?: string;\n before?: string;\n}\n\nexport function extractOutlookFilters(parsed: QueryNode): ExtractedFilters {\n const filters: ExtractedFilters = {\n subjectIncludes: [],\n bodyIncludes: [],\n textIncludes: [],\n fromIncludes: [],\n toIncludes: [],\n ccIncludes: [],\n bccIncludes: [],\n categoriesIncludes: [],\n labelIncludes: [],\n };\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('hasAttachment' in node && node.hasAttachment !== undefined) {\n filters.hasAttachment = node.hasAttachment === true;\n return;\n }\n if ('date' in node && node.date) {\n if (node.date.$gte) filters.since = node.date.$gte;\n if (node.date.$lt) filters.before = node.date.$lt;\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n filters.subjectIncludes.push(node.subject);\n } else {\n if (node.subject.$any) filters.subjectIncludes.push(...node.subject.$any);\n if (node.subject.$all) filters.subjectIncludes.push(...node.subject.$all);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n filters.bodyIncludes.push(node.body);\n } else {\n if (node.body.$any) filters.bodyIncludes.push(...node.body.$any);\n if (node.body.$all) filters.bodyIncludes.push(...node.body.$all);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n filters.textIncludes.push(node.text);\n filters.bodyIncludes.push(node.text);\n } else {\n if (node.text.$any) {\n filters.textIncludes.push(...node.text.$any);\n filters.bodyIncludes.push(...node.text.$any);\n }\n if (node.text.$all) {\n filters.textIncludes.push(...node.text.$all);\n filters.bodyIncludes.push(...node.text.$all);\n }\n }\n }\n if ('from' in node && node.from) {\n if (typeof node.from === 'string') {\n filters.fromIncludes.push(node.from);\n } else {\n if (node.from.$any) filters.fromIncludes.push(...node.from.$any);\n if (node.from.$all) filters.fromIncludes.push(...node.from.$all);\n }\n }\n if ('to' in node && node.to) {\n if (typeof node.to === 'string') {\n filters.toIncludes.push(node.to);\n } else {\n if (node.to.$any) filters.toIncludes.push(...node.to.$any);\n if (node.to.$all) filters.toIncludes.push(...node.to.$all);\n }\n }\n if ('cc' in node && node.cc) {\n if (typeof node.cc === 'string') {\n filters.ccIncludes.push(node.cc);\n } else {\n if (node.cc.$any) filters.ccIncludes.push(...node.cc.$any);\n if (node.cc.$all) filters.ccIncludes.push(...node.cc.$all);\n }\n }\n if ('bcc' in node && node.bcc) {\n if (typeof node.bcc === 'string') {\n filters.bccIncludes.push(node.bcc);\n } else {\n if (node.bcc.$any) filters.bccIncludes.push(...node.bcc.$any);\n if (node.bcc.$all) filters.bccIncludes.push(...node.bcc.$all);\n }\n }\n if ('categories' in node && node.categories) {\n if (typeof node.categories === 'string') {\n if (mapOutlookCategory(node.categories) !== null) {\n filters.categoriesIncludes.push(node.categories);\n }\n } else {\n // Filter out invalid categories to prevent memory leaks and maintain clean state\n if (node.categories.$any) {\n const validCategories = node.categories.$any.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$all) {\n const validCategories = node.categories.$all.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$none) {\n const validCategories = node.categories.$none.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n }\n }\n if ('label' in node && node.label) {\n if (typeof node.label === 'string') {\n filters.labelIncludes.push(node.label);\n } else {\n if (node.label.$any) filters.labelIncludes.push(...node.label.$any);\n if (node.label.$all) filters.labelIncludes.push(...node.label.$all);\n if (node.label.$none) filters.labelIncludes.push(...node.label.$none);\n }\n }\n }\n walk(parsed);\n return filters;\n}\n"],"names":["extractOutlookFilters","toGraphFilter","toOutlookFilter","OUTLOOK_CATEGORIES","personal","work","family","travel","important","urgent","mapOutlookCategory","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemCategory","Object","keys","join","query","kqlQuery","search","filter","requireBodyClientFilter","L","s","p","recip","coll","V","left","right","fv","field","raw","rawStr","String","replace","includes","addrEq","nameEq","length","chain","op","arr","first","joined","fieldExpr","Array","isArray","$any","results","map","v","validResults","$all","$none","JSON","stringify","dateExpr","d","parts","$gte","push","$lt","emit","n","$and","andParts","part","Boolean","firstPart","$or","orParts","$not","notExpr","hasAttachment","date","k0","fieldValue","filterStr","terms","pushTerms","t","toString","walk","node","forEach","exactPhrase","subject","body","text","escapeKQL","term","mapped","escaped","parsed","_options","graphResult","filters","subjectIncludes","bodyIncludes","textIncludes","fromIncludes","toIncludes","ccIncludes","bccIncludes","categoriesIncludes","labelIncludes","undefined","since","before","from","to","cc","bcc","categories","validCategories","cat","label"],"mappings":"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"}
@@ -142,46 +142,19 @@ function _ts_generator(thisArg, body) {
142
142
  };
143
143
  }
144
144
  }
145
- function parseDefaultTtl(uri) {
146
- try {
147
- var url = new URL(uri);
148
- var ttlParam = url.searchParams.get('ttl');
149
- var ttlSecondsParam = url.searchParams.get('ttlSeconds');
150
- var ttlMs = ttlSecondsParam ? Number(ttlSecondsParam) * 1000 : ttlParam ? Number(ttlParam) : undefined;
151
- url.searchParams.delete('ttl');
152
- url.searchParams.delete('ttlSeconds');
153
- return Number.isFinite(ttlMs) && ttlMs > 0 ? {
154
- uri: url.toString(),
155
- ttl: ttlMs
156
- } : {
157
- uri: url.toString()
158
- };
159
- } catch (unused) {
160
- return {
161
- uri: uri
162
- };
163
- }
164
- }
165
145
  function createStore(uri) {
166
146
  return _async_to_generator(function() {
167
- var _parseDefaultTtl, parsedUri, defaultTtl, store, originalSet;
147
+ var store;
168
148
  return _ts_generator(this, function(_state) {
169
149
  switch(_state.label){
170
150
  case 0:
171
- _parseDefaultTtl = parseDefaultTtl(uri), parsedUri = _parseDefaultTtl.uri, defaultTtl = _parseDefaultTtl.ttl;
172
151
  return [
173
152
  4,
174
- (0, _keyvregistry.default)(parsedUri)
153
+ (0, _keyvregistry.default)(uri)
175
154
  ];
176
155
  case 1:
177
156
  store = _state.sent();
178
157
  if (!store) throw new Error("Failed to create store for URI: ".concat(uri));
179
- if (defaultTtl !== undefined) {
180
- originalSet = store.set.bind(store);
181
- store.set = function(key, value, ttl) {
182
- return originalSet(key, value, ttl !== null && ttl !== void 0 ? ttl : defaultTtl);
183
- };
184
- }
185
158
  return [
186
159
  2,
187
160
  store
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\nfunction parseDefaultTtl(uri: string): { uri: string; ttl?: number } {\n try {\n const url = new URL(uri);\n const ttlParam = url.searchParams.get('ttl');\n const ttlSecondsParam = url.searchParams.get('ttlSeconds');\n const ttlMs = ttlSecondsParam ? Number(ttlSecondsParam) * 1000 : ttlParam ? Number(ttlParam) : undefined;\n url.searchParams.delete('ttl');\n url.searchParams.delete('ttlSeconds');\n return Number.isFinite(ttlMs) && (ttlMs as number) > 0 ? { uri: url.toString(), ttl: ttlMs } : { uri: url.toString() };\n } catch {\n return { uri };\n }\n}\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const { uri: parsedUri, ttl: defaultTtl } = parseDefaultTtl(uri);\n const store = await keyvRegistry<T>(parsedUri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n if (defaultTtl !== undefined) {\n const originalSet = store.set.bind(store);\n store.set = ((key, value, ttl) => originalSet(key, value, ttl ?? defaultTtl)) as typeof store.set;\n }\n return store;\n}\n"],"names":["createStore","parseDefaultTtl","uri","url","URL","ttlParam","searchParams","get","ttlSecondsParam","ttlMs","Number","undefined","delete","isFinite","toString","ttl","parsedUri","defaultTtl","store","originalSet","keyvRegistry","Error","set","bind","key","value"],"mappings":";;;;+BAiBA;;;eAA8BA;;;mEAhBL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEzB,SAASC,gBAAgBC,GAAW;IAClC,IAAI;QACF,IAAMC,MAAM,IAAIC,IAAIF;QACpB,IAAMG,WAAWF,IAAIG,YAAY,CAACC,GAAG,CAAC;QACtC,IAAMC,kBAAkBL,IAAIG,YAAY,CAACC,GAAG,CAAC;QAC7C,IAAME,QAAQD,kBAAkBE,OAAOF,mBAAmB,OAAOH,WAAWK,OAAOL,YAAYM;QAC/FR,IAAIG,YAAY,CAACM,MAAM,CAAC;QACxBT,IAAIG,YAAY,CAACM,MAAM,CAAC;QACxB,OAAOF,OAAOG,QAAQ,CAACJ,UAAU,AAACA,QAAmB,IAAI;YAAEP,KAAKC,IAAIW,QAAQ;YAAIC,KAAKN;QAAM,IAAI;YAAEP,KAAKC,IAAIW,QAAQ;QAAG;IACvH,EAAE,eAAM;QACN,OAAO;YAAEZ,KAAAA;QAAI;IACf;AACF;AAEe,SAAeF,YAAeE,GAAW;;YACVD,kBAA/Be,WAAgBC,YACvBC,OAGEC;;;;oBAJoClB,mBAAAA,gBAAgBC,MAA/Cc,YAA+Bf,iBAApCC,KAAqBe,aAAehB,iBAApBc;oBACV;;wBAAMK,IAAAA,qBAAY,EAAIJ;;;oBAA9BE,QAAQ;oBACd,IAAI,CAACA,OAAO,MAAM,IAAIG,MAAM,AAAC,mCAAsC,OAAJnB;oBAC/D,IAAIe,eAAeN,WAAW;wBACtBQ,cAAcD,MAAMI,GAAG,CAACC,IAAI,CAACL;wBACnCA,MAAMI,GAAG,GAAI,SAACE,KAAKC,OAAOV;mCAAQI,YAAYK,KAAKC,OAAOV,gBAAAA,iBAAAA,MAAOE;;oBACnE;oBACA;;wBAAOC;;;;IACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const store = await keyvRegistry<T>(uri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n return store;\n}\n"],"names":["createStore","uri","store","keyvRegistry","Error"],"mappings":";;;;+BAGA;;;eAA8BA;;;mEAFL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEV,SAAeA,YAAeC,GAAW;;YAChDC;;;;oBAAQ;;wBAAMC,IAAAA,qBAAY,EAAIF;;;oBAA9BC,QAAQ;oBACd,IAAI,CAACA,OAAO,MAAM,IAAIE,MAAM,AAAC,mCAAsC,OAAJH;oBAC/D;;wBAAOC;;;;IACT"}
@@ -205,7 +205,7 @@ function _ts_generator(thisArg, body) {
205
205
  }
206
206
  var AuthRequiredBranchSchema = _oauthmicrosoft.schemas.AuthRequiredBranchSchema;
207
207
  var inputSchema = _zod.z.object(_object_spread_props(_object_spread({
208
- query: _outlookqueryschemats.OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),
208
+ query: _outlookqueryschemats.OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),
209
209
  fields: (0, _server.createFieldsSchema)({
210
210
  availableFields: _email.EMAIL_FIELDS,
211
211
  fieldDescriptions: _email.EMAIL_FIELD_DESCRIPTIONS,
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/mcp/tools/message-search.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } 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, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } 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';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQuerySchema } from '../../schemas/outlook-query-schema.ts';\n\nconst inputSchema = z.object({\n query: OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({\n defaultPageSize: 50,\n maxPageSize: 500,\n provider: 'outlook',\n }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Outlook messages using structured query objects 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({ query, pageSize = 50, pageToken, fields, shape = 'arrays', contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const includeBody = requestedFields === 'all' || requestedFields.has('body');\n\n logger.info('outlook.search called with', {\n query,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields: fields || 'all',\n includeBody,\n });\n\n try {\n const graph = Client.initWithMiddleware({\n authProvider: extra.authContext.auth,\n });\n const started = Date.now();\n const exec = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(pageToken ? { pageToken } : {}),\n includeBody,\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const fromAddr = message?.from?.emailAddress?.address ?? null;\n const fromName = message?.from?.emailAddress?.name ?? null;\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent: string | undefined;\n if (includeBody && message?.body?.content) {\n const isHtml = message.body.contentType?.toLowerCase() === 'html';\n bodyContent = message.body.content;\n\n if (isHtml && excludeThreadHistory) {\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body.content);\n }\n }\n\n const mapped: Partial<EmailDetail> = {\n id: message?.id ?? undefined,\n subject: message?.subject ?? undefined,\n from: fromAddr ?? undefined,\n fromName: fromName ?? undefined,\n to,\n cc,\n bcc,\n date: message?.receivedDateTime ?? undefined,\n snippet: message?.bodyPreview ?? undefined,\n ...(bodyContent && { body: bodyContent, bodyContentType: contentType }),\n };\n return mapped;\n }\n );\n const durationMs = Date.now() - started;\n\n const filteredItems = exec.items.map((item) => filterFields(item, requestedFields));\n\n logger.info('outlook.message.search returning', {\n query,\n pageSize,\n itemsLength: filteredItems.length,\n fields: fields || 'all',\n });\n logger.info('outlook.message.search metrics', {\n durationMs,\n metadata: exec.metadata,\n });\n\n // Type-safe metadata access\n const metadataObj = exec.metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\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.search error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","inputSchema","z","object","query","OutlookQuerySchema","optional","describe","fields","createFieldsSchema","availableFields","EMAIL_FIELDS","fieldDescriptions","EMAIL_FIELD_DESCRIPTIONS","commonPatterns","EMAIL_COMMON_PATTERNS","resourceName","createPaginationSchema","defaultPageSize","maxPageSize","provider","shape","createShapeSchema","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successObjectsBranchSchema","type","literal","items","array","EmailDetailSchema","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","extra","pageSize","pageToken","logger","requestedFields","includeBody","graph","started","exec","durationMs","filteredItems","metadataObj","error","message","parseFields","has","info","undefined","Client","initWithMiddleware","authProvider","authContext","auth","Date","now","executeOutlookQuery","limit","m","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","fromName","name","bodyContent","body","content","isHtml","toLowerCase","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","mapped","id","subject","date","receivedDateTime","snippet","bodyPreview","bodyContentType","item","filterFields","itemsLength","length","metadata","toColumnarFormat","text","JSON","stringify","structuredContent","Error","String","McpError","ErrorCode","InternalError","stack"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/mcp/tools/message-search.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } 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, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } 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';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQueryParameterSchema } from '../../schemas/outlook-query-schema.ts';\n\nconst inputSchema = z.object({\n query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({\n defaultPageSize: 50,\n maxPageSize: 500,\n provider: 'outlook',\n }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Outlook messages using structured query objects 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({ query, pageSize = 50, pageToken, fields, shape = 'arrays', contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const includeBody = requestedFields === 'all' || requestedFields.has('body');\n\n logger.info('outlook.search called with', {\n query,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields: fields || 'all',\n includeBody,\n });\n\n try {\n const graph = Client.initWithMiddleware({\n authProvider: extra.authContext.auth,\n });\n const started = Date.now();\n const exec = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(pageToken ? { pageToken } : {}),\n includeBody,\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const fromAddr = message?.from?.emailAddress?.address ?? null;\n const fromName = message?.from?.emailAddress?.name ?? null;\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent: string | undefined;\n if (includeBody && message?.body?.content) {\n const isHtml = message.body.contentType?.toLowerCase() === 'html';\n bodyContent = message.body.content;\n\n if (isHtml && excludeThreadHistory) {\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body.content);\n }\n }\n\n const mapped: Partial<EmailDetail> = {\n id: message?.id ?? undefined,\n subject: message?.subject ?? undefined,\n from: fromAddr ?? undefined,\n fromName: fromName ?? undefined,\n to,\n cc,\n bcc,\n date: message?.receivedDateTime ?? undefined,\n snippet: message?.bodyPreview ?? undefined,\n ...(bodyContent && { body: bodyContent, bodyContentType: contentType }),\n };\n return mapped;\n }\n );\n const durationMs = Date.now() - started;\n\n const filteredItems = exec.items.map((item) => filterFields(item, requestedFields));\n\n logger.info('outlook.message.search returning', {\n query,\n pageSize,\n itemsLength: filteredItems.length,\n fields: fields || 'all',\n });\n logger.info('outlook.message.search metrics', {\n durationMs,\n metadata: exec.metadata,\n });\n\n // Type-safe metadata access\n const metadataObj = exec.metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\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.search error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","inputSchema","z","object","query","OutlookQueryParameterSchema","optional","describe","fields","createFieldsSchema","availableFields","EMAIL_FIELDS","fieldDescriptions","EMAIL_FIELD_DESCRIPTIONS","commonPatterns","EMAIL_COMMON_PATTERNS","resourceName","createPaginationSchema","defaultPageSize","maxPageSize","provider","shape","createShapeSchema","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successObjectsBranchSchema","type","literal","items","array","EmailDetailSchema","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","extra","pageSize","pageToken","logger","requestedFields","includeBody","graph","started","exec","durationMs","filteredItems","metadataObj","error","message","parseFields","has","info","undefined","Client","initWithMiddleware","authProvider","authContext","auth","Date","now","executeOutlookQuery","limit","m","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","fromName","name","bodyContent","body","content","isHtml","toLowerCase","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","mapped","id","subject","date","receivedDateTime","snippet","bodyPreview","bodyContentType","item","filterFields","itemsLength","length","metadata","toColumnarFormat","text","JSON","stringify","structuredContent","Error","String","McpError","ErrorCode","InternalError","stack"],"mappings":"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"}
@@ -217,7 +217,7 @@ var ExportResultSchema = _zod.z.object({
217
217
  truncated: _zod.z.boolean().describe('Whether export was truncated at maxItems')
218
218
  });
219
219
  var inputSchema = _zod.z.object({
220
- query: _outlookqueryschemats.OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),
220
+ query: _outlookqueryschemats.OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),
221
221
  maxItems: _zod.z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe("Maximum messages to export (default: ".concat(DEFAULT_MAX_ITEMS, ", max: ").concat(MAX_EXPORT_ITEMS, ")")),
222
222
  filename: _zod.z.string().trim().min(1).default('outlook-messages.csv').describe('Output filename (default: outlook-messages.csv)'),
223
223
  contentType: _email.EmailContentTypeSchema,
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/mcp/tools/messages-export-csv.ts"],"sourcesContent":["/** Outlook message CSV export tool - streams results to file without loading all data into context */\n\nimport { EmailContentTypeSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } 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 { getFileUri, reserveFile, 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 { stringify } from 'csv-stringify/sync';\nimport { createWriteStream } from 'fs';\nimport { unlink } from 'fs/promises';\nimport { z } from 'zod';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQuerySchema } from '../../schemas/outlook-query-schema.ts';\nimport type { StorageExtra } from '../../types.ts';\n\nconst DEFAULT_PAGE_SIZE = 50;\nconst DEFAULT_MAX_ITEMS = 10000;\nconst MAX_EXPORT_ITEMS = 50000;\n\nconst ExportResultSchema = z.object({\n uri: z.string().describe('File URI (file:// or http://)'),\n filename: z.string().describe('Stored filename'),\n rowCount: z.number().describe('Number of messages exported'),\n truncated: z.boolean().describe('Whether export was truncated at maxItems'),\n});\n\nconst inputSchema = z.object({\n query: OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),\n maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),\n filename: z.string().trim().min(1).default('outlook-messages.csv').describe('Output filename (default: outlook-messages.csv)'),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schema\nconst successBranchSchema = ExportResultSchema.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: 'Export Outlook messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',\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\n/**\n * Handler for outlook-messages-export-csv tool\n *\n * CRITICAL: Streaming implementation per user requirements\n * - Generate UUID upfront\n * - Write CSV header immediately\n * - Append rows as batches arrive\n * - Delete partial file on error\n * - NO RETRIES (fail fast on error)\n */\nasync function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n const { storageContext } = extra;\n const { transport, resourceStoreUri, baseUrl } = storageContext;\n\n logger.info('outlook.messages.export-csv called', {\n query,\n maxItems,\n filename,\n accountId: extra.authContext.accountId,\n });\n\n // Reserve file location for streaming write (creates directory, generates ID, formats filename)\n const reservation = await reserveFile(filename, {\n resourceStoreUri,\n });\n const { storedName, fullPath } = reservation;\n\n logger.info('outlook.messages.export-csv starting streaming export', { path: fullPath, maxItems });\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n\n // Create CSV headers (all email fields)\n const csvHeaders = ['id', 'threadId', 'from', 'to', 'cc', 'bcc', 'subject', 'date', 'snippet', 'body', 'provider', 'labels'];\n\n // Create write stream and write headers immediately\n const writeStream = createWriteStream(fullPath, { encoding: 'utf-8' });\n const headerLine = stringify([csvHeaders], { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(headerLine);\n\n // Internal pagination loop - append to CSV with each batch\n // NO RETRIES: If any error occurs, fail the whole operation and clean up\n let totalRows = 0;\n let nextPageToken: string | undefined;\n const started = Date.now();\n\n while (totalRows < maxItems) {\n const remainingItems = maxItems - totalRows;\n const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);\n\n const exec: {\n items: Array<{\n id: string;\n threadId?: string;\n from: string;\n to: string;\n cc: string;\n bcc: string;\n subject: string;\n date: string;\n snippet: string;\n body: string;\n provider: string;\n labels: string;\n }>;\n metadata?: { nextPageToken?: string };\n } = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(nextPageToken !== undefined && { pageToken: nextPageToken }),\n includeBody: true, // Always include body for CSV export\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const fromAddr = message?.from?.emailAddress?.address ?? (message?.from as { address?: string })?.address ?? '';\n const categories = Array.isArray(message?.categories) ? message.categories.join(';') : '';\n\n // Process body based on contentType and excludeThreadHistory options\n let body = message?.body?.content ?? '';\n const isHtml = message?.body?.contentType?.toLowerCase() === 'html';\n\n if (isHtml && excludeThreadHistory) {\n body = extractCurrentMessageFromHtml(body);\n }\n\n if (isHtml && contentType === 'text') {\n body = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(body) : extractCurrentMessageFromHtmlToText(message?.body?.content ?? '');\n }\n\n return {\n id: String(message?.id ?? ''),\n threadId: message?.conversationId ? String(message.conversationId) : '',\n from: fromAddr,\n to,\n cc,\n bcc,\n subject: message?.subject ?? '',\n date: message?.receivedDateTime ?? '',\n snippet: message?.bodyPreview ?? '',\n body,\n provider: 'outlook' as const,\n labels: categories,\n };\n }\n );\n\n const csvRows = exec.items.map((item) => {\n return [item.id, item.threadId, item.from, item.to, item.cc, item.bcc, item.subject, item.date, item.snippet, item.body, item.provider, item.labels];\n });\n\n // Append rows to CSV file immediately\n if (csvRows.length > 0) {\n const rowsContent = stringify(csvRows, { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(rowsContent);\n }\n\n totalRows += exec.items.length;\n nextPageToken = exec.metadata?.nextPageToken;\n\n logger.info('outlook.messages.export-csv batch written', {\n batchSize: exec.items.length,\n totalRows,\n hasMore: Boolean(nextPageToken),\n });\n\n // Exit if no more results or reached maxItems\n if (!nextPageToken || exec.items.length === 0) {\n break;\n }\n }\n\n // Close write stream\n await new Promise<void>((resolve, reject) => {\n writeStream.end(() => resolve());\n writeStream.on('error', reject);\n });\n\n const durationMs = Date.now() - started;\n const truncated = totalRows >= maxItems && Boolean(nextPageToken);\n\n logger.info('outlook.messages.export-csv completed', {\n rowCount: totalRows,\n truncated,\n durationMs,\n filename: storedName,\n });\n\n // Generate URI based on transport type (stdio: file://, HTTP: http://)\n const uri = getFileUri(storedName, transport, {\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n endpoint: '/files',\n });\n\n const result: Output = {\n type: 'success' as const,\n uri,\n filename: storedName,\n rowCount: totalRows,\n truncated,\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 // CRITICAL: Clean up partial CSV file on error\n try {\n await unlink(fullPath);\n logger.debug('Cleaned up partial CSV file after error', { path: fullPath });\n } catch (_cleanupError) {\n logger.debug('Could not clean up CSV file (may not exist)', { path: fullPath });\n }\n\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.messages.export-csv error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'messages-export-csv',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","DEFAULT_PAGE_SIZE","DEFAULT_MAX_ITEMS","MAX_EXPORT_ITEMS","ExportResultSchema","z","object","uri","string","describe","filename","rowCount","number","truncated","boolean","inputSchema","query","OutlookQuerySchema","optional","maxItems","int","positive","max","default","trim","min","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","storageContext","transport","resourceStoreUri","baseUrl","reservation","storedName","fullPath","graph","csvHeaders","writeStream","headerLine","totalRows","nextPageToken","started","exec","remainingItems","pageSize","csvRows","rowsContent","durationMs","error","_cleanupError","message","info","accountId","authContext","reserveFile","path","Client","initWithMiddleware","authProvider","auth","createWriteStream","encoding","stringify","header","quoted","quote","escape","write","Date","now","Math","executeOutlookQuery","undefined","pageToken","includeBody","limit","m","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","categories","body","content","isHtml","toLowerCase","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","id","String","threadId","conversationId","subject","date","receivedDateTime","snippet","bodyPreview","provider","labels","items","item","length","metadata","batchSize","hasMore","Promise","resolve","reject","end","on","getFileUri","endpoint","text","JSON","structuredContent","unlink","debug","Error","McpError","ErrorCode","InternalError","stack","name"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/mcp/tools/messages-export-csv.ts"],"sourcesContent":["/** Outlook message CSV export tool - streams results to file without loading all data into context */\n\nimport { EmailContentTypeSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } 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 { getFileUri, reserveFile, 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 { stringify } from 'csv-stringify/sync';\nimport { createWriteStream } from 'fs';\nimport { unlink } from 'fs/promises';\nimport { z } from 'zod';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQueryParameterSchema } from '../../schemas/outlook-query-schema.ts';\nimport type { StorageExtra } from '../../types.ts';\n\nconst DEFAULT_PAGE_SIZE = 50;\nconst DEFAULT_MAX_ITEMS = 10000;\nconst MAX_EXPORT_ITEMS = 50000;\n\nconst ExportResultSchema = z.object({\n uri: z.string().describe('File URI (file:// or http://)'),\n filename: z.string().describe('Stored filename'),\n rowCount: z.number().describe('Number of messages exported'),\n truncated: z.boolean().describe('Whether export was truncated at maxItems'),\n});\n\nconst inputSchema = z.object({\n query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),\n maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),\n filename: z.string().trim().min(1).default('outlook-messages.csv').describe('Output filename (default: outlook-messages.csv)'),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schema\nconst successBranchSchema = ExportResultSchema.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: 'Export Outlook messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',\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\n/**\n * Handler for outlook-messages-export-csv tool\n *\n * CRITICAL: Streaming implementation per user requirements\n * - Generate UUID upfront\n * - Write CSV header immediately\n * - Append rows as batches arrive\n * - Delete partial file on error\n * - NO RETRIES (fail fast on error)\n */\nasync function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n const { storageContext } = extra;\n const { transport, resourceStoreUri, baseUrl } = storageContext;\n\n logger.info('outlook.messages.export-csv called', {\n query,\n maxItems,\n filename,\n accountId: extra.authContext.accountId,\n });\n\n // Reserve file location for streaming write (creates directory, generates ID, formats filename)\n const reservation = await reserveFile(filename, {\n resourceStoreUri,\n });\n const { storedName, fullPath } = reservation;\n\n logger.info('outlook.messages.export-csv starting streaming export', { path: fullPath, maxItems });\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n\n // Create CSV headers (all email fields)\n const csvHeaders = ['id', 'threadId', 'from', 'to', 'cc', 'bcc', 'subject', 'date', 'snippet', 'body', 'provider', 'labels'];\n\n // Create write stream and write headers immediately\n const writeStream = createWriteStream(fullPath, { encoding: 'utf-8' });\n const headerLine = stringify([csvHeaders], { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(headerLine);\n\n // Internal pagination loop - append to CSV with each batch\n // NO RETRIES: If any error occurs, fail the whole operation and clean up\n let totalRows = 0;\n let nextPageToken: string | undefined;\n const started = Date.now();\n\n while (totalRows < maxItems) {\n const remainingItems = maxItems - totalRows;\n const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);\n\n const exec: {\n items: Array<{\n id: string;\n threadId?: string;\n from: string;\n to: string;\n cc: string;\n bcc: string;\n subject: string;\n date: string;\n snippet: string;\n body: string;\n provider: string;\n labels: string;\n }>;\n metadata?: { nextPageToken?: string };\n } = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(nextPageToken !== undefined && { pageToken: nextPageToken }),\n includeBody: true, // Always include body for CSV export\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const fromAddr = message?.from?.emailAddress?.address ?? (message?.from as { address?: string })?.address ?? '';\n const categories = Array.isArray(message?.categories) ? message.categories.join(';') : '';\n\n // Process body based on contentType and excludeThreadHistory options\n let body = message?.body?.content ?? '';\n const isHtml = message?.body?.contentType?.toLowerCase() === 'html';\n\n if (isHtml && excludeThreadHistory) {\n body = extractCurrentMessageFromHtml(body);\n }\n\n if (isHtml && contentType === 'text') {\n body = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(body) : extractCurrentMessageFromHtmlToText(message?.body?.content ?? '');\n }\n\n return {\n id: String(message?.id ?? ''),\n threadId: message?.conversationId ? String(message.conversationId) : '',\n from: fromAddr,\n to,\n cc,\n bcc,\n subject: message?.subject ?? '',\n date: message?.receivedDateTime ?? '',\n snippet: message?.bodyPreview ?? '',\n body,\n provider: 'outlook' as const,\n labels: categories,\n };\n }\n );\n\n const csvRows = exec.items.map((item) => {\n return [item.id, item.threadId, item.from, item.to, item.cc, item.bcc, item.subject, item.date, item.snippet, item.body, item.provider, item.labels];\n });\n\n // Append rows to CSV file immediately\n if (csvRows.length > 0) {\n const rowsContent = stringify(csvRows, { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(rowsContent);\n }\n\n totalRows += exec.items.length;\n nextPageToken = exec.metadata?.nextPageToken;\n\n logger.info('outlook.messages.export-csv batch written', {\n batchSize: exec.items.length,\n totalRows,\n hasMore: Boolean(nextPageToken),\n });\n\n // Exit if no more results or reached maxItems\n if (!nextPageToken || exec.items.length === 0) {\n break;\n }\n }\n\n // Close write stream\n await new Promise<void>((resolve, reject) => {\n writeStream.end(() => resolve());\n writeStream.on('error', reject);\n });\n\n const durationMs = Date.now() - started;\n const truncated = totalRows >= maxItems && Boolean(nextPageToken);\n\n logger.info('outlook.messages.export-csv completed', {\n rowCount: totalRows,\n truncated,\n durationMs,\n filename: storedName,\n });\n\n // Generate URI based on transport type (stdio: file://, HTTP: http://)\n const uri = getFileUri(storedName, transport, {\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n endpoint: '/files',\n });\n\n const result: Output = {\n type: 'success' as const,\n uri,\n filename: storedName,\n rowCount: totalRows,\n truncated,\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 // CRITICAL: Clean up partial CSV file on error\n try {\n await unlink(fullPath);\n logger.debug('Cleaned up partial CSV file after error', { path: fullPath });\n } catch (_cleanupError) {\n logger.debug('Could not clean up CSV file (may not exist)', { path: fullPath });\n }\n\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.messages.export-csv error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'messages-export-csv',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","DEFAULT_PAGE_SIZE","DEFAULT_MAX_ITEMS","MAX_EXPORT_ITEMS","ExportResultSchema","z","object","uri","string","describe","filename","rowCount","number","truncated","boolean","inputSchema","query","OutlookQueryParameterSchema","optional","maxItems","int","positive","max","default","trim","min","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","storageContext","transport","resourceStoreUri","baseUrl","reservation","storedName","fullPath","graph","csvHeaders","writeStream","headerLine","totalRows","nextPageToken","started","exec","remainingItems","pageSize","csvRows","rowsContent","durationMs","error","_cleanupError","message","info","accountId","authContext","reserveFile","path","Client","initWithMiddleware","authProvider","auth","createWriteStream","encoding","stringify","header","quoted","quote","escape","write","Date","now","Math","executeOutlookQuery","undefined","pageToken","includeBody","limit","m","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","categories","body","content","isHtml","toLowerCase","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","id","String","threadId","conversationId","subject","date","receivedDateTime","snippet","bodyPreview","provider","labels","items","item","length","metadata","batchSize","hasMore","Promise","resolve","reject","end","on","getFileUri","endpoint","text","JSON","structuredContent","unlink","debug","Error","McpError","ErrorCode","InternalError","stack","name"],"mappings":"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"}
@@ -37,6 +37,8 @@ export declare const OutlookSystemCategorySchema: z.ZodEnum<{
37
37
  * TypeScript sees the strict OutlookQuery type everywhere the schema is used.
38
38
  */
39
39
  export declare const OutlookQuerySchema: z.ZodType<OutlookQuery>;
40
+ export declare const OutlookQueryParameterSchema: z.ZodType<OutlookQuery>;
41
+ export type OutlookQueryParameter = z.infer<typeof OutlookQueryParameterSchema>;
40
42
  export type OutlookQuery = BaseEmailQueryFields & {
41
43
  $and?: OutlookQuery[];
42
44
  $or?: OutlookQuery[];
@@ -37,6 +37,8 @@ export declare const OutlookSystemCategorySchema: z.ZodEnum<{
37
37
  * TypeScript sees the strict OutlookQuery type everywhere the schema is used.
38
38
  */
39
39
  export declare const OutlookQuerySchema: z.ZodType<OutlookQuery>;
40
+ export declare const OutlookQueryParameterSchema: z.ZodType<OutlookQuery>;
41
+ export type OutlookQueryParameter = z.infer<typeof OutlookQueryParameterSchema>;
40
42
  export type OutlookQuery = BaseEmailQueryFields & {
41
43
  $and?: OutlookQuery[];
42
44
  $or?: OutlookQuery[];
@@ -9,6 +9,9 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
+ get OutlookQueryParameterSchema () {
13
+ return OutlookQueryParameterSchema;
14
+ },
12
15
  get OutlookQuerySchema () {
13
16
  return OutlookQuerySchema;
14
17
  },
@@ -31,6 +34,13 @@ function _define_property(obj, key, value) {
31
34
  }
32
35
  return obj;
33
36
  }
37
+ function _instanceof(left, right) {
38
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
39
+ return !!right[Symbol.hasInstance](left);
40
+ } else {
41
+ return left instanceof right;
42
+ }
43
+ }
34
44
  function _object_spread(target) {
35
45
  for(var i = 1; i < arguments.length; i++){
36
46
  var source = arguments[i] != null ? arguments[i] : {};
@@ -112,4 +122,28 @@ var OutlookQuerySchema = _zod.z.lazy(function() {
112
122
  kqlQuery: _zod.z.string().min(1).optional().describe('Raw KQL (Keyword Query Language) syntax for advanced use cases. Bypasses schema validation - use sparingly.')
113
123
  })).strict();
114
124
  });
125
+ var OutlookQueryParameterSchema = _zod.z.any().transform(function(value, ctx) {
126
+ var parsed = value;
127
+ if (typeof value === 'string') {
128
+ try {
129
+ parsed = JSON.parse(value);
130
+ } catch (error) {
131
+ var message = _instanceof(error, Error) ? error.message : 'Invalid JSON';
132
+ ctx.addIssue({
133
+ code: _zod.z.ZodIssueCode.custom,
134
+ message: "Query must be valid JSON. ".concat(message, '. Wrap KQL syntax in {"kqlQuery":"<query>"} if needed.')
135
+ });
136
+ return _zod.z.NEVER;
137
+ }
138
+ }
139
+ var validated = OutlookQuerySchema.safeParse(parsed);
140
+ if (!validated.success) {
141
+ ctx.addIssue({
142
+ code: _zod.z.ZodIssueCode.custom,
143
+ message: "Invalid query JSON: ".concat(validated.error.message, '. Use {"kqlQuery":"<query>"} for KQL syntax.')
144
+ });
145
+ return _zod.z.NEVER;
146
+ }
147
+ return validated.data;
148
+ });
115
149
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/schemas/outlook-query-schema.ts"],"sourcesContent":["import { type BaseEmailQueryFields, baseEmailQueryFields, type FieldOperator, FieldOperatorSchema } from '@mcp-z/email';\nimport { z } from 'zod';\n\n/**\n * Outlook system category values.\n * These are the built-in category types that Outlook recognizes.\n * Note: This is distinct from OutlookCategory (user-created category objects with id/displayName/color).\n */\nexport type OutlookSystemCategory = 'work' | 'personal' | 'family' | 'travel' | 'important' | 'urgent';\n\n/** Zod schema for validating OutlookSystemCategory values */\nexport const OutlookSystemCategorySchema = z.enum(['work', 'personal', 'family', 'travel', 'important', 'urgent']);\n\n/**\n * Outlook-specific query schema with recursive operators and Outlook features.\n *\n * Includes Microsoft Graph/Outlook-specific features:\n * - exactPhrase: Strict exact phrase matching via KQL $search parameter\n * - categories: Outlook system categories (work, personal, family, travel, important, urgent)\n * - label: User-created Outlook categories (case-sensitive, discovered via outlook-categories-list)\n * - importance: Message importance level (high, normal, low)\n * - kqlQuery: Escape hatch for advanced KQL (Keyword Query Language) syntax\n *\n * Plus all base fields from baseEmailQueryFields:\n * - Email addresses: from, to, cc, bcc (support string or field operators)\n * - Content: subject, body, text\n * - Flags: hasAttachment, isRead\n * - Date range: date { $gte, $lt }\n * - Logical operators: $and, $or, $not (recursive)\n *\n * Note: Cast through unknown to work around Zod's lazy schema type inference issue\n * with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures\n * TypeScript sees the strict OutlookQuery type everywhere the schema is used.\n */\nexport const OutlookQuerySchema = z.lazy(() =>\n z\n .object({\n // Logical operators for combining conditions (recursive)\n $and: z.array(OutlookQuerySchema).optional().describe('Array of conditions that must ALL match'),\n $or: z.array(OutlookQuerySchema).optional().describe('Array of conditions where ANY must match'),\n $not: OutlookQuerySchema.optional().describe('Nested condition that must NOT match'),\n\n // Spread base email query fields (from, to, subject, body, etc.)\n ...baseEmailQueryFields,\n\n // Outlook-specific features\n\n // Exact phrase matching - KQL strict search with double quotes\n exactPhrase: z.string().min(1).optional().describe('Exact phrase matching - words must appear together in exact order (strict matching). Outlook uses KQL.'),\n\n // Outlook system categories with field operator support\n categories: z\n .union([\n OutlookSystemCategorySchema,\n z\n .object({\n $any: z.array(OutlookSystemCategorySchema).optional(),\n $all: z.array(OutlookSystemCategorySchema).optional(),\n $none: z.array(OutlookSystemCategorySchema).optional(),\n })\n .strict(),\n ])\n .optional()\n .describe('Filter by Outlook system categories (work, personal, family, travel, important, urgent)'),\n\n // User-created categories\n label: z\n .union([z.string().min(1), FieldOperatorSchema])\n .optional()\n .describe('Filter by user-created categories (case-sensitive). Use outlook-categories-list to see available categories'),\n\n // Message importance level - Outlook-specific property\n importance: z.enum(['high', 'normal', 'low']).optional().describe('Filter by message importance level (high, normal, low)'),\n\n // Raw KQL query string - escape hatch for advanced syntax\n kqlQuery: z.string().min(1).optional().describe('Raw KQL (Keyword Query Language) syntax for advanced use cases. Bypasses schema validation - use sparingly.'),\n })\n .strict()\n) as unknown as z.ZodType<OutlookQuery>;\n\nexport type OutlookQuery = BaseEmailQueryFields & {\n $and?: OutlookQuery[];\n $or?: OutlookQuery[];\n $not?: OutlookQuery;\n exactPhrase?: string;\n categories?:\n | OutlookSystemCategory\n | {\n $any?: OutlookSystemCategory[];\n $all?: OutlookSystemCategory[];\n $none?: OutlookSystemCategory[];\n };\n label?: string | FieldOperator;\n importance?: 'high' | 'normal' | 'low';\n kqlQuery?: string;\n};\n"],"names":["OutlookQuerySchema","OutlookSystemCategorySchema","z","enum","lazy","object","$and","array","optional","describe","$or","$not","baseEmailQueryFields","exactPhrase","string","min","categories","union","$any","$all","$none","strict","label","FieldOperatorSchema","importance","kqlQuery"],"mappings":";;;;;;;;;;;QAkCaA;eAAAA;;QAvBAC;eAAAA;;;qBAX4F;mBACvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUX,IAAMA,8BAA8BC,MAAC,CAACC,IAAI,CAAC;IAAC;IAAQ;IAAY;IAAU;IAAU;IAAa;CAAS;AAuB1G,IAAMH,qBAAqBE,MAAC,CAACE,IAAI,CAAC;WACvCF,MAAC,CACEG,MAAM,CAAC;QACN,yDAAyD;QACzDC,MAAMJ,MAAC,CAACK,KAAK,CAACP,oBAAoBQ,QAAQ,GAAGC,QAAQ,CAAC;QACtDC,KAAKR,MAAC,CAACK,KAAK,CAACP,oBAAoBQ,QAAQ,GAAGC,QAAQ,CAAC;QACrDE,MAAMX,mBAAmBQ,QAAQ,GAAGC,QAAQ,CAAC;OAG1CG,2BAAoB;QAEvB,4BAA4B;QAE5B,+DAA+D;QAC/DC,aAAaX,MAAC,CAACY,MAAM,GAAGC,GAAG,CAAC,GAAGP,QAAQ,GAAGC,QAAQ,CAAC;QAEnD,wDAAwD;QACxDO,YAAYd,MAAC,CACVe,KAAK,CAAC;YACLhB;YACAC,MAAC,CACEG,MAAM,CAAC;gBACNa,MAAMhB,MAAC,CAACK,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDW,MAAMjB,MAAC,CAACK,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDY,OAAOlB,MAAC,CAACK,KAAK,CAACN,6BAA6BO,QAAQ;YACtD,GACCa,MAAM;SACV,EACAb,QAAQ,GACRC,QAAQ,CAAC;QAEZ,0BAA0B;QAC1Ba,OAAOpB,MAAC,CACLe,KAAK,CAAC;YAACf,MAAC,CAACY,MAAM,GAAGC,GAAG,CAAC;YAAIQ,0BAAmB;SAAC,EAC9Cf,QAAQ,GACRC,QAAQ,CAAC;QAEZ,uDAAuD;QACvDe,YAAYtB,MAAC,CAACC,IAAI,CAAC;YAAC;YAAQ;YAAU;SAAM,EAAEK,QAAQ,GAAGC,QAAQ,CAAC;QAElE,0DAA0D;QAC1DgB,UAAUvB,MAAC,CAACY,MAAM,GAAGC,GAAG,CAAC,GAAGP,QAAQ,GAAGC,QAAQ,CAAC;QAEjDY,MAAM"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/schemas/outlook-query-schema.ts"],"sourcesContent":["import { type BaseEmailQueryFields, baseEmailQueryFields, type FieldOperator, FieldOperatorSchema } from '@mcp-z/email';\nimport { z } from 'zod';\n\n/**\n * Outlook system category values.\n * These are the built-in category types that Outlook recognizes.\n * Note: This is distinct from OutlookCategory (user-created category objects with id/displayName/color).\n */\nexport type OutlookSystemCategory = 'work' | 'personal' | 'family' | 'travel' | 'important' | 'urgent';\n\n/** Zod schema for validating OutlookSystemCategory values */\nexport const OutlookSystemCategorySchema = z.enum(['work', 'personal', 'family', 'travel', 'important', 'urgent']);\n\n/**\n * Outlook-specific query schema with recursive operators and Outlook features.\n *\n * Includes Microsoft Graph/Outlook-specific features:\n * - exactPhrase: Strict exact phrase matching via KQL $search parameter\n * - categories: Outlook system categories (work, personal, family, travel, important, urgent)\n * - label: User-created Outlook categories (case-sensitive, discovered via outlook-categories-list)\n * - importance: Message importance level (high, normal, low)\n * - kqlQuery: Escape hatch for advanced KQL (Keyword Query Language) syntax\n *\n * Plus all base fields from baseEmailQueryFields:\n * - Email addresses: from, to, cc, bcc (support string or field operators)\n * - Content: subject, body, text\n * - Flags: hasAttachment, isRead\n * - Date range: date { $gte, $lt }\n * - Logical operators: $and, $or, $not (recursive)\n *\n * Note: Cast through unknown to work around Zod's lazy schema type inference issue\n * with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures\n * TypeScript sees the strict OutlookQuery type everywhere the schema is used.\n */\nexport const OutlookQuerySchema = z.lazy(() =>\n z\n .object({\n // Logical operators for combining conditions (recursive)\n $and: z.array(OutlookQuerySchema).optional().describe('Array of conditions that must ALL match'),\n $or: z.array(OutlookQuerySchema).optional().describe('Array of conditions where ANY must match'),\n $not: OutlookQuerySchema.optional().describe('Nested condition that must NOT match'),\n\n // Spread base email query fields (from, to, subject, body, etc.)\n ...baseEmailQueryFields,\n\n // Outlook-specific features\n\n // Exact phrase matching - KQL strict search with double quotes\n exactPhrase: z.string().min(1).optional().describe('Exact phrase matching - words must appear together in exact order (strict matching). Outlook uses KQL.'),\n\n // Outlook system categories with field operator support\n categories: z\n .union([\n OutlookSystemCategorySchema,\n z\n .object({\n $any: z.array(OutlookSystemCategorySchema).optional(),\n $all: z.array(OutlookSystemCategorySchema).optional(),\n $none: z.array(OutlookSystemCategorySchema).optional(),\n })\n .strict(),\n ])\n .optional()\n .describe('Filter by Outlook system categories (work, personal, family, travel, important, urgent)'),\n\n // User-created categories\n label: z\n .union([z.string().min(1), FieldOperatorSchema])\n .optional()\n .describe('Filter by user-created categories (case-sensitive). Use outlook-categories-list to see available categories'),\n\n // Message importance level - Outlook-specific property\n importance: z.enum(['high', 'normal', 'low']).optional().describe('Filter by message importance level (high, normal, low)'),\n\n // Raw KQL query string - escape hatch for advanced syntax\n kqlQuery: z.string().min(1).optional().describe('Raw KQL (Keyword Query Language) syntax for advanced use cases. Bypasses schema validation - use sparingly.'),\n })\n .strict()\n) as unknown as z.ZodType<OutlookQuery>;\n\nexport const OutlookQueryParameterSchema = z.any().transform((value, ctx) => {\n let parsed = value;\n if (typeof value === 'string') {\n try {\n parsed = JSON.parse(value);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid JSON';\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Query must be valid JSON. ${message}. Wrap KQL syntax in {\"kqlQuery\":\"<query>\"} if needed.`,\n });\n return z.NEVER;\n }\n }\n\n const validated = OutlookQuerySchema.safeParse(parsed);\n if (!validated.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid query JSON: ${validated.error.message}. Use {\"kqlQuery\":\"<query>\"} for KQL syntax.`,\n });\n return z.NEVER;\n }\n\n return validated.data;\n}) as z.ZodType<OutlookQuery>;\nexport type OutlookQueryParameter = z.infer<typeof OutlookQueryParameterSchema>;\n\nexport type OutlookQuery = BaseEmailQueryFields & {\n $and?: OutlookQuery[];\n $or?: OutlookQuery[];\n $not?: OutlookQuery;\n exactPhrase?: string;\n categories?:\n | OutlookSystemCategory\n | {\n $any?: OutlookSystemCategory[];\n $all?: OutlookSystemCategory[];\n $none?: OutlookSystemCategory[];\n };\n label?: string | FieldOperator;\n importance?: 'high' | 'normal' | 'low';\n kqlQuery?: string;\n};\n"],"names":["OutlookQueryParameterSchema","OutlookQuerySchema","OutlookSystemCategorySchema","z","enum","lazy","object","$and","array","optional","describe","$or","$not","baseEmailQueryFields","exactPhrase","string","min","categories","union","$any","$all","$none","strict","label","FieldOperatorSchema","importance","kqlQuery","any","transform","value","ctx","parsed","JSON","parse","error","message","Error","addIssue","code","ZodIssueCode","custom","NEVER","validated","safeParse","success","data"],"mappings":";;;;;;;;;;;QAgFaA;eAAAA;;QA9CAC;eAAAA;;QAvBAC;eAAAA;;;qBAX4F;mBACvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUX,IAAMA,8BAA8BC,MAAC,CAACC,IAAI,CAAC;IAAC;IAAQ;IAAY;IAAU;IAAU;IAAa;CAAS;AAuB1G,IAAMH,qBAAqBE,MAAC,CAACE,IAAI,CAAC;WACvCF,MAAC,CACEG,MAAM,CAAC;QACN,yDAAyD;QACzDC,MAAMJ,MAAC,CAACK,KAAK,CAACP,oBAAoBQ,QAAQ,GAAGC,QAAQ,CAAC;QACtDC,KAAKR,MAAC,CAACK,KAAK,CAACP,oBAAoBQ,QAAQ,GAAGC,QAAQ,CAAC;QACrDE,MAAMX,mBAAmBQ,QAAQ,GAAGC,QAAQ,CAAC;OAG1CG,2BAAoB;QAEvB,4BAA4B;QAE5B,+DAA+D;QAC/DC,aAAaX,MAAC,CAACY,MAAM,GAAGC,GAAG,CAAC,GAAGP,QAAQ,GAAGC,QAAQ,CAAC;QAEnD,wDAAwD;QACxDO,YAAYd,MAAC,CACVe,KAAK,CAAC;YACLhB;YACAC,MAAC,CACEG,MAAM,CAAC;gBACNa,MAAMhB,MAAC,CAACK,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDW,MAAMjB,MAAC,CAACK,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDY,OAAOlB,MAAC,CAACK,KAAK,CAACN,6BAA6BO,QAAQ;YACtD,GACCa,MAAM;SACV,EACAb,QAAQ,GACRC,QAAQ,CAAC;QAEZ,0BAA0B;QAC1Ba,OAAOpB,MAAC,CACLe,KAAK,CAAC;YAACf,MAAC,CAACY,MAAM,GAAGC,GAAG,CAAC;YAAIQ,0BAAmB;SAAC,EAC9Cf,QAAQ,GACRC,QAAQ,CAAC;QAEZ,uDAAuD;QACvDe,YAAYtB,MAAC,CAACC,IAAI,CAAC;YAAC;YAAQ;YAAU;SAAM,EAAEK,QAAQ,GAAGC,QAAQ,CAAC;QAElE,0DAA0D;QAC1DgB,UAAUvB,MAAC,CAACY,MAAM,GAAGC,GAAG,CAAC,GAAGP,QAAQ,GAAGC,QAAQ,CAAC;QAEjDY,MAAM;;AAGJ,IAAMtB,8BAA8BG,MAAC,CAACwB,GAAG,GAAGC,SAAS,CAAC,SAACC,OAAOC;IACnE,IAAIC,SAASF;IACb,IAAI,OAAOA,UAAU,UAAU;QAC7B,IAAI;YACFE,SAASC,KAAKC,KAAK,CAACJ;QACtB,EAAE,OAAOK,OAAO;YACd,IAAMC,UAAUD,AAAK,YAALA,OAAiBE,SAAQF,MAAMC,OAAO,GAAG;YACzDL,IAAIO,QAAQ,CAAC;gBACXC,MAAMnC,MAAC,CAACoC,YAAY,CAACC,MAAM;gBAC3BL,SAAS,AAAC,6BAAoC,OAARA,SAAQ;YAChD;YACA,OAAOhC,MAAC,CAACsC,KAAK;QAChB;IACF;IAEA,IAAMC,YAAYzC,mBAAmB0C,SAAS,CAACZ;IAC/C,IAAI,CAACW,UAAUE,OAAO,EAAE;QACtBd,IAAIO,QAAQ,CAAC;YACXC,MAAMnC,MAAC,CAACoC,YAAY,CAACC,MAAM;YAC3BL,SAAS,AAAC,uBAA8C,OAAxBO,UAAUR,KAAK,CAACC,OAAO,EAAC;QAC1D;QACA,OAAOhC,MAAC,CAACsC,KAAK;IAChB;IAEA,OAAOC,UAAUG,IAAI;AACvB"}
@@ -30,6 +30,13 @@
30
30
  return systemCategory;
31
31
  }
32
32
  export function toGraphFilter(query) {
33
+ if (query.kqlQuery) {
34
+ return {
35
+ search: query.kqlQuery,
36
+ filter: null,
37
+ requireBodyClientFilter: false
38
+ };
39
+ }
33
40
  let requireBodyClientFilter = false;
34
41
  function L(s) {
35
42
  // Microsoft Graph does NOT support toLower() function in OData filters
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/querying/query-builder.ts"],"sourcesContent":["import type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\n\ntype FieldOperator = {\n $any?: string[];\n $all?: string[];\n $none?: string[];\n};\n\ntype DateOperator = {\n $gte?: string;\n $lt?: string;\n};\n\ntype FieldQuery = {\n from?: FieldOperator | string;\n to?: FieldOperator | string;\n cc?: FieldOperator | string;\n bcc?: FieldOperator | string;\n subject?: FieldOperator | string;\n text?: FieldOperator | string;\n body?: FieldOperator | string;\n categories?: FieldOperator | string;\n label?: FieldOperator | string;\n};\n\n/**\n * Outlook category mappings - case insensitive input to exact system categories\n * Note: These are user-defined categories in Outlook, not system categories like Gmail\n */\nconst OUTLOOK_CATEGORIES = {\n personal: 'Personal',\n work: 'Work',\n family: 'Family',\n travel: 'Travel',\n important: 'Important',\n urgent: 'Urgent',\n} as const;\n\n/**\n * Validate and map category name to Outlook system category\n * Throws error for invalid categories (fail fast principle)\n */\nfunction mapOutlookCategory(category: string): string {\n // Input validation - fail fast on invalid input\n if (!category || typeof category !== 'string') {\n throw new Error(`Invalid category: expected non-empty string, got ${typeof category}`);\n }\n\n const trimmed = category.trim();\n if (trimmed === '') {\n throw new Error('Invalid category: empty string after trimming');\n }\n\n // Fail fast on unknown categories\n const normalizedCategory = trimmed.toLowerCase();\n const systemCategory = OUTLOOK_CATEGORIES[normalizedCategory as keyof typeof OUTLOOK_CATEGORIES];\n\n if (!systemCategory) {\n throw new Error(`Invalid Outlook category: \"${category}\". Valid categories: ${Object.keys(OUTLOOK_CATEGORIES).join(', ')}`);\n }\n\n return systemCategory;\n}\n\nexport interface ODataFilterResult {\n search: string | null;\n filter: string | null;\n requireBodyClientFilter: boolean;\n}\n\nexport function toGraphFilter(query: QueryNode): ODataFilterResult {\n let requireBodyClientFilter = false;\n\n function L(s: string) {\n // Microsoft Graph does NOT support toLower() function in OData filters\n // Case-insensitive matching must be done client-side or via $search\n return s;\n }\n function p(s: string) {\n return `(${s})`;\n }\n\n function recip(coll: string, V: string) {\n // Graph may reject functions on nested properties; use equality on nested address/name fields.\n const left = `r/emailAddress/address eq ${V}`;\n const right = `r/emailAddress/name eq ${V}`;\n return `${coll}/any(r: ${left} or ${right})`;\n }\n\n function fv(field: string, raw: string | number | boolean | null | undefined): string {\n if (raw == null) return '';\n const rawStr = String(raw);\n\n // For text and body fields, skip OData filtering entirely (uses KQL search instead)\n // Do this BEFORE validation so we don't throw on valid text/body queries\n if (field === 'text' || field === 'body') {\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n requireBodyClientFilter = true;\n return '';\n }\n\n // For all other fields, validate non-empty AFTER checking for null\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n\n const V = `'${rawStr.toLowerCase().replace(/'/g, \"''\")}'`;\n switch (field) {\n case 'from': {\n // For email addresses emit equality checks on nested address/name;\n // for name-only tokens, skip server-side filter (handled client-side or via $search).\n if (rawStr.includes('@')) {\n const addrEq = `${L('from/emailAddress/address')} eq ${V}`;\n const nameEq = `${L('from/emailAddress/name')} eq ${V}`;\n return p(`${addrEq} or ${nameEq}`);\n }\n // Don't emit a server-side filter for name-only 'from' tokens.\n return '';\n }\n case 'to':\n return recip('toRecipients', V);\n case 'cc':\n return recip('ccRecipients', V);\n case 'bcc':\n return recip('bccRecipients', V);\n case 'subject':\n // Microsoft Graph does NOT support contains() function in OData filters\n // Use startswith as a partial alternative or rely on $search\n if (rawStr.includes('-') || rawStr.length < 3) return '';\n return `startswith(subject, ${V})`;\n case 'categories': {\n // mapOutlookCategory will throw on invalid input (fail fast)\n const systemCategory = mapOutlookCategory(rawStr);\n // Use the categories OData property with exact case-sensitive match\n return `categories/any(c: c eq '${systemCategory}')`;\n }\n case 'label': {\n // Direct passthrough to categories for Outlook (case-sensitive)\n return `categories/any(c: c eq '${rawStr.replace(/'/g, \"''\")}')`;\n }\n default:\n // Microsoft Graph does NOT support contains() function\n // For unknown fields, skip server-side filtering\n return '';\n }\n }\n\n function chain(op: 'and' | 'or', arr: Array<string | undefined>) {\n if (!arr || arr.length === 0) {\n throw new Error(`chain: empty array for ${op} operation`);\n }\n if (arr.length === 1) {\n const first = arr[0] ?? '';\n return String(first);\n }\n const joined = arr.join(` ${op} `);\n return p(joined);\n }\n function fieldExpr(field: string, op: FieldOperator | string): string {\n if (typeof op === 'string') {\n return fv(field, op);\n }\n\n if (Array.isArray(op.$any)) {\n const results = op.$any.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('or', validResults);\n }\n if (Array.isArray(op.$all)) {\n const results = op.$all.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('and', validResults);\n }\n if (Array.isArray(op.$none)) {\n const results = op.$none.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return `not ${p(chain('or', validResults))}`;\n }\n throw new Error(`Unknown field operator ${JSON.stringify(op)}`);\n }\n\n function dateExpr(d: DateOperator): string {\n const parts: string[] = [];\n if (d.$gte) parts.push(`receivedDateTime ge ${d.$gte}T00:00:00Z`);\n if (d.$lt) parts.push(`receivedDateTime lt ${d.$lt}T00:00:00Z`);\n return parts.length > 1 ? p(parts.join(' and ')) : (parts[0] ?? '');\n }\n\n function emit(n: QueryNode): string {\n if (!n || typeof n !== 'object') return '';\n\n if ('$and' in n && n.$and) {\n const andParts = n.$and.map(emit).filter((part: string): part is string => Boolean(part));\n if (andParts.length === 0) return '';\n if (andParts.length === 1) {\n const firstPart = andParts[0];\n return firstPart ?? '';\n }\n return p(andParts.join(' and '));\n }\n if ('$or' in n && n.$or) {\n const orParts = n.$or.map(emit).filter((part: string): part is string => Boolean(part));\n if (orParts.length === 0) return '';\n if (orParts.length === 1) {\n const firstPart = orParts[0];\n return firstPart ?? '';\n }\n return p(orParts.join(' or '));\n }\n if ('$not' in n && n.$not) {\n const notExpr = emit(n.$not);\n return notExpr ? `not (${notExpr})` : '';\n }\n if ('hasAttachment' in n && n.hasAttachment) return 'hasAttachments eq true';\n if ('date' in n && n.date) return dateExpr(n.date);\n\n const keys = Object.keys(n);\n if (keys.length === 1) {\n const k0 = String(keys[0] ?? '');\n if (k0 && ['from', 'to', 'cc', 'bcc', 'subject', 'text', 'body', 'categories', 'label'].includes(k0)) {\n const fieldValue = (n as FieldQuery)[k0 as keyof FieldQuery];\n if (fieldValue) return fieldExpr(k0, fieldValue);\n }\n }\n return '';\n }\n\n const filterStr = emit(query);\n\n const terms: string[] = [];\n function pushTerms(arr?: string[]) {\n if (Array.isArray(arr)) for (const t of arr) if ((t ?? '').toString().trim()) terms.push(String(t).trim());\n }\n\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('exactPhrase' in node && node.exactPhrase) {\n // KQL uses double quotes for exact phrase matching\n pushTerms([`\"${String(node.exactPhrase).replace(/\"/g, '\\\\\"')}\"`]);\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n pushTerms([node.subject]);\n } else {\n pushTerms(node.subject.$any);\n pushTerms(node.subject.$all);\n pushTerms(node.subject.$none);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n pushTerms([node.body]);\n } else {\n pushTerms(node.body.$any);\n pushTerms(node.body.$all);\n pushTerms(node.body.$none);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n pushTerms([node.text]);\n } else {\n pushTerms(node.text.$any);\n pushTerms(node.text.$all);\n pushTerms(node.text.$none);\n }\n }\n }\n walk(query);\n\n /**\n * Escape KQL (Keyword Query Language) special characters in search terms.\n * KQL special characters that need escaping: \\ : ( ) { } [ ] \" * ? < > - _\n * According to Microsoft Graph KQL syntax, these must be escaped with backslash.\n */\n function escapeKQL(term: string): string {\n if (!term) return term;\n // Escape backslash first, then other special characters\n return term\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/:/g, '\\\\:')\n .replace(/\\(/g, '\\\\(')\n .replace(/\\)/g, '\\\\)')\n .replace(/\\{/g, '\\\\{')\n .replace(/\\}/g, '\\\\}')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\*/g, '\\\\*')\n .replace(/\\?/g, '\\\\?')\n .replace(/</g, '\\\\<')\n .replace(/>/g, '\\\\>')\n .replace(/-/g, '\\\\-')\n .replace(/_/g, '\\\\_');\n }\n\n const mapped = terms.map((t) => {\n const escaped = escapeKQL(String(t));\n return escaped;\n });\n const search = mapped.length ? mapped.join(' OR ') : null;\n\n return { search, filter: filterStr && typeof filterStr === 'string' && filterStr.length ? filterStr : null, requireBodyClientFilter };\n}\n\nexport function toOutlookFilter(parsed: QueryNode, _options?: { includeBodyContent?: boolean; useCaseInsensitiveWrap?: boolean }) {\n const graphResult = toGraphFilter(parsed);\n const filters = extractOutlookFilters(parsed);\n return {\n filter: graphResult.filter,\n search: graphResult.search,\n requireBodyClientFilter: graphResult.requireBodyClientFilter,\n filters,\n };\n}\n\ninterface ExtractedFilters {\n subjectIncludes: string[];\n bodyIncludes: string[];\n textIncludes: string[];\n fromIncludes: string[];\n toIncludes: string[];\n ccIncludes: string[];\n bccIncludes: string[];\n categoriesIncludes: string[];\n labelIncludes: string[];\n hasAttachment?: boolean;\n since?: string;\n before?: string;\n}\n\nexport function extractOutlookFilters(parsed: QueryNode): ExtractedFilters {\n const filters: ExtractedFilters = {\n subjectIncludes: [],\n bodyIncludes: [],\n textIncludes: [],\n fromIncludes: [],\n toIncludes: [],\n ccIncludes: [],\n bccIncludes: [],\n categoriesIncludes: [],\n labelIncludes: [],\n };\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('hasAttachment' in node && node.hasAttachment !== undefined) {\n filters.hasAttachment = node.hasAttachment === true;\n return;\n }\n if ('date' in node && node.date) {\n if (node.date.$gte) filters.since = node.date.$gte;\n if (node.date.$lt) filters.before = node.date.$lt;\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n filters.subjectIncludes.push(node.subject);\n } else {\n if (node.subject.$any) filters.subjectIncludes.push(...node.subject.$any);\n if (node.subject.$all) filters.subjectIncludes.push(...node.subject.$all);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n filters.bodyIncludes.push(node.body);\n } else {\n if (node.body.$any) filters.bodyIncludes.push(...node.body.$any);\n if (node.body.$all) filters.bodyIncludes.push(...node.body.$all);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n filters.textIncludes.push(node.text);\n filters.bodyIncludes.push(node.text);\n } else {\n if (node.text.$any) {\n filters.textIncludes.push(...node.text.$any);\n filters.bodyIncludes.push(...node.text.$any);\n }\n if (node.text.$all) {\n filters.textIncludes.push(...node.text.$all);\n filters.bodyIncludes.push(...node.text.$all);\n }\n }\n }\n if ('from' in node && node.from) {\n if (typeof node.from === 'string') {\n filters.fromIncludes.push(node.from);\n } else {\n if (node.from.$any) filters.fromIncludes.push(...node.from.$any);\n if (node.from.$all) filters.fromIncludes.push(...node.from.$all);\n }\n }\n if ('to' in node && node.to) {\n if (typeof node.to === 'string') {\n filters.toIncludes.push(node.to);\n } else {\n if (node.to.$any) filters.toIncludes.push(...node.to.$any);\n if (node.to.$all) filters.toIncludes.push(...node.to.$all);\n }\n }\n if ('cc' in node && node.cc) {\n if (typeof node.cc === 'string') {\n filters.ccIncludes.push(node.cc);\n } else {\n if (node.cc.$any) filters.ccIncludes.push(...node.cc.$any);\n if (node.cc.$all) filters.ccIncludes.push(...node.cc.$all);\n }\n }\n if ('bcc' in node && node.bcc) {\n if (typeof node.bcc === 'string') {\n filters.bccIncludes.push(node.bcc);\n } else {\n if (node.bcc.$any) filters.bccIncludes.push(...node.bcc.$any);\n if (node.bcc.$all) filters.bccIncludes.push(...node.bcc.$all);\n }\n }\n if ('categories' in node && node.categories) {\n if (typeof node.categories === 'string') {\n if (mapOutlookCategory(node.categories) !== null) {\n filters.categoriesIncludes.push(node.categories);\n }\n } else {\n // Filter out invalid categories to prevent memory leaks and maintain clean state\n if (node.categories.$any) {\n const validCategories = node.categories.$any.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$all) {\n const validCategories = node.categories.$all.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$none) {\n const validCategories = node.categories.$none.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n }\n }\n if ('label' in node && node.label) {\n if (typeof node.label === 'string') {\n filters.labelIncludes.push(node.label);\n } else {\n if (node.label.$any) filters.labelIncludes.push(...node.label.$any);\n if (node.label.$all) filters.labelIncludes.push(...node.label.$all);\n if (node.label.$none) filters.labelIncludes.push(...node.label.$none);\n }\n }\n }\n walk(parsed);\n return filters;\n}\n"],"names":["OUTLOOK_CATEGORIES","personal","work","family","travel","important","urgent","mapOutlookCategory","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemCategory","Object","keys","join","toGraphFilter","query","requireBodyClientFilter","L","s","p","recip","coll","V","left","right","fv","field","raw","rawStr","String","replace","includes","addrEq","nameEq","length","chain","op","arr","first","joined","fieldExpr","Array","isArray","$any","results","map","v","validResults","filter","$all","$none","JSON","stringify","dateExpr","d","parts","$gte","push","$lt","emit","n","$and","andParts","part","Boolean","firstPart","$or","orParts","$not","notExpr","hasAttachment","date","k0","fieldValue","filterStr","terms","pushTerms","t","toString","walk","node","forEach","exactPhrase","subject","body","text","escapeKQL","term","mapped","escaped","search","toOutlookFilter","parsed","_options","graphResult","filters","extractOutlookFilters","subjectIncludes","bodyIncludes","textIncludes","fromIncludes","toIncludes","ccIncludes","bccIncludes","categoriesIncludes","labelIncludes","undefined","since","before","from","to","cc","bcc","categories","validCategories","cat","label"],"mappings":"AAyBA;;;CAGC,GACD,MAAMA,qBAAqB;IACzBC,UAAU;IACVC,MAAM;IACNC,QAAQ;IACRC,QAAQ;IACRC,WAAW;IACXC,QAAQ;AACV;AAEA;;;CAGC,GACD,SAASC,mBAAmBC,QAAgB;IAC1C,gDAAgD;IAChD,IAAI,CAACA,YAAY,OAAOA,aAAa,UAAU;QAC7C,MAAM,IAAIC,MAAM,CAAC,iDAAiD,EAAE,OAAOD,UAAU;IACvF;IAEA,MAAME,UAAUF,SAASG,IAAI;IAC7B,IAAID,YAAY,IAAI;QAClB,MAAM,IAAID,MAAM;IAClB;IAEA,kCAAkC;IAClC,MAAMG,qBAAqBF,QAAQG,WAAW;IAC9C,MAAMC,iBAAiBd,kBAAkB,CAACY,mBAAsD;IAEhG,IAAI,CAACE,gBAAgB;QACnB,MAAM,IAAIL,MAAM,CAAC,2BAA2B,EAAED,SAAS,qBAAqB,EAAEO,OAAOC,IAAI,CAAChB,oBAAoBiB,IAAI,CAAC,OAAO;IAC5H;IAEA,OAAOH;AACT;AAQA,OAAO,SAASI,cAAcC,KAAgB;IAC5C,IAAIC,0BAA0B;IAE9B,SAASC,EAAEC,CAAS;QAClB,uEAAuE;QACvE,oEAAoE;QACpE,OAAOA;IACT;IACA,SAASC,EAAED,CAAS;QAClB,OAAO,CAAC,CAAC,EAAEA,EAAE,CAAC,CAAC;IACjB;IAEA,SAASE,MAAMC,IAAY,EAAEC,CAAS;QACpC,+FAA+F;QAC/F,MAAMC,OAAO,CAAC,0BAA0B,EAAED,GAAG;QAC7C,MAAME,QAAQ,CAAC,uBAAuB,EAAEF,GAAG;QAC3C,OAAO,GAAGD,KAAK,QAAQ,EAAEE,KAAK,IAAI,EAAEC,MAAM,CAAC,CAAC;IAC9C;IAEA,SAASC,GAAGC,KAAa,EAAEC,GAAiD;QAC1E,IAAIA,OAAO,MAAM,OAAO;QACxB,MAAMC,SAASC,OAAOF;QAEtB,oFAAoF;QACpF,yEAAyE;QACzE,IAAID,UAAU,UAAUA,UAAU,QAAQ;YACxC,IAAIE,OAAOrB,IAAI,OAAO,IAAI;gBACxB,MAAM,IAAIF,MAAM,CAAC,QAAQ,EAAEqB,MAAM,oBAAoB,CAAC;YACxD;YACAV,0BAA0B;YAC1B,OAAO;QACT;QAEA,mEAAmE;QACnE,IAAIY,OAAOrB,IAAI,OAAO,IAAI;YACxB,MAAM,IAAIF,MAAM,CAAC,QAAQ,EAAEqB,MAAM,oBAAoB,CAAC;QACxD;QAEA,MAAMJ,IAAI,CAAC,CAAC,EAAEM,OAAOnB,WAAW,GAAGqB,OAAO,CAAC,MAAM,MAAM,CAAC,CAAC;QACzD,OAAQJ;YACN,KAAK;gBAAQ;oBACX,mEAAmE;oBACnE,sFAAsF;oBACtF,IAAIE,OAAOG,QAAQ,CAAC,MAAM;wBACxB,MAAMC,SAAS,GAAGf,EAAE,6BAA6B,IAAI,EAAEK,GAAG;wBAC1D,MAAMW,SAAS,GAAGhB,EAAE,0BAA0B,IAAI,EAAEK,GAAG;wBACvD,OAAOH,EAAE,GAAGa,OAAO,IAAI,EAAEC,QAAQ;oBACnC;oBACA,+DAA+D;oBAC/D,OAAO;gBACT;YACA,KAAK;gBACH,OAAOb,MAAM,gBAAgBE;YAC/B,KAAK;gBACH,OAAOF,MAAM,gBAAgBE;YAC/B,KAAK;gBACH,OAAOF,MAAM,iBAAiBE;YAChC,KAAK;gBACH,wEAAwE;gBACxE,6DAA6D;gBAC7D,IAAIM,OAAOG,QAAQ,CAAC,QAAQH,OAAOM,MAAM,GAAG,GAAG,OAAO;gBACtD,OAAO,CAAC,oBAAoB,EAAEZ,EAAE,CAAC,CAAC;YACpC,KAAK;gBAAc;oBACjB,6DAA6D;oBAC7D,MAAMZ,iBAAiBP,mBAAmByB;oBAC1C,oEAAoE;oBACpE,OAAO,CAAC,wBAAwB,EAAElB,eAAe,EAAE,CAAC;gBACtD;YACA,KAAK;gBAAS;oBACZ,gEAAgE;oBAChE,OAAO,CAAC,wBAAwB,EAAEkB,OAAOE,OAAO,CAAC,MAAM,MAAM,EAAE,CAAC;gBAClE;YACA;gBACE,uDAAuD;gBACvD,iDAAiD;gBACjD,OAAO;QACX;IACF;IAEA,SAASK,MAAMC,EAAgB,EAAEC,GAA8B;QAC7D,IAAI,CAACA,OAAOA,IAAIH,MAAM,KAAK,GAAG;YAC5B,MAAM,IAAI7B,MAAM,CAAC,uBAAuB,EAAE+B,GAAG,UAAU,CAAC;QAC1D;QACA,IAAIC,IAAIH,MAAM,KAAK,GAAG;gBACNG;YAAd,MAAMC,SAAQD,QAAAA,GAAG,CAAC,EAAE,cAANA,mBAAAA,QAAU;YACxB,OAAOR,OAAOS;QAChB;QACA,MAAMC,SAASF,IAAIxB,IAAI,CAAC,CAAC,CAAC,EAAEuB,GAAG,CAAC,CAAC;QACjC,OAAOjB,EAAEoB;IACX;IACA,SAASC,UAAUd,KAAa,EAAEU,EAA0B;QAC1D,IAAI,OAAOA,OAAO,UAAU;YAC1B,OAAOX,GAAGC,OAAOU;QACnB;QAEA,IAAIK,MAAMC,OAAO,CAACN,GAAGO,IAAI,GAAG;YAC1B,MAAMC,UAAUR,GAAGO,IAAI,CAACE,GAAG,CAAC,CAACC,IAAMrB,GAAGC,OAAOG,OAAOiB,cAAAA,eAAAA,IAAK;YACzD,0FAA0F;YAC1F,MAAMC,eAAeH,QAAQI,MAAM,CAAC,CAAC9B,IAAMA,KAAKA,EAAEX,IAAI;YACtD,IAAIwC,aAAab,MAAM,KAAK,GAAG,OAAO;YACtC,OAAOC,MAAM,MAAMY;QACrB;QACA,IAAIN,MAAMC,OAAO,CAACN,GAAGa,IAAI,GAAG;YAC1B,MAAML,UAAUR,GAAGa,IAAI,CAACJ,GAAG,CAAC,CAACC,IAAMrB,GAAGC,OAAOG,OAAOiB,cAAAA,eAAAA,IAAK;YACzD,0FAA0F;YAC1F,MAAMC,eAAeH,QAAQI,MAAM,CAAC,CAAC9B,IAAMA,KAAKA,EAAEX,IAAI;YACtD,IAAIwC,aAAab,MAAM,KAAK,GAAG,OAAO;YACtC,OAAOC,MAAM,OAAOY;QACtB;QACA,IAAIN,MAAMC,OAAO,CAACN,GAAGc,KAAK,GAAG;YAC3B,MAAMN,UAAUR,GAAGc,KAAK,CAACL,GAAG,CAAC,CAACC,IAAMrB,GAAGC,OAAOG,OAAOiB,cAAAA,eAAAA,IAAK;YAC1D,0FAA0F;YAC1F,MAAMC,eAAeH,QAAQI,MAAM,CAAC,CAAC9B,IAAMA,KAAKA,EAAEX,IAAI;YACtD,IAAIwC,aAAab,MAAM,KAAK,GAAG,OAAO;YACtC,OAAO,CAAC,IAAI,EAAEf,EAAEgB,MAAM,MAAMY,gBAAgB;QAC9C;QACA,MAAM,IAAI1C,MAAM,CAAC,uBAAuB,EAAE8C,KAAKC,SAAS,CAAChB,KAAK;IAChE;IAEA,SAASiB,SAASC,CAAe;YAIqBC;QAHpD,MAAMA,QAAkB,EAAE;QAC1B,IAAID,EAAEE,IAAI,EAAED,MAAME,IAAI,CAAC,CAAC,oBAAoB,EAAEH,EAAEE,IAAI,CAAC,UAAU,CAAC;QAChE,IAAIF,EAAEI,GAAG,EAAEH,MAAME,IAAI,CAAC,CAAC,oBAAoB,EAAEH,EAAEI,GAAG,CAAC,UAAU,CAAC;QAC9D,OAAOH,MAAMrB,MAAM,GAAG,IAAIf,EAAEoC,MAAM1C,IAAI,CAAC,aAAa0C,UAAAA,KAAK,CAAC,EAAE,cAARA,qBAAAA,UAAY;IAClE;IAEA,SAASI,KAAKC,CAAY;QACxB,IAAI,CAACA,KAAK,OAAOA,MAAM,UAAU,OAAO;QAExC,IAAI,UAAUA,KAAKA,EAAEC,IAAI,EAAE;YACzB,MAAMC,WAAWF,EAAEC,IAAI,CAAChB,GAAG,CAACc,MAAMX,MAAM,CAAC,CAACe,OAAiCC,QAAQD;YACnF,IAAID,SAAS5B,MAAM,KAAK,GAAG,OAAO;YAClC,IAAI4B,SAAS5B,MAAM,KAAK,GAAG;gBACzB,MAAM+B,YAAYH,QAAQ,CAAC,EAAE;gBAC7B,OAAOG,sBAAAA,uBAAAA,YAAa;YACtB;YACA,OAAO9C,EAAE2C,SAASjD,IAAI,CAAC;QACzB;QACA,IAAI,SAAS+C,KAAKA,EAAEM,GAAG,EAAE;YACvB,MAAMC,UAAUP,EAAEM,GAAG,CAACrB,GAAG,CAACc,MAAMX,MAAM,CAAC,CAACe,OAAiCC,QAAQD;YACjF,IAAII,QAAQjC,MAAM,KAAK,GAAG,OAAO;YACjC,IAAIiC,QAAQjC,MAAM,KAAK,GAAG;gBACxB,MAAM+B,YAAYE,OAAO,CAAC,EAAE;gBAC5B,OAAOF,sBAAAA,uBAAAA,YAAa;YACtB;YACA,OAAO9C,EAAEgD,QAAQtD,IAAI,CAAC;QACxB;QACA,IAAI,UAAU+C,KAAKA,EAAEQ,IAAI,EAAE;YACzB,MAAMC,UAAUV,KAAKC,EAAEQ,IAAI;YAC3B,OAAOC,UAAU,CAAC,KAAK,EAAEA,QAAQ,CAAC,CAAC,GAAG;QACxC;QACA,IAAI,mBAAmBT,KAAKA,EAAEU,aAAa,EAAE,OAAO;QACpD,IAAI,UAAUV,KAAKA,EAAEW,IAAI,EAAE,OAAOlB,SAASO,EAAEW,IAAI;QAEjD,MAAM3D,OAAOD,OAAOC,IAAI,CAACgD;QACzB,IAAIhD,KAAKsB,MAAM,KAAK,GAAG;gBACHtB;YAAlB,MAAM4D,KAAK3C,QAAOjB,SAAAA,IAAI,CAAC,EAAE,cAAPA,oBAAAA,SAAW;YAC7B,IAAI4D,MAAM;gBAAC;gBAAQ;gBAAM;gBAAM;gBAAO;gBAAW;gBAAQ;gBAAQ;gBAAc;aAAQ,CAACzC,QAAQ,CAACyC,KAAK;gBACpG,MAAMC,aAAa,AAACb,CAAgB,CAACY,GAAuB;gBAC5D,IAAIC,YAAY,OAAOjC,UAAUgC,IAAIC;YACvC;QACF;QACA,OAAO;IACT;IAEA,MAAMC,YAAYf,KAAK5C;IAEvB,MAAM4D,QAAkB,EAAE;IAC1B,SAASC,UAAUvC,GAAc;QAC/B,IAAII,MAAMC,OAAO,CAACL,MAAM;YAAA,KAAK,MAAMwC,KAAKxC,IAAK,IAAI,CAACwC,cAAAA,eAAAA,IAAK,IAAIC,QAAQ,GAAGvE,IAAI,IAAIoE,MAAMlB,IAAI,CAAC5B,OAAOgD,GAAGtE,IAAI;QAAG;IAC5G;IAEA,SAASwE,KAAKC,IAAe;QAC3B,IAAI,CAACA,QAAQ,OAAOA,SAAS,UAAU;QACvC,IAAI,UAAUA,QAAQA,KAAKnB,IAAI,EAAE;YAC/BmB,KAAKnB,IAAI,CAACoB,OAAO,CAACF;YAClB;QACF;QACA,IAAI,SAASC,QAAQA,KAAKd,GAAG,EAAE;YAC7Bc,KAAKd,GAAG,CAACe,OAAO,CAACF;YACjB;QACF;QACA,IAAI,UAAUC,QAAQA,KAAKZ,IAAI,EAAE;YAC/BW,KAAKC,KAAKZ,IAAI;YACd;QACF;QAEA,IAAI,iBAAiBY,QAAQA,KAAKE,WAAW,EAAE;YAC7C,mDAAmD;YACnDN,UAAU;gBAAC,CAAC,CAAC,EAAE/C,OAAOmD,KAAKE,WAAW,EAAEpD,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC;aAAC;YAChE;QACF;QAEA,IAAI,aAAakD,QAAQA,KAAKG,OAAO,EAAE;YACrC,IAAI,OAAOH,KAAKG,OAAO,KAAK,UAAU;gBACpCP,UAAU;oBAACI,KAAKG,OAAO;iBAAC;YAC1B,OAAO;gBACLP,UAAUI,KAAKG,OAAO,CAACxC,IAAI;gBAC3BiC,UAAUI,KAAKG,OAAO,CAAClC,IAAI;gBAC3B2B,UAAUI,KAAKG,OAAO,CAACjC,KAAK;YAC9B;QACF;QACA,IAAI,UAAU8B,QAAQA,KAAKI,IAAI,EAAE;YAC/B,IAAI,OAAOJ,KAAKI,IAAI,KAAK,UAAU;gBACjCR,UAAU;oBAACI,KAAKI,IAAI;iBAAC;YACvB,OAAO;gBACLR,UAAUI,KAAKI,IAAI,CAACzC,IAAI;gBACxBiC,UAAUI,KAAKI,IAAI,CAACnC,IAAI;gBACxB2B,UAAUI,KAAKI,IAAI,CAAClC,KAAK;YAC3B;QACF;QACA,IAAI,UAAU8B,QAAQA,KAAKK,IAAI,EAAE;YAC/B,IAAI,OAAOL,KAAKK,IAAI,KAAK,UAAU;gBACjCT,UAAU;oBAACI,KAAKK,IAAI;iBAAC;YACvB,OAAO;gBACLT,UAAUI,KAAKK,IAAI,CAAC1C,IAAI;gBACxBiC,UAAUI,KAAKK,IAAI,CAACpC,IAAI;gBACxB2B,UAAUI,KAAKK,IAAI,CAACnC,KAAK;YAC3B;QACF;IACF;IACA6B,KAAKhE;IAEL;;;;GAIC,GACD,SAASuE,UAAUC,IAAY;QAC7B,IAAI,CAACA,MAAM,OAAOA;QAClB,wDAAwD;QACxD,OAAOA,KACJzD,OAAO,CAAC,OAAO,QACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,MAAM;IACnB;IAEA,MAAM0D,SAASb,MAAM9B,GAAG,CAAC,CAACgC;QACxB,MAAMY,UAAUH,UAAUzD,OAAOgD;QACjC,OAAOY;IACT;IACA,MAAMC,SAASF,OAAOtD,MAAM,GAAGsD,OAAO3E,IAAI,CAAC,UAAU;IAErD,OAAO;QAAE6E;QAAQ1C,QAAQ0B,aAAa,OAAOA,cAAc,YAAYA,UAAUxC,MAAM,GAAGwC,YAAY;QAAM1D;IAAwB;AACtI;AAEA,OAAO,SAAS2E,gBAAgBC,MAAiB,EAAEC,QAA6E;IAC9H,MAAMC,cAAchF,cAAc8E;IAClC,MAAMG,UAAUC,sBAAsBJ;IACtC,OAAO;QACL5C,QAAQ8C,YAAY9C,MAAM;QAC1B0C,QAAQI,YAAYJ,MAAM;QAC1B1E,yBAAyB8E,YAAY9E,uBAAuB;QAC5D+E;IACF;AACF;AAiBA,OAAO,SAASC,sBAAsBJ,MAAiB;IACrD,MAAMG,UAA4B;QAChCE,iBAAiB,EAAE;QACnBC,cAAc,EAAE;QAChBC,cAAc,EAAE;QAChBC,cAAc,EAAE;QAChBC,YAAY,EAAE;QACdC,YAAY,EAAE;QACdC,aAAa,EAAE;QACfC,oBAAoB,EAAE;QACtBC,eAAe,EAAE;IACnB;IACA,SAAS1B,KAAKC,IAAe;QAC3B,IAAI,CAACA,QAAQ,OAAOA,SAAS,UAAU;QAEvC,IAAI,UAAUA,QAAQA,KAAKnB,IAAI,EAAE;YAC/BmB,KAAKnB,IAAI,CAACoB,OAAO,CAACF;YAClB;QACF;QACA,IAAI,SAASC,QAAQA,KAAKd,GAAG,EAAE;YAC7Bc,KAAKd,GAAG,CAACe,OAAO,CAACF;YACjB;QACF;QACA,IAAI,UAAUC,QAAQA,KAAKZ,IAAI,EAAE;YAC/BW,KAAKC,KAAKZ,IAAI;YACd;QACF;QAEA,IAAI,mBAAmBY,QAAQA,KAAKV,aAAa,KAAKoC,WAAW;YAC/DX,QAAQzB,aAAa,GAAGU,KAAKV,aAAa,KAAK;YAC/C;QACF;QACA,IAAI,UAAUU,QAAQA,KAAKT,IAAI,EAAE;YAC/B,IAAIS,KAAKT,IAAI,CAACf,IAAI,EAAEuC,QAAQY,KAAK,GAAG3B,KAAKT,IAAI,CAACf,IAAI;YAClD,IAAIwB,KAAKT,IAAI,CAACb,GAAG,EAAEqC,QAAQa,MAAM,GAAG5B,KAAKT,IAAI,CAACb,GAAG;YACjD;QACF;QAEA,IAAI,aAAasB,QAAQA,KAAKG,OAAO,EAAE;YACrC,IAAI,OAAOH,KAAKG,OAAO,KAAK,UAAU;gBACpCY,QAAQE,eAAe,CAACxC,IAAI,CAACuB,KAAKG,OAAO;YAC3C,OAAO;gBACL,IAAIH,KAAKG,OAAO,CAACxC,IAAI,EAAEoD,QAAQE,eAAe,CAACxC,IAAI,IAAIuB,KAAKG,OAAO,CAACxC,IAAI;gBACxE,IAAIqC,KAAKG,OAAO,CAAClC,IAAI,EAAE8C,QAAQE,eAAe,CAACxC,IAAI,IAAIuB,KAAKG,OAAO,CAAClC,IAAI;YAC1E;QACF;QACA,IAAI,UAAU+B,QAAQA,KAAKI,IAAI,EAAE;YAC/B,IAAI,OAAOJ,KAAKI,IAAI,KAAK,UAAU;gBACjCW,QAAQG,YAAY,CAACzC,IAAI,CAACuB,KAAKI,IAAI;YACrC,OAAO;gBACL,IAAIJ,KAAKI,IAAI,CAACzC,IAAI,EAAEoD,QAAQG,YAAY,CAACzC,IAAI,IAAIuB,KAAKI,IAAI,CAACzC,IAAI;gBAC/D,IAAIqC,KAAKI,IAAI,CAACnC,IAAI,EAAE8C,QAAQG,YAAY,CAACzC,IAAI,IAAIuB,KAAKI,IAAI,CAACnC,IAAI;YACjE;QACF;QACA,IAAI,UAAU+B,QAAQA,KAAKK,IAAI,EAAE;YAC/B,IAAI,OAAOL,KAAKK,IAAI,KAAK,UAAU;gBACjCU,QAAQI,YAAY,CAAC1C,IAAI,CAACuB,KAAKK,IAAI;gBACnCU,QAAQG,YAAY,CAACzC,IAAI,CAACuB,KAAKK,IAAI;YACrC,OAAO;gBACL,IAAIL,KAAKK,IAAI,CAAC1C,IAAI,EAAE;oBAClBoD,QAAQI,YAAY,CAAC1C,IAAI,IAAIuB,KAAKK,IAAI,CAAC1C,IAAI;oBAC3CoD,QAAQG,YAAY,CAACzC,IAAI,IAAIuB,KAAKK,IAAI,CAAC1C,IAAI;gBAC7C;gBACA,IAAIqC,KAAKK,IAAI,CAACpC,IAAI,EAAE;oBAClB8C,QAAQI,YAAY,CAAC1C,IAAI,IAAIuB,KAAKK,IAAI,CAACpC,IAAI;oBAC3C8C,QAAQG,YAAY,CAACzC,IAAI,IAAIuB,KAAKK,IAAI,CAACpC,IAAI;gBAC7C;YACF;QACF;QACA,IAAI,UAAU+B,QAAQA,KAAK6B,IAAI,EAAE;YAC/B,IAAI,OAAO7B,KAAK6B,IAAI,KAAK,UAAU;gBACjCd,QAAQK,YAAY,CAAC3C,IAAI,CAACuB,KAAK6B,IAAI;YACrC,OAAO;gBACL,IAAI7B,KAAK6B,IAAI,CAAClE,IAAI,EAAEoD,QAAQK,YAAY,CAAC3C,IAAI,IAAIuB,KAAK6B,IAAI,CAAClE,IAAI;gBAC/D,IAAIqC,KAAK6B,IAAI,CAAC5D,IAAI,EAAE8C,QAAQK,YAAY,CAAC3C,IAAI,IAAIuB,KAAK6B,IAAI,CAAC5D,IAAI;YACjE;QACF;QACA,IAAI,QAAQ+B,QAAQA,KAAK8B,EAAE,EAAE;YAC3B,IAAI,OAAO9B,KAAK8B,EAAE,KAAK,UAAU;gBAC/Bf,QAAQM,UAAU,CAAC5C,IAAI,CAACuB,KAAK8B,EAAE;YACjC,OAAO;gBACL,IAAI9B,KAAK8B,EAAE,CAACnE,IAAI,EAAEoD,QAAQM,UAAU,CAAC5C,IAAI,IAAIuB,KAAK8B,EAAE,CAACnE,IAAI;gBACzD,IAAIqC,KAAK8B,EAAE,CAAC7D,IAAI,EAAE8C,QAAQM,UAAU,CAAC5C,IAAI,IAAIuB,KAAK8B,EAAE,CAAC7D,IAAI;YAC3D;QACF;QACA,IAAI,QAAQ+B,QAAQA,KAAK+B,EAAE,EAAE;YAC3B,IAAI,OAAO/B,KAAK+B,EAAE,KAAK,UAAU;gBAC/BhB,QAAQO,UAAU,CAAC7C,IAAI,CAACuB,KAAK+B,EAAE;YACjC,OAAO;gBACL,IAAI/B,KAAK+B,EAAE,CAACpE,IAAI,EAAEoD,QAAQO,UAAU,CAAC7C,IAAI,IAAIuB,KAAK+B,EAAE,CAACpE,IAAI;gBACzD,IAAIqC,KAAK+B,EAAE,CAAC9D,IAAI,EAAE8C,QAAQO,UAAU,CAAC7C,IAAI,IAAIuB,KAAK+B,EAAE,CAAC9D,IAAI;YAC3D;QACF;QACA,IAAI,SAAS+B,QAAQA,KAAKgC,GAAG,EAAE;YAC7B,IAAI,OAAOhC,KAAKgC,GAAG,KAAK,UAAU;gBAChCjB,QAAQQ,WAAW,CAAC9C,IAAI,CAACuB,KAAKgC,GAAG;YACnC,OAAO;gBACL,IAAIhC,KAAKgC,GAAG,CAACrE,IAAI,EAAEoD,QAAQQ,WAAW,CAAC9C,IAAI,IAAIuB,KAAKgC,GAAG,CAACrE,IAAI;gBAC5D,IAAIqC,KAAKgC,GAAG,CAAC/D,IAAI,EAAE8C,QAAQQ,WAAW,CAAC9C,IAAI,IAAIuB,KAAKgC,GAAG,CAAC/D,IAAI;YAC9D;QACF;QACA,IAAI,gBAAgB+B,QAAQA,KAAKiC,UAAU,EAAE;YAC3C,IAAI,OAAOjC,KAAKiC,UAAU,KAAK,UAAU;gBACvC,IAAI9G,mBAAmB6E,KAAKiC,UAAU,MAAM,MAAM;oBAChDlB,QAAQS,kBAAkB,CAAC/C,IAAI,CAACuB,KAAKiC,UAAU;gBACjD;YACF,OAAO;gBACL,iFAAiF;gBACjF,IAAIjC,KAAKiC,UAAU,CAACtE,IAAI,EAAE;oBACxB,MAAMuE,kBAAkBlC,KAAKiC,UAAU,CAACtE,IAAI,CAACK,MAAM,CAAC,CAACmE,MAAgBhH,mBAAmBgH,SAAS;oBACjG,IAAID,gBAAgBhF,MAAM,GAAG,GAAG6D,QAAQS,kBAAkB,CAAC/C,IAAI,IAAIyD;gBACrE;gBACA,IAAIlC,KAAKiC,UAAU,CAAChE,IAAI,EAAE;oBACxB,MAAMiE,kBAAkBlC,KAAKiC,UAAU,CAAChE,IAAI,CAACD,MAAM,CAAC,CAACmE,MAAgBhH,mBAAmBgH,SAAS;oBACjG,IAAID,gBAAgBhF,MAAM,GAAG,GAAG6D,QAAQS,kBAAkB,CAAC/C,IAAI,IAAIyD;gBACrE;gBACA,IAAIlC,KAAKiC,UAAU,CAAC/D,KAAK,EAAE;oBACzB,MAAMgE,kBAAkBlC,KAAKiC,UAAU,CAAC/D,KAAK,CAACF,MAAM,CAAC,CAACmE,MAAgBhH,mBAAmBgH,SAAS;oBAClG,IAAID,gBAAgBhF,MAAM,GAAG,GAAG6D,QAAQS,kBAAkB,CAAC/C,IAAI,IAAIyD;gBACrE;YACF;QACF;QACA,IAAI,WAAWlC,QAAQA,KAAKoC,KAAK,EAAE;YACjC,IAAI,OAAOpC,KAAKoC,KAAK,KAAK,UAAU;gBAClCrB,QAAQU,aAAa,CAAChD,IAAI,CAACuB,KAAKoC,KAAK;YACvC,OAAO;gBACL,IAAIpC,KAAKoC,KAAK,CAACzE,IAAI,EAAEoD,QAAQU,aAAa,CAAChD,IAAI,IAAIuB,KAAKoC,KAAK,CAACzE,IAAI;gBAClE,IAAIqC,KAAKoC,KAAK,CAACnE,IAAI,EAAE8C,QAAQU,aAAa,CAAChD,IAAI,IAAIuB,KAAKoC,KAAK,CAACnE,IAAI;gBAClE,IAAI+B,KAAKoC,KAAK,CAAClE,KAAK,EAAE6C,QAAQU,aAAa,CAAChD,IAAI,IAAIuB,KAAKoC,KAAK,CAAClE,KAAK;YACtE;QACF;IACF;IACA6B,KAAKa;IACL,OAAOG;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/querying/query-builder.ts"],"sourcesContent":["import type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\n\ntype FieldOperator = {\n $any?: string[];\n $all?: string[];\n $none?: string[];\n};\n\ntype DateOperator = {\n $gte?: string;\n $lt?: string;\n};\n\ntype FieldQuery = {\n from?: FieldOperator | string;\n to?: FieldOperator | string;\n cc?: FieldOperator | string;\n bcc?: FieldOperator | string;\n subject?: FieldOperator | string;\n text?: FieldOperator | string;\n body?: FieldOperator | string;\n categories?: FieldOperator | string;\n label?: FieldOperator | string;\n};\n\n/**\n * Outlook category mappings - case insensitive input to exact system categories\n * Note: These are user-defined categories in Outlook, not system categories like Gmail\n */\nconst OUTLOOK_CATEGORIES = {\n personal: 'Personal',\n work: 'Work',\n family: 'Family',\n travel: 'Travel',\n important: 'Important',\n urgent: 'Urgent',\n} as const;\n\n/**\n * Validate and map category name to Outlook system category\n * Throws error for invalid categories (fail fast principle)\n */\nfunction mapOutlookCategory(category: string): string {\n // Input validation - fail fast on invalid input\n if (!category || typeof category !== 'string') {\n throw new Error(`Invalid category: expected non-empty string, got ${typeof category}`);\n }\n\n const trimmed = category.trim();\n if (trimmed === '') {\n throw new Error('Invalid category: empty string after trimming');\n }\n\n // Fail fast on unknown categories\n const normalizedCategory = trimmed.toLowerCase();\n const systemCategory = OUTLOOK_CATEGORIES[normalizedCategory as keyof typeof OUTLOOK_CATEGORIES];\n\n if (!systemCategory) {\n throw new Error(`Invalid Outlook category: \"${category}\". Valid categories: ${Object.keys(OUTLOOK_CATEGORIES).join(', ')}`);\n }\n\n return systemCategory;\n}\n\nexport interface ODataFilterResult {\n search: string | null;\n filter: string | null;\n requireBodyClientFilter: boolean;\n}\n\nexport function toGraphFilter(query: QueryNode): ODataFilterResult {\n if (query.kqlQuery) {\n return { search: query.kqlQuery, filter: null, requireBodyClientFilter: false };\n }\n let requireBodyClientFilter = false;\n\n function L(s: string) {\n // Microsoft Graph does NOT support toLower() function in OData filters\n // Case-insensitive matching must be done client-side or via $search\n return s;\n }\n function p(s: string) {\n return `(${s})`;\n }\n\n function recip(coll: string, V: string) {\n // Graph may reject functions on nested properties; use equality on nested address/name fields.\n const left = `r/emailAddress/address eq ${V}`;\n const right = `r/emailAddress/name eq ${V}`;\n return `${coll}/any(r: ${left} or ${right})`;\n }\n\n function fv(field: string, raw: string | number | boolean | null | undefined): string {\n if (raw == null) return '';\n const rawStr = String(raw);\n\n // For text and body fields, skip OData filtering entirely (uses KQL search instead)\n // Do this BEFORE validation so we don't throw on valid text/body queries\n if (field === 'text' || field === 'body') {\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n requireBodyClientFilter = true;\n return '';\n }\n\n // For all other fields, validate non-empty AFTER checking for null\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n\n const V = `'${rawStr.toLowerCase().replace(/'/g, \"''\")}'`;\n switch (field) {\n case 'from': {\n // For email addresses emit equality checks on nested address/name;\n // for name-only tokens, skip server-side filter (handled client-side or via $search).\n if (rawStr.includes('@')) {\n const addrEq = `${L('from/emailAddress/address')} eq ${V}`;\n const nameEq = `${L('from/emailAddress/name')} eq ${V}`;\n return p(`${addrEq} or ${nameEq}`);\n }\n // Don't emit a server-side filter for name-only 'from' tokens.\n return '';\n }\n case 'to':\n return recip('toRecipients', V);\n case 'cc':\n return recip('ccRecipients', V);\n case 'bcc':\n return recip('bccRecipients', V);\n case 'subject':\n // Microsoft Graph does NOT support contains() function in OData filters\n // Use startswith as a partial alternative or rely on $search\n if (rawStr.includes('-') || rawStr.length < 3) return '';\n return `startswith(subject, ${V})`;\n case 'categories': {\n // mapOutlookCategory will throw on invalid input (fail fast)\n const systemCategory = mapOutlookCategory(rawStr);\n // Use the categories OData property with exact case-sensitive match\n return `categories/any(c: c eq '${systemCategory}')`;\n }\n case 'label': {\n // Direct passthrough to categories for Outlook (case-sensitive)\n return `categories/any(c: c eq '${rawStr.replace(/'/g, \"''\")}')`;\n }\n default:\n // Microsoft Graph does NOT support contains() function\n // For unknown fields, skip server-side filtering\n return '';\n }\n }\n\n function chain(op: 'and' | 'or', arr: Array<string | undefined>) {\n if (!arr || arr.length === 0) {\n throw new Error(`chain: empty array for ${op} operation`);\n }\n if (arr.length === 1) {\n const first = arr[0] ?? '';\n return String(first);\n }\n const joined = arr.join(` ${op} `);\n return p(joined);\n }\n function fieldExpr(field: string, op: FieldOperator | string): string {\n if (typeof op === 'string') {\n return fv(field, op);\n }\n\n if (Array.isArray(op.$any)) {\n const results = op.$any.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('or', validResults);\n }\n if (Array.isArray(op.$all)) {\n const results = op.$all.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('and', validResults);\n }\n if (Array.isArray(op.$none)) {\n const results = op.$none.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return `not ${p(chain('or', validResults))}`;\n }\n throw new Error(`Unknown field operator ${JSON.stringify(op)}`);\n }\n\n function dateExpr(d: DateOperator): string {\n const parts: string[] = [];\n if (d.$gte) parts.push(`receivedDateTime ge ${d.$gte}T00:00:00Z`);\n if (d.$lt) parts.push(`receivedDateTime lt ${d.$lt}T00:00:00Z`);\n return parts.length > 1 ? p(parts.join(' and ')) : (parts[0] ?? '');\n }\n\n function emit(n: QueryNode): string {\n if (!n || typeof n !== 'object') return '';\n\n if ('$and' in n && n.$and) {\n const andParts = n.$and.map(emit).filter((part: string): part is string => Boolean(part));\n if (andParts.length === 0) return '';\n if (andParts.length === 1) {\n const firstPart = andParts[0];\n return firstPart ?? '';\n }\n return p(andParts.join(' and '));\n }\n if ('$or' in n && n.$or) {\n const orParts = n.$or.map(emit).filter((part: string): part is string => Boolean(part));\n if (orParts.length === 0) return '';\n if (orParts.length === 1) {\n const firstPart = orParts[0];\n return firstPart ?? '';\n }\n return p(orParts.join(' or '));\n }\n if ('$not' in n && n.$not) {\n const notExpr = emit(n.$not);\n return notExpr ? `not (${notExpr})` : '';\n }\n if ('hasAttachment' in n && n.hasAttachment) return 'hasAttachments eq true';\n if ('date' in n && n.date) return dateExpr(n.date);\n\n const keys = Object.keys(n);\n if (keys.length === 1) {\n const k0 = String(keys[0] ?? '');\n if (k0 && ['from', 'to', 'cc', 'bcc', 'subject', 'text', 'body', 'categories', 'label'].includes(k0)) {\n const fieldValue = (n as FieldQuery)[k0 as keyof FieldQuery];\n if (fieldValue) return fieldExpr(k0, fieldValue);\n }\n }\n return '';\n }\n\n const filterStr = emit(query);\n\n const terms: string[] = [];\n function pushTerms(arr?: string[]) {\n if (Array.isArray(arr)) for (const t of arr) if ((t ?? '').toString().trim()) terms.push(String(t).trim());\n }\n\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('exactPhrase' in node && node.exactPhrase) {\n // KQL uses double quotes for exact phrase matching\n pushTerms([`\"${String(node.exactPhrase).replace(/\"/g, '\\\\\"')}\"`]);\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n pushTerms([node.subject]);\n } else {\n pushTerms(node.subject.$any);\n pushTerms(node.subject.$all);\n pushTerms(node.subject.$none);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n pushTerms([node.body]);\n } else {\n pushTerms(node.body.$any);\n pushTerms(node.body.$all);\n pushTerms(node.body.$none);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n pushTerms([node.text]);\n } else {\n pushTerms(node.text.$any);\n pushTerms(node.text.$all);\n pushTerms(node.text.$none);\n }\n }\n }\n walk(query);\n\n /**\n * Escape KQL (Keyword Query Language) special characters in search terms.\n * KQL special characters that need escaping: \\ : ( ) { } [ ] \" * ? < > - _\n * According to Microsoft Graph KQL syntax, these must be escaped with backslash.\n */\n function escapeKQL(term: string): string {\n if (!term) return term;\n // Escape backslash first, then other special characters\n return term\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/:/g, '\\\\:')\n .replace(/\\(/g, '\\\\(')\n .replace(/\\)/g, '\\\\)')\n .replace(/\\{/g, '\\\\{')\n .replace(/\\}/g, '\\\\}')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\*/g, '\\\\*')\n .replace(/\\?/g, '\\\\?')\n .replace(/</g, '\\\\<')\n .replace(/>/g, '\\\\>')\n .replace(/-/g, '\\\\-')\n .replace(/_/g, '\\\\_');\n }\n\n const mapped = terms.map((t) => {\n const escaped = escapeKQL(String(t));\n return escaped;\n });\n const search = mapped.length ? mapped.join(' OR ') : null;\n\n return { search, filter: filterStr && typeof filterStr === 'string' && filterStr.length ? filterStr : null, requireBodyClientFilter };\n}\n\nexport function toOutlookFilter(parsed: QueryNode, _options?: { includeBodyContent?: boolean; useCaseInsensitiveWrap?: boolean }) {\n const graphResult = toGraphFilter(parsed);\n const filters = extractOutlookFilters(parsed);\n return {\n filter: graphResult.filter,\n search: graphResult.search,\n requireBodyClientFilter: graphResult.requireBodyClientFilter,\n filters,\n };\n}\n\ninterface ExtractedFilters {\n subjectIncludes: string[];\n bodyIncludes: string[];\n textIncludes: string[];\n fromIncludes: string[];\n toIncludes: string[];\n ccIncludes: string[];\n bccIncludes: string[];\n categoriesIncludes: string[];\n labelIncludes: string[];\n hasAttachment?: boolean;\n since?: string;\n before?: string;\n}\n\nexport function extractOutlookFilters(parsed: QueryNode): ExtractedFilters {\n const filters: ExtractedFilters = {\n subjectIncludes: [],\n bodyIncludes: [],\n textIncludes: [],\n fromIncludes: [],\n toIncludes: [],\n ccIncludes: [],\n bccIncludes: [],\n categoriesIncludes: [],\n labelIncludes: [],\n };\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('hasAttachment' in node && node.hasAttachment !== undefined) {\n filters.hasAttachment = node.hasAttachment === true;\n return;\n }\n if ('date' in node && node.date) {\n if (node.date.$gte) filters.since = node.date.$gte;\n if (node.date.$lt) filters.before = node.date.$lt;\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n filters.subjectIncludes.push(node.subject);\n } else {\n if (node.subject.$any) filters.subjectIncludes.push(...node.subject.$any);\n if (node.subject.$all) filters.subjectIncludes.push(...node.subject.$all);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n filters.bodyIncludes.push(node.body);\n } else {\n if (node.body.$any) filters.bodyIncludes.push(...node.body.$any);\n if (node.body.$all) filters.bodyIncludes.push(...node.body.$all);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n filters.textIncludes.push(node.text);\n filters.bodyIncludes.push(node.text);\n } else {\n if (node.text.$any) {\n filters.textIncludes.push(...node.text.$any);\n filters.bodyIncludes.push(...node.text.$any);\n }\n if (node.text.$all) {\n filters.textIncludes.push(...node.text.$all);\n filters.bodyIncludes.push(...node.text.$all);\n }\n }\n }\n if ('from' in node && node.from) {\n if (typeof node.from === 'string') {\n filters.fromIncludes.push(node.from);\n } else {\n if (node.from.$any) filters.fromIncludes.push(...node.from.$any);\n if (node.from.$all) filters.fromIncludes.push(...node.from.$all);\n }\n }\n if ('to' in node && node.to) {\n if (typeof node.to === 'string') {\n filters.toIncludes.push(node.to);\n } else {\n if (node.to.$any) filters.toIncludes.push(...node.to.$any);\n if (node.to.$all) filters.toIncludes.push(...node.to.$all);\n }\n }\n if ('cc' in node && node.cc) {\n if (typeof node.cc === 'string') {\n filters.ccIncludes.push(node.cc);\n } else {\n if (node.cc.$any) filters.ccIncludes.push(...node.cc.$any);\n if (node.cc.$all) filters.ccIncludes.push(...node.cc.$all);\n }\n }\n if ('bcc' in node && node.bcc) {\n if (typeof node.bcc === 'string') {\n filters.bccIncludes.push(node.bcc);\n } else {\n if (node.bcc.$any) filters.bccIncludes.push(...node.bcc.$any);\n if (node.bcc.$all) filters.bccIncludes.push(...node.bcc.$all);\n }\n }\n if ('categories' in node && node.categories) {\n if (typeof node.categories === 'string') {\n if (mapOutlookCategory(node.categories) !== null) {\n filters.categoriesIncludes.push(node.categories);\n }\n } else {\n // Filter out invalid categories to prevent memory leaks and maintain clean state\n if (node.categories.$any) {\n const validCategories = node.categories.$any.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$all) {\n const validCategories = node.categories.$all.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$none) {\n const validCategories = node.categories.$none.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n }\n }\n if ('label' in node && node.label) {\n if (typeof node.label === 'string') {\n filters.labelIncludes.push(node.label);\n } else {\n if (node.label.$any) filters.labelIncludes.push(...node.label.$any);\n if (node.label.$all) filters.labelIncludes.push(...node.label.$all);\n if (node.label.$none) filters.labelIncludes.push(...node.label.$none);\n }\n }\n }\n walk(parsed);\n return filters;\n}\n"],"names":["OUTLOOK_CATEGORIES","personal","work","family","travel","important","urgent","mapOutlookCategory","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemCategory","Object","keys","join","toGraphFilter","query","kqlQuery","search","filter","requireBodyClientFilter","L","s","p","recip","coll","V","left","right","fv","field","raw","rawStr","String","replace","includes","addrEq","nameEq","length","chain","op","arr","first","joined","fieldExpr","Array","isArray","$any","results","map","v","validResults","$all","$none","JSON","stringify","dateExpr","d","parts","$gte","push","$lt","emit","n","$and","andParts","part","Boolean","firstPart","$or","orParts","$not","notExpr","hasAttachment","date","k0","fieldValue","filterStr","terms","pushTerms","t","toString","walk","node","forEach","exactPhrase","subject","body","text","escapeKQL","term","mapped","escaped","toOutlookFilter","parsed","_options","graphResult","filters","extractOutlookFilters","subjectIncludes","bodyIncludes","textIncludes","fromIncludes","toIncludes","ccIncludes","bccIncludes","categoriesIncludes","labelIncludes","undefined","since","before","from","to","cc","bcc","categories","validCategories","cat","label"],"mappings":"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"}
@@ -1,31 +1,6 @@
1
1
  import keyvRegistry from 'keyv-registry';
2
- function parseDefaultTtl(uri) {
3
- try {
4
- const url = new URL(uri);
5
- const ttlParam = url.searchParams.get('ttl');
6
- const ttlSecondsParam = url.searchParams.get('ttlSeconds');
7
- const ttlMs = ttlSecondsParam ? Number(ttlSecondsParam) * 1000 : ttlParam ? Number(ttlParam) : undefined;
8
- url.searchParams.delete('ttl');
9
- url.searchParams.delete('ttlSeconds');
10
- return Number.isFinite(ttlMs) && ttlMs > 0 ? {
11
- uri: url.toString(),
12
- ttl: ttlMs
13
- } : {
14
- uri: url.toString()
15
- };
16
- } catch {
17
- return {
18
- uri
19
- };
20
- }
21
- }
22
2
  export default async function createStore(uri) {
23
- const { uri: parsedUri, ttl: defaultTtl } = parseDefaultTtl(uri);
24
- const store = await keyvRegistry(parsedUri);
3
+ const store = await keyvRegistry(uri);
25
4
  if (!store) throw new Error(`Failed to create store for URI: ${uri}`);
26
- if (defaultTtl !== undefined) {
27
- const originalSet = store.set.bind(store);
28
- store.set = (key, value, ttl)=>originalSet(key, value, ttl !== null && ttl !== void 0 ? ttl : defaultTtl);
29
- }
30
5
  return store;
31
6
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\nfunction parseDefaultTtl(uri: string): { uri: string; ttl?: number } {\n try {\n const url = new URL(uri);\n const ttlParam = url.searchParams.get('ttl');\n const ttlSecondsParam = url.searchParams.get('ttlSeconds');\n const ttlMs = ttlSecondsParam ? Number(ttlSecondsParam) * 1000 : ttlParam ? Number(ttlParam) : undefined;\n url.searchParams.delete('ttl');\n url.searchParams.delete('ttlSeconds');\n return Number.isFinite(ttlMs) && (ttlMs as number) > 0 ? { uri: url.toString(), ttl: ttlMs } : { uri: url.toString() };\n } catch {\n return { uri };\n }\n}\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const { uri: parsedUri, ttl: defaultTtl } = parseDefaultTtl(uri);\n const store = await keyvRegistry<T>(parsedUri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n if (defaultTtl !== undefined) {\n const originalSet = store.set.bind(store);\n store.set = ((key, value, ttl) => originalSet(key, value, ttl ?? defaultTtl)) as typeof store.set;\n }\n return store;\n}\n"],"names":["keyvRegistry","parseDefaultTtl","uri","url","URL","ttlParam","searchParams","get","ttlSecondsParam","ttlMs","Number","undefined","delete","isFinite","toString","ttl","createStore","parsedUri","defaultTtl","store","Error","originalSet","set","bind","key","value"],"mappings":"AACA,OAAOA,kBAAkB,gBAAgB;AAEzC,SAASC,gBAAgBC,GAAW;IAClC,IAAI;QACF,MAAMC,MAAM,IAAIC,IAAIF;QACpB,MAAMG,WAAWF,IAAIG,YAAY,CAACC,GAAG,CAAC;QACtC,MAAMC,kBAAkBL,IAAIG,YAAY,CAACC,GAAG,CAAC;QAC7C,MAAME,QAAQD,kBAAkBE,OAAOF,mBAAmB,OAAOH,WAAWK,OAAOL,YAAYM;QAC/FR,IAAIG,YAAY,CAACM,MAAM,CAAC;QACxBT,IAAIG,YAAY,CAACM,MAAM,CAAC;QACxB,OAAOF,OAAOG,QAAQ,CAACJ,UAAU,AAACA,QAAmB,IAAI;YAAEP,KAAKC,IAAIW,QAAQ;YAAIC,KAAKN;QAAM,IAAI;YAAEP,KAAKC,IAAIW,QAAQ;QAAG;IACvH,EAAE,OAAM;QACN,OAAO;YAAEZ;QAAI;IACf;AACF;AAEA,eAAe,eAAec,YAAed,GAAW;IACtD,MAAM,EAAEA,KAAKe,SAAS,EAAEF,KAAKG,UAAU,EAAE,GAAGjB,gBAAgBC;IAC5D,MAAMiB,QAAQ,MAAMnB,aAAgBiB;IACpC,IAAI,CAACE,OAAO,MAAM,IAAIC,MAAM,CAAC,gCAAgC,EAAElB,KAAK;IACpE,IAAIgB,eAAeP,WAAW;QAC5B,MAAMU,cAAcF,MAAMG,GAAG,CAACC,IAAI,CAACJ;QACnCA,MAAMG,GAAG,GAAI,CAACE,KAAKC,OAAOV,MAAQM,YAAYG,KAAKC,OAAOV,gBAAAA,iBAAAA,MAAOG;IACnE;IACA,OAAOC;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const store = await keyvRegistry<T>(uri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n return store;\n}\n"],"names":["keyvRegistry","createStore","uri","store","Error"],"mappings":"AACA,OAAOA,kBAAkB,gBAAgB;AAEzC,eAAe,eAAeC,YAAeC,GAAW;IACtD,MAAMC,QAAQ,MAAMH,aAAgBE;IACpC,IAAI,CAACC,OAAO,MAAM,IAAIC,MAAM,CAAC,gCAAgC,EAAEF,KAAK;IACpE,OAAOC;AACT"}
@@ -6,9 +6,9 @@ import { Client } from '@microsoft/microsoft-graph-client';
6
6
  import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
7
7
  import { z } from 'zod';
8
8
  import { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.js';
9
- import { OutlookQuerySchema } from '../../schemas/outlook-query-schema.js';
9
+ import { OutlookQueryParameterSchema } from '../../schemas/outlook-query-schema.js';
10
10
  const inputSchema = z.object({
11
- query: OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),
11
+ query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),
12
12
  fields: createFieldsSchema({
13
13
  availableFields: EMAIL_FIELDS,
14
14
  fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/mcp/tools/message-search.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } 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, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } 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';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQuerySchema } from '../../schemas/outlook-query-schema.ts';\n\nconst inputSchema = z.object({\n query: OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({\n defaultPageSize: 50,\n maxPageSize: 500,\n provider: 'outlook',\n }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Outlook messages using structured query objects 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({ query, pageSize = 50, pageToken, fields, shape = 'arrays', contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const includeBody = requestedFields === 'all' || requestedFields.has('body');\n\n logger.info('outlook.search called with', {\n query,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields: fields || 'all',\n includeBody,\n });\n\n try {\n const graph = Client.initWithMiddleware({\n authProvider: extra.authContext.auth,\n });\n const started = Date.now();\n const exec = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(pageToken ? { pageToken } : {}),\n includeBody,\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const fromAddr = message?.from?.emailAddress?.address ?? null;\n const fromName = message?.from?.emailAddress?.name ?? null;\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent: string | undefined;\n if (includeBody && message?.body?.content) {\n const isHtml = message.body.contentType?.toLowerCase() === 'html';\n bodyContent = message.body.content;\n\n if (isHtml && excludeThreadHistory) {\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body.content);\n }\n }\n\n const mapped: Partial<EmailDetail> = {\n id: message?.id ?? undefined,\n subject: message?.subject ?? undefined,\n from: fromAddr ?? undefined,\n fromName: fromName ?? undefined,\n to,\n cc,\n bcc,\n date: message?.receivedDateTime ?? undefined,\n snippet: message?.bodyPreview ?? undefined,\n ...(bodyContent && { body: bodyContent, bodyContentType: contentType }),\n };\n return mapped;\n }\n );\n const durationMs = Date.now() - started;\n\n const filteredItems = exec.items.map((item) => filterFields(item, requestedFields));\n\n logger.info('outlook.message.search returning', {\n query,\n pageSize,\n itemsLength: filteredItems.length,\n fields: fields || 'all',\n });\n logger.info('outlook.message.search metrics', {\n durationMs,\n metadata: exec.metadata,\n });\n\n // Type-safe metadata access\n const metadataObj = exec.metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\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.search error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EMAIL_COMMON_PATTERNS","EMAIL_FIELD_DESCRIPTIONS","EMAIL_FIELDS","EmailContentTypeSchema","EmailDetailSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","schemas","AuthRequiredBranchSchema","createFieldsSchema","createPaginationSchema","createShapeSchema","filterFields","parseFields","toColumnarFormat","Client","ErrorCode","McpError","z","executeQuery","executeOutlookQuery","OutlookQuerySchema","inputSchema","object","query","optional","describe","fields","availableFields","fieldDescriptions","commonPatterns","resourceName","defaultPageSize","maxPageSize","provider","shape","contentType","excludeThreadHistory","successObjectsBranchSchema","type","literal","items","array","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","pageSize","pageToken","extra","logger","requestedFields","includeBody","has","info","undefined","graph","initWithMiddleware","authProvider","authContext","auth","started","Date","now","exec","limit","m","message","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","fromName","name","bodyContent","body","content","isHtml","toLowerCase","mapped","id","subject","date","receivedDateTime","snippet","bodyPreview","bodyContentType","durationMs","filteredItems","item","itemsLength","length","metadata","metadataObj","text","JSON","stringify","structuredContent","error","Error","String","InternalError","stack","createTool"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/mcp/tools/message-search.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } 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, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } 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';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQueryParameterSchema } from '../../schemas/outlook-query-schema.ts';\n\nconst inputSchema = z.object({\n query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({\n defaultPageSize: 50,\n maxPageSize: 500,\n provider: 'outlook',\n }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Outlook messages using structured query objects 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({ query, pageSize = 50, pageToken, fields, shape = 'arrays', contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const includeBody = requestedFields === 'all' || requestedFields.has('body');\n\n logger.info('outlook.search called with', {\n query,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields: fields || 'all',\n includeBody,\n });\n\n try {\n const graph = Client.initWithMiddleware({\n authProvider: extra.authContext.auth,\n });\n const started = Date.now();\n const exec = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(pageToken ? { pageToken } : {}),\n includeBody,\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const fromAddr = message?.from?.emailAddress?.address ?? null;\n const fromName = message?.from?.emailAddress?.name ?? null;\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent: string | undefined;\n if (includeBody && message?.body?.content) {\n const isHtml = message.body.contentType?.toLowerCase() === 'html';\n bodyContent = message.body.content;\n\n if (isHtml && excludeThreadHistory) {\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body.content);\n }\n }\n\n const mapped: Partial<EmailDetail> = {\n id: message?.id ?? undefined,\n subject: message?.subject ?? undefined,\n from: fromAddr ?? undefined,\n fromName: fromName ?? undefined,\n to,\n cc,\n bcc,\n date: message?.receivedDateTime ?? undefined,\n snippet: message?.bodyPreview ?? undefined,\n ...(bodyContent && { body: bodyContent, bodyContentType: contentType }),\n };\n return mapped;\n }\n );\n const durationMs = Date.now() - started;\n\n const filteredItems = exec.items.map((item) => filterFields(item, requestedFields));\n\n logger.info('outlook.message.search returning', {\n query,\n pageSize,\n itemsLength: filteredItems.length,\n fields: fields || 'all',\n });\n logger.info('outlook.message.search metrics', {\n durationMs,\n metadata: exec.metadata,\n });\n\n // Type-safe metadata access\n const metadataObj = exec.metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\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.search error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EMAIL_COMMON_PATTERNS","EMAIL_FIELD_DESCRIPTIONS","EMAIL_FIELDS","EmailContentTypeSchema","EmailDetailSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","schemas","AuthRequiredBranchSchema","createFieldsSchema","createPaginationSchema","createShapeSchema","filterFields","parseFields","toColumnarFormat","Client","ErrorCode","McpError","z","executeQuery","executeOutlookQuery","OutlookQueryParameterSchema","inputSchema","object","query","optional","describe","fields","availableFields","fieldDescriptions","commonPatterns","resourceName","defaultPageSize","maxPageSize","provider","shape","contentType","excludeThreadHistory","successObjectsBranchSchema","type","literal","items","array","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","pageSize","pageToken","extra","logger","requestedFields","includeBody","has","info","undefined","graph","initWithMiddleware","authProvider","authContext","auth","started","Date","now","exec","limit","m","message","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","fromName","name","bodyContent","body","content","isHtml","toLowerCase","mapped","id","subject","date","receivedDateTime","snippet","bodyPreview","bodyContentType","durationMs","filteredItems","item","itemsLength","length","metadata","metadataObj","text","JSON","stringify","structuredContent","error","Error","String","InternalError","stack","createTool"],"mappings":"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"}
@@ -9,7 +9,7 @@ import { createWriteStream } from 'fs';
9
9
  import { unlink } from 'fs/promises';
10
10
  import { z } from 'zod';
11
11
  import { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.js';
12
- import { OutlookQuerySchema } from '../../schemas/outlook-query-schema.js';
12
+ import { OutlookQueryParameterSchema } from '../../schemas/outlook-query-schema.js';
13
13
  const DEFAULT_PAGE_SIZE = 50;
14
14
  const DEFAULT_MAX_ITEMS = 10000;
15
15
  const MAX_EXPORT_ITEMS = 50000;
@@ -20,7 +20,7 @@ const ExportResultSchema = z.object({
20
20
  truncated: z.boolean().describe('Whether export was truncated at maxItems')
21
21
  });
22
22
  const inputSchema = z.object({
23
- query: OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),
23
+ query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),
24
24
  maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),
25
25
  filename: z.string().trim().min(1).default('outlook-messages.csv').describe('Output filename (default: outlook-messages.csv)'),
26
26
  contentType: EmailContentTypeSchema,
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/mcp/tools/messages-export-csv.ts"],"sourcesContent":["/** Outlook message CSV export tool - streams results to file without loading all data into context */\n\nimport { EmailContentTypeSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } 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 { getFileUri, reserveFile, 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 { stringify } from 'csv-stringify/sync';\nimport { createWriteStream } from 'fs';\nimport { unlink } from 'fs/promises';\nimport { z } from 'zod';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQuerySchema } from '../../schemas/outlook-query-schema.ts';\nimport type { StorageExtra } from '../../types.ts';\n\nconst DEFAULT_PAGE_SIZE = 50;\nconst DEFAULT_MAX_ITEMS = 10000;\nconst MAX_EXPORT_ITEMS = 50000;\n\nconst ExportResultSchema = z.object({\n uri: z.string().describe('File URI (file:// or http://)'),\n filename: z.string().describe('Stored filename'),\n rowCount: z.number().describe('Number of messages exported'),\n truncated: z.boolean().describe('Whether export was truncated at maxItems'),\n});\n\nconst inputSchema = z.object({\n query: OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),\n maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),\n filename: z.string().trim().min(1).default('outlook-messages.csv').describe('Output filename (default: outlook-messages.csv)'),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schema\nconst successBranchSchema = ExportResultSchema.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: 'Export Outlook messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',\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\n/**\n * Handler for outlook-messages-export-csv tool\n *\n * CRITICAL: Streaming implementation per user requirements\n * - Generate UUID upfront\n * - Write CSV header immediately\n * - Append rows as batches arrive\n * - Delete partial file on error\n * - NO RETRIES (fail fast on error)\n */\nasync function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n const { storageContext } = extra;\n const { transport, resourceStoreUri, baseUrl } = storageContext;\n\n logger.info('outlook.messages.export-csv called', {\n query,\n maxItems,\n filename,\n accountId: extra.authContext.accountId,\n });\n\n // Reserve file location for streaming write (creates directory, generates ID, formats filename)\n const reservation = await reserveFile(filename, {\n resourceStoreUri,\n });\n const { storedName, fullPath } = reservation;\n\n logger.info('outlook.messages.export-csv starting streaming export', { path: fullPath, maxItems });\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n\n // Create CSV headers (all email fields)\n const csvHeaders = ['id', 'threadId', 'from', 'to', 'cc', 'bcc', 'subject', 'date', 'snippet', 'body', 'provider', 'labels'];\n\n // Create write stream and write headers immediately\n const writeStream = createWriteStream(fullPath, { encoding: 'utf-8' });\n const headerLine = stringify([csvHeaders], { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(headerLine);\n\n // Internal pagination loop - append to CSV with each batch\n // NO RETRIES: If any error occurs, fail the whole operation and clean up\n let totalRows = 0;\n let nextPageToken: string | undefined;\n const started = Date.now();\n\n while (totalRows < maxItems) {\n const remainingItems = maxItems - totalRows;\n const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);\n\n const exec: {\n items: Array<{\n id: string;\n threadId?: string;\n from: string;\n to: string;\n cc: string;\n bcc: string;\n subject: string;\n date: string;\n snippet: string;\n body: string;\n provider: string;\n labels: string;\n }>;\n metadata?: { nextPageToken?: string };\n } = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(nextPageToken !== undefined && { pageToken: nextPageToken }),\n includeBody: true, // Always include body for CSV export\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const fromAddr = message?.from?.emailAddress?.address ?? (message?.from as { address?: string })?.address ?? '';\n const categories = Array.isArray(message?.categories) ? message.categories.join(';') : '';\n\n // Process body based on contentType and excludeThreadHistory options\n let body = message?.body?.content ?? '';\n const isHtml = message?.body?.contentType?.toLowerCase() === 'html';\n\n if (isHtml && excludeThreadHistory) {\n body = extractCurrentMessageFromHtml(body);\n }\n\n if (isHtml && contentType === 'text') {\n body = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(body) : extractCurrentMessageFromHtmlToText(message?.body?.content ?? '');\n }\n\n return {\n id: String(message?.id ?? ''),\n threadId: message?.conversationId ? String(message.conversationId) : '',\n from: fromAddr,\n to,\n cc,\n bcc,\n subject: message?.subject ?? '',\n date: message?.receivedDateTime ?? '',\n snippet: message?.bodyPreview ?? '',\n body,\n provider: 'outlook' as const,\n labels: categories,\n };\n }\n );\n\n const csvRows = exec.items.map((item) => {\n return [item.id, item.threadId, item.from, item.to, item.cc, item.bcc, item.subject, item.date, item.snippet, item.body, item.provider, item.labels];\n });\n\n // Append rows to CSV file immediately\n if (csvRows.length > 0) {\n const rowsContent = stringify(csvRows, { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(rowsContent);\n }\n\n totalRows += exec.items.length;\n nextPageToken = exec.metadata?.nextPageToken;\n\n logger.info('outlook.messages.export-csv batch written', {\n batchSize: exec.items.length,\n totalRows,\n hasMore: Boolean(nextPageToken),\n });\n\n // Exit if no more results or reached maxItems\n if (!nextPageToken || exec.items.length === 0) {\n break;\n }\n }\n\n // Close write stream\n await new Promise<void>((resolve, reject) => {\n writeStream.end(() => resolve());\n writeStream.on('error', reject);\n });\n\n const durationMs = Date.now() - started;\n const truncated = totalRows >= maxItems && Boolean(nextPageToken);\n\n logger.info('outlook.messages.export-csv completed', {\n rowCount: totalRows,\n truncated,\n durationMs,\n filename: storedName,\n });\n\n // Generate URI based on transport type (stdio: file://, HTTP: http://)\n const uri = getFileUri(storedName, transport, {\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n endpoint: '/files',\n });\n\n const result: Output = {\n type: 'success' as const,\n uri,\n filename: storedName,\n rowCount: totalRows,\n truncated,\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 // CRITICAL: Clean up partial CSV file on error\n try {\n await unlink(fullPath);\n logger.debug('Cleaned up partial CSV file after error', { path: fullPath });\n } catch (_cleanupError) {\n logger.debug('Could not clean up CSV file (may not exist)', { path: fullPath });\n }\n\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.messages.export-csv error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'messages-export-csv',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EmailContentTypeSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","schemas","AuthRequiredBranchSchema","getFileUri","reserveFile","Client","ErrorCode","McpError","stringify","createWriteStream","unlink","z","executeQuery","executeOutlookQuery","OutlookQuerySchema","DEFAULT_PAGE_SIZE","DEFAULT_MAX_ITEMS","MAX_EXPORT_ITEMS","ExportResultSchema","object","uri","string","describe","filename","rowCount","number","truncated","boolean","inputSchema","query","optional","maxItems","int","positive","max","default","trim","min","contentType","excludeThreadHistory","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","storageContext","transport","resourceStoreUri","baseUrl","info","accountId","authContext","reservation","storedName","fullPath","path","graph","initWithMiddleware","authProvider","auth","csvHeaders","writeStream","encoding","headerLine","header","quoted","quote","escape","write","totalRows","nextPageToken","started","Date","now","exec","remainingItems","pageSize","Math","undefined","pageToken","includeBody","limit","m","message","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","categories","body","content","isHtml","toLowerCase","id","String","threadId","conversationId","subject","date","receivedDateTime","snippet","bodyPreview","provider","labels","csvRows","items","item","length","rowsContent","metadata","batchSize","hasMore","Promise","resolve","reject","end","on","durationMs","endpoint","text","JSON","structuredContent","error","debug","_cleanupError","Error","InternalError","stack","createTool","name"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/mcp/tools/messages-export-csv.ts"],"sourcesContent":["/** Outlook message CSV export tool - streams results to file without loading all data into context */\n\nimport { EmailContentTypeSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } 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 { getFileUri, reserveFile, 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 { stringify } from 'csv-stringify/sync';\nimport { createWriteStream } from 'fs';\nimport { unlink } from 'fs/promises';\nimport { z } from 'zod';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQueryParameterSchema } from '../../schemas/outlook-query-schema.ts';\nimport type { StorageExtra } from '../../types.ts';\n\nconst DEFAULT_PAGE_SIZE = 50;\nconst DEFAULT_MAX_ITEMS = 10000;\nconst MAX_EXPORT_ITEMS = 50000;\n\nconst ExportResultSchema = z.object({\n uri: z.string().describe('File URI (file:// or http://)'),\n filename: z.string().describe('Stored filename'),\n rowCount: z.number().describe('Number of messages exported'),\n truncated: z.boolean().describe('Whether export was truncated at maxItems'),\n});\n\nconst inputSchema = z.object({\n query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),\n maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),\n filename: z.string().trim().min(1).default('outlook-messages.csv').describe('Output filename (default: outlook-messages.csv)'),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schema\nconst successBranchSchema = ExportResultSchema.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: 'Export Outlook messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',\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\n/**\n * Handler for outlook-messages-export-csv tool\n *\n * CRITICAL: Streaming implementation per user requirements\n * - Generate UUID upfront\n * - Write CSV header immediately\n * - Append rows as batches arrive\n * - Delete partial file on error\n * - NO RETRIES (fail fast on error)\n */\nasync function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n const { storageContext } = extra;\n const { transport, resourceStoreUri, baseUrl } = storageContext;\n\n logger.info('outlook.messages.export-csv called', {\n query,\n maxItems,\n filename,\n accountId: extra.authContext.accountId,\n });\n\n // Reserve file location for streaming write (creates directory, generates ID, formats filename)\n const reservation = await reserveFile(filename, {\n resourceStoreUri,\n });\n const { storedName, fullPath } = reservation;\n\n logger.info('outlook.messages.export-csv starting streaming export', { path: fullPath, maxItems });\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n\n // Create CSV headers (all email fields)\n const csvHeaders = ['id', 'threadId', 'from', 'to', 'cc', 'bcc', 'subject', 'date', 'snippet', 'body', 'provider', 'labels'];\n\n // Create write stream and write headers immediately\n const writeStream = createWriteStream(fullPath, { encoding: 'utf-8' });\n const headerLine = stringify([csvHeaders], { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(headerLine);\n\n // Internal pagination loop - append to CSV with each batch\n // NO RETRIES: If any error occurs, fail the whole operation and clean up\n let totalRows = 0;\n let nextPageToken: string | undefined;\n const started = Date.now();\n\n while (totalRows < maxItems) {\n const remainingItems = maxItems - totalRows;\n const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);\n\n const exec: {\n items: Array<{\n id: string;\n threadId?: string;\n from: string;\n to: string;\n cc: string;\n bcc: string;\n subject: string;\n date: string;\n snippet: string;\n body: string;\n provider: string;\n labels: string;\n }>;\n metadata?: { nextPageToken?: string };\n } = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(nextPageToken !== undefined && { pageToken: nextPageToken }),\n includeBody: true, // Always include body for CSV export\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const fromAddr = message?.from?.emailAddress?.address ?? (message?.from as { address?: string })?.address ?? '';\n const categories = Array.isArray(message?.categories) ? message.categories.join(';') : '';\n\n // Process body based on contentType and excludeThreadHistory options\n let body = message?.body?.content ?? '';\n const isHtml = message?.body?.contentType?.toLowerCase() === 'html';\n\n if (isHtml && excludeThreadHistory) {\n body = extractCurrentMessageFromHtml(body);\n }\n\n if (isHtml && contentType === 'text') {\n body = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(body) : extractCurrentMessageFromHtmlToText(message?.body?.content ?? '');\n }\n\n return {\n id: String(message?.id ?? ''),\n threadId: message?.conversationId ? String(message.conversationId) : '',\n from: fromAddr,\n to,\n cc,\n bcc,\n subject: message?.subject ?? '',\n date: message?.receivedDateTime ?? '',\n snippet: message?.bodyPreview ?? '',\n body,\n provider: 'outlook' as const,\n labels: categories,\n };\n }\n );\n\n const csvRows = exec.items.map((item) => {\n return [item.id, item.threadId, item.from, item.to, item.cc, item.bcc, item.subject, item.date, item.snippet, item.body, item.provider, item.labels];\n });\n\n // Append rows to CSV file immediately\n if (csvRows.length > 0) {\n const rowsContent = stringify(csvRows, { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(rowsContent);\n }\n\n totalRows += exec.items.length;\n nextPageToken = exec.metadata?.nextPageToken;\n\n logger.info('outlook.messages.export-csv batch written', {\n batchSize: exec.items.length,\n totalRows,\n hasMore: Boolean(nextPageToken),\n });\n\n // Exit if no more results or reached maxItems\n if (!nextPageToken || exec.items.length === 0) {\n break;\n }\n }\n\n // Close write stream\n await new Promise<void>((resolve, reject) => {\n writeStream.end(() => resolve());\n writeStream.on('error', reject);\n });\n\n const durationMs = Date.now() - started;\n const truncated = totalRows >= maxItems && Boolean(nextPageToken);\n\n logger.info('outlook.messages.export-csv completed', {\n rowCount: totalRows,\n truncated,\n durationMs,\n filename: storedName,\n });\n\n // Generate URI based on transport type (stdio: file://, HTTP: http://)\n const uri = getFileUri(storedName, transport, {\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n endpoint: '/files',\n });\n\n const result: Output = {\n type: 'success' as const,\n uri,\n filename: storedName,\n rowCount: totalRows,\n truncated,\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 // CRITICAL: Clean up partial CSV file on error\n try {\n await unlink(fullPath);\n logger.debug('Cleaned up partial CSV file after error', { path: fullPath });\n } catch (_cleanupError) {\n logger.debug('Could not clean up CSV file (may not exist)', { path: fullPath });\n }\n\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.messages.export-csv error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'messages-export-csv',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EmailContentTypeSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","schemas","AuthRequiredBranchSchema","getFileUri","reserveFile","Client","ErrorCode","McpError","stringify","createWriteStream","unlink","z","executeQuery","executeOutlookQuery","OutlookQueryParameterSchema","DEFAULT_PAGE_SIZE","DEFAULT_MAX_ITEMS","MAX_EXPORT_ITEMS","ExportResultSchema","object","uri","string","describe","filename","rowCount","number","truncated","boolean","inputSchema","query","optional","maxItems","int","positive","max","default","trim","min","contentType","excludeThreadHistory","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","storageContext","transport","resourceStoreUri","baseUrl","info","accountId","authContext","reservation","storedName","fullPath","path","graph","initWithMiddleware","authProvider","auth","csvHeaders","writeStream","encoding","headerLine","header","quoted","quote","escape","write","totalRows","nextPageToken","started","Date","now","exec","remainingItems","pageSize","Math","undefined","pageToken","includeBody","limit","m","message","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","categories","body","content","isHtml","toLowerCase","id","String","threadId","conversationId","subject","date","receivedDateTime","snippet","bodyPreview","provider","labels","csvRows","items","item","length","rowsContent","metadata","batchSize","hasMore","Promise","resolve","reject","end","on","durationMs","endpoint","text","JSON","structuredContent","error","debug","_cleanupError","Error","InternalError","stack","createTool","name"],"mappings":"AAAA,oGAAoG,GAEpG,SAASA,sBAAsB,EAAEC,0BAA0B,EAAEC,6BAA6B,EAAEC,mCAAmC,QAAQ,eAAe;AAEtJ,SAASC,OAAO,QAAQ,yBAAyB;AAEjD,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAErC,SAASE,UAAU,EAAEC,WAAW,QAAyB,gBAAgB;AACzE,SAASC,MAAM,QAAQ,oCAAoC;AAE3D,SAA8BC,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AAC9F,SAASC,SAAS,QAAQ,qBAAqB;AAC/C,SAASC,iBAAiB,QAAQ,KAAK;AACvC,SAASC,MAAM,QAAQ,cAAc;AACrC,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,gBAAgBC,mBAAmB,QAAQ,wCAAwC;AAC5F,SAASC,2BAA2B,QAAQ,wCAAwC;AAGpF,MAAMC,oBAAoB;AAC1B,MAAMC,oBAAoB;AAC1B,MAAMC,mBAAmB;AAEzB,MAAMC,qBAAqBP,EAAEQ,MAAM,CAAC;IAClCC,KAAKT,EAAEU,MAAM,GAAGC,QAAQ,CAAC;IACzBC,UAAUZ,EAAEU,MAAM,GAAGC,QAAQ,CAAC;IAC9BE,UAAUb,EAAEc,MAAM,GAAGH,QAAQ,CAAC;IAC9BI,WAAWf,EAAEgB,OAAO,GAAGL,QAAQ,CAAC;AAClC;AAEA,MAAMM,cAAcjB,EAAEQ,MAAM,CAAC;IAC3BU,OAAOf,4BAA4BgB,QAAQ,GAAGR,QAAQ,CAAC;IACvDS,UAAUpB,EAAEc,MAAM,GAAGO,GAAG,GAAGC,QAAQ,GAAGC,GAAG,CAACjB,kBAAkBkB,OAAO,CAACnB,mBAAmBM,QAAQ,CAAC,CAAC,qCAAqC,EAAEN,kBAAkB,OAAO,EAAEC,iBAAiB,CAAC,CAAC;IACtLM,UAAUZ,EAAEU,MAAM,GAAGe,IAAI,GAAGC,GAAG,CAAC,GAAGF,OAAO,CAAC,wBAAwBb,QAAQ,CAAC;IAC5EgB,aAAazC;IACb0C,sBAAsBzC;AACxB;AAEA,wBAAwB;AACxB,MAAM0C,sBAAsBtB,mBAAmBuB,MAAM,CAAC;IACpDC,MAAM/B,EAAEgC,OAAO,CAAC;AAClB;AAEA,2CAA2C;AAC3C,MAAMC,eAAejC,EAAEkC,kBAAkB,CAAC,QAAQ;IAACL;IAAqBtC;CAAyB;AAEjG,MAAM4C,SAAS;IACbC,aAAa;IACbnB,aAAaA;IACbgB,cAAcjC,EAAEQ,MAAM,CAAC;QACrB6B,QAAQJ;IACV;AACF;AAKA;;;;;;;;;CASC,GACD,eAAeK,QAAQ,EAAEpB,KAAK,EAAEE,QAAQ,EAAER,QAAQ,EAAEe,WAAW,EAAEC,oBAAoB,EAAS,EAAEW,KAAmC;IACjI,MAAMC,SAASD,MAAMC,MAAM;IAC3B,MAAM,EAAEC,cAAc,EAAE,GAAGF;IAC3B,MAAM,EAAEG,SAAS,EAAEC,gBAAgB,EAAEC,OAAO,EAAE,GAAGH;IAEjDD,OAAOK,IAAI,CAAC,sCAAsC;QAChD3B;QACAE;QACAR;QACAkC,WAAWP,MAAMQ,WAAW,CAACD,SAAS;IACxC;IAEA,gGAAgG;IAChG,MAAME,cAAc,MAAMvD,YAAYmB,UAAU;QAC9C+B;IACF;IACA,MAAM,EAAEM,UAAU,EAAEC,QAAQ,EAAE,GAAGF;IAEjCR,OAAOK,IAAI,CAAC,yDAAyD;QAAEM,MAAMD;QAAU9B;IAAS;IAEhG,IAAI;QACF,MAAMgC,QAAQ1D,OAAO2D,kBAAkB,CAAC;YAAEC,cAAcf,MAAMQ,WAAW,CAACQ,IAAI;QAAC;QAE/E,wCAAwC;QACxC,MAAMC,aAAa;YAAC;YAAM;YAAY;YAAQ;YAAM;YAAM;YAAO;YAAW;YAAQ;YAAW;YAAQ;YAAY;SAAS;QAE5H,oDAAoD;QACpD,MAAMC,cAAc3D,kBAAkBoD,UAAU;YAAEQ,UAAU;QAAQ;QACpE,MAAMC,aAAa9D,UAAU;YAAC2D;SAAW,EAAE;YAAEI,QAAQ;YAAOC,QAAQ;YAAMC,OAAO;YAAKC,QAAQ;QAAI;QAClGN,YAAYO,KAAK,CAACL;QAElB,2DAA2D;QAC3D,yEAAyE;QACzE,IAAIM,YAAY;QAChB,IAAIC;QACJ,MAAMC,UAAUC,KAAKC,GAAG;QAExB,MAAOJ,YAAY7C,SAAU;gBA6FXkD;YA5FhB,MAAMC,iBAAiBnD,WAAW6C;YAClC,MAAMO,WAAWC,KAAK/C,GAAG,CAAC6C,gBAAgBnE;YAE1C,MAAMkE,OAgBF,MAAMpE,oBACRkD,OACAlC,OACA;gBACEsB;gBACAgC;gBACA,GAAIN,kBAAkBQ,aAAa;oBAAEC,WAAWT;gBAAc,CAAC;gBAC/DU,aAAa;gBACbC,OAAOL;YACT,GACA,CAACM;oBAoBkBC;oBAAAA,4BAAAA,eAAyCA,gBAI/CA,eACIA,2BAAAA;gBAxBf,MAAMA,UAAUD;gBAChB,MAAME,KAAKC,MAAMC,OAAO,CAACH,oBAAAA,8BAAAA,QAASI,YAAY,IAC1CJ,QAAQI,YAAY,CACjBC,GAAG,CAAC,CAACC;;wBAAgCA;mCAAAA,cAAAA,yBAAAA,kBAAAA,EAAGC,YAAY,cAAfD,sCAAAA,gBAAiBE,OAAO,uCAAKF,cAAAA,wBAAD,AAACA,EAA4BE,OAAO;mBACrGC,MAAM,CAACC,SACPC,IAAI,CAAC,QACR;gBACJ,MAAMC,KAAKV,MAAMC,OAAO,CAACH,oBAAAA,8BAAAA,QAASa,YAAY,IAC1Cb,QAAQa,YAAY,CACjBR,GAAG,CAAC,CAACC;;wBAAgCA;mCAAAA,cAAAA,yBAAAA,kBAAAA,EAAGC,YAAY,cAAfD,sCAAAA,gBAAiBE,OAAO,uCAAKF,cAAAA,wBAAD,AAACA,EAA4BE,OAAO;mBACrGC,MAAM,CAACC,SACPC,IAAI,CAAC,QACR;gBACJ,MAAMG,MAAMZ,MAAMC,OAAO,CAACH,oBAAAA,8BAAAA,QAASe,aAAa,IAC5Cf,QAAQe,aAAa,CAClBV,GAAG,CAAC,CAACC;;wBAAgCA;mCAAAA,cAAAA,yBAAAA,kBAAAA,EAAGC,YAAY,cAAfD,sCAAAA,gBAAiBE,OAAO,uCAAKF,cAAAA,wBAAD,AAACA,EAA4BE,OAAO;mBACrGC,MAAM,CAACC,SACPC,IAAI,CAAC,QACR;gBACJ,MAAMK,YAAWhB,gBAAAA,oBAAAA,+BAAAA,gBAAAA,QAASiB,IAAI,cAAbjB,qCAAAA,6BAAAA,cAAeO,YAAY,cAA3BP,iDAAAA,2BAA6BQ,OAAO,yCAAKR,oBAAAA,+BAAAA,iBAAAA,QAASiB,IAAI,cAAbjB,qCAAD,AAACA,eAAwCQ,OAAO,cAAxFR,kBAAAA,OAA4F;gBAC7G,MAAMkB,aAAahB,MAAMC,OAAO,CAACH,oBAAAA,8BAAAA,QAASkB,UAAU,IAAIlB,QAAQkB,UAAU,CAACP,IAAI,CAAC,OAAO;gBAEvF,qEAAqE;gBACrE,IAAIQ,gBAAOnB,oBAAAA,+BAAAA,gBAAAA,QAASmB,IAAI,cAAbnB,oCAAAA,cAAeoB,OAAO,yCAAI;gBACrC,MAAMC,SAASrB,CAAAA,oBAAAA,+BAAAA,iBAAAA,QAASmB,IAAI,cAAbnB,sCAAAA,4BAAAA,eAAepD,WAAW,cAA1BoD,gDAAAA,0BAA4BsB,WAAW,QAAO;gBAE7D,IAAID,UAAUxE,sBAAsB;oBAClCsE,OAAO9G,8BAA8B8G;gBACvC;gBAEA,IAAIE,UAAUzE,gBAAgB,QAAQ;;wBAC0EoD;oBAA9GmB,OAAOtE,uBAAuBvC,oCAAoC6G,QAAQ7G,6CAAoC0F,oBAAAA,+BAAAA,iBAAAA,QAASmB,IAAI,cAAbnB,qCAAAA,eAAeoB,OAAO,yCAAI;gBAC1I;gBAEA,OAAO;oBACLG,IAAIC,gBAAOxB,oBAAAA,8BAAAA,QAASuB,EAAE,yCAAI;oBAC1BE,UAAUzB,CAAAA,oBAAAA,8BAAAA,QAAS0B,cAAc,IAAGF,OAAOxB,QAAQ0B,cAAc,IAAI;oBACrET,MAAMD;oBACNf;oBACAW;oBACAE;oBACAa,OAAO,WAAE3B,oBAAAA,8BAAAA,QAAS2B,OAAO,yCAAI;oBAC7BC,IAAI,WAAE5B,oBAAAA,8BAAAA,QAAS6B,gBAAgB,yCAAI;oBACnCC,OAAO,WAAE9B,oBAAAA,8BAAAA,QAAS+B,WAAW,yCAAI;oBACjCZ;oBACAa,UAAU;oBACVC,QAAQf;gBACV;YACF;YAGF,MAAMgB,UAAU3C,KAAK4C,KAAK,CAAC9B,GAAG,CAAC,CAAC+B;gBAC9B,OAAO;oBAACA,KAAKb,EAAE;oBAAEa,KAAKX,QAAQ;oBAAEW,KAAKnB,IAAI;oBAAEmB,KAAKnC,EAAE;oBAAEmC,KAAKxB,EAAE;oBAAEwB,KAAKtB,GAAG;oBAAEsB,KAAKT,OAAO;oBAAES,KAAKR,IAAI;oBAAEQ,KAAKN,OAAO;oBAAEM,KAAKjB,IAAI;oBAAEiB,KAAKJ,QAAQ;oBAAEI,KAAKH,MAAM;iBAAC;YACtJ;YAEA,sCAAsC;YACtC,IAAIC,QAAQG,MAAM,GAAG,GAAG;gBACtB,MAAMC,cAAcxH,UAAUoH,SAAS;oBAAErD,QAAQ;oBAAOC,QAAQ;oBAAMC,OAAO;oBAAKC,QAAQ;gBAAI;gBAC9FN,YAAYO,KAAK,CAACqD;YACpB;YAEApD,aAAaK,KAAK4C,KAAK,CAACE,MAAM;YAC9BlD,iBAAgBI,iBAAAA,KAAKgD,QAAQ,cAAbhD,qCAAAA,eAAeJ,aAAa;YAE5C1B,OAAOK,IAAI,CAAC,6CAA6C;gBACvD0E,WAAWjD,KAAK4C,KAAK,CAACE,MAAM;gBAC5BnD;gBACAuD,SAAS/B,QAAQvB;YACnB;YAEA,8CAA8C;YAC9C,IAAI,CAACA,iBAAiBI,KAAK4C,KAAK,CAACE,MAAM,KAAK,GAAG;gBAC7C;YACF;QACF;QAEA,qBAAqB;QACrB,MAAM,IAAIK,QAAc,CAACC,SAASC;YAChClE,YAAYmE,GAAG,CAAC,IAAMF;YACtBjE,YAAYoE,EAAE,CAAC,SAASF;QAC1B;QAEA,MAAMG,aAAa1D,KAAKC,GAAG,KAAKF;QAChC,MAAMpD,YAAYkD,aAAa7C,YAAYqE,QAAQvB;QAEnD1B,OAAOK,IAAI,CAAC,yCAAyC;YACnDhC,UAAUoD;YACVlD;YACA+G;YACAlH,UAAUqC;QACZ;QAEA,uEAAuE;QACvE,MAAMxC,MAAMjB,WAAWyD,YAAYP,WAAW;YAC5CC;YACA,GAAIC,WAAW;gBAAEA;YAAQ,CAAC;YAC1BmF,UAAU;QACZ;QAEA,MAAM1F,SAAiB;YACrBN,MAAM;YACNtB;YACAG,UAAUqC;YACVpC,UAAUoD;YACVlD;QACF;QAEA,OAAO;YACLoF,SAAS;gBACP;oBACEpE,MAAM;oBACNiG,MAAMC,KAAKpI,SAAS,CAACwC;gBACvB;aACD;YACD6F,mBAAmB;gBAAE7F;YAAO;QAC9B;IACF,EAAE,OAAO8F,OAAO;QACd,+CAA+C;QAC/C,IAAI;YACF,MAAMpI,OAAOmD;YACbV,OAAO4F,KAAK,CAAC,2CAA2C;gBAAEjF,MAAMD;YAAS;QAC3E,EAAE,OAAOmF,eAAe;YACtB7F,OAAO4F,KAAK,CAAC,+CAA+C;gBAAEjF,MAAMD;YAAS;QAC/E;QAEA,MAAM6B,UAAUoD,iBAAiBG,QAAQH,MAAMpD,OAAO,GAAGwB,OAAO4B;QAChE3F,OAAO2F,KAAK,CAAC,qCAAqC;YAAEA,OAAOpD;QAAQ;QAEnE,MAAM,IAAInF,SAASD,UAAU4I,aAAa,EAAE,CAAC,iCAAiC,EAAExD,SAAS,EAAE;YACzFyD,OAAOL,iBAAiBG,QAAQH,MAAMK,KAAK,GAAG9D;QAChD;IACF;AACF;AAEA,eAAe,SAAS+D;IACtB,OAAO;QACLC,MAAM;QACNvG;QACAG;IACF;AACF"}
@@ -37,6 +37,8 @@ export declare const OutlookSystemCategorySchema: z.ZodEnum<{
37
37
  * TypeScript sees the strict OutlookQuery type everywhere the schema is used.
38
38
  */
39
39
  export declare const OutlookQuerySchema: z.ZodType<OutlookQuery>;
40
+ export declare const OutlookQueryParameterSchema: z.ZodType<OutlookQuery>;
41
+ export type OutlookQueryParameter = z.infer<typeof OutlookQueryParameterSchema>;
40
42
  export type OutlookQuery = BaseEmailQueryFields & {
41
43
  $and?: OutlookQuery[];
42
44
  $or?: OutlookQuery[];
@@ -61,3 +61,27 @@ import { z } from 'zod';
61
61
  // Raw KQL query string - escape hatch for advanced syntax
62
62
  kqlQuery: z.string().min(1).optional().describe('Raw KQL (Keyword Query Language) syntax for advanced use cases. Bypasses schema validation - use sparingly.')
63
63
  }).strict());
64
+ export const OutlookQueryParameterSchema = z.any().transform((value, ctx)=>{
65
+ let parsed = value;
66
+ if (typeof value === 'string') {
67
+ try {
68
+ parsed = JSON.parse(value);
69
+ } catch (error) {
70
+ const message = error instanceof Error ? error.message : 'Invalid JSON';
71
+ ctx.addIssue({
72
+ code: z.ZodIssueCode.custom,
73
+ message: `Query must be valid JSON. ${message}. Wrap KQL syntax in {"kqlQuery":"<query>"} if needed.`
74
+ });
75
+ return z.NEVER;
76
+ }
77
+ }
78
+ const validated = OutlookQuerySchema.safeParse(parsed);
79
+ if (!validated.success) {
80
+ ctx.addIssue({
81
+ code: z.ZodIssueCode.custom,
82
+ message: `Invalid query JSON: ${validated.error.message}. Use {"kqlQuery":"<query>"} for KQL syntax.`
83
+ });
84
+ return z.NEVER;
85
+ }
86
+ return validated.data;
87
+ });
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/schemas/outlook-query-schema.ts"],"sourcesContent":["import { type BaseEmailQueryFields, baseEmailQueryFields, type FieldOperator, FieldOperatorSchema } from '@mcp-z/email';\nimport { z } from 'zod';\n\n/**\n * Outlook system category values.\n * These are the built-in category types that Outlook recognizes.\n * Note: This is distinct from OutlookCategory (user-created category objects with id/displayName/color).\n */\nexport type OutlookSystemCategory = 'work' | 'personal' | 'family' | 'travel' | 'important' | 'urgent';\n\n/** Zod schema for validating OutlookSystemCategory values */\nexport const OutlookSystemCategorySchema = z.enum(['work', 'personal', 'family', 'travel', 'important', 'urgent']);\n\n/**\n * Outlook-specific query schema with recursive operators and Outlook features.\n *\n * Includes Microsoft Graph/Outlook-specific features:\n * - exactPhrase: Strict exact phrase matching via KQL $search parameter\n * - categories: Outlook system categories (work, personal, family, travel, important, urgent)\n * - label: User-created Outlook categories (case-sensitive, discovered via outlook-categories-list)\n * - importance: Message importance level (high, normal, low)\n * - kqlQuery: Escape hatch for advanced KQL (Keyword Query Language) syntax\n *\n * Plus all base fields from baseEmailQueryFields:\n * - Email addresses: from, to, cc, bcc (support string or field operators)\n * - Content: subject, body, text\n * - Flags: hasAttachment, isRead\n * - Date range: date { $gte, $lt }\n * - Logical operators: $and, $or, $not (recursive)\n *\n * Note: Cast through unknown to work around Zod's lazy schema type inference issue\n * with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures\n * TypeScript sees the strict OutlookQuery type everywhere the schema is used.\n */\nexport const OutlookQuerySchema = z.lazy(() =>\n z\n .object({\n // Logical operators for combining conditions (recursive)\n $and: z.array(OutlookQuerySchema).optional().describe('Array of conditions that must ALL match'),\n $or: z.array(OutlookQuerySchema).optional().describe('Array of conditions where ANY must match'),\n $not: OutlookQuerySchema.optional().describe('Nested condition that must NOT match'),\n\n // Spread base email query fields (from, to, subject, body, etc.)\n ...baseEmailQueryFields,\n\n // Outlook-specific features\n\n // Exact phrase matching - KQL strict search with double quotes\n exactPhrase: z.string().min(1).optional().describe('Exact phrase matching - words must appear together in exact order (strict matching). Outlook uses KQL.'),\n\n // Outlook system categories with field operator support\n categories: z\n .union([\n OutlookSystemCategorySchema,\n z\n .object({\n $any: z.array(OutlookSystemCategorySchema).optional(),\n $all: z.array(OutlookSystemCategorySchema).optional(),\n $none: z.array(OutlookSystemCategorySchema).optional(),\n })\n .strict(),\n ])\n .optional()\n .describe('Filter by Outlook system categories (work, personal, family, travel, important, urgent)'),\n\n // User-created categories\n label: z\n .union([z.string().min(1), FieldOperatorSchema])\n .optional()\n .describe('Filter by user-created categories (case-sensitive). Use outlook-categories-list to see available categories'),\n\n // Message importance level - Outlook-specific property\n importance: z.enum(['high', 'normal', 'low']).optional().describe('Filter by message importance level (high, normal, low)'),\n\n // Raw KQL query string - escape hatch for advanced syntax\n kqlQuery: z.string().min(1).optional().describe('Raw KQL (Keyword Query Language) syntax for advanced use cases. Bypasses schema validation - use sparingly.'),\n })\n .strict()\n) as unknown as z.ZodType<OutlookQuery>;\n\nexport type OutlookQuery = BaseEmailQueryFields & {\n $and?: OutlookQuery[];\n $or?: OutlookQuery[];\n $not?: OutlookQuery;\n exactPhrase?: string;\n categories?:\n | OutlookSystemCategory\n | {\n $any?: OutlookSystemCategory[];\n $all?: OutlookSystemCategory[];\n $none?: OutlookSystemCategory[];\n };\n label?: string | FieldOperator;\n importance?: 'high' | 'normal' | 'low';\n kqlQuery?: string;\n};\n"],"names":["baseEmailQueryFields","FieldOperatorSchema","z","OutlookSystemCategorySchema","enum","OutlookQuerySchema","lazy","object","$and","array","optional","describe","$or","$not","exactPhrase","string","min","categories","union","$any","$all","$none","strict","label","importance","kqlQuery"],"mappings":"AAAA,SAAoCA,oBAAoB,EAAsBC,mBAAmB,QAAQ,eAAe;AACxH,SAASC,CAAC,QAAQ,MAAM;AASxB,2DAA2D,GAC3D,OAAO,MAAMC,8BAA8BD,EAAEE,IAAI,CAAC;IAAC;IAAQ;IAAY;IAAU;IAAU;IAAa;CAAS,EAAE;AAEnH;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,OAAO,MAAMC,qBAAqBH,EAAEI,IAAI,CAAC,IACvCJ,EACGK,MAAM,CAAC;QACN,yDAAyD;QACzDC,MAAMN,EAAEO,KAAK,CAACJ,oBAAoBK,QAAQ,GAAGC,QAAQ,CAAC;QACtDC,KAAKV,EAAEO,KAAK,CAACJ,oBAAoBK,QAAQ,GAAGC,QAAQ,CAAC;QACrDE,MAAMR,mBAAmBK,QAAQ,GAAGC,QAAQ,CAAC;QAE7C,iEAAiE;QACjE,GAAGX,oBAAoB;QAEvB,4BAA4B;QAE5B,+DAA+D;QAC/Dc,aAAaZ,EAAEa,MAAM,GAAGC,GAAG,CAAC,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;QAEnD,wDAAwD;QACxDM,YAAYf,EACTgB,KAAK,CAAC;YACLf;YACAD,EACGK,MAAM,CAAC;gBACNY,MAAMjB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDU,MAAMlB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDW,OAAOnB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;YACtD,GACCY,MAAM;SACV,EACAZ,QAAQ,GACRC,QAAQ,CAAC;QAEZ,0BAA0B;QAC1BY,OAAOrB,EACJgB,KAAK,CAAC;YAAChB,EAAEa,MAAM,GAAGC,GAAG,CAAC;YAAIf;SAAoB,EAC9CS,QAAQ,GACRC,QAAQ,CAAC;QAEZ,uDAAuD;QACvDa,YAAYtB,EAAEE,IAAI,CAAC;YAAC;YAAQ;YAAU;SAAM,EAAEM,QAAQ,GAAGC,QAAQ,CAAC;QAElE,0DAA0D;QAC1Dc,UAAUvB,EAAEa,MAAM,GAAGC,GAAG,CAAC,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;IAClD,GACCW,MAAM,IAC6B"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/schemas/outlook-query-schema.ts"],"sourcesContent":["import { type BaseEmailQueryFields, baseEmailQueryFields, type FieldOperator, FieldOperatorSchema } from '@mcp-z/email';\nimport { z } from 'zod';\n\n/**\n * Outlook system category values.\n * These are the built-in category types that Outlook recognizes.\n * Note: This is distinct from OutlookCategory (user-created category objects with id/displayName/color).\n */\nexport type OutlookSystemCategory = 'work' | 'personal' | 'family' | 'travel' | 'important' | 'urgent';\n\n/** Zod schema for validating OutlookSystemCategory values */\nexport const OutlookSystemCategorySchema = z.enum(['work', 'personal', 'family', 'travel', 'important', 'urgent']);\n\n/**\n * Outlook-specific query schema with recursive operators and Outlook features.\n *\n * Includes Microsoft Graph/Outlook-specific features:\n * - exactPhrase: Strict exact phrase matching via KQL $search parameter\n * - categories: Outlook system categories (work, personal, family, travel, important, urgent)\n * - label: User-created Outlook categories (case-sensitive, discovered via outlook-categories-list)\n * - importance: Message importance level (high, normal, low)\n * - kqlQuery: Escape hatch for advanced KQL (Keyword Query Language) syntax\n *\n * Plus all base fields from baseEmailQueryFields:\n * - Email addresses: from, to, cc, bcc (support string or field operators)\n * - Content: subject, body, text\n * - Flags: hasAttachment, isRead\n * - Date range: date { $gte, $lt }\n * - Logical operators: $and, $or, $not (recursive)\n *\n * Note: Cast through unknown to work around Zod's lazy schema type inference issue\n * with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures\n * TypeScript sees the strict OutlookQuery type everywhere the schema is used.\n */\nexport const OutlookQuerySchema = z.lazy(() =>\n z\n .object({\n // Logical operators for combining conditions (recursive)\n $and: z.array(OutlookQuerySchema).optional().describe('Array of conditions that must ALL match'),\n $or: z.array(OutlookQuerySchema).optional().describe('Array of conditions where ANY must match'),\n $not: OutlookQuerySchema.optional().describe('Nested condition that must NOT match'),\n\n // Spread base email query fields (from, to, subject, body, etc.)\n ...baseEmailQueryFields,\n\n // Outlook-specific features\n\n // Exact phrase matching - KQL strict search with double quotes\n exactPhrase: z.string().min(1).optional().describe('Exact phrase matching - words must appear together in exact order (strict matching). Outlook uses KQL.'),\n\n // Outlook system categories with field operator support\n categories: z\n .union([\n OutlookSystemCategorySchema,\n z\n .object({\n $any: z.array(OutlookSystemCategorySchema).optional(),\n $all: z.array(OutlookSystemCategorySchema).optional(),\n $none: z.array(OutlookSystemCategorySchema).optional(),\n })\n .strict(),\n ])\n .optional()\n .describe('Filter by Outlook system categories (work, personal, family, travel, important, urgent)'),\n\n // User-created categories\n label: z\n .union([z.string().min(1), FieldOperatorSchema])\n .optional()\n .describe('Filter by user-created categories (case-sensitive). Use outlook-categories-list to see available categories'),\n\n // Message importance level - Outlook-specific property\n importance: z.enum(['high', 'normal', 'low']).optional().describe('Filter by message importance level (high, normal, low)'),\n\n // Raw KQL query string - escape hatch for advanced syntax\n kqlQuery: z.string().min(1).optional().describe('Raw KQL (Keyword Query Language) syntax for advanced use cases. Bypasses schema validation - use sparingly.'),\n })\n .strict()\n) as unknown as z.ZodType<OutlookQuery>;\n\nexport const OutlookQueryParameterSchema = z.any().transform((value, ctx) => {\n let parsed = value;\n if (typeof value === 'string') {\n try {\n parsed = JSON.parse(value);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid JSON';\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Query must be valid JSON. ${message}. Wrap KQL syntax in {\"kqlQuery\":\"<query>\"} if needed.`,\n });\n return z.NEVER;\n }\n }\n\n const validated = OutlookQuerySchema.safeParse(parsed);\n if (!validated.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid query JSON: ${validated.error.message}. Use {\"kqlQuery\":\"<query>\"} for KQL syntax.`,\n });\n return z.NEVER;\n }\n\n return validated.data;\n}) as z.ZodType<OutlookQuery>;\nexport type OutlookQueryParameter = z.infer<typeof OutlookQueryParameterSchema>;\n\nexport type OutlookQuery = BaseEmailQueryFields & {\n $and?: OutlookQuery[];\n $or?: OutlookQuery[];\n $not?: OutlookQuery;\n exactPhrase?: string;\n categories?:\n | OutlookSystemCategory\n | {\n $any?: OutlookSystemCategory[];\n $all?: OutlookSystemCategory[];\n $none?: OutlookSystemCategory[];\n };\n label?: string | FieldOperator;\n importance?: 'high' | 'normal' | 'low';\n kqlQuery?: string;\n};\n"],"names":["baseEmailQueryFields","FieldOperatorSchema","z","OutlookSystemCategorySchema","enum","OutlookQuerySchema","lazy","object","$and","array","optional","describe","$or","$not","exactPhrase","string","min","categories","union","$any","$all","$none","strict","label","importance","kqlQuery","OutlookQueryParameterSchema","any","transform","value","ctx","parsed","JSON","parse","error","message","Error","addIssue","code","ZodIssueCode","custom","NEVER","validated","safeParse","success","data"],"mappings":"AAAA,SAAoCA,oBAAoB,EAAsBC,mBAAmB,QAAQ,eAAe;AACxH,SAASC,CAAC,QAAQ,MAAM;AASxB,2DAA2D,GAC3D,OAAO,MAAMC,8BAA8BD,EAAEE,IAAI,CAAC;IAAC;IAAQ;IAAY;IAAU;IAAU;IAAa;CAAS,EAAE;AAEnH;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,OAAO,MAAMC,qBAAqBH,EAAEI,IAAI,CAAC,IACvCJ,EACGK,MAAM,CAAC;QACN,yDAAyD;QACzDC,MAAMN,EAAEO,KAAK,CAACJ,oBAAoBK,QAAQ,GAAGC,QAAQ,CAAC;QACtDC,KAAKV,EAAEO,KAAK,CAACJ,oBAAoBK,QAAQ,GAAGC,QAAQ,CAAC;QACrDE,MAAMR,mBAAmBK,QAAQ,GAAGC,QAAQ,CAAC;QAE7C,iEAAiE;QACjE,GAAGX,oBAAoB;QAEvB,4BAA4B;QAE5B,+DAA+D;QAC/Dc,aAAaZ,EAAEa,MAAM,GAAGC,GAAG,CAAC,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;QAEnD,wDAAwD;QACxDM,YAAYf,EACTgB,KAAK,CAAC;YACLf;YACAD,EACGK,MAAM,CAAC;gBACNY,MAAMjB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDU,MAAMlB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDW,OAAOnB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;YACtD,GACCY,MAAM;SACV,EACAZ,QAAQ,GACRC,QAAQ,CAAC;QAEZ,0BAA0B;QAC1BY,OAAOrB,EACJgB,KAAK,CAAC;YAAChB,EAAEa,MAAM,GAAGC,GAAG,CAAC;YAAIf;SAAoB,EAC9CS,QAAQ,GACRC,QAAQ,CAAC;QAEZ,uDAAuD;QACvDa,YAAYtB,EAAEE,IAAI,CAAC;YAAC;YAAQ;YAAU;SAAM,EAAEM,QAAQ,GAAGC,QAAQ,CAAC;QAElE,0DAA0D;QAC1Dc,UAAUvB,EAAEa,MAAM,GAAGC,GAAG,CAAC,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;IAClD,GACCW,MAAM,IAC6B;AAExC,OAAO,MAAMI,8BAA8BxB,EAAEyB,GAAG,GAAGC,SAAS,CAAC,CAACC,OAAOC;IACnE,IAAIC,SAASF;IACb,IAAI,OAAOA,UAAU,UAAU;QAC7B,IAAI;YACFE,SAASC,KAAKC,KAAK,CAACJ;QACtB,EAAE,OAAOK,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAG;YACzDL,IAAIO,QAAQ,CAAC;gBACXC,MAAMpC,EAAEqC,YAAY,CAACC,MAAM;gBAC3BL,SAAS,CAAC,0BAA0B,EAAEA,QAAQ,sDAAsD,CAAC;YACvG;YACA,OAAOjC,EAAEuC,KAAK;QAChB;IACF;IAEA,MAAMC,YAAYrC,mBAAmBsC,SAAS,CAACZ;IAC/C,IAAI,CAACW,UAAUE,OAAO,EAAE;QACtBd,IAAIO,QAAQ,CAAC;YACXC,MAAMpC,EAAEqC,YAAY,CAACC,MAAM;YAC3BL,SAAS,CAAC,oBAAoB,EAAEO,UAAUR,KAAK,CAACC,OAAO,CAAC,4CAA4C,CAAC;QACvG;QACA,OAAOjC,EAAEuC,KAAK;IAChB;IAEA,OAAOC,UAAUG,IAAI;AACvB,GAA8B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-z/mcp-outlook",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "MCP server for Outlook integration with OAuth authentication, message search, and batch operations",
5
5
  "keywords": [
6
6
  "outlook",