@opentabs-dev/opentabs-plugin-outlook 0.0.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +59 -0
  2. package/dist/adapter.iife.js +15081 -0
  3. package/dist/adapter.iife.js.map +7 -0
  4. package/dist/index.d.ts +14 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +54 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/outlook-api.d.ts +13 -0
  9. package/dist/outlook-api.d.ts.map +1 -0
  10. package/dist/outlook-api.js +231 -0
  11. package/dist/outlook-api.js.map +1 -0
  12. package/dist/tools/create-draft.d.ts +21 -0
  13. package/dist/tools/create-draft.d.ts.map +1 -0
  14. package/dist/tools/create-draft.js +46 -0
  15. package/dist/tools/create-draft.js.map +1 -0
  16. package/dist/tools/delete-message.d.ts +7 -0
  17. package/dist/tools/delete-message.d.ts.map +1 -0
  18. package/dist/tools/delete-message.js +22 -0
  19. package/dist/tools/delete-message.js.map +1 -0
  20. package/dist/tools/forward-message.d.ts +9 -0
  21. package/dist/tools/forward-message.d.ts.map +1 -0
  22. package/dist/tools/forward-message.js +30 -0
  23. package/dist/tools/forward-message.js.map +1 -0
  24. package/dist/tools/get-attachment-content.d.ts +15 -0
  25. package/dist/tools/get-attachment-content.d.ts.map +1 -0
  26. package/dist/tools/get-attachment-content.js +66 -0
  27. package/dist/tools/get-attachment-content.js.map +1 -0
  28. package/dist/tools/get-current-user.d.ts +9 -0
  29. package/dist/tools/get-current-user.d.ts.map +1 -0
  30. package/dist/tools/get-current-user.js +21 -0
  31. package/dist/tools/get-current-user.js.map +1 -0
  32. package/dist/tools/get-message.d.ts +37 -0
  33. package/dist/tools/get-message.d.ts.map +1 -0
  34. package/dist/tools/get-message.js +23 -0
  35. package/dist/tools/get-message.js.map +1 -0
  36. package/dist/tools/list-attachments.d.ts +13 -0
  37. package/dist/tools/list-attachments.d.ts.map +1 -0
  38. package/dist/tools/list-attachments.js +25 -0
  39. package/dist/tools/list-attachments.js.map +1 -0
  40. package/dist/tools/list-folders.d.ts +15 -0
  41. package/dist/tools/list-folders.d.ts.map +1 -0
  42. package/dist/tools/list-folders.js +36 -0
  43. package/dist/tools/list-folders.js.map +1 -0
  44. package/dist/tools/list-messages.d.ts +27 -0
  45. package/dist/tools/list-messages.d.ts.map +1 -0
  46. package/dist/tools/list-messages.js +48 -0
  47. package/dist/tools/list-messages.js.map +1 -0
  48. package/dist/tools/move-message.d.ts +8 -0
  49. package/dist/tools/move-message.d.ts.map +1 -0
  50. package/dist/tools/move-message.js +26 -0
  51. package/dist/tools/move-message.js.map +1 -0
  52. package/dist/tools/reply-to-message.d.ts +13 -0
  53. package/dist/tools/reply-to-message.d.ts.map +1 -0
  54. package/dist/tools/reply-to-message.js +35 -0
  55. package/dist/tools/reply-to-message.js.map +1 -0
  56. package/dist/tools/schemas.d.ts +199 -0
  57. package/dist/tools/schemas.d.ts.map +1 -0
  58. package/dist/tools/schemas.js +101 -0
  59. package/dist/tools/schemas.js.map +1 -0
  60. package/dist/tools/search-messages.d.ts +24 -0
  61. package/dist/tools/search-messages.d.ts.map +1 -0
  62. package/dist/tools/search-messages.js +30 -0
  63. package/dist/tools/search-messages.js.map +1 -0
  64. package/dist/tools/send-message.d.ts +21 -0
  65. package/dist/tools/send-message.d.ts.map +1 -0
  66. package/dist/tools/send-message.js +46 -0
  67. package/dist/tools/send-message.js.map +1 -0
  68. package/dist/tools/update-message.d.ts +19 -0
  69. package/dist/tools/update-message.d.ts.map +1 -0
  70. package/dist/tools/update-message.js +38 -0
  71. package/dist/tools/update-message.js.map +1 -0
  72. package/dist/tools.json +1113 -0
  73. package/package.json +64 -0
