@mcp-z/mcp-outlook 1.0.2 → 1.0.4
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.
- package/README.md +32 -3
- package/bin/server.js +1 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/email/composition/outlook-message-builder.js.map +1 -1
- package/dist/cjs/email/messages/messages.js +5 -5
- package/dist/cjs/email/messages/messages.js.map +1 -1
- package/dist/cjs/email/parsing/header-parsing.js.map +1 -1
- package/dist/cjs/email/parsing/message-extraction.js +2 -2
- package/dist/cjs/email/parsing/message-extraction.js.map +1 -1
- package/dist/cjs/email/parsing/message-mapping.js +4 -4
- package/dist/cjs/email/parsing/message-mapping.js.map +1 -1
- package/dist/cjs/email/querying/execute-query.js +2 -2
- package/dist/cjs/email/querying/execute-query.js.map +1 -1
- package/dist/cjs/email/querying/query-builder.js.map +1 -1
- package/dist/cjs/email/querying/search-execution.js +2 -2
- package/dist/cjs/email/querying/search-execution.js.map +1 -1
- package/dist/cjs/index.d.cts +5 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +21 -13
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/create-store.js.map +1 -1
- package/dist/cjs/lib/messages-to-row.js.map +1 -1
- package/dist/cjs/lib/outlook/index.js +19 -19
- package/dist/cjs/lib/outlook/index.js.map +1 -1
- package/dist/cjs/lib/outlook/types.js.map +1 -1
- package/dist/cjs/mcp/index.js +6 -6
- package/dist/cjs/mcp/index.js.map +1 -1
- package/dist/cjs/mcp/prompts/draft-email.js.map +1 -1
- package/dist/cjs/mcp/prompts/index.js +4 -4
- package/dist/cjs/mcp/prompts/index.js.map +1 -1
- package/dist/cjs/mcp/prompts/query-syntax.js.map +1 -1
- package/dist/cjs/mcp/resources/email.js.map +1 -1
- package/dist/cjs/mcp/resources/index.js +2 -2
- package/dist/cjs/mcp/resources/index.js.map +1 -1
- package/dist/cjs/mcp/tools/categories-list.d.cts +11 -1
- package/dist/cjs/mcp/tools/categories-list.d.ts +11 -1
- package/dist/cjs/mcp/tools/categories-list.js +13 -5
- package/dist/cjs/mcp/tools/categories-list.js.map +1 -1
- package/dist/cjs/mcp/tools/index.js +22 -22
- package/dist/cjs/mcp/tools/index.js.map +1 -1
- package/dist/cjs/mcp/tools/label-add.js.map +1 -1
- package/dist/cjs/mcp/tools/label-delete.js.map +1 -1
- package/dist/cjs/mcp/tools/labels-list.d.cts +11 -1
- package/dist/cjs/mcp/tools/labels-list.d.ts +11 -1
- package/dist/cjs/mcp/tools/labels-list.js +13 -5
- package/dist/cjs/mcp/tools/labels-list.js.map +1 -1
- package/dist/cjs/mcp/tools/message-get.js.map +1 -1
- package/dist/cjs/mcp/tools/message-mark-read.js.map +1 -1
- package/dist/cjs/mcp/tools/message-move-to-trash.js.map +1 -1
- package/dist/cjs/mcp/tools/message-respond.js.map +1 -1
- package/dist/cjs/mcp/tools/message-search.js +4 -4
- package/dist/cjs/mcp/tools/message-search.js.map +1 -1
- package/dist/cjs/mcp/tools/message-send.js +2 -2
- package/dist/cjs/mcp/tools/message-send.js.map +1 -1
- package/dist/cjs/mcp/tools/messages-export-csv.js +4 -4
- package/dist/cjs/mcp/tools/messages-export-csv.js.map +1 -1
- package/dist/cjs/schemas/index.js.map +1 -1
- package/dist/cjs/schemas/outlook-query-schema.js.map +1 -1
- package/dist/cjs/schemas/outlook-validation.js.map +1 -1
- package/dist/cjs/setup/config.js +11 -1
- package/dist/cjs/setup/config.js.map +1 -1
- package/dist/cjs/setup/http.js +6 -2
- package/dist/cjs/setup/http.js.map +1 -1
- package/dist/cjs/setup/index.js +9 -9
- package/dist/cjs/setup/index.js.map +1 -1
- package/dist/cjs/setup/oauth-microsoft.d.cts +11 -2
- package/dist/cjs/setup/oauth-microsoft.d.ts +11 -2
- package/dist/cjs/setup/oauth-microsoft.js +11 -12
- package/dist/cjs/setup/oauth-microsoft.js.map +1 -1
- package/dist/cjs/setup/runtime.js +9 -9
- package/dist/cjs/setup/runtime.js.map +1 -1
- package/dist/cjs/setup/stdio.js +2 -2
- package/dist/cjs/setup/stdio.js.map +1 -1
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/email/composition/outlook-message-builder.js.map +1 -1
- package/dist/esm/email/messages/messages.js.map +1 -1
- package/dist/esm/email/parsing/header-parsing.js.map +1 -1
- package/dist/esm/email/parsing/message-extraction.js.map +1 -1
- package/dist/esm/email/parsing/message-mapping.js.map +1 -1
- package/dist/esm/email/querying/execute-query.js.map +1 -1
- package/dist/esm/email/querying/query-builder.js.map +1 -1
- package/dist/esm/email/querying/search-execution.js.map +1 -1
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/create-store.js.map +1 -1
- package/dist/esm/lib/messages-to-row.js.map +1 -1
- package/dist/esm/lib/outlook/index.js.map +1 -1
- package/dist/esm/lib/outlook/types.js.map +1 -1
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/mcp/prompts/draft-email.js.map +1 -1
- package/dist/esm/mcp/prompts/index.js.map +1 -1
- package/dist/esm/mcp/prompts/query-syntax.js.map +1 -1
- package/dist/esm/mcp/resources/email.js.map +1 -1
- package/dist/esm/mcp/resources/index.js.map +1 -1
- package/dist/esm/mcp/tools/categories-list.d.ts +11 -1
- package/dist/esm/mcp/tools/categories-list.js +5 -1
- package/dist/esm/mcp/tools/categories-list.js.map +1 -1
- package/dist/esm/mcp/tools/index.js.map +1 -1
- package/dist/esm/mcp/tools/label-add.js.map +1 -1
- package/dist/esm/mcp/tools/label-delete.js.map +1 -1
- package/dist/esm/mcp/tools/labels-list.d.ts +11 -1
- package/dist/esm/mcp/tools/labels-list.js +6 -2
- package/dist/esm/mcp/tools/labels-list.js.map +1 -1
- package/dist/esm/mcp/tools/message-get.js.map +1 -1
- package/dist/esm/mcp/tools/message-mark-read.js.map +1 -1
- package/dist/esm/mcp/tools/message-move-to-trash.js.map +1 -1
- package/dist/esm/mcp/tools/message-respond.js.map +1 -1
- package/dist/esm/mcp/tools/message-search.js.map +1 -1
- package/dist/esm/mcp/tools/message-send.js.map +1 -1
- package/dist/esm/mcp/tools/messages-export-csv.js.map +1 -1
- package/dist/esm/schemas/index.js.map +1 -1
- package/dist/esm/schemas/outlook-query-schema.js.map +1 -1
- package/dist/esm/schemas/outlook-validation.js.map +1 -1
- package/dist/esm/setup/config.js +12 -2
- package/dist/esm/setup/config.js.map +1 -1
- package/dist/esm/setup/http.js +4 -0
- package/dist/esm/setup/http.js.map +1 -1
- package/dist/esm/setup/index.js.map +1 -1
- package/dist/esm/setup/oauth-microsoft.d.ts +11 -2
- package/dist/esm/setup/oauth-microsoft.js +9 -11
- package/dist/esm/setup/oauth-microsoft.js.map +1 -1
- package/dist/esm/setup/runtime.js.map +1 -1
- package/dist/esm/setup/stdio.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -50,6 +50,11 @@ MCP supports stdio and HTTP.
|
|
|
50
50
|
3. Click New registration.
|
|
51
51
|
4. Choose a name and select a supported account type.
|
|
52
52
|
5. Copy the Application (client) ID and Directory (tenant) ID.
|
|
53
|
+
6. Select your MCP transport (stdio for local and http for remote) and platform
|
|
54
|
+
- For stdio, choose "Authentication", + Add Redirect URI, "Mobile and desktop applications" platform
|
|
55
|
+
- For http, choose "Authentication", + Add Redirect URI, "Web" platform, add your URL (default is http://localhost:3000/oauth/callback based on the --port or PORT)
|
|
56
|
+
- For local hosting, add "http://localhost" for [Ephemeral redirect URL](https://en.wikipedia.org/wiki/Ephemeral_port)
|
|
57
|
+
7. Enable OAuth2 scopes in API Permissions: openid profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite
|
|
53
58
|
|
|
54
59
|
## OAuth modes
|
|
55
60
|
|
|
@@ -65,7 +70,7 @@ MS_TENANT_ID=common
|
|
|
65
70
|
MS_CLIENT_SECRET=your-client-secret
|
|
66
71
|
```
|
|
67
72
|
|
|
68
|
-
Example:
|
|
73
|
+
Example (stdio) - Create .mcp.json:
|
|
69
74
|
```json
|
|
70
75
|
{
|
|
71
76
|
"mcpServers": {
|
|
@@ -74,14 +79,38 @@ Example:
|
|
|
74
79
|
"args": ["-y", "@mcp-z/mcp-outlook"],
|
|
75
80
|
"env": {
|
|
76
81
|
"MS_CLIENT_ID": "your-client-id",
|
|
77
|
-
"MS_TENANT_ID": "common"
|
|
78
|
-
|
|
82
|
+
"MS_TENANT_ID": "common"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Example (http) - Create .mcp.json:
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"mcpServers": {
|
|
93
|
+
"outlook": {
|
|
94
|
+
"type": "http",
|
|
95
|
+
"url": "http://localhost:3000",
|
|
96
|
+
"start": {
|
|
97
|
+
"command": "npx",
|
|
98
|
+
"args": ["-y", "@mcp-z/mcp-outlook", "--port=3000"],
|
|
99
|
+
"env": {
|
|
100
|
+
"MS_CLIENT_ID": "your-client-id",
|
|
101
|
+
"MS_TENANT_ID": "common"
|
|
102
|
+
}
|
|
79
103
|
}
|
|
80
104
|
}
|
|
81
105
|
}
|
|
82
106
|
}
|
|
83
107
|
```
|
|
84
108
|
|
|
109
|
+
Local (default): omit REDIRECT_URI → ephemeral loopback.
|
|
110
|
+
Cloud: set REDIRECT_URI to your public /oauth/callback and expose the service publicly.
|
|
111
|
+
|
|
112
|
+
Note: start block is a helper in "npx @mcp-z/cli up" for starting an http server from your .mpc.json. See [@mcp-z/cli](https://github.com/mcp-z/cli) for details.
|
|
113
|
+
|
|
85
114
|
### Device code
|
|
86
115
|
|
|
87
116
|
Useful for headless or remote environments.
|
package/bin/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// biome-ignore lint/security/noGlobalEval: dual esm and cjs
|
|
4
|
-
if (typeof require === 'undefined') eval("import('../dist/esm/index.js').then((cli) => cli.default(process.argv.slice(2), 'mcp-outlook')).catch((err) => { console.
|
|
4
|
+
if (typeof require === 'undefined') eval("import('../dist/esm/index.js').then((cli) => cli.default(process.argv.slice(2), 'mcp-outlook')).catch((err) => { console.error(err); process.exit(-1); });");
|
|
5
5
|
else require('../dist/cjs/index.js')(process.argv.slice(2), 'mcp-outlook');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/constants.ts"],"sourcesContent":["/**\n * Outlook MCP Server Constants\n *\n * These scopes are required for Microsoft Outlook functionality and are hardcoded\n * rather than externally configured since this server knows its own requirements.\n */\n\nimport { EMAIL_CHUNK_SIZE, EMAIL_MAX_BATCH_SIZE } from '@mcp-z/email';\n\n// Microsoft OAuth scopes required for Outlook operations\nexport const MS_SCOPE = 'openid profile offline_access https://graph.microsoft.com/User.Read https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/MailboxSettings.ReadWrite';\n\n// Batch processing configuration (from shared email constants)\nexport const CHUNK_SIZE = EMAIL_CHUNK_SIZE;\nexport const MAX_BATCH_SIZE = EMAIL_MAX_BATCH_SIZE;\n\n// Pagination configuration\nexport const MAX_PAGE_SIZE = 1000; // Maximum number of items per page\n"],"names":["CHUNK_SIZE","MAX_BATCH_SIZE","MAX_PAGE_SIZE","MS_SCOPE","EMAIL_CHUNK_SIZE","EMAIL_MAX_BATCH_SIZE"],"mappings":"AAAA;;;;;CAKC;;;;;;;;;;;QAQYA;eAAAA;;QACAC;eAAAA;;QAGAC;eAAAA;;QAPAC;eAAAA;;;qBAH0C;AAGhD,IAAMA,WAAW;AAGjB,IAAMH,aAAaI,uBAAgB;AACnC,IAAMH,iBAAiBI,2BAAoB;AAG3C,IAAMH,gBAAgB,MAAM,mCAAmC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/composition/outlook-message-builder.ts"],"sourcesContent":["/**\n * Outlook-specific message builder for composing emails using Microsoft Graph API format\n * This is the Outlook equivalent of Gmail's RFC822 builder\n */\n\nexport interface OutlookRecipient {\n emailAddress: {\n address: string;\n name?: string;\n };\n}\n\nexport interface OutlookMessageArgs {\n to?: string | string[] | undefined;\n cc?: string | string[] | undefined;\n bcc?: string | string[] | undefined;\n subject?: string;\n body?: string;\n from?: string;\n importance?: 'Low' | 'Normal' | 'High';\n contentType?: 'Text' | 'HTML';\n}\n\nexport interface OutlookMessage {\n subject?: string;\n body?: {\n contentType: string;\n content: string;\n };\n toRecipients?: OutlookRecipient[];\n ccRecipients?: OutlookRecipient[];\n bccRecipients?: OutlookRecipient[];\n importance?: string;\n}\n\n/**\n * Build an Outlook message object from email arguments for Microsoft Graph API\n * This is the Outlook equivalent of buildRfc822FromArgs for Gmail\n */\nexport function buildOutlookMessage(args: OutlookMessageArgs): OutlookMessage {\n const { to = [], cc = [], bcc = [], subject = '', body = '', importance = 'Normal', contentType = 'Text' } = args;\n\n const message: OutlookMessage = {};\n\n if (subject) {\n message.subject = subject;\n }\n\n if (body) {\n message.body = {\n contentType: contentType,\n content: body,\n };\n }\n\n function parseEmailAddresses(emails: string | string[]): OutlookRecipient[] {\n const emailArray = Array.isArray(emails) ? emails : [emails];\n return emailArray\n .filter((email) => email && email.trim())\n .map((email) => {\n const trimmed = email.trim();\n // Simple email parsing - could be enhanced for name parsing\n return {\n emailAddress: {\n address: trimmed,\n },\n };\n });\n }\n\n if (to && (Array.isArray(to) ? to.length > 0 : to.trim())) {\n message.toRecipients = parseEmailAddresses(to);\n }\n\n if (cc && (Array.isArray(cc) ? cc.length > 0 : cc.trim())) {\n message.ccRecipients = parseEmailAddresses(cc);\n }\n\n if (bcc && (Array.isArray(bcc) ? bcc.length > 0 : bcc.trim())) {\n message.bccRecipients = parseEmailAddresses(bcc);\n }\n\n if (importance && importance !== 'Normal') {\n message.importance = importance;\n }\n\n return message;\n}\n"],"names":["buildOutlookMessage","args","to","cc","bcc","subject","body","importance","contentType","message","content","parseEmailAddresses","emails","emailArray","Array","isArray","filter","email","trim","map","trimmed","emailAddress","address","length","toRecipients","ccRecipients","bccRecipients"],"mappings":"AAAA;;;CAGC;;;;+BAoCeA;;;eAAAA;;;AAAT,SAASA,oBAAoBC,IAAwB;IAC1D,eAA6GA,KAArGC,IAAAA,2BAAK,EAAE,wBAA8FD,KAA5FE,IAAAA,2BAAK,EAAE,yBAAqFF,KAAnFG,KAAAA,6BAAM,EAAE,8BAA2EH,KAAzEI,SAAAA,qCAAU,iCAA+DJ,KAA3DK,MAAAA,+BAAO,oCAAoDL,KAAhDM,YAAAA,2CAAa,iDAAmCN,KAAzBO,aAAAA,6CAAc;IAElG,IAAMC,UAA0B,CAAC;IAEjC,IAAIJ,SAAS;QACXI,QAAQJ,OAAO,GAAGA;IACpB;IAEA,IAAIC,MAAM;QACRG,QAAQH,IAAI,GAAG;YACbE,aAAaA;YACbE,SAASJ;QACX;IACF;IAEA,SAASK,oBAAoBC,MAAyB;QACpD,IAAMC,aAAaC,MAAMC,OAAO,CAACH,UAAUA,SAAS;YAACA;SAAO;QAC5D,OAAOC,WACJG,MAAM,CAAC,SAACC;mBAAUA,SAASA,MAAMC,IAAI;WACrCC,GAAG,CAAC,SAACF;YACJ,IAAMG,UAAUH,MAAMC,IAAI;YAC1B,4DAA4D;YAC5D,OAAO;gBACLG,cAAc;oBACZC,SAASF;gBACX;YACF;QACF;IACJ;IAEA,IAAIlB,MAAOY,CAAAA,MAAMC,OAAO,CAACb,MAAMA,GAAGqB,MAAM,GAAG,IAAIrB,GAAGgB,IAAI,EAAC,GAAI;QACzDT,QAAQe,YAAY,GAAGb,oBAAoBT;IAC7C;IAEA,IAAIC,MAAOW,CAAAA,MAAMC,OAAO,CAACZ,MAAMA,GAAGoB,MAAM,GAAG,IAAIpB,GAAGe,IAAI,EAAC,GAAI;QACzDT,QAAQgB,YAAY,GAAGd,oBAAoBR;IAC7C;IAEA,IAAIC,OAAQU,CAAAA,MAAMC,OAAO,CAACX,OAAOA,IAAImB,MAAM,GAAG,IAAInB,IAAIc,IAAI,EAAC,GAAI;QAC7DT,QAAQiB,aAAa,GAAGf,oBAAoBP;IAC9C;IAEA,IAAIG,cAAcA,eAAe,UAAU;QACzCE,QAAQF,UAAU,GAAGA;IACvB;IAEA,OAAOE;AACT"}
|
|
@@ -17,7 +17,7 @@ _export(exports, {
|
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
var _email = require("@mcp-z/email");
|
|
20
|
-
var
|
|
20
|
+
var _headerparsingts = require("../parsing/header-parsing.js");
|
|
21
21
|
function toRowFromOutlook(msg) {
|
|
22
22
|
var opts = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
|
|
23
23
|
body: false,
|
|
@@ -27,10 +27,10 @@ function toRowFromOutlook(msg) {
|
|
|
27
27
|
var id = (_msg_id = msg.id) !== null && _msg_id !== void 0 ? _msg_id : '';
|
|
28
28
|
var provider = 'outlook';
|
|
29
29
|
var threadId = (_msg_conversationId = msg.conversationId) !== null && _msg_conversationId !== void 0 ? _msg_conversationId : '';
|
|
30
|
-
var to = msg.toRecipients ? (0,
|
|
31
|
-
var from = msg.from ? (_extractFrom = (0,
|
|
32
|
-
var cc = msg.ccRecipients ? (0,
|
|
33
|
-
var bcc = msg.bccRecipients ? (0,
|
|
30
|
+
var to = msg.toRecipients ? (0, _headerparsingts.formatAddressList)(msg.toRecipients, opts.addressFormat) : '';
|
|
31
|
+
var from = msg.from ? (_extractFrom = (0, _headerparsingts.extractFrom)(msg.from)) !== null && _extractFrom !== void 0 ? _extractFrom : '' : '';
|
|
32
|
+
var cc = msg.ccRecipients ? (0, _headerparsingts.formatAddressList)(msg.ccRecipients, opts.addressFormat) : '';
|
|
33
|
+
var bcc = msg.bccRecipients ? (0, _headerparsingts.formatAddressList)(msg.bccRecipients, opts.addressFormat) : '';
|
|
34
34
|
var date = msg.receivedDateTime ? (0, _email.normalizeDateToISO)(msg.receivedDateTime) || msg.receivedDateTime : '';
|
|
35
35
|
var subject = (_msg_subject = msg.subject) !== null && _msg_subject !== void 0 ? _msg_subject : '';
|
|
36
36
|
var labels = msg.categories ? msg.categories.join(';') : '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/messages/messages.ts"],"sourcesContent":["import { buildContentForItems, stripHtml, normalizeDateToISO as toIsoUtc } from '@mcp-z/email';\nimport type { OutlookMessage } from '../../lib/outlook/types.ts';\nimport { extractFrom, formatAddressList } from '../parsing/header-parsing.ts';\n\nexport { buildContentForItems };\n\nexport function toRowFromOutlook(msg: OutlookMessage, opts: { body?: boolean; addressFormat?: 'email' | 'name' | 'raw' } = { body: false, addressFormat: 'email' }) {\n const id = msg.id ?? '';\n const provider = 'outlook';\n const threadId = msg.conversationId ?? '';\n const to = msg.toRecipients ? formatAddressList(msg.toRecipients, opts.addressFormat) : '';\n const from = msg.from ? (extractFrom(msg.from) ?? '') : '';\n const cc = msg.ccRecipients ? formatAddressList(msg.ccRecipients, opts.addressFormat) : '';\n const bcc = msg.bccRecipients ? formatAddressList(msg.bccRecipients, opts.addressFormat) : '';\n const date = msg.receivedDateTime ? toIsoUtc(msg.receivedDateTime) || msg.receivedDateTime : '';\n const subject = msg.subject ?? '';\n const labels = msg.categories ? msg.categories.join(';') : '';\n const snippet = msg.bodyPreview ?? '';\n let bodyFull = '';\n if (opts.body && msg.body) {\n const raw = msg.body.content ?? '';\n if (raw) {\n bodyFull = msg.body.contentType && msg.body.contentType.toLowerCase() === 'html' ? stripHtml(raw) : String(raw);\n }\n }\n return [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, bodyFull];\n}\n"],"names":["buildContentForItems","toRowFromOutlook","msg","opts","body","addressFormat","extractFrom","id","provider","threadId","conversationId","to","toRecipients","formatAddressList","from","cc","ccRecipients","bcc","bccRecipients","date","receivedDateTime","toIsoUtc","subject","labels","categories","join","snippet","bodyPreview","bodyFull","raw","content","contentType","toLowerCase","stripHtml","String"],"mappings":";;;;;;;;;;;QAISA;eAAAA,2BAAoB;;QAEbC;eAAAA;;;qBANgE;+BAEjC;AAIxC,SAASA,iBAAiBC,GAAmB;QAAEC,OAAAA,iEAAqE;QAAEC,MAAM;QAAOC,eAAe;IAAQ;QACpJH,SAEMA,qBAEQI,cAITJ,cAEAA;IAVhB,IAAMK,MAAKL,UAAAA,IAAIK,EAAE,cAANL,qBAAAA,UAAU;IACrB,IAAMM,WAAW;IACjB,IAAMC,YAAWP,sBAAAA,IAAIQ,cAAc,cAAlBR,iCAAAA,sBAAsB;IACvC,IAAMS,KAAKT,IAAIU,YAAY,GAAGC,IAAAA,kCAAiB,EAACX,IAAIU,YAAY,EAAET,KAAKE,aAAa,IAAI;IACxF,IAAMS,OAAOZ,IAAIY,IAAI,IAAIR,eAAAA,IAAAA,4BAAW,EAACJ,IAAIY,IAAI,eAApBR,0BAAAA,eAAyB,KAAM;IACxD,IAAMS,KAAKb,IAAIc,YAAY,GAAGH,IAAAA,kCAAiB,EAACX,IAAIc,YAAY,EAAEb,KAAKE,aAAa,IAAI;IACxF,IAAMY,MAAMf,IAAIgB,aAAa,GAAGL,IAAAA,kCAAiB,EAACX,IAAIgB,aAAa,EAAEf,KAAKE,aAAa,IAAI;IAC3F,IAAMc,OAAOjB,IAAIkB,gBAAgB,GAAGC,IAAAA,yBAAQ,EAACnB,IAAIkB,gBAAgB,KAAKlB,IAAIkB,gBAAgB,GAAG;IAC7F,IAAME,WAAUpB,eAAAA,IAAIoB,OAAO,cAAXpB,0BAAAA,eAAe;IAC/B,IAAMqB,SAASrB,IAAIsB,UAAU,GAAGtB,IAAIsB,UAAU,CAACC,IAAI,CAAC,OAAO;IAC3D,IAAMC,WAAUxB,mBAAAA,IAAIyB,WAAW,cAAfzB,8BAAAA,mBAAmB;IACnC,IAAI0B,WAAW;IACf,IAAIzB,KAAKC,IAAI,IAAIF,IAAIE,IAAI,EAAE;YACbF;QAAZ,IAAM2B,OAAM3B,oBAAAA,IAAIE,IAAI,CAAC0B,OAAO,cAAhB5B,+BAAAA,oBAAoB;QAChC,IAAI2B,KAAK;YACPD,WAAW1B,IAAIE,IAAI,CAAC2B,WAAW,IAAI7B,IAAIE,IAAI,CAAC2B,WAAW,CAACC,WAAW,OAAO,SAASC,IAAAA,gBAAS,EAACJ,OAAOK,OAAOL;QAC7G;IACF;IACA,OAAO;QAACtB;QAAIC;QAAUC;QAAUE;QAAIG;QAAMC;QAAIE;QAAKE;QAAMG;QAASC;QAAQG;QAASE;KAAS;AAC9F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/parsing/header-parsing.ts"],"sourcesContent":["export function extractEmailsFromRecipients(recipients: Array<{ emailAddress?: { address?: string; name?: string } }>, mode: 'email' | 'name' | 'raw' = 'email'): string[] {\n if (!Array.isArray(recipients)) return [];\n return recipients\n .map((r) => {\n const name = r?.emailAddress?.name ?? '';\n const email = r?.emailAddress?.address ?? '';\n return mode === 'email' ? email : mode === 'name' ? name || email : `${name} <${email}>`;\n })\n .filter(Boolean);\n}\n\nexport function formatAddressList(recipients: Array<{ emailAddress?: { address?: string; name?: string } }>, mode: 'email' | 'name' | 'raw' = 'email'): string {\n return extractEmailsFromRecipients(recipients, mode).join(', ');\n}\n\nexport function extractFrom(from: { emailAddress?: { address?: string; name?: string } } | undefined): string | undefined {\n if (!from) return undefined;\n return from.emailAddress?.address || from.emailAddress?.name || undefined;\n}\n"],"names":["extractEmailsFromRecipients","extractFrom","formatAddressList","recipients","mode","Array","isArray","map","r","name","emailAddress","email","address","filter","Boolean","join","from","undefined"],"mappings":";;;;;;;;;;;QAAgBA;eAAAA;;QAeAC;eAAAA;;QAJAC;eAAAA;;;AAXT,SAASF,4BAA4BG,UAAyE;QAAEC,OAAAA,iEAAiC;IACtJ,IAAI,CAACC,MAAMC,OAAO,CAACH,aAAa,OAAO,EAAE;IACzC,OAAOA,WACJI,GAAG,CAAC,SAACC;;YACSA,iBACCA;QADd,IAAMC,eAAOD,cAAAA,yBAAAA,kBAAAA,EAAGE,YAAY,cAAfF,sCAAAA,gBAAiBC,IAAI,uCAAI;QACtC,IAAME,iBAAQH,cAAAA,yBAAAA,mBAAAA,EAAGE,YAAY,cAAfF,uCAAAA,iBAAiBI,OAAO,yCAAI;QAC1C,OAAOR,SAAS,UAAUO,QAAQP,SAAS,SAASK,QAAQE,QAAQ,AAAC,GAAWA,OAATF,MAAK,MAAU,OAANE,OAAM;IACxF,GACCE,MAAM,CAACC;AACZ;AAEO,SAASZ,kBAAkBC,UAAyE;QAAEC,OAAAA,iEAAiC;IAC5I,OAAOJ,4BAA4BG,YAAYC,MAAMW,IAAI,CAAC;AAC5D;AAEO,SAASd,YAAYe,IAAwE;QAE3FA,oBAA8BA;IADrC,IAAI,CAACA,MAAM,OAAOC;IAClB,OAAOD,EAAAA,qBAAAA,KAAKN,YAAY,cAAjBM,yCAAAA,mBAAmBJ,OAAO,OAAII,sBAAAA,KAAKN,YAAY,cAAjBM,0CAAAA,oBAAmBP,IAAI,KAAIQ;AAClE"}
|
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "fetchOutlookMessage", {
|
|
|
8
8
|
return fetchOutlookMessage;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
var
|
|
11
|
+
var _messagemappingts = require("./message-mapping.js");
|
|
12
12
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
13
13
|
try {
|
|
14
14
|
var info = gen[key](arg);
|
|
@@ -173,7 +173,7 @@ function fetchOutlookMessage(graph, id) {
|
|
|
173
173
|
data = _state.sent();
|
|
174
174
|
return [
|
|
175
175
|
2,
|
|
176
|
-
(0,
|
|
176
|
+
(0, _messagemappingts.mapOutlookMessage)(data, {
|
|
177
177
|
preferHtml: true
|
|
178
178
|
})
|
|
179
179
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/parsing/message-extraction.ts"],"sourcesContent":["import type { Client } from '@microsoft/microsoft-graph-client';\nimport type { OutlookMessage } from '../../lib/outlook/types.ts';\nimport { mapOutlookMessage, type NormalizedMessage } from './message-mapping.ts';\n\n/** Fetch a single Outlook message. Throws on non-OK Graph responses. */\nexport async function fetchOutlookMessage(graph: Client, id: string): Promise<NormalizedMessage> {\n if (!id) throw new Error('fetchOutlookMessage: id required');\n const selectFields = ['id', 'conversationId', 'receivedDateTime', 'subject', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients', 'bodyPreview', 'categories', 'body'];\n try {\n const data: unknown = await graph\n .api(`/me/messages/${encodeURIComponent(id)}`)\n .select(selectFields.join(','))\n .get();\n return mapOutlookMessage(data as OutlookMessage, { preferHtml: true });\n } catch (e: unknown) {\n const status = (e as Record<string, unknown>)?.status || (e as Record<string, unknown>)?.code || 'unknown';\n throw new Error(`outlook.fetchMessage: failed (${status})`);\n }\n}\n"],"names":["fetchOutlookMessage","graph","id","selectFields","data","e","status","Error","api","encodeURIComponent","select","join","get","mapOutlookMessage","preferHtml","code"],"mappings":";;;;+BAKsBA;;;eAAAA;;;gCAHoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGnD,SAAeA,oBAAoBC,KAAa,EAAEC,EAAU;;YAE3DC,cAEEC,MAKCC,GACDC;;;;oBATR,IAAI,CAACJ,IAAI,MAAM,IAAIK,MAAM;oBACnBJ;wBAAgB;wBAAM;wBAAkB;wBAAoB;wBAAW;wBAAQ;wBAAgB;wBAAgB;wBAAiB;wBAAe;wBAAc;;;;;;;;;;oBAE3I;;wBAAMF,MACzBO,GAAG,CAAC,AAAC,gBAAsC,OAAvBC,mBAAmBP,MACvCQ,MAAM,CAACP,aAAaQ,IAAI,CAAC,MACzBC,GAAG;;;oBAHAR,OAAgB;oBAItB;;wBAAOS,IAAAA,mCAAiB,EAACT,MAAwB;4BAAEU,YAAY;wBAAK;;;oBAC7DT;oBACDC,SAAS,CAACD,cAAAA,wBAAD,AAACA,EAA+BC,MAAM,MAAKD,cAAAA,wBAAD,AAACA,EAA+BU,IAAI,KAAI;oBACjG,MAAM,IAAIR,MAAM,AAAC,iCAAuC,OAAPD,QAAO;;;;;;;IAE5D"}
|
|
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "mapOutlookMessage", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
var _email = require("@mcp-z/email");
|
|
12
|
-
var
|
|
12
|
+
var _headerparsingts = require("./header-parsing.js");
|
|
13
13
|
function mapOutlookMessage(msg) {
|
|
14
14
|
var opts = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
15
15
|
var _ref, _ref1, _msg_id, _toIsoUtc, _msg_toRecipients, _msg_ccRecipients, _msg_bccRecipients;
|
|
@@ -33,11 +33,11 @@ function mapOutlookMessage(msg) {
|
|
|
33
33
|
name: fromAddr.name || undefined
|
|
34
34
|
} : undefined;
|
|
35
35
|
if (fromObj && (fromObj.address || fromObj.name)) out.from = fromObj;
|
|
36
|
-
var toList = (0,
|
|
36
|
+
var toList = (0, _headerparsingts.extractEmailsFromRecipients)((_msg_toRecipients = msg.toRecipients) !== null && _msg_toRecipients !== void 0 ? _msg_toRecipients : []);
|
|
37
37
|
if (Array.isArray(toList) && toList.length) out.to = toList;
|
|
38
|
-
var ccList = (0,
|
|
38
|
+
var ccList = (0, _headerparsingts.extractEmailsFromRecipients)((_msg_ccRecipients = msg.ccRecipients) !== null && _msg_ccRecipients !== void 0 ? _msg_ccRecipients : []);
|
|
39
39
|
if (Array.isArray(ccList) && ccList.length) out.cc = ccList;
|
|
40
|
-
var bccList = (0,
|
|
40
|
+
var bccList = (0, _headerparsingts.extractEmailsFromRecipients)((_msg_bccRecipients = msg.bccRecipients) !== null && _msg_bccRecipients !== void 0 ? _msg_bccRecipients : []);
|
|
41
41
|
if (Array.isArray(bccList) && bccList.length) out.bcc = bccList;
|
|
42
42
|
if (msg.bodyPreview) out.snippet = String(msg.bodyPreview);
|
|
43
43
|
if (Array.isArray(msg.categories) && msg.categories.length) out.labels = msg.categories.map(String);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/parsing/message-mapping.ts"],"sourcesContent":["import { stripHtml, normalizeDateToISO as toIsoUtc } from '@mcp-z/email';\nimport type { OutlookMessage } from '../../lib/outlook/types.ts';\nimport { extractEmailsFromRecipients } from './header-parsing.ts';\n\nexport interface NormalizedAddress {\n address?: string | undefined;\n name?: string | undefined;\n}\nexport interface NormalizedMessage {\n id: string;\n threadId?: string;\n date?: string;\n subject?: string;\n from?: NormalizedAddress;\n to?: string[];\n cc?: string[];\n bcc?: string[];\n snippet?: string;\n labels?: string[];\n body?: string;\n}\n\nexport function mapOutlookMessage(msg: OutlookMessage, opts: { preferHtml?: boolean } = {}): NormalizedMessage {\n const fromAddr = msg.from?.emailAddress;\n const bodyContent = msg.body?.content ?? '';\n const bodyType = String(msg.body?.contentType ?? '').toLowerCase();\n\n let body: string | undefined;\n if (bodyContent) {\n if (opts.preferHtml && bodyType === 'html') body = stripHtml(bodyContent);\n else body = bodyType === 'html' ? stripHtml(bodyContent) : String(bodyContent);\n }\n\n const out: NormalizedMessage = { id: msg.id ?? '' };\n\n if (msg.conversationId) out.threadId = String(msg.conversationId);\n if (msg.receivedDateTime) out.date = toIsoUtc(msg.receivedDateTime) ?? String(msg.receivedDateTime);\n if (msg.subject) out.subject = String(msg.subject);\n\n const fromObj = fromAddr ? { address: fromAddr.address || undefined, name: fromAddr.name || undefined } : undefined;\n if (fromObj && (fromObj.address || fromObj.name)) out.from = fromObj;\n\n const toList = extractEmailsFromRecipients(msg.toRecipients ?? []);\n if (Array.isArray(toList) && toList.length) out.to = toList;\n\n const ccList = extractEmailsFromRecipients(msg.ccRecipients ?? []);\n if (Array.isArray(ccList) && ccList.length) out.cc = ccList;\n\n const bccList = extractEmailsFromRecipients(msg.bccRecipients ?? []);\n if (Array.isArray(bccList) && bccList.length) out.bcc = bccList;\n\n if (msg.bodyPreview) out.snippet = String(msg.bodyPreview);\n if (Array.isArray(msg.categories) && msg.categories.length) out.labels = msg.categories.map(String);\n if (body) out.body = body;\n\n return out;\n}\n"],"names":["mapOutlookMessage","msg","opts","toIsoUtc","fromAddr","from","emailAddress","bodyContent","body","content","bodyType","String","contentType","toLowerCase","preferHtml","stripHtml","out","id","conversationId","threadId","receivedDateTime","date","subject","fromObj","address","undefined","name","toList","extractEmailsFromRecipients","toRecipients","Array","isArray","length","to","ccList","ccRecipients","cc","bccList","bccRecipients","bcc","bodyPreview","snippet","categories","labels","map"],"mappings":";;;;+BAsBgBA;;;eAAAA;;;qBAtB0C;+BAEd;AAoBrC,SAASA,kBAAkBC,GAAmB;QAAEC,OAAAA,iEAAiC,CAAC;qBAWlDD,SAGAE,WAMMF,mBAGAA,mBAGCA;QAzB3BA,WACGA,WACIA;IAFxB,IAAMG,YAAWH,YAAAA,IAAII,IAAI,cAARJ,gCAAAA,UAAUK,YAAY;IACvC,IAAMC,uBAAcN,YAAAA,IAAIO,IAAI,cAARP,gCAAAA,UAAUQ,OAAO,uCAAI;IACzC,IAAMC,WAAWC,iBAAOV,aAAAA,IAAIO,IAAI,cAARP,iCAAAA,WAAUW,WAAW,yCAAI,IAAIC,WAAW;IAEhE,IAAIL;IACJ,IAAID,aAAa;QACf,IAAIL,KAAKY,UAAU,IAAIJ,aAAa,QAAQF,OAAOO,IAAAA,gBAAS,EAACR;aACxDC,OAAOE,aAAa,SAASK,IAAAA,gBAAS,EAACR,eAAeI,OAAOJ;IACpE;IAEA,IAAMS,MAAyB;QAAEC,EAAE,GAAEhB,UAAAA,IAAIgB,EAAE,cAANhB,qBAAAA,UAAU;IAAG;IAElD,IAAIA,IAAIiB,cAAc,EAAEF,IAAIG,QAAQ,GAAGR,OAAOV,IAAIiB,cAAc;IAChE,IAAIjB,IAAImB,gBAAgB,EAAEJ,IAAIK,IAAI,IAAGlB,YAAAA,IAAAA,yBAAQ,EAACF,IAAImB,gBAAgB,eAA7BjB,uBAAAA,YAAkCQ,OAAOV,IAAImB,gBAAgB;IAClG,IAAInB,IAAIqB,OAAO,EAAEN,IAAIM,OAAO,GAAGX,OAAOV,IAAIqB,OAAO;IAEjD,IAAMC,UAAUnB,WAAW;QAAEoB,SAASpB,SAASoB,OAAO,IAAIC;QAAWC,MAAMtB,SAASsB,IAAI,IAAID;IAAU,IAAIA;IAC1G,IAAIF,WAAYA,CAAAA,QAAQC,OAAO,IAAID,QAAQG,IAAI,AAAD,GAAIV,IAAIX,IAAI,GAAGkB;IAE7D,IAAMI,SAASC,IAAAA,4CAA2B,GAAC3B,oBAAAA,IAAI4B,YAAY,cAAhB5B,+BAAAA,oBAAoB,EAAE;IACjE,IAAI6B,MAAMC,OAAO,CAACJ,WAAWA,OAAOK,MAAM,EAAEhB,IAAIiB,EAAE,GAAGN;IAErD,IAAMO,SAASN,IAAAA,4CAA2B,GAAC3B,oBAAAA,IAAIkC,YAAY,cAAhBlC,+BAAAA,oBAAoB,EAAE;IACjE,IAAI6B,MAAMC,OAAO,CAACG,WAAWA,OAAOF,MAAM,EAAEhB,IAAIoB,EAAE,GAAGF;IAErD,IAAMG,UAAUT,IAAAA,4CAA2B,GAAC3B,qBAAAA,IAAIqC,aAAa,cAAjBrC,gCAAAA,qBAAqB,EAAE;IACnE,IAAI6B,MAAMC,OAAO,CAACM,YAAYA,QAAQL,MAAM,EAAEhB,IAAIuB,GAAG,GAAGF;IAExD,IAAIpC,IAAIuC,WAAW,EAAExB,IAAIyB,OAAO,GAAG9B,OAAOV,IAAIuC,WAAW;IACzD,IAAIV,MAAMC,OAAO,CAAC9B,IAAIyC,UAAU,KAAKzC,IAAIyC,UAAU,CAACV,MAAM,EAAEhB,IAAI2B,MAAM,GAAG1C,IAAIyC,UAAU,CAACE,GAAG,CAACjC;IAC5F,IAAIH,MAAMQ,IAAIR,IAAI,GAAGA;IAErB,OAAOQ;AACT"}
|
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "executeQuery", {
|
|
|
8
8
|
return executeQuery;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
var
|
|
11
|
+
var _searchexecutionts = require("./search-execution.js");
|
|
12
12
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
13
13
|
try {
|
|
14
14
|
var info = gen[key](arg);
|
|
@@ -215,7 +215,7 @@ function executeQuery(graph, query, options, transform) {
|
|
|
215
215
|
]);
|
|
216
216
|
return [
|
|
217
217
|
4,
|
|
218
|
-
(0,
|
|
218
|
+
(0, _searchexecutionts.searchMessages)(graph, _object_spread_props(_object_spread({}, query !== undefined && {
|
|
219
219
|
query: query
|
|
220
220
|
}), {
|
|
221
221
|
limit: limit !== null && limit !== void 0 ? limit : 50,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/querying/execute-query.ts"],"sourcesContent":["import type { ExecutionResult } from '@mcp-z/email';\nimport type { Client } from '@microsoft/microsoft-graph-client';\nimport type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { searchMessages } from './search-execution.ts';\n\nexport interface ExecuteQueryOptions {\n readonly logger: Logger;\n readonly limit?: number;\n readonly includeBody?: boolean;\n readonly maxPages?: number | null;\n readonly pageSize?: number;\n readonly pageToken?: string;\n readonly timezone?: string;\n readonly abortSignal?: AbortSignal;\n}\n\n/**\n * Execute an Outlook query with direct, single-attempt execution.\n * No planning, no fallbacks, no retries.\n * Microsoft Graph errors are returned directly to the caller for actionable feedback.\n */\nexport async function executeQuery<T>(graph: Client, query: QueryNode | undefined, options: ExecuteQueryOptions, transform: (item: unknown) => T): Promise<ExecutionResult<T>> {\n const { logger, limit, includeBody, maxPages, pageSize, pageToken } = options;\n\n // Single execution - direct query to Microsoft Graph API\n logger.info('executeQuery: executing direct Outlook query');\n\n try {\n const result = await searchMessages(graph, {\n ...(query !== undefined && { query }),\n limit: limit ?? 50,\n includeBody: includeBody ?? false,\n maxPages: maxPages ?? null,\n pageSize: pageSize ?? 50,\n pageToken: pageToken ?? undefined,\n logger,\n });\n\n // Transform directly - if Microsoft Graph returns invalid data, fail loud\n const transformedResults = result.messages.map((item, index) => {\n try {\n return transform(item);\n } catch (transformError) {\n logger.error(`Transform function failed for item ${index}`, {\n itemIndex: index,\n error: transformError instanceof Error ? transformError.message : String(transformError),\n });\n throw new Error(`Transform failed at item ${index}: ${transformError}`);\n }\n });\n\n logger.info(`executeQuery: succeeded with ${transformedResults.length} results`);\n\n return {\n success: true,\n items: transformedResults,\n metadata: {\n nextPageToken: result.nextPageToken,\n totalFetched: result.messages.length,\n },\n };\n } catch (error) {\n // Re-throw errors directly - no fallback logic\n logger.error('executeQuery: failed', error as Record<string, unknown>);\n throw error;\n }\n}\n"],"names":["executeQuery","graph","query","options","transform","logger","limit","includeBody","maxPages","pageSize","pageToken","result","transformedResults","error","info","searchMessages","undefined","messages","map","item","index","transformError","itemIndex","Error","message","String","length","success","items","metadata","nextPageToken","totalFetched"],"mappings":";;;;+BAsBsBA;;;eAAAA;;;iCAlBS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBxB,SAAeA,aAAgBC,KAAa,EAAEC,KAA4B,EAAEC,OAA4B,EAAEC,SAA+B;;YACtIC,QAAQC,OAAOC,aAAaC,UAAUC,UAAUC,WAMhDC,QAWAC,oBAsBCC;;;;oBAvCDR,SAA8DF,QAA9DE,QAAQC,QAAsDH,QAAtDG,OAAOC,cAA+CJ,QAA/CI,aAAaC,WAAkCL,QAAlCK,UAAUC,WAAwBN,QAAxBM,UAAUC,YAAcP,QAAdO;oBAExD,yDAAyD;oBACzDL,OAAOS,IAAI,CAAC;;;;;;;;;oBAGK;;wBAAMC,IAAAA,iCAAc,EAACd,OAAO,wCACrCC,UAAUc,aAAa;4BAAEd,OAAAA;wBAAM;4BACnCI,KAAK,EAAEA,kBAAAA,mBAAAA,QAAS;4BAChBC,WAAW,EAAEA,wBAAAA,yBAAAA,cAAe;4BAC5BC,QAAQ,EAAEA,qBAAAA,sBAAAA,WAAY;4BACtBC,QAAQ,EAAEA,qBAAAA,sBAAAA,WAAY;4BACtBC,SAAS,EAAEA,sBAAAA,uBAAAA,YAAaM;4BACxBX,QAAAA;;;;oBAPIM,SAAS;oBAUf,0EAA0E;oBACpEC,qBAAqBD,OAAOM,QAAQ,CAACC,GAAG,CAAC,SAACC,MAAMC;wBACpD,IAAI;4BACF,OAAOhB,UAAUe;wBACnB,EAAE,OAAOE,gBAAgB;4BACvBhB,OAAOQ,KAAK,CAAC,AAAC,sCAA2C,OAANO,QAAS;gCAC1DE,WAAWF;gCACXP,OAAOQ,AAAc,YAAdA,gBAA0BE,SAAQF,eAAeG,OAAO,GAAGC,OAAOJ;4BAC3E;4BACA,MAAM,IAAIE,MAAM,AAAC,4BAAqCF,OAAVD,OAAM,MAAmB,OAAfC;wBACxD;oBACF;oBAEAhB,OAAOS,IAAI,CAAC,AAAC,gCAAyD,OAA1BF,mBAAmBc,MAAM,EAAC;oBAEtE;;wBAAO;4BACLC,SAAS;4BACTC,OAAOhB;4BACPiB,UAAU;gCACRC,eAAenB,OAAOmB,aAAa;gCACnCC,cAAcpB,OAAOM,QAAQ,CAACS,MAAM;4BACtC;wBACF;;;oBACOb;oBACP,+CAA+C;oBAC/CR,OAAOQ,KAAK,CAAC,wBAAwBA;oBACrC,MAAMA;;;;;;;IAEV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/email/querying/query-builder.ts"],"sourcesContent":["import type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.js';\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 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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"}
|
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "searchMessages", {
|
|
|
8
8
|
return searchMessages;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
var
|
|
11
|
+
var _querybuilderts = require("./query-builder.js");
|
|
12
12
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
13
13
|
try {
|
|
14
14
|
var info = gen[key](arg);
|
|
@@ -147,7 +147,7 @@ function _ts_generator(thisArg, body) {
|
|
|
147
147
|
function buildGraphQuery(query) {
|
|
148
148
|
var _r_search, _r_filter;
|
|
149
149
|
if (!query) return {};
|
|
150
|
-
var r = (0,
|
|
150
|
+
var r = (0, _querybuilderts.toGraphFilter)(query) || {
|
|
151
151
|
search: undefined,
|
|
152
152
|
filter: undefined
|
|
153
153
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/querying/search-execution.ts"],"sourcesContent":["import type { Client } from '@microsoft/microsoft-graph-client';\nimport type { Message } from '@microsoft/microsoft-graph-types';\nimport type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { toGraphFilter } from './query-builder.ts';\n\nexport interface OutlookSearchOptions {\n query?: QueryNode;\n limit?: number;\n includeBody?: boolean;\n maxPages?: number | null;\n pageSize?: number;\n pageToken?: string | undefined;\n logger: Logger;\n}\n\nexport interface OutlookSearchResult {\n messages: Message[];\n nextPageToken?: string | undefined;\n}\n\nfunction buildGraphQuery(query: QueryNode | undefined): {\n search?: string | undefined;\n filter?: string | undefined;\n} {\n if (!query) return {};\n const r = toGraphFilter(query) || { search: undefined, filter: undefined };\n return { search: r.search ?? undefined, filter: r.filter ?? undefined };\n}\n\n/**\n * Execute a direct Microsoft Graph API query.\n * Single attempt with no fallbacks or retries.\n * Errors are returned directly for actionable feedback.\n * Returns raw Graph API Message objects for transformation by caller.\n */\nexport async function searchMessages(graph: Client, opts: OutlookSearchOptions): Promise<OutlookSearchResult> {\n const { query, includeBody = false, pageSize = 50, pageToken, logger } = opts;\n\n const { search, filter } = buildGraphQuery(query);\n\n let request = graph.api('/me/messages');\n\n if (search) {\n request = request.search(search);\n }\n\n if (filter) {\n request = request.filter(filter);\n }\n\n request = request.top(Math.min(pageSize, 1000)); // Graph API max is 1000\n\n const selectFields = includeBody ? ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'body', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'] : ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'];\n request = request.select(selectFields.join(','));\n\n if (pageToken && pageToken.trim().length > 0) {\n request = request.skipToken(pageToken);\n }\n\n logger.info('Executing direct Outlook query', {\n hasSearch: !!search,\n hasFilter: !!filter,\n pageSize,\n hasPageToken: !!pageToken,\n });\n\n try {\n // Execute the request\n const response = await request.get();\n\n // Extract messages and nextLink\n const messages: Message[] = response.value || [];\n const nextLink: string | undefined = response['@odata.nextLink'];\n\n // Extract skipToken from nextLink if present\n let nextPageToken: string | undefined;\n if (nextLink) {\n try {\n const url = new URL(nextLink);\n nextPageToken = url.searchParams.get('$skiptoken') || undefined;\n } catch {\n logger.info('Failed to parse nextLink for skipToken', { nextLink });\n }\n }\n\n logger.info(`Query succeeded with ${messages.length} results`, {\n hasNextPage: !!nextPageToken,\n });\n\n return {\n messages,\n nextPageToken,\n };\n } catch (error) {\n // Log and re-throw error directly - no fallback logic\n logger.error('Outlook query failed', {\n error: error instanceof Error ? error.message : String(error),\n hasSearch: !!search,\n hasFilter: !!filter,\n });\n throw error;\n }\n}\n"],"names":["searchMessages","buildGraphQuery","query","r","toGraphFilter","search","undefined","filter","graph","opts","includeBody","pageSize","pageToken","logger","request","selectFields","response","messages","nextLink","nextPageToken","url","error","api","top","Math","min","select","join","trim","length","skipToken","info","hasSearch","hasFilter","hasPageToken","get","value","URL","searchParams","hasNextPage","Error","message","String"],"mappings":"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"}
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { ServerConfig } from './types.js';
|
|
2
2
|
export { MS_SCOPE } from './constants.js';
|
|
3
3
|
export * as mcp from './mcp/index.js';
|
|
4
|
+
export type { Input as CategoriesListInput } from './mcp/tools/categories-list.js';
|
|
5
|
+
export { inputSchema as categoriesListInputSchema } from './mcp/tools/categories-list.js';
|
|
6
|
+
export type { Input as LabelsListInput } from './mcp/tools/labels-list.js';
|
|
7
|
+
export { inputSchema as labelsListInputSchema } from './mcp/tools/labels-list.js';
|
|
4
8
|
export * as schemas from './schemas/index.js';
|
|
5
9
|
export * as setup from './setup/index.js';
|
|
10
|
+
export type { AuthMiddleware, OAuthAdapters, OAuthRuntimeDeps } from './setup/oauth-microsoft.js';
|
|
6
11
|
export * from './types.js';
|
|
7
12
|
export declare function startServer(config: ServerConfig): Promise<void>;
|
|
8
13
|
export default function main(): Promise<void>;
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { ServerConfig } from './types.js';
|
|
2
2
|
export { MS_SCOPE } from './constants.js';
|
|
3
3
|
export * as mcp from './mcp/index.js';
|
|
4
|
+
export type { Input as CategoriesListInput } from './mcp/tools/categories-list.js';
|
|
5
|
+
export { inputSchema as categoriesListInputSchema } from './mcp/tools/categories-list.js';
|
|
6
|
+
export type { Input as LabelsListInput } from './mcp/tools/labels-list.js';
|
|
7
|
+
export { inputSchema as labelsListInputSchema } from './mcp/tools/labels-list.js';
|
|
4
8
|
export * as schemas from './schemas/index.js';
|
|
5
9
|
export * as setup from './setup/index.js';
|
|
10
|
+
export type { AuthMiddleware, OAuthAdapters, OAuthRuntimeDeps } from './setup/oauth-microsoft.js';
|
|
6
11
|
export * from './types.js';
|
|
7
12
|
export declare function startServer(config: ServerConfig): Promise<void>;
|
|
8
13
|
export default function main(): Promise<void>;
|