@softeria/ms-365-mcp-server 0.161.1 → 0.161.3

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.
@@ -401,7 +401,7 @@ class GraphClient {
401
401
  const removeODataProps2 = (obj) => {
402
402
  if (typeof obj === "object" && obj !== null) {
403
403
  Object.keys(obj).forEach((key) => {
404
- if (key.startsWith("@odata.") && key !== "@odata.nextLink" && key !== "@odata.deltaLink") {
404
+ if (key.startsWith("@odata.") && key !== "@odata.nextLink" && key !== "@odata.deltaLink" && key !== "@odata.count") {
405
405
  delete obj[key];
406
406
  } else if (typeof obj[key] === "object") {
407
407
  removeODataProps2(obj[key]);
@@ -430,7 +430,7 @@ class GraphClient {
430
430
  const removeODataProps = (obj) => {
431
431
  if (typeof obj === "object" && obj !== null) {
432
432
  Object.keys(obj).forEach((key) => {
433
- if (key.startsWith("@odata.") && key !== "@odata.nextLink" && key !== "@odata.deltaLink") {
433
+ if (key.startsWith("@odata.") && key !== "@odata.nextLink" && key !== "@odata.deltaLink" && key !== "@odata.count") {
434
434
  delete obj[key];
435
435
  } else if (typeof obj[key] === "object") {
436
436
  removeODataProps(obj[key]);
@@ -1036,6 +1036,19 @@ const UTILITY_TOOLS = [
1036
1036
  }
1037
1037
  const pathPart = target.replace(/\/+$/, "");
1038
1038
  if (/^(\/me|\/users\/[^/]+)\/messages\/[^/]+\/attachments\//.test(pathPart) || /^(\/me|\/users\/[^/]+)\/events\/[^/]+\/attachments\//.test(pathPart) || /^\/groups\/[^/]+\/messages\/[^/]+\/attachments\//.test(pathPart) || /^\/groups\/[^/]+\/events\/[^/]+\/attachments\//.test(pathPart)) {
1039
+ if (getAttachmentMinting() && !pathPart.endsWith("/$value")) {
1040
+ return {
1041
+ content: [
1042
+ {
1043
+ type: "text",
1044
+ text: JSON.stringify({
1045
+ error: "Only the /$value byte endpoint can be minted a download URL: end target with /$value, e.g. /me/messages/{message-id}/attachments/{attachment-id}/$value. The attachment resource itself returns JSON with base64 contentBytes."
1046
+ })
1047
+ }
1048
+ ],
1049
+ isError: true
1050
+ };
1051
+ }
1039
1052
  const minted = await mintDownloadUrl(pathPart, accountParam, authManager);
1040
1053
  if (minted) return minted;
1041
1054
  return {
@@ -1053,6 +1066,19 @@ const UTILITY_TOOLS = [
1053
1066
  if (/^(\/me|\/users\/[^/]+)\/onlineMeetings\/[^/]+\/recordings\/[^/]+(?:\/content)?$/.test(
1054
1067
  pathPart
1055
1068
  ) || /^\/communications\/calls\/[^/]+\/recordings\/[^/]+(?:\/content)?$/.test(pathPart)) {
1069
+ if (getAttachmentMinting() && !pathPart.endsWith("/content")) {
1070
+ return {
1071
+ content: [
1072
+ {
1073
+ type: "text",
1074
+ text: JSON.stringify({
1075
+ error: "Only the /content byte endpoint can be minted a download URL: end target with /content, e.g. /me/onlineMeetings/{meeting-id}/recordings/{recording-id}/content."
1076
+ })
1077
+ }
1078
+ ],
1079
+ isError: true
1080
+ };
1081
+ }
1056
1082
  const minted = await mintDownloadUrl(pathPart, accountParam, authManager);
1057
1083
  if (minted) return minted;
1058
1084
  return {
@@ -1771,9 +1797,6 @@ async function executeGraphTool(tool, config, graphClient, params, authManager,
1771
1797
  );
1772
1798
  }
1773
1799
  combinedResponse.value = allItems;
1774
- if (combinedResponse["@odata.count"]) {
1775
- combinedResponse["@odata.count"] = allItems.length;
1776
- }
1777
1800
  if (unmergeablePage && nextLink) {
1778
1801
  combinedResponse["@odata.nextLink"] = nextLink;
1779
1802
  } else {
@@ -44,7 +44,7 @@ function isSkiptokenApplicable(tool, paramNames) {
44
44
  }
45
45
  return false;
46
46
  }
47
- const COUNT_PARAM_DESCRIPTION = "Set true to enable advanced query mode (ConsistencyLevel: eventual). Required for complex $filter on flag/flagStatus or contains().";
47
+ const COUNT_PARAM_DESCRIPTION = "Set true to enable advanced query mode (ConsistencyLevel: eventual). Required for complex $filter on flag/flagStatus or contains(). The response then includes @odata.count, the total for the filtered collection, which can exceed the items returned when fetchAllPages hits its page/item cap.";
48
48
  const CONFIRM_PARAM_DESCRIPTION = 'For destructive operations when the confirm gate is enabled (MS365_MCP_REQUIRE_CONFIRM=true; off by default). Set to true only after the user has explicitly approved this action. When the gate is on, calls without confirm: true return { error: "confirmation_required" } without touching user data.';
49
49
  const TIMEZONE_PARAM_DESCRIPTION = 'IANA timezone name (e.g., "America/New_York", "Europe/London", "Asia/Tokyo") for calendar event times. If not specified, times are returned in UTC.';
50
50
  const EXPAND_EXTENDED_PROPERTIES_PARAM_DESCRIPTION = "When true, expands singleValueExtendedProperties on each event. Use this to retrieve custom extended properties (e.g., sync metadata) stored on calendar events.";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@softeria/ms-365-mcp-server",
3
3
  "mcpName": "io.github.Softeria/ms-365-mcp-server",
4
- "version": "0.161.1",
4
+ "version": "0.161.3",
5
5
  "description": " A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Office services through the Graph API",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",