@tgai96/outlook-mcp 1.0.1 → 1.1.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/README.md +33 -12
- package/auth/tools.js +11 -2
- package/config.js +1 -1
- package/email/date-utils.js +21 -0
- package/email/list.js +4 -3
- package/email/read.js +3 -2
- package/email/search.js +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -133,13 +133,23 @@ To use this MCP server with an MCP client, you can either use the published npm
|
|
|
133
133
|
|
|
134
134
|
#### Option 1: Using Published npm Package (Recommended)
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
**To use the current package as-is**, use `@tgai96/outlook-mcp`:
|
|
137
137
|
|
|
138
138
|
```json
|
|
139
|
-
|
|
139
|
+
{
|
|
140
|
+
"mcpServers": {
|
|
141
|
+
"outlook": {
|
|
142
|
+
"command": "npx",
|
|
143
|
+
"args": [
|
|
144
|
+
"-y",
|
|
145
|
+
"@tgai96/outlook-mcp"
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
140
150
|
```
|
|
141
151
|
|
|
142
|
-
**
|
|
152
|
+
**To create and publish your own version**, replace `@tgai96/outlook-mcp` with your own package name and follow the [Publishing to npm](#publishing-to-npm) guide below.
|
|
143
153
|
|
|
144
154
|
#### Option 2: Using Local Installation
|
|
145
155
|
|
|
@@ -344,29 +354,36 @@ If you see "Access is denied" errors:
|
|
|
344
354
|
|
|
345
355
|
## Publishing to npm
|
|
346
356
|
|
|
347
|
-
To publish this package to npm:
|
|
357
|
+
To publish this package to npm under your own namespace:
|
|
348
358
|
|
|
349
|
-
1. **Update package.json metadata
|
|
350
|
-
- `name` field
|
|
351
|
-
- `author` field
|
|
359
|
+
1. **Update package.json metadata**:
|
|
360
|
+
- Update the `name` field to your desired package name (e.g., `@your-username/outlook-mcp` or `outlook-mcp`)
|
|
361
|
+
- Update the `author` field with your name/username
|
|
352
362
|
- Optionally add `repository`, `bugs`, and `homepage` fields if you have a GitHub repo
|
|
363
|
+
- Update the `version` field (following semantic versioning)
|
|
353
364
|
|
|
354
365
|
2. **Login to npm**:
|
|
355
366
|
```bash
|
|
356
367
|
npm login
|
|
357
368
|
```
|
|
369
|
+
|
|
370
|
+
Enter your npm username, password, and email when prompted.
|
|
358
371
|
|
|
359
|
-
3. **
|
|
372
|
+
3. **Verify what will be published** (recommended):
|
|
360
373
|
```bash
|
|
361
|
-
npm
|
|
374
|
+
npm pack --dry-run
|
|
362
375
|
```
|
|
363
376
|
|
|
364
|
-
|
|
377
|
+
This shows which files will be included in the package (based on the `files` field in `package.json`).
|
|
378
|
+
|
|
379
|
+
4. **Publish to npm**:
|
|
380
|
+
|
|
381
|
+
For scoped packages (packages starting with `@username/`), use:
|
|
365
382
|
```bash
|
|
366
383
|
npm publish --access public
|
|
367
384
|
```
|
|
368
385
|
|
|
369
|
-
|
|
386
|
+
5. **After publishing**, users can use it in their MCP client configuration:
|
|
370
387
|
```json
|
|
371
388
|
{
|
|
372
389
|
"mcpServers": {
|
|
@@ -374,12 +391,16 @@ To publish this package to npm:
|
|
|
374
391
|
"command": "npx",
|
|
375
392
|
"args": [
|
|
376
393
|
"-y",
|
|
377
|
-
"@
|
|
394
|
+
"@your-username/outlook-mcp"
|
|
378
395
|
]
|
|
379
396
|
}
|
|
380
397
|
}
|
|
381
398
|
}
|
|
382
399
|
```
|
|
400
|
+
|
|
401
|
+
Replace `@your-username/outlook-mcp` with your actual published package name.
|
|
402
|
+
|
|
403
|
+
**Note**: Make sure to review the `files` field in `package.json` to ensure only necessary files are published (sensitive files, test files, and development scripts should be excluded).
|
|
383
404
|
|
|
384
405
|
## License
|
|
385
406
|
|
package/auth/tools.js
CHANGED
|
@@ -3,7 +3,15 @@
|
|
|
3
3
|
*/
|
|
4
4
|
const config = require('../config');
|
|
5
5
|
const tokenManager = require('./token-manager');
|
|
6
|
-
|
|
6
|
+
// Lazy load to avoid circular dependency with ./index
|
|
7
|
+
let ensureAuthenticated = null;
|
|
8
|
+
function getEnsureAuthenticated() {
|
|
9
|
+
if (!ensureAuthenticated) {
|
|
10
|
+
const authModule = require('./index');
|
|
11
|
+
ensureAuthenticated = authModule.ensureAuthenticated;
|
|
12
|
+
}
|
|
13
|
+
return ensureAuthenticated;
|
|
14
|
+
}
|
|
7
15
|
|
|
8
16
|
/**
|
|
9
17
|
* About tool handler
|
|
@@ -42,7 +50,8 @@ async function handleAuthenticate(args) {
|
|
|
42
50
|
// If not forcing, try to get a valid token first (will auto-refresh if needed)
|
|
43
51
|
if (!force) {
|
|
44
52
|
try {
|
|
45
|
-
const
|
|
53
|
+
const ensureAuth = getEnsureAuthenticated();
|
|
54
|
+
const accessToken = await ensureAuth();
|
|
46
55
|
if (accessToken) {
|
|
47
56
|
console.error('[AUTHENTICATE] Successfully obtained valid access token (may have been refreshed)');
|
|
48
57
|
return {
|
package/config.js
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date formatting utilities for email module
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Format date to show both UTC and local time
|
|
7
|
+
* @param {string} dateTimeString - ISO 8601 date string from API
|
|
8
|
+
* @returns {string} - Formatted date string with UTC and local time
|
|
9
|
+
*/
|
|
10
|
+
function formatDateTime(dateTimeString) {
|
|
11
|
+
const date = new Date(dateTimeString);
|
|
12
|
+
const utcString = date.toUTCString();
|
|
13
|
+
const localString = date.toLocaleString();
|
|
14
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
15
|
+
return `${utcString} (UTC) / ${localString} (${timezone})`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
formatDateTime
|
|
20
|
+
};
|
|
21
|
+
|
package/email/list.js
CHANGED
|
@@ -5,11 +5,12 @@ const config = require('../config');
|
|
|
5
5
|
const { callGraphAPI, callGraphAPIPaginated } = require('../utils/graph-api');
|
|
6
6
|
const { ensureAuthenticated } = require('../auth');
|
|
7
7
|
const { resolveFolderPath } = require('./folder-utils');
|
|
8
|
+
const { formatDateTime } = require('./date-utils');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* List emails handler
|
|
11
12
|
* @param {object} args - Tool arguments
|
|
12
|
-
* @returns {object} - MCP response
|
|
13
|
+
* @returns {Promise<object>} - MCP response
|
|
13
14
|
*/
|
|
14
15
|
async function handleListEmails(args) {
|
|
15
16
|
const folder = args.folder || "inbox";
|
|
@@ -44,10 +45,10 @@ async function handleListEmails(args) {
|
|
|
44
45
|
// Format results
|
|
45
46
|
const emailList = response.value.map((email, index) => {
|
|
46
47
|
const sender = email.from ? email.from.emailAddress : { name: 'Unknown', address: 'unknown' };
|
|
47
|
-
const date =
|
|
48
|
+
const date = formatDateTime(email.receivedDateTime);
|
|
48
49
|
const readStatus = email.isRead ? '' : '[UNREAD] ';
|
|
49
50
|
|
|
50
|
-
return `${index + 1}. ${readStatus}${date}
|
|
51
|
+
return `${index + 1}. ${readStatus}Date: ${date}\nFrom: ${sender.name} (${sender.address})\nSubject: ${email.subject}\nID: ${email.id}\n`;
|
|
51
52
|
}).join("\n");
|
|
52
53
|
|
|
53
54
|
return {
|
package/email/read.js
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
const config = require('../config');
|
|
5
5
|
const { callGraphAPI } = require('../utils/graph-api');
|
|
6
6
|
const { ensureAuthenticated } = require('../auth');
|
|
7
|
+
const { formatDateTime } = require('./date-utils');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Read email handler
|
|
10
11
|
* @param {object} args - Tool arguments
|
|
11
|
-
* @returns {object} - MCP response
|
|
12
|
+
* @returns {Promise<object>} - MCP response
|
|
12
13
|
*/
|
|
13
14
|
async function handleReadEmail(args) {
|
|
14
15
|
const emailId = args.id;
|
|
@@ -51,7 +52,7 @@ async function handleReadEmail(args) {
|
|
|
51
52
|
const to = email.toRecipients ? email.toRecipients.map(r => `${r.emailAddress.name} (${r.emailAddress.address})`).join(", ") : 'None';
|
|
52
53
|
const cc = email.ccRecipients && email.ccRecipients.length > 0 ? email.ccRecipients.map(r => `${r.emailAddress.name} (${r.emailAddress.address})`).join(", ") : 'None';
|
|
53
54
|
const bcc = email.bccRecipients && email.bccRecipients.length > 0 ? email.bccRecipients.map(r => `${r.emailAddress.name} (${r.emailAddress.address})`).join(", ") : 'None';
|
|
54
|
-
const date =
|
|
55
|
+
const date = formatDateTime(email.receivedDateTime);
|
|
55
56
|
|
|
56
57
|
// Extract body content
|
|
57
58
|
let body = '';
|
package/email/search.js
CHANGED
|
@@ -5,11 +5,12 @@ const config = require('../config');
|
|
|
5
5
|
const { callGraphAPI, callGraphAPIPaginated } = require('../utils/graph-api');
|
|
6
6
|
const { ensureAuthenticated } = require('../auth');
|
|
7
7
|
const { resolveFolderPath } = require('./folder-utils');
|
|
8
|
+
const { formatDateTime } = require('./date-utils');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Search emails handler
|
|
11
12
|
* @param {object} args - Tool arguments
|
|
12
|
-
* @returns {object} - MCP response
|
|
13
|
+
* @returns {Promise<object>} - MCP response
|
|
13
14
|
*/
|
|
14
15
|
async function handleSearchEmails(args) {
|
|
15
16
|
const folder = args.folder || "inbox";
|
|
@@ -262,10 +263,10 @@ function formatSearchResults(response) {
|
|
|
262
263
|
// Format results
|
|
263
264
|
const emailList = response.value.map((email, index) => {
|
|
264
265
|
const sender = email.from?.emailAddress || { name: 'Unknown', address: 'unknown' };
|
|
265
|
-
const date =
|
|
266
|
+
const date = formatDateTime(email.receivedDateTime);
|
|
266
267
|
const readStatus = email.isRead ? '' : '[UNREAD] ';
|
|
267
268
|
|
|
268
|
-
return `${index + 1}. ${readStatus}${date}
|
|
269
|
+
return `${index + 1}. ${readStatus}Date: ${date}\nFrom: ${sender.name} (${sender.address})\nSubject: ${email.subject}\nID: ${email.id}\n`;
|
|
269
270
|
}).join("\n");
|
|
270
271
|
|
|
271
272
|
// Add search strategy info if available
|