ms365-mcp-server 1.1.12 → 1.1.13
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/dist/index.js +4 -4
- package/dist/utils/ms365-operations.js +60 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -67,7 +67,7 @@ function parseArgs() {
|
|
|
67
67
|
}
|
|
68
68
|
const server = new Server({
|
|
69
69
|
name: "ms365-mcp-server",
|
|
70
|
-
version: "1.1.
|
|
70
|
+
version: "1.1.13"
|
|
71
71
|
}, {
|
|
72
72
|
capabilities: {
|
|
73
73
|
resources: {
|
|
@@ -83,7 +83,7 @@ const server = new Server({
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
|
-
logger.log('Server started with version 1.1.
|
|
86
|
+
logger.log('Server started with version 1.1.13');
|
|
87
87
|
// Set up the resource listing request handler
|
|
88
88
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
89
89
|
logger.log('Received list resources request');
|
|
@@ -937,7 +937,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
937
937
|
if (!args?.originalMessageId) {
|
|
938
938
|
throw new Error("originalMessageId is required for reply_draft action");
|
|
939
939
|
}
|
|
940
|
-
const replyDraftResult = await ms365Ops.createReplyDraft(args.originalMessageId, args.draftBody, args.replyToAll || false);
|
|
940
|
+
const replyDraftResult = await ms365Ops.createReplyDraft(args.originalMessageId, args.draftBody, args.replyToAll || false, args.draftBodyType || 'text');
|
|
941
941
|
return {
|
|
942
942
|
content: [
|
|
943
943
|
{
|
|
@@ -950,7 +950,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
950
950
|
if (!args?.originalMessageId) {
|
|
951
951
|
throw new Error("originalMessageId is required for forward_draft action");
|
|
952
952
|
}
|
|
953
|
-
const forwardDraftResult = await ms365Ops.createForwardDraft(args.originalMessageId, args.draftBody);
|
|
953
|
+
const forwardDraftResult = await ms365Ops.createForwardDraft(args.originalMessageId, args.draftBody, args.draftBodyType || 'text');
|
|
954
954
|
return {
|
|
955
955
|
content: [
|
|
956
956
|
{
|
|
@@ -522,7 +522,7 @@ export class MS365Operations {
|
|
|
522
522
|
/**
|
|
523
523
|
* Create a threaded reply draft from a specific message
|
|
524
524
|
*/
|
|
525
|
-
async createReplyDraft(originalMessageId, body, replyToAll = false) {
|
|
525
|
+
async createReplyDraft(originalMessageId, body, replyToAll = false, bodyType = 'text') {
|
|
526
526
|
try {
|
|
527
527
|
const graphClient = await this.getGraphClient();
|
|
528
528
|
logger.log(`Creating reply draft for message: ${originalMessageId}`);
|
|
@@ -536,7 +536,25 @@ export class MS365Operations {
|
|
|
536
536
|
const originalBodyContent = originalMessage.body?.content || '';
|
|
537
537
|
const fromDisplay = originalMessage.from?.emailAddress?.name || originalMessage.from?.emailAddress?.address || '';
|
|
538
538
|
const sentDate = new Date(originalMessage.sentDateTime).toLocaleString();
|
|
539
|
-
|
|
539
|
+
// Helper function to escape HTML characters
|
|
540
|
+
const escapeHtml = (text) => {
|
|
541
|
+
return text
|
|
542
|
+
.replace(/&/g, '&')
|
|
543
|
+
.replace(/</g, '<')
|
|
544
|
+
.replace(/>/g, '>')
|
|
545
|
+
.replace(/"/g, '"')
|
|
546
|
+
.replace(/'/g, ''');
|
|
547
|
+
};
|
|
548
|
+
// Helper function to convert text to HTML
|
|
549
|
+
const textToHtml = (text) => {
|
|
550
|
+
return escapeHtml(text).replace(/\n/g, '<br>');
|
|
551
|
+
};
|
|
552
|
+
// Process the user's body based on the specified type
|
|
553
|
+
let processedUserBody = body || '';
|
|
554
|
+
if (bodyType === 'text' && processedUserBody) {
|
|
555
|
+
processedUserBody = textToHtml(processedUserBody);
|
|
556
|
+
}
|
|
557
|
+
const completeReplyBody = `${processedUserBody}
|
|
540
558
|
|
|
541
559
|
<br><br>
|
|
542
560
|
<div style="border-left: 2px solid #ccc; padding-left: 10px; margin-top: 10px;">
|
|
@@ -670,20 +688,38 @@ ${originalBodyContent}
|
|
|
670
688
|
/**
|
|
671
689
|
* Create a threaded forward draft from a specific message
|
|
672
690
|
*/
|
|
673
|
-
async createForwardDraft(originalMessageId, comment) {
|
|
691
|
+
async createForwardDraft(originalMessageId, comment, bodyType = 'text') {
|
|
674
692
|
try {
|
|
675
693
|
const graphClient = await this.getGraphClient();
|
|
676
694
|
logger.log(`Creating forward draft for message: ${originalMessageId}`);
|
|
677
695
|
// First, try using the official Microsoft Graph createForward endpoint for proper threading
|
|
678
696
|
try {
|
|
679
697
|
logger.log(`Using official Graph API endpoint: /me/messages/${originalMessageId}/createForward`);
|
|
698
|
+
// Helper function to escape HTML characters
|
|
699
|
+
const escapeHtml = (text) => {
|
|
700
|
+
return text
|
|
701
|
+
.replace(/&/g, '&')
|
|
702
|
+
.replace(/</g, '<')
|
|
703
|
+
.replace(/>/g, '>')
|
|
704
|
+
.replace(/"/g, '"')
|
|
705
|
+
.replace(/'/g, ''');
|
|
706
|
+
};
|
|
707
|
+
// Helper function to convert text to HTML
|
|
708
|
+
const textToHtml = (text) => {
|
|
709
|
+
return escapeHtml(text).replace(/\n/g, '<br>');
|
|
710
|
+
};
|
|
711
|
+
// Process the comment based on the specified type
|
|
712
|
+
let processedComment = comment || '';
|
|
713
|
+
if (bodyType === 'text' && processedComment) {
|
|
714
|
+
processedComment = textToHtml(processedComment);
|
|
715
|
+
}
|
|
680
716
|
const forwardDraft = await graphClient
|
|
681
717
|
.api(`/me/messages/${originalMessageId}/createForward`)
|
|
682
718
|
.post({
|
|
683
719
|
message: {
|
|
684
720
|
body: {
|
|
685
721
|
contentType: 'html',
|
|
686
|
-
content:
|
|
722
|
+
content: processedComment
|
|
687
723
|
}
|
|
688
724
|
}
|
|
689
725
|
});
|
|
@@ -717,11 +753,29 @@ ${originalBodyContent}
|
|
|
717
753
|
referencesHeader = `${existingReferences.value} ${referencesHeader}`;
|
|
718
754
|
}
|
|
719
755
|
}
|
|
720
|
-
|
|
756
|
+
// Helper function to escape HTML characters for fallback
|
|
757
|
+
const escapeHtml = (text) => {
|
|
758
|
+
return text
|
|
759
|
+
.replace(/&/g, '&')
|
|
760
|
+
.replace(/</g, '<')
|
|
761
|
+
.replace(/>/g, '>')
|
|
762
|
+
.replace(/"/g, '"')
|
|
763
|
+
.replace(/'/g, ''');
|
|
764
|
+
};
|
|
765
|
+
// Helper function to convert text to HTML for fallback
|
|
766
|
+
const textToHtml = (text) => {
|
|
767
|
+
return escapeHtml(text).replace(/\n/g, '<br>');
|
|
768
|
+
};
|
|
769
|
+
// Process the comment based on the specified type for fallback
|
|
770
|
+
let processedComment = comment || '';
|
|
771
|
+
if (bodyType === 'text' && processedComment) {
|
|
772
|
+
processedComment = textToHtml(processedComment);
|
|
773
|
+
}
|
|
774
|
+
const forwardedBody = `${processedComment ? processedComment + '<br><br>' : ''}---------- Forwarded message ----------<br>From: ${originalMessage.from?.emailAddress?.name || originalMessage.from?.emailAddress?.address}<br>Date: ${originalMessage.sentDateTime}<br>Subject: ${originalMessage.subject}<br>To: ${originalMessage.toRecipients?.map((r) => r.emailAddress.address).join(', ')}<br><br>${originalMessage.body?.content || ''}`;
|
|
721
775
|
const draftBody = {
|
|
722
776
|
subject: originalMessage.subject?.startsWith('Fwd:') ? originalMessage.subject : `Fwd: ${originalMessage.subject}`,
|
|
723
777
|
body: {
|
|
724
|
-
contentType:
|
|
778
|
+
contentType: 'html',
|
|
725
779
|
content: forwardedBody
|
|
726
780
|
},
|
|
727
781
|
conversationId: originalMessage.conversationId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ms365-mcp-server",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.13",
|
|
4
4
|
"description": "Microsoft 365 MCP Server for managing Microsoft 365 email through natural language interactions with full OAuth2 authentication support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|