@@ -0,0 +1,14 @@
1
+ import { OpenTabsPlugin } from '@opentabs-dev/plugin-sdk';
2
+ import type { ToolDefinition } from '@opentabs-dev/plugin-sdk';
3
+ declare class OutlookPlugin extends OpenTabsPlugin {
4
+ readonly name = "outlook";
5
+ readonly description = "OpenTabs plugin for Microsoft Outlook \u2014 read, search, send, and manage emails";
6
+ readonly displayName = "Microsoft Outlook";
7
+ readonly urlPatterns: string[];
8
+ readonly homepage = "https://outlook.cloud.microsoft";
9
+ readonly tools: ToolDefinition[];
10
+ isReady(): Promise<boolean>;
11
+ }
12
+ declare const _default: OutlookPlugin;
13
+ export default _default;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAiB/D,cAAM,aAAc,SAAQ,cAAc;IACxC,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,WAAW,wFAAmF;IACvG,SAAkB,WAAW,uBAAuB;IACpD,QAAQ,CAAC,WAAW,WAKlB;IACF,SAAkB,QAAQ,qCAAqC;IAC/D,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,CAkB9B;IAEI,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;CAIlC;;AAED,wBAAmC"}
package/dist/index.js ADDED
@@ -0,0 +1,54 @@
1
+ import { OpenTabsPlugin } from '@opentabs-dev/plugin-sdk';
2
+ import { isAuthenticated, waitForAuth } from './outlook-api.js';
3
+ import { createDraft } from './tools/create-draft.js';
4
+ import { deleteMessage } from './tools/delete-message.js';
5
+ import { forwardMessage } from './tools/forward-message.js';
6
+ import { getAttachmentContent } from './tools/get-attachment-content.js';
7
+ import { getCurrentUser } from './tools/get-current-user.js';
8
+ import { getMessage } from './tools/get-message.js';
9
+ import { listAttachments } from './tools/list-attachments.js';
10
+ import { listFolders } from './tools/list-folders.js';
11
+ import { listMessages } from './tools/list-messages.js';
12
+ import { moveMessage } from './tools/move-message.js';
13
+ import { replyToMessage } from './tools/reply-to-message.js';
14
+ import { searchMessages } from './tools/search-messages.js';
15
+ import { sendMessage } from './tools/send-message.js';
16
+ import { updateMessage } from './tools/update-message.js';
17
+ class OutlookPlugin extends OpenTabsPlugin {
18
+ name = 'outlook';
19
+ description = 'OpenTabs plugin for Microsoft Outlook — read, search, send, and manage emails';
20
+ displayName = 'Microsoft Outlook';
21
+ urlPatterns = [
22
+ '*://outlook.cloud.microsoft/*',
23
+ '*://outlook.live.com/*',
24
+ '*://outlook.office.com/*',
25
+ '*://outlook.office365.com/*',
26
+ ];
27
+ homepage = 'https://outlook.cloud.microsoft';
28
+ tools = [
29
+ // Account
30
+ getCurrentUser,
31
+ // Messages
32
+ listMessages,
33
+ getMessage,
34
+ searchMessages,
35
+ sendMessage,
36
+ replyToMessage,
37
+ forwardMessage,
38
+ createDraft,
39
+ updateMessage,
40
+ moveMessage,
41
+ deleteMessage,
42
+ listAttachments,
43
+ getAttachmentContent,
44
+ // Folders
45
+ listFolders,
46
+ ];
47
+ async isReady() {
48
+ if (isAuthenticated())
49
+ return true;
50
+ return waitForAuth();
51
+ }
52
+ }
53
+ export default new OutlookPlugin();
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,aAAc,SAAQ,cAAc;IAC/B,IAAI,GAAG,SAAS,CAAC;IACjB,WAAW,GAAG,+EAA+E,CAAC;IACrF,WAAW,GAAG,mBAAmB,CAAC;IAC3C,WAAW,GAAG;QACrB,+BAA+B;QAC/B,wBAAwB;QACxB,0BAA0B;QAC1B,6BAA6B;KAC9B,CAAC;IACgB,QAAQ,GAAG,iCAAiC,CAAC;IACtD,KAAK,GAAqB;QACjC,UAAU;QACV,cAAc;QACd,WAAW;QACX,YAAY;QACZ,UAAU;QACV,cAAc;QACd,WAAW;QACX,cAAc;QACd,cAAc;QACd,WAAW;QACX,aAAa;QACb,WAAW;QACX,aAAa;QACb,eAAe;QACf,oBAAoB;QACpB,UAAU;QACV,WAAW;KACZ,CAAC;IAEF,KAAK,CAAC,OAAO;QACX,IAAI,eAAe,EAAE;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,WAAW,EAAE,CAAC;IACvB,CAAC;CACF;AAED,eAAe,IAAI,aAAa,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ export declare const isAuthenticated: () => boolean;
2
+ export declare const waitForAuth: () => Promise<boolean>;
3
+ /**
4
+ * Make an authenticated request to Microsoft mail APIs.
5
+ * Automatically uses whichever API the current token supports (Graph or Outlook REST).
6
+ */
7
+ export declare const api: <T>(endpoint: string, options?: {
8
+ method?: string;
9
+ body?: unknown;
10
+ query?: Record<string, string | number | boolean | undefined>;
11
+ headers?: Record<string, string>;
12
+ }) => Promise<T>;
13
+ //# sourceMappingURL=outlook-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlook-api.d.ts","sourceRoot":"","sources":["../src/outlook-api.ts"],"names":[],"mappings":"AAwIA,eAAO,MAAM,eAAe,QAAO,OAIlC,CAAC;AAEF,eAAO,MAAM,WAAW,QAAO,OAAO,CAAC,OAAO,CAI3C,CAAC;AAqBJ;;;GAGG;AACH,eAAO,MAAM,GAAG,GAAU,CAAC,EACzB,UAAU,MAAM,EAChB,UAAS;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B,KACL,OAAO,CAAC,CAAC,CAuFX,CAAC"}
@@ -0,0 +1,231 @@
1
+ import { ToolError, buildQueryString, clearAuthCache, findLocalStorageEntry, getAuthCache, getLocalStorage, setAuthCache, waitUntil, } from '@opentabs-dev/plugin-sdk';
2
+ const GRAPH_API_BASE = 'https://graph.microsoft.com/v1.0';
3
+ const OUTLOOK_API_BASE = 'https://outlook.office.com/api/v2.0';
4
+ // Outlook enterprise MSAL client ID
5
+ const MSAL_CLIENT_ID = '9199bf20-a13f-4107-85dc-02114787ef48';
6
+ // Consumer fallback
7
+ const MSAL_CLIENT_ID_CONSUMER = '2821b473-fe24-4c86-ba16-62834d6e80c3';
8
+ /**
9
+ * Search MSAL v2 token cache for a valid access token matching a target scope pattern.
10
+ */
11
+ const findMsalV2Token = (clientId, scopeMatch) => {
12
+ const tokenKeysRaw = getLocalStorage(`msal.2.token.keys.${clientId}`);
13
+ if (!tokenKeysRaw)
14
+ return null;
15
+ let tokenKeys;
16
+ try {
17
+ tokenKeys = JSON.parse(tokenKeysRaw);
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ if (!tokenKeys.accessToken)
23
+ return null;
24
+ for (const key of tokenKeys.accessToken) {
25
+ const raw = getLocalStorage(key);
26
+ if (!raw)
27
+ continue;
28
+ try {
29
+ const parsed = JSON.parse(raw);
30
+ if (!parsed.secret)
31
+ continue;
32
+ const target = parsed.target ?? '';
33
+ const matches = target.toLowerCase().includes(scopeMatch) || key.toLowerCase().includes(scopeMatch);
34
+ if (!matches)
35
+ continue;
36
+ const expiresOn = Number.parseInt(parsed.expiresOn, 10);
37
+ if (expiresOn && expiresOn * 1000 < Date.now())
38
+ continue;
39
+ const apiBase = scopeMatch.includes('graph.microsoft.com') ? GRAPH_API_BASE : OUTLOOK_API_BASE;
40
+ return { token: parsed.secret, apiBase };
41
+ }
42
+ catch {
43
+ // skip invalid entries
44
+ }
45
+ }
46
+ return null;
47
+ };
48
+ /**
49
+ * Search MSAL v1 token cache for a valid Graph API access token.
50
+ */
51
+ const findMsalV1Token = (clientId) => {
52
+ const tokenKeysRaw = getLocalStorage(`msal.token.keys.${clientId}`);
53
+ if (!tokenKeysRaw)
54
+ return null;
55
+ let tokenKeys;
56
+ try {
57
+ tokenKeys = JSON.parse(tokenKeysRaw);
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ if (!tokenKeys.accessToken)
63
+ return null;
64
+ for (const key of tokenKeys.accessToken) {
65
+ if (!key.includes('graph.microsoft.com'))
66
+ continue;
67
+ const raw = getLocalStorage(key);
68
+ if (!raw)
69
+ continue;
70
+ try {
71
+ const parsed = JSON.parse(raw);
72
+ if (!parsed.secret)
73
+ continue;
74
+ const expiresOn = Number.parseInt(parsed.expiresOn, 10);
75
+ if (expiresOn && expiresOn * 1000 < Date.now())
76
+ continue;
77
+ return { token: parsed.secret, apiBase: GRAPH_API_BASE };
78
+ }
79
+ catch {
80
+ // skip invalid entries
81
+ }
82
+ }
83
+ return null;
84
+ };
85
+ /**
86
+ * Extract a valid access token from MSAL localStorage cache.
87
+ * Priority: Graph API token > Outlook REST API token.
88
+ * Supports MSAL v2 (enterprise) and v1 (consumer) formats.
89
+ */
90
+ const getAuth = () => {
91
+ const cached = getAuthCache('outlook');
92
+ if (cached)
93
+ return cached;
94
+ // 1. Enterprise MSAL v2 — Graph API token
95
+ let auth = findMsalV2Token(MSAL_CLIENT_ID, 'graph.microsoft.com');
96
+ // 2. Enterprise MSAL v2 — Outlook REST API token (has mail.readwrite scopes)
97
+ if (!auth)
98
+ auth = findMsalV2Token(MSAL_CLIENT_ID, 'outlook.office.com');
99
+ // 3. Consumer MSAL v1 — Graph API token
100
+ if (!auth)
101
+ auth = findMsalV1Token(MSAL_CLIENT_ID_CONSUMER);
102
+ // 4. Fallback: scan for any MSAL v2 entry with Graph scope
103
+ if (!auth) {
104
+ const entry = findLocalStorageEntry(key => key.startsWith('msal.2.token.keys.'));
105
+ if (entry) {
106
+ const cid = entry.key.replace('msal.2.token.keys.', '');
107
+ auth = findMsalV2Token(cid, 'graph.microsoft.com');
108
+ if (!auth)
109
+ auth = findMsalV2Token(cid, 'outlook.office.com');
110
+ }
111
+ }
112
+ // 5. Fallback: scan for any MSAL v1 entry
113
+ if (!auth) {
114
+ const entry = findLocalStorageEntry(key => key.startsWith('msal.token.keys.'));
115
+ if (entry) {
116
+ const cid = entry.key.replace('msal.token.keys.', '');
117
+ auth = findMsalV1Token(cid);
118
+ }
119
+ }
120
+ if (auth)
121
+ setAuthCache('outlook', auth);
122
+ return auth;
123
+ };
124
+ export const isAuthenticated = () => {
125
+ if (getAuth() !== null)
126
+ return true;
127
+ // Fallback: Outlook sets olk-isauthed=1 when the user is signed in
128
+ return getLocalStorage('olk-isauthed') === '1';
129
+ };
130
+ export const waitForAuth = () => waitUntil(() => isAuthenticated(), { interval: 500, timeout: 5000 }).then(() => true, () => false);
131
+ /**
132
+ * Recursively convert PascalCase keys to camelCase.
133
+ * Outlook REST API returns PascalCase; Graph returns camelCase.
134
+ * Normalizing to camelCase lets all mappers work with both APIs.
135
+ */
136
+ const toCamelCase = (str) => str.charAt(0).toLowerCase() + str.slice(1);
137
+ const normalizeKeys = (obj) => {
138
+ if (obj === null || obj === undefined || typeof obj !== 'object')
139
+ return obj;
140
+ if (Array.isArray(obj))
141
+ return obj.map(normalizeKeys);
142
+ const result = {};
143
+ for (const [key, value] of Object.entries(obj)) {
144
+ // Skip OData metadata keys like @odata.context
145
+ const newKey = key.startsWith('@') ? key : toCamelCase(key);
146
+ result[newKey] = normalizeKeys(value);
147
+ }
148
+ return result;
149
+ };
150
+ /**
151
+ * Make an authenticated request to Microsoft mail APIs.
152
+ * Automatically uses whichever API the current token supports (Graph or Outlook REST).
153
+ */
154
+ export const api = async (endpoint, options = {}) => {
155
+ const auth = getAuth();
156
+ if (!auth)
157
+ throw ToolError.auth('Not authenticated — please sign in to Microsoft 365.');
158
+ const isOutlookApi = auth.apiBase === OUTLOOK_API_BASE;
159
+ // Outlook REST API uses different $select field names, so drop $select
160
+ // and let it return all fields. The normalizeKeys step handles casing.
161
+ const query = options.query ? { ...options.query } : undefined;
162
+ if (isOutlookApi && query) {
163
+ delete query.$select;
164
+ }
165
+ const qs = query ? buildQueryString(query) : '';
166
+ const url = qs ? `${auth.apiBase}${endpoint}?${qs}` : `${auth.apiBase}${endpoint}`;
167
+ const method = options.method ?? 'GET';
168
+ const headers = {
169
+ Authorization: `Bearer ${auth.token}`,
170
+ ...options.headers,
171
+ };
172
+ const init = { method, headers };
173
+ if (options.body) {
174
+ headers['Content-Type'] = 'application/json';
175
+ init.body = JSON.stringify(options.body);
176
+ }
177
+ let response;
178
+ try {
179
+ response = await fetch(url, {
180
+ ...init,
181
+ credentials: 'omit',
182
+ signal: AbortSignal.timeout(30_000),
183
+ });
184
+ }
185
+ catch (err) {
186
+ if (err instanceof DOMException && err.name === 'TimeoutError') {
187
+ throw ToolError.timeout('Microsoft API request timed out.');
188
+ }
189
+ if (err instanceof DOMException && err.name === 'AbortError') {
190
+ throw new ToolError('Request aborted', 'aborted');
191
+ }
192
+ throw new ToolError(`Network error: ${err instanceof Error ? err.message : 'unknown'}`, 'network_error', {
193
+ category: 'internal',
194
+ retryable: true,
195
+ });
196
+ }
197
+ if (response.status === 204)
198
+ return {};
199
+ if (response.status === 429) {
200
+ const retryAfter = response.headers.get('Retry-After');
201
+ const retryMs = retryAfter ? Number.parseInt(retryAfter, 10) * 1000 : undefined;
202
+ throw ToolError.rateLimited('Microsoft API rate limit exceeded.', retryMs);
203
+ }
204
+ if (response.status === 401 || response.status === 403) {
205
+ clearAuthCache('outlook');
206
+ throw ToolError.auth('Authentication expired — please refresh the Outlook page.');
207
+ }
208
+ if (response.status === 404) {
209
+ throw ToolError.notFound('The requested resource was not found.');
210
+ }
211
+ if (!response.ok) {
212
+ let errorMsg = `Microsoft API error (${response.status})`;
213
+ try {
214
+ const errBody = (await response.json());
215
+ if (errBody.error?.message) {
216
+ errorMsg = errBody.error.message;
217
+ }
218
+ }
219
+ catch {
220
+ // ignore parse errors
221
+ }
222
+ if (response.status === 400 || response.status === 422) {
223
+ throw ToolError.validation(errorMsg);
224
+ }
225
+ throw ToolError.internal(errorMsg);
226
+ }
227
+ const json = await response.json();
228
+ // Normalize PascalCase keys from Outlook REST API to camelCase
229
+ return (isOutlookApi ? normalizeKeys(json) : json);
230
+ };
231
+ //# sourceMappingURL=outlook-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlook-api.js","sourceRoot":"","sources":["../src/outlook-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod';
2
+ export declare const createDraft: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{
3
+ to: z.ZodArray<z.ZodString>;
4
+ subject: z.ZodString;
5
+ body: z.ZodString;
6
+ body_type: z.ZodOptional<z.ZodEnum<{
7
+ text: "text";
8
+ html: "html";
9
+ }>>;
10
+ cc: z.ZodOptional<z.ZodArray<z.ZodString>>;
11
+ bcc: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
+ importance: z.ZodOptional<z.ZodEnum<{
13
+ low: "low";
14
+ normal: "normal";
15
+ high: "high";
16
+ }>>;
17
+ }, z.core.$strip>, z.ZodObject<{
18
+ draft_id: z.ZodString;
19
+ web_link: z.ZodString;
20
+ }, z.core.$strip>>;
21
+ //# sourceMappingURL=create-draft.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-draft.d.ts","sourceRoot":"","sources":["../../src/tools/create-draft.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;kBA2CtB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { defineTool } from '@opentabs-dev/plugin-sdk';
2
+ import { z } from 'zod';
3
+ import { api } from '../outlook-api.js';
4
+ export const createDraft = defineTool({
5
+ name: 'create_draft',
6
+ displayName: 'Create Draft',
7
+ description: 'Create a draft email message in the Drafts folder. The user can review and send it manually from Outlook.',
8
+ summary: 'Create a draft email',
9
+ icon: 'file-edit',
10
+ group: 'Messages',
11
+ input: z.object({
12
+ to: z.array(z.string()).describe('Recipient email addresses'),
13
+ subject: z.string().describe('Email subject'),
14
+ body: z.string().describe('Email body content'),
15
+ body_type: z.enum(['text', 'html']).optional().describe('Body content type (default: text)'),
16
+ cc: z.array(z.string()).optional().describe('CC recipient email addresses'),
17
+ bcc: z.array(z.string()).optional().describe('BCC recipient email addresses'),
18
+ importance: z.enum(['low', 'normal', 'high']).optional().describe('Importance level'),
19
+ }),
20
+ output: z.object({
21
+ draft_id: z.string().describe('The created draft message ID'),
22
+ web_link: z.string().describe('Link to open the draft in Outlook'),
23
+ }),
24
+ handle: async (params) => {
25
+ const toRecipients = (addrs) => addrs.map(addr => ({ emailAddress: { address: addr } }));
26
+ const data = await api('/me/messages', {
27
+ method: 'POST',
28
+ body: {
29
+ subject: params.subject,
30
+ body: {
31
+ contentType: params.body_type === 'html' ? 'HTML' : 'Text',
32
+ content: params.body,
33
+ },
34
+ toRecipients: toRecipients(params.to),
35
+ ccRecipients: params.cc ? toRecipients(params.cc) : undefined,
36
+ bccRecipients: params.bcc ? toRecipients(params.bcc) : undefined,
37
+ importance: params.importance,
38
+ },
39
+ });
40
+ return {
41
+ draft_id: data.id ?? '',
42
+ web_link: data.webLink ?? '',
43
+ };
44
+ },
45
+ });
46
+ //# sourceMappingURL=create-draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-draft.js","sourceRoot":"","sources":["../../src/tools/create-draft.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;IACpC,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,cAAc;IAC3B,WAAW,EACT,2GAA2G;IAC7G,OAAO,EAAE,sBAAsB;IAC/B,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAC7D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC7C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAC/C,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QAC5F,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAC3E,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;QAC7E,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;KACtF,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAC7D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;KACnE,CAAC;IACF,MAAM,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QACrB,MAAM,YAAY,GAAG,CAAC,KAAe,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAEnG,MAAM,IAAI,GAAG,MAAM,GAAG,CAAmC,cAAc,EAAE;YACvE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE;gBACJ,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE;oBACJ,WAAW,EAAE,MAAM,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;oBAC1D,OAAO,EAAE,MAAM,CAAC,IAAI;iBACrB;gBACD,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrC,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC7D,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;gBAChE,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B;SACF,CAAC,CAAC;QACH,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;YACvB,QAAQ,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;SAC7B,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { z } from 'zod';
2
+ export declare const deleteMessage: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{
3
+ message_id: z.ZodString;
4
+ }, z.core.$strip>, z.ZodObject<{
5
+ success: z.ZodBoolean;
6
+ }, z.core.$strip>>;
7
+ //# sourceMappingURL=delete-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-message.d.ts","sourceRoot":"","sources":["../../src/tools/delete-message.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,aAAa;;;;kBAiBxB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { defineTool } from '@opentabs-dev/plugin-sdk';
2
+ import { z } from 'zod';
3
+ import { api } from '../outlook-api.js';
4
+ export const deleteMessage = defineTool({
5
+ name: 'delete_message',
6
+ displayName: 'Delete Message',
7
+ description: 'Delete an email message. This moves it to Deleted Items (not permanent deletion).',
8
+ summary: 'Delete an email',
9
+ icon: 'trash-2',
10
+ group: 'Messages',
11
+ input: z.object({
12
+ message_id: z.string().describe('The message ID to delete'),
13
+ }),
14
+ output: z.object({
15
+ success: z.boolean().describe('Whether the message was deleted'),
16
+ }),
17
+ handle: async (params) => {
18
+ await api(`/me/messages/${params.message_id}`, { method: 'DELETE' });
19
+ return { success: true };
20
+ },
21
+ });
22
+ //# sourceMappingURL=delete-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-message.js","sourceRoot":"","sources":["../../src/tools/delete-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;IACtC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,gBAAgB;IAC7B,WAAW,EAAE,mFAAmF;IAChG,OAAO,EAAE,iBAAiB;IAC1B,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;KAC5D,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;KACjE,CAAC;IACF,MAAM,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QACrB,MAAM,GAAG,CAAC,gBAAgB,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export declare const forwardMessage: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{
3
+ message_id: z.ZodString;
4
+ to: z.ZodArray<z.ZodString>;
5
+ comment: z.ZodOptional<z.ZodString>;
6
+ }, z.core.$strip>, z.ZodObject<{
7
+ success: z.ZodBoolean;
8
+ }, z.core.$strip>>;
9
+ //# sourceMappingURL=forward-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forward-message.d.ts","sourceRoot":"","sources":["../../src/tools/forward-message.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,cAAc;;;;;;kBAyBzB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { defineTool } from '@opentabs-dev/plugin-sdk';
2
+ import { z } from 'zod';
3
+ import { api } from '../outlook-api.js';
4
+ export const forwardMessage = defineTool({
5
+ name: 'forward_message',
6
+ displayName: 'Forward Message',
7
+ description: 'Forward an email message to one or more recipients with an optional comment.',
8
+ summary: 'Forward an email',
9
+ icon: 'forward',
10
+ group: 'Messages',
11
+ input: z.object({
12
+ message_id: z.string().describe('The message ID to forward'),
13
+ to: z.array(z.string()).describe('Recipient email addresses'),
14
+ comment: z.string().optional().describe('Optional comment to include above the forwarded message'),
15
+ }),
16
+ output: z.object({
17
+ success: z.boolean().describe('Whether the message was forwarded'),
18
+ }),
19
+ handle: async (params) => {
20
+ await api(`/me/messages/${params.message_id}/forward`, {
21
+ method: 'POST',
22
+ body: {
23
+ comment: params.comment ?? '',
24
+ toRecipients: params.to.map(addr => ({ emailAddress: { address: addr } })),
25
+ },
26
+ });
27
+ return { success: true };
28
+ },
29
+ });
30
+ //# sourceMappingURL=forward-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forward-message.js","sourceRoot":"","sources":["../../src/tools/forward-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;IACvC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,iBAAiB;IAC9B,WAAW,EAAE,8EAA8E;IAC3F,OAAO,EAAE,kBAAkB;IAC3B,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAC5D,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAC7D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;KACnG,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;KACnE,CAAC;IACF,MAAM,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QACrB,MAAM,GAAG,CAAC,gBAAgB,MAAM,CAAC,UAAU,UAAU,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE;gBACJ,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;gBAC7B,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;aAC3E;SACF,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { z } from 'zod';
2
+ export declare const getAttachmentContent: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{
3
+ message_id: z.ZodString;
4
+ attachment_id: z.ZodString;
5
+ }, z.core.$strip>, z.ZodObject<{
6
+ name: z.ZodString;
7
+ content_type: z.ZodString;
8
+ size: z.ZodNumber;
9
+ encoding: z.ZodEnum<{
10
+ text: "text";
11
+ base64: "base64";
12
+ }>;
13
+ content: z.ZodString;
14
+ }, z.core.$strip>>;
15
+ //# sourceMappingURL=get-attachment-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-attachment-content.d.ts","sourceRoot":"","sources":["../../src/tools/get-attachment-content.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;kBAsE/B,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { defineTool } from '@opentabs-dev/plugin-sdk';
2
+ import { z } from 'zod';
3
+ import { api } from '../outlook-api.js';
4
+ export const getAttachmentContent = defineTool({
5
+ name: 'get_attachment_content',
6
+ displayName: 'Get Attachment Content',
7
+ description: 'Download and read the content of an email attachment. For text-based files (plain text, CSV, HTML, JSON, XML), returns decoded text. For binary files (PDF, images, Office documents), returns base64-encoded content.',
8
+ summary: 'Get attachment content',
9
+ icon: 'file-down',
10
+ group: 'Messages',
11
+ input: z.object({
12
+ message_id: z.string().describe('The message ID'),
13
+ attachment_id: z.string().describe('The attachment ID (from list_attachments)'),
14
+ }),
15
+ output: z.object({
16
+ name: z.string().describe('File name'),
17
+ content_type: z.string().describe('MIME type'),
18
+ size: z.number().describe('Size in bytes'),
19
+ encoding: z.enum(['text', 'base64']).describe('Content encoding — text for readable files, base64 for binary'),
20
+ content: z.string().describe('File content (decoded text or base64 string)'),
21
+ }),
22
+ handle: async (params) => {
23
+ const data = await api(`/me/messages/${params.message_id}/attachments/${params.attachment_id}`, {
24
+ query: { $select: 'id,name,contentType,size,isInline,contentBytes' },
25
+ });
26
+ const name = data.name ?? '';
27
+ const contentType = data.contentType ?? 'application/octet-stream';
28
+ const size = data.size ?? 0;
29
+ const contentBytes = data.contentBytes ?? '';
30
+ // Determine if this is a text-based file we can decode
31
+ const isText = contentType.startsWith('text/') ||
32
+ contentType.includes('+json') ||
33
+ contentType.includes('+xml') ||
34
+ contentType === 'application/json' ||
35
+ contentType === 'application/xml' ||
36
+ contentType === 'application/csv' ||
37
+ contentType === 'application/javascript' ||
38
+ contentType === 'application/yaml' ||
39
+ name.endsWith('.csv') ||
40
+ name.endsWith('.json') ||
41
+ name.endsWith('.xml') ||
42
+ name.endsWith('.txt') ||
43
+ name.endsWith('.md') ||
44
+ name.endsWith('.html') ||
45
+ name.endsWith('.htm') ||
46
+ name.endsWith('.yaml') ||
47
+ name.endsWith('.yml') ||
48
+ name.endsWith('.js') ||
49
+ name.endsWith('.ts') ||
50
+ name.endsWith('.py') ||
51
+ name.endsWith('.sh');
52
+ let content;
53
+ let encoding;
54
+ if (isText && contentBytes) {
55
+ const bytes = Uint8Array.from(atob(contentBytes), c => c.charCodeAt(0));
56
+ content = new TextDecoder().decode(bytes);
57
+ encoding = 'text';
58
+ }
59
+ else {
60
+ content = contentBytes;
61
+ encoding = 'base64';
62
+ }
63
+ return { name, content_type: contentType, size, encoding, content };
64
+ },
65
+ });
66
+ //# sourceMappingURL=get-attachment-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-attachment-content.js","sourceRoot":"","sources":["../../src/tools/get-attachment-content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export declare const getCurrentUser: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
3
+ user: z.ZodObject<{
4
+ id: z.ZodString;
5
+ display_name: z.ZodString;
6
+ email: z.ZodString;
7
+ }, z.core.$strip>;
8
+ }, z.core.$strip>>;
9
+ //# sourceMappingURL=get-current-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-current-user.d.ts","sourceRoot":"","sources":["../../src/tools/get-current-user.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,cAAc;;;;;;kBAezB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { defineTool } from '@opentabs-dev/plugin-sdk';
2
+ import { z } from 'zod';
3
+ import { api } from '../outlook-api.js';
4
+ import { mapUser, userSchema } from './schemas.js';
5
+ export const getCurrentUser = defineTool({
6
+ name: 'get_current_user',
7
+ displayName: 'Get Current User',
8
+ description: 'Get the profile of the currently authenticated Microsoft 365 user including name and email.',
9
+ summary: 'Get the current user profile',
10
+ icon: 'user',
11
+ group: 'Account',
12
+ input: z.object({}),
13
+ output: z.object({ user: userSchema }),
14
+ handle: async () => {
15
+ const data = await api('/me', {
16
+ query: { $select: 'id,displayName,mail,userPrincipalName' },
17
+ });
18
+ return { user: mapUser(data) };
19
+ },
20
+ });
21
+ //# sourceMappingURL=get-current-user.js.map