@softeria/ms-365-mcp-server 0.125.1 → 0.126.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.
@@ -145,6 +145,10 @@ export function createAndSaveSimplifiedOpenAPI(
145
145
  }
146
146
  }
147
147
 
148
+ if (apiVersion === 'beta') {
149
+ normalizeWildcardSuccessResponses(openApiSpec.paths);
150
+ }
151
+
148
152
  if (openApiSpec.components && openApiSpec.components.schemas) {
149
153
  removeODataTypeRecursively(openApiSpec.components.schemas);
150
154
  flattenComplexSchemasRecursively(openApiSpec.components.schemas);
@@ -162,6 +166,29 @@ export function createAndSaveSimplifiedOpenAPI(
162
166
  fs.writeFileSync(openapiTrimmedFile, yaml.dump(openApiSpec));
163
167
  }
164
168
 
169
+ function normalizeWildcardSuccessResponses(paths) {
170
+ Object.values(paths || {}).forEach((pathItem) => {
171
+ if (!pathItem || typeof pathItem !== 'object') return;
172
+
173
+ Object.entries(pathItem).forEach(([method, operation]) => {
174
+ if (!operation || typeof operation !== 'object') return;
175
+ if (!operation.responses || !operation.responses['2XX']) return;
176
+
177
+ const hasConcreteSuccess = Object.keys(operation.responses).some((statusCode) =>
178
+ /^2\d\d$/.test(statusCode)
179
+ );
180
+ if (hasConcreteSuccess) {
181
+ delete operation.responses['2XX'];
182
+ return;
183
+ }
184
+
185
+ const successStatus = method === 'post' ? '201' : method === 'delete' ? '204' : '200';
186
+ operation.responses[successStatus] = operation.responses['2XX'];
187
+ delete operation.responses['2XX'];
188
+ });
189
+ });
190
+ }
191
+
165
192
  function removeODataTypeRecursively(obj) {
166
193
  if (!obj || typeof obj !== 'object') return;
167
194
 
@@ -1167,6 +1167,30 @@
1167
1167
  "scopes": ["Tasks.ReadWrite"],
1168
1168
  "llmTip": "CRITICAL: Requires If-Match header with ETag from get-planner-bucket (use includeHeaders=true)."
1169
1169
  },
1170
+ {
1171
+ "pathPattern": "/planner/tasks/{plannerTask-id}/messages",
1172
+ "method": "get",
1173
+ "toolName": "list-planner-task-messages",
1174
+ "scopes": ["Tasks.Read"],
1175
+ "apiVersion": "beta",
1176
+ "llmTip": "Lists messages in a Planner task's chat — the modern Planner 'task chat', distinct from the legacy conversationThreadId comments (which live in the M365 group conversation thread). Each message has id, content (HTML), createdBy, createdDateTime, mentions, reactions. BETA Graph API: subject to change; delegated work/school accounts only — no application permissions, no personal Microsoft accounts, global cloud only (not GCC/DoD/21Vianet)."
1177
+ },
1178
+ {
1179
+ "pathPattern": "/planner/tasks/{plannerTask-id}/messages",
1180
+ "method": "post",
1181
+ "toolName": "create-planner-task-message",
1182
+ "scopes": ["Tasks.ReadWrite"],
1183
+ "apiVersion": "beta",
1184
+ "llmTip": "Posts a message to a Planner task's chat (the modern 'task chat', not the legacy conversationThreadId comment). Microsoft is retiring the classic task comments experience and hiding it from the task (Planner 2026 update), so task chat is the current supported way to post per-task updates teammates will see, with @mentions. Body: { content: 'plain text or sanitized HTML', mentions?: [{ mentioned: 'user-id', position: 0, mentionType: 'user' }] } (mentions optional). No ETag/If-Match required. BETA Graph API: subject to change; delegated work/school accounts only — no application permissions, no personal Microsoft accounts, global cloud only (not GCC/DoD/21Vianet)."
1185
+ },
1186
+ {
1187
+ "pathPattern": "/planner/tasks/{plannerTask-id}/messages/{plannerTaskChatMessage-id}",
1188
+ "method": "delete",
1189
+ "toolName": "delete-planner-task-message",
1190
+ "scopes": ["Tasks.ReadWrite"],
1191
+ "apiVersion": "beta",
1192
+ "llmTip": "Deletes a message from a Planner task's chat. No request body; If-Match is optional if you want conditional deletion; returns 204. BETA Graph API: subject to change; delegated work/school accounts only — no application permissions, no personal Microsoft accounts, global cloud only (not GCC/DoD/21Vianet)."
1193
+ },
1170
1194
  {
1171
1195
  "pathPattern": "/me/contacts",
1172
1196
  "method": "get",
@@ -690,6 +690,58 @@ const microsoft_graph_ODataErrors_MainError = z.object({
690
690
  innerError: microsoft_graph_ODataErrors_InnerError.optional()
691
691
  }).passthrough();
692
692
  const microsoft_graph_ODataErrors_ODataError = z.object({ error: microsoft_graph_ODataErrors_MainError }).passthrough();
693
+ const microsoft_graph_plannerTaskChatMentionType = z.enum([
694
+ "user",
695
+ "application",
696
+ "unknownFutureValue"
697
+ ]);
698
+ const microsoft_graph_plannerTaskChatMention = z.object({
699
+ mentioned: z.string().describe("The ID of the mentioned user.").nullish(),
700
+ mentionType: microsoft_graph_plannerTaskChatMentionType.optional(),
701
+ position: z.number().gte(-2147483648).lte(2147483647).describe("The zero-based position of the mention in the message content.").optional()
702
+ }).passthrough();
703
+ const microsoft_graph_plannerTaskChatMessageType = z.enum([
704
+ "richTextHtml",
705
+ "plainText",
706
+ "unknownFutureValue"
707
+ ]);
708
+ const microsoft_graph_plannerTaskChatReactionEvent = z.object({
709
+ createdBy: microsoft_graph_identitySet.optional(),
710
+ createdDateTime: z.string().regex(
711
+ /^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$/
712
+ ).datetime({ offset: true }).describe(
713
+ "The date and time when the reaction was added. The timestamp type represents date and time information using ISO 8601 format and is always in UTC. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z."
714
+ ).optional()
715
+ }).passthrough();
716
+ const microsoft_graph_plannerTaskChatReaction = z.object({
717
+ reactionEvents: z.array(microsoft_graph_plannerTaskChatReactionEvent).optional(),
718
+ reactionType: z.string().describe("The type of reaction, such as like, heart, or emoji characters.").nullish()
719
+ }).passthrough();
720
+ const microsoft_graph_plannerTaskChatMessage = z.object({
721
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
722
+ content: z.string().describe("The content of the chat message. Supports plain text and sanitized HTML.").nullish(),
723
+ createdBy: microsoft_graph_identitySet.optional(),
724
+ createdDateTime: z.string().regex(
725
+ /^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$/
726
+ ).datetime({ offset: true }).describe(
727
+ "The date and time when the message was created. The timestamp type represents date and time information using ISO 8601 format and is always in UTC. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z."
728
+ ).optional(),
729
+ deletedDateTime: z.string().regex(
730
+ /^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$/
731
+ ).datetime({ offset: true }).nullish(),
732
+ editedDateTime: z.string().regex(
733
+ /^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$/
734
+ ).datetime({ offset: true }).nullish(),
735
+ mentions: z.array(microsoft_graph_plannerTaskChatMention).describe("The list of mentions in the message.").optional(),
736
+ messageType: microsoft_graph_plannerTaskChatMessageType.optional(),
737
+ parentEntityId: z.string().describe("The ID of the parent plannerTask that this message belongs to.").nullish(),
738
+ reactions: z.array(microsoft_graph_plannerTaskChatReaction).describe("The reactions on the message.").optional()
739
+ }).passthrough();
740
+ const microsoft_graph_plannerTaskChatMessageCollectionResponse = z.object({
741
+ "@odata.count": z.number().int().nullable(),
742
+ "@odata.nextLink": z.string().nullable(),
743
+ value: z.array(microsoft_graph_plannerTaskChatMessage)
744
+ }).partial().passthrough();
693
745
  const schemas = {
694
746
  microsoft_graph_allowedAudiences,
695
747
  microsoft_graph_identity,
@@ -741,7 +793,14 @@ const schemas = {
741
793
  microsoft_graph_ODataErrors_ErrorDetails,
742
794
  microsoft_graph_ODataErrors_InnerError,
743
795
  microsoft_graph_ODataErrors_MainError,
744
- microsoft_graph_ODataErrors_ODataError
796
+ microsoft_graph_ODataErrors_ODataError,
797
+ microsoft_graph_plannerTaskChatMentionType,
798
+ microsoft_graph_plannerTaskChatMention,
799
+ microsoft_graph_plannerTaskChatMessageType,
800
+ microsoft_graph_plannerTaskChatReactionEvent,
801
+ microsoft_graph_plannerTaskChatReaction,
802
+ microsoft_graph_plannerTaskChatMessage,
803
+ microsoft_graph_plannerTaskChatMessageCollectionResponse
745
804
  };
746
805
  const endpoints = makeApi([
747
806
  {
@@ -762,6 +821,87 @@ const endpoints = makeApi([
762
821
  schema: z.array(z.string()).describe("Expand related entities").optional()
763
822
  }
764
823
  ],
824
+ response: microsoft_graph_profile
825
+ },
826
+ {
827
+ method: "get",
828
+ path: "/planner/tasks/:plannerTaskId/messages",
829
+ alias: "list-planner-task-messages",
830
+ description: `Retrieve a list of plannerTaskChatMessage objects associated with a plannerTask.`,
831
+ requestFormat: "json",
832
+ parameters: [
833
+ {
834
+ name: "$top",
835
+ type: "Query",
836
+ schema: z.number().int().gte(0).describe("Show only the first n items").optional()
837
+ },
838
+ {
839
+ name: "$skip",
840
+ type: "Query",
841
+ schema: z.number().int().gte(0).describe("Skip the first n items").optional()
842
+ },
843
+ {
844
+ name: "$search",
845
+ type: "Query",
846
+ schema: z.string().describe("Search items by search phrases").optional()
847
+ },
848
+ {
849
+ name: "$filter",
850
+ type: "Query",
851
+ schema: z.string().describe("Filter items by property values").optional()
852
+ },
853
+ {
854
+ name: "$count",
855
+ type: "Query",
856
+ schema: z.boolean().describe("Include count of items").optional()
857
+ },
858
+ {
859
+ name: "$orderby",
860
+ type: "Query",
861
+ schema: z.array(z.string()).describe("Order items by property values").optional()
862
+ },
863
+ {
864
+ name: "$select",
865
+ type: "Query",
866
+ schema: z.array(z.string()).describe("Select properties to be returned").optional()
867
+ },
868
+ {
869
+ name: "$expand",
870
+ type: "Query",
871
+ schema: z.array(z.string()).describe("Expand related entities").optional()
872
+ }
873
+ ],
874
+ response: microsoft_graph_plannerTaskChatMessageCollectionResponse
875
+ },
876
+ {
877
+ method: "post",
878
+ path: "/planner/tasks/:plannerTaskId/messages",
879
+ alias: "create-planner-task-message",
880
+ description: `Create a new plannerTaskChatMessage on a plannerTask.`,
881
+ requestFormat: "json",
882
+ parameters: [
883
+ {
884
+ name: "body",
885
+ description: `New navigation property`,
886
+ type: "Body",
887
+ schema: microsoft_graph_plannerTaskChatMessage
888
+ }
889
+ ],
890
+ response: microsoft_graph_plannerTaskChatMessage
891
+ },
892
+ {
893
+ method: "delete",
894
+ path: "/planner/tasks/:plannerTaskId/messages/:plannerTaskChatMessageId",
895
+ alias: "delete-planner-task-message",
896
+ description: `Delete a plannerTaskChatMessage object.`,
897
+ requestFormat: "json",
898
+ parameters: [
899
+ {
900
+ name: "If-Match",
901
+ type: "Header",
902
+ schema: z.string().describe("ETag").optional()
903
+ }
904
+ ],
765
905
  response: z.void()
766
906
  }
767
907
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softeria/ms-365-mcp-server",
3
- "version": "0.125.1",
3
+ "version": "0.126.0",
4
4
  "description": " A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Office services through the Graph API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1167,6 +1167,30 @@
1167
1167
  "scopes": ["Tasks.ReadWrite"],
1168
1168
  "llmTip": "CRITICAL: Requires If-Match header with ETag from get-planner-bucket (use includeHeaders=true)."
1169
1169
  },
1170
+ {
1171
+ "pathPattern": "/planner/tasks/{plannerTask-id}/messages",
1172
+ "method": "get",
1173
+ "toolName": "list-planner-task-messages",
1174
+ "scopes": ["Tasks.Read"],
1175
+ "apiVersion": "beta",
1176
+ "llmTip": "Lists messages in a Planner task's chat — the modern Planner 'task chat', distinct from the legacy conversationThreadId comments (which live in the M365 group conversation thread). Each message has id, content (HTML), createdBy, createdDateTime, mentions, reactions. BETA Graph API: subject to change; delegated work/school accounts only — no application permissions, no personal Microsoft accounts, global cloud only (not GCC/DoD/21Vianet)."
1177
+ },
1178
+ {
1179
+ "pathPattern": "/planner/tasks/{plannerTask-id}/messages",
1180
+ "method": "post",
1181
+ "toolName": "create-planner-task-message",
1182
+ "scopes": ["Tasks.ReadWrite"],
1183
+ "apiVersion": "beta",
1184
+ "llmTip": "Posts a message to a Planner task's chat (the modern 'task chat', not the legacy conversationThreadId comment). Microsoft is retiring the classic task comments experience and hiding it from the task (Planner 2026 update), so task chat is the current supported way to post per-task updates teammates will see, with @mentions. Body: { content: 'plain text or sanitized HTML', mentions?: [{ mentioned: 'user-id', position: 0, mentionType: 'user' }] } (mentions optional). No ETag/If-Match required. BETA Graph API: subject to change; delegated work/school accounts only — no application permissions, no personal Microsoft accounts, global cloud only (not GCC/DoD/21Vianet)."
1185
+ },
1186
+ {
1187
+ "pathPattern": "/planner/tasks/{plannerTask-id}/messages/{plannerTaskChatMessage-id}",
1188
+ "method": "delete",
1189
+ "toolName": "delete-planner-task-message",
1190
+ "scopes": ["Tasks.ReadWrite"],
1191
+ "apiVersion": "beta",
1192
+ "llmTip": "Deletes a message from a Planner task's chat. No request body; If-Match is optional if you want conditional deletion; returns 204. BETA Graph API: subject to change; delegated work/school accounts only — no application permissions, no personal Microsoft accounts, global cloud only (not GCC/DoD/21Vianet)."
1193
+ },
1170
1194
  {
1171
1195
  "pathPattern": "/me/contacts",
1172
1196
  "method": "get",