@littlebearapps/outlook-assistant 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +22 -0
- package/LICENSE +21 -0
- package/README.md +422 -0
- package/advanced/index.js +652 -0
- package/auth/index.js +32 -0
- package/auth/oauth-server.js +233 -0
- package/auth/token-manager.js +105 -0
- package/auth/token-storage.js +359 -0
- package/auth/tools.js +159 -0
- package/calendar/accept.js +72 -0
- package/calendar/cancel.js +72 -0
- package/calendar/create.js +115 -0
- package/calendar/decline.js +72 -0
- package/calendar/delete.js +67 -0
- package/calendar/index.js +130 -0
- package/calendar/list.js +108 -0
- package/categories/index.js +955 -0
- package/config.js +95 -0
- package/contacts/index.js +754 -0
- package/email/attachments.js +365 -0
- package/email/conversations.js +666 -0
- package/email/delta.js +210 -0
- package/email/export.js +572 -0
- package/email/folder-utils.js +192 -0
- package/email/headers.js +344 -0
- package/email/index.js +537 -0
- package/email/list.js +136 -0
- package/email/mark-as-read.js +114 -0
- package/email/mime.js +286 -0
- package/email/read.js +161 -0
- package/email/search.js +628 -0
- package/email/send.js +169 -0
- package/folder/create.js +137 -0
- package/folder/delete.js +108 -0
- package/folder/index.js +112 -0
- package/folder/list.js +289 -0
- package/folder/move.js +186 -0
- package/folder/stats.js +322 -0
- package/index.js +162 -0
- package/llms.txt +76 -0
- package/outlook-auth-server.js +384 -0
- package/package.json +97 -0
- package/rules/create.js +273 -0
- package/rules/index.js +276 -0
- package/rules/list.js +216 -0
- package/settings/index.js +678 -0
- package/utils/field-presets.js +311 -0
- package/utils/graph-api.js +268 -0
- package/utils/mock-data.js +154 -0
- package/utils/odata-helpers.js +33 -0
- package/utils/response-formatter.js +457 -0
- package/utils/safety.js +123 -0
package/rules/list.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List rules functionality
|
|
3
|
+
*/
|
|
4
|
+
const { callGraphAPI } = require('../utils/graph-api');
|
|
5
|
+
const { ensureAuthenticated } = require('../auth');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* List rules handler
|
|
9
|
+
* @param {object} args - Tool arguments
|
|
10
|
+
* @returns {object} - MCP response
|
|
11
|
+
*/
|
|
12
|
+
async function handleListRules(args) {
|
|
13
|
+
const includeDetails = args.includeDetails === true;
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
// Get access token
|
|
17
|
+
const accessToken = await ensureAuthenticated();
|
|
18
|
+
|
|
19
|
+
// Get all inbox rules
|
|
20
|
+
const rules = await getInboxRules(accessToken);
|
|
21
|
+
|
|
22
|
+
// Format the rules based on detail level
|
|
23
|
+
const formattedRules = formatRulesList(rules, includeDetails);
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: 'text',
|
|
29
|
+
text: formattedRules,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if (error.message === 'Authentication required') {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: 'text',
|
|
39
|
+
text: "Authentication required. Please use the 'authenticate' tool first.",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: 'text',
|
|
49
|
+
text: `Error listing rules: ${error.message}`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get all inbox rules
|
|
58
|
+
* @param {string} accessToken - Access token
|
|
59
|
+
* @returns {Promise<Array>} - Array of rule objects
|
|
60
|
+
*/
|
|
61
|
+
async function getInboxRules(accessToken) {
|
|
62
|
+
try {
|
|
63
|
+
const response = await callGraphAPI(
|
|
64
|
+
accessToken,
|
|
65
|
+
'GET',
|
|
66
|
+
'me/mailFolders/inbox/messageRules',
|
|
67
|
+
null
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return response.value || [];
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error(`Error getting inbox rules: ${error.message}`);
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Format rules list for display
|
|
79
|
+
* @param {Array} rules - Array of rule objects
|
|
80
|
+
* @param {boolean} includeDetails - Whether to include detailed conditions and actions
|
|
81
|
+
* @returns {string} - Formatted rules list
|
|
82
|
+
*/
|
|
83
|
+
function formatRulesList(rules, includeDetails) {
|
|
84
|
+
if (!rules || rules.length === 0) {
|
|
85
|
+
return "No inbox rules found.\n\nTip: You can create rules using the 'create-rule' tool. Rules are processed in order of their sequence number (lower numbers are processed first).";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Sort rules by sequence to show execution order
|
|
89
|
+
const sortedRules = [...rules].sort((a, b) => {
|
|
90
|
+
return (a.sequence || 9999) - (b.sequence || 9999);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Format rules based on detail level
|
|
94
|
+
if (includeDetails) {
|
|
95
|
+
// Detailed format
|
|
96
|
+
const detailedRules = sortedRules.map((rule) => {
|
|
97
|
+
// Format rule header with sequence
|
|
98
|
+
let ruleText = `[${rule.sequence || 'N/A'}] ${rule.displayName}${rule.isEnabled ? '' : ' (Disabled)'}`;
|
|
99
|
+
|
|
100
|
+
// Format conditions
|
|
101
|
+
const conditions = formatRuleConditions(rule);
|
|
102
|
+
if (conditions) {
|
|
103
|
+
ruleText += `\n Conditions: ${conditions}`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Format actions
|
|
107
|
+
const actions = formatRuleActions(rule);
|
|
108
|
+
if (actions) {
|
|
109
|
+
ruleText += `\n Actions: ${actions}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return ruleText;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return `Found ${rules.length} inbox rules (sorted by execution order):\n\n${detailedRules.join('\n\n')}\n\nRules are processed in order of their sequence number. You can change rule order using manage-rules with action=reorder.`;
|
|
116
|
+
} else {
|
|
117
|
+
// Simple format
|
|
118
|
+
const simpleRules = sortedRules.map((rule) => {
|
|
119
|
+
return `[${rule.sequence || 'N/A'}] ${rule.displayName}${rule.isEnabled ? '' : ' (Disabled)'}`;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
return `Found ${rules.length} inbox rules (sorted by execution order):\n\n${simpleRules.join('\n')}\n\nTip: Use 'list-rules with includeDetails=true' to see more information about each rule.`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Format rule conditions for display
|
|
128
|
+
* @param {object} rule - Rule object
|
|
129
|
+
* @returns {string} - Formatted conditions
|
|
130
|
+
*/
|
|
131
|
+
function formatRuleConditions(rule) {
|
|
132
|
+
const conditions = [];
|
|
133
|
+
|
|
134
|
+
// From addresses
|
|
135
|
+
if (rule.conditions?.fromAddresses?.length > 0) {
|
|
136
|
+
const senders = rule.conditions.fromAddresses
|
|
137
|
+
.map((addr) => addr.emailAddress.address)
|
|
138
|
+
.join(', ');
|
|
139
|
+
conditions.push(`From: ${senders}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Subject contains
|
|
143
|
+
if (rule.conditions?.subjectContains?.length > 0) {
|
|
144
|
+
conditions.push(
|
|
145
|
+
`Subject contains: "${rule.conditions.subjectContains.join(', ')}"`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Contains body text
|
|
150
|
+
if (rule.conditions?.bodyContains?.length > 0) {
|
|
151
|
+
conditions.push(
|
|
152
|
+
`Body contains: "${rule.conditions.bodyContains.join(', ')}"`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Has attachment
|
|
157
|
+
if (rule.conditions?.hasAttachment === true) {
|
|
158
|
+
conditions.push('Has attachment');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Importance
|
|
162
|
+
if (rule.conditions?.importance) {
|
|
163
|
+
conditions.push(`Importance: ${rule.conditions.importance}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return conditions.join('; ');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Format rule actions for display
|
|
171
|
+
* @param {object} rule - Rule object
|
|
172
|
+
* @returns {string} - Formatted actions
|
|
173
|
+
*/
|
|
174
|
+
function formatRuleActions(rule) {
|
|
175
|
+
const actions = [];
|
|
176
|
+
|
|
177
|
+
// Move to folder
|
|
178
|
+
if (rule.actions?.moveToFolder) {
|
|
179
|
+
actions.push(`Move to folder: ${rule.actions.moveToFolder}`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Copy to folder
|
|
183
|
+
if (rule.actions?.copyToFolder) {
|
|
184
|
+
actions.push(`Copy to folder: ${rule.actions.copyToFolder}`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Mark as read
|
|
188
|
+
if (rule.actions?.markAsRead === true) {
|
|
189
|
+
actions.push('Mark as read');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Mark importance
|
|
193
|
+
if (rule.actions?.markImportance) {
|
|
194
|
+
actions.push(`Mark importance: ${rule.actions.markImportance}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Forward
|
|
198
|
+
if (rule.actions?.forwardTo?.length > 0) {
|
|
199
|
+
const recipients = rule.actions.forwardTo
|
|
200
|
+
.map((r) => r.emailAddress.address)
|
|
201
|
+
.join(', ');
|
|
202
|
+
actions.push(`Forward to: ${recipients}`);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Delete
|
|
206
|
+
if (rule.actions?.delete === true) {
|
|
207
|
+
actions.push('Delete');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return actions.join('; ');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
module.exports = {
|
|
214
|
+
handleListRules,
|
|
215
|
+
getInboxRules,
|
|
216
|
+
};
|