@softeria/ms-365-mcp-server 0.170.1 → 0.171.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.
@@ -1447,6 +1447,30 @@
1447
1447
  "presets": ["tasks", "work"],
1448
1448
  "scopes": ["Tasks.Read"]
1449
1449
  },
1450
+ {
1451
+ "pathPattern": "/planner/plans",
1452
+ "method": "post",
1453
+ "toolName": "create-planner-plan",
1454
+ "presets": ["tasks", "work"],
1455
+ "scopes": ["Tasks.ReadWrite"],
1456
+ "llmTip": "Body: {\"container\": {\"url\": \"https://graph.microsoft.com/v1.0/groups/{group-id}\"}, \"title\": \"...\"}. For a team, the group id is the team id. The signed-in user must be a member of the group. The container cannot be changed later. Returns the new plan id; to show the plan in a channel, add a Planner tab with create-channel-tab."
1457
+ },
1458
+ {
1459
+ "pathPattern": "/planner/plans/{plannerPlan-id}",
1460
+ "method": "patch",
1461
+ "toolName": "update-planner-plan",
1462
+ "presets": ["tasks", "work"],
1463
+ "scopes": ["Tasks.ReadWrite"],
1464
+ "llmTip": "CRITICAL: Requires If-Match header with ETag from get-planner-plan (use includeHeaders=true)."
1465
+ },
1466
+ {
1467
+ "pathPattern": "/groups/{group-id}/planner/plans",
1468
+ "method": "get",
1469
+ "toolName": "list-group-planner-plans",
1470
+ "presets": ["tasks", "work"],
1471
+ "scopes": ["Tasks.Read"],
1472
+ "llmTip": "Lists the plans owned by a Microsoft 365 group. For a team, the group id is the team id."
1473
+ },
1450
1474
  {
1451
1475
  "pathPattern": "/planner/plans/{plannerPlan-id}/tasks",
1452
1476
  "method": "get",
@@ -1959,6 +1983,14 @@
1959
1983
  "presets": ["teams", "work"],
1960
1984
  "workScopes": ["TeamsTab.Read.All"]
1961
1985
  },
1986
+ {
1987
+ "pathPattern": "/teams/{team-id}/channels/{channel-id}/tabs",
1988
+ "method": "post",
1989
+ "toolName": "create-channel-tab",
1990
+ "presets": ["teams", "work"],
1991
+ "workScopes": ["TeamsTab.Create"],
1992
+ "llmTip": "Body: {\"displayName\": \"...\", \"teamsApp@odata.bind\": \"https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/{teamsAppId}\", \"configuration\": {\"entityId\": ..., \"contentUrl\": ..., \"websiteUrl\": ..., \"removeUrl\": ...}}. Built-in app ids: website com.microsoft.teamspace.tab.web, document library com.microsoft.teamspace.tab.files.sharepoint, Planner com.microsoft.teamspace.tab.planner (see https://learn.microsoft.com/graph/teams-configuring-builtin-tabs). Planner tab for a basic plan (create it first with create-planner-plan): entityId \"planner.v1.{new-guid}_p_{planId}\"; contentUrl \"https://tasks.teams.microsoft.com/teamsui/{tid}/Home/PlannerFrame?page=7&auth_pvr=OrgId&auth_upn={userPrincipalName}&groupId={groupId}&planRoute=/v1/plan/{planId}&subEntityId={subEntityId}&channelId={channelId}&entityId={entityId}&tid={tid}&userObjectId={userObjectId}&sessionId={sessionId}&theme={theme}&mkt={locale}&ringId={ringId}&PlannerRouteHint={tid}&tabVersion=20200228.1_s\"; removeUrl the same with page=13; websiteUrl \"https://planner.cloud.microsoft/webui/v1/plan/{planId}?tid={tenantId}\". Replace only {planId}, {new-guid} and {tenantId} with real values; every other {placeholder} must stay literal, Teams fills it in. A tasks.office.com URL or a missing placeholder renders an error inside the tab."
1993
+ },
1962
1994
  {
1963
1995
  "pathPattern": "/teams/{team-id}/channels/{channel-id}/messages/{chatMessage-id}/setReaction",
1964
1996
  "method": "post",
@@ -448,6 +448,9 @@ const microsoft_graph_personRelationship = z.enum([
448
448
  const microsoft_graph_relatedPerson = z.object({
449
449
  displayName: z.string().describe("Name of the person.").nullish(),
450
450
  relationship: microsoft_graph_personRelationship.optional(),
451
+ relationshipLabel: z.string().describe(
452
+ "Information (free-text) describing the relationship between the user and the related person. This property provides additional context beyond the predefined relationship values and can be used by clients, including AI-powered experiences, to better understand and reason about the relationship."
453
+ ).nullish(),
451
454
  userId: z.string().describe("The user's directory object ID (Microsoft Entra ID or CID).").nullish(),
452
455
  userPrincipalName: z.string().describe("Email address or reference to person within the organization.").nullish()
453
456
  }).passthrough();
@@ -537,10 +537,10 @@ const microsoft_graph_userWorkLocation = z.object({
537
537
  const microsoft_graph_presence = z.object({
538
538
  id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
539
539
  activity: z.string().describe(
540
- "The supplemental information to a user's availability. Possible values are available, away, beRightBack, busy, doNotDisturb, offline, outOfOffice, presenceUnknown."
540
+ "The supplemental information to a user's availability. Possible values are Available, Away, BeRightBack, Busy, DoNotDisturb, Offline, OutOfOffice, PresenceUnknown."
541
541
  ).nullish(),
542
542
  availability: z.string().describe(
543
- "The base presence information for a user. Possible values are available, away, beRightBack, busy, doNotDisturb, focusing, inACall, inAMeeting, offline, presenting, presenceUnknown."
543
+ "The base presence information for a user. Possible values are Available, Away, BeRightBack, Busy, DoNotDisturb, Focusing, InACall, InAMeeting, Offline, Presenting, PresenceUnknown."
544
544
  ).nullish(),
545
545
  outOfOfficeSettings: microsoft_graph_outOfOfficeSettings.optional(),
546
546
  sequenceNumber: z.string().describe(
@@ -1615,7 +1615,7 @@ const microsoft_graph_group = z.object({
1615
1615
  "Indicates if people external to the organization can send messages to the group. The default value is false. Requires $select to retrieve. Supported only on the Get group API (GET /groups/{ID})."
1616
1616
  ).nullish(),
1617
1617
  assignedLabels: z.array(microsoft_graph_assignedLabel).describe(
1618
- "The list of sensitivity label pairs (label ID, label name) associated with a Microsoft 365 group or a cloud security group. Requires a Microsoft Entra ID P1 license. Requires $select to retrieve. This property can be specified during group creation or update. However, for cloud security groups, it's immutable once set. This property can be updated only in delegated scenarios where the caller requires both the Microsoft Graph permission and a supported administrator role. See Key differences from Microsoft 365 group labeling to learn more about managing this property for Microsoft 365 vs. cloud security groups."
1618
+ "The list of sensitivity label pairs (label ID, label name) associated with a Microsoft 365 group or a cloud security group. Requires a Microsoft Entra ID P1 license. Requires $select to retrieve. This property can be specified during group creation or update. However, for cloud security groups, it's immutable once set. This property can be updated only in delegated scenarios where the caller requires both the Microsoft Graph permission and a supported administrator role. To learn more about managing this property for Microsoft 365 vs. cloud security groups, see Key differences from Microsoft 365 group labeling."
1619
1619
  ).optional(),
1620
1620
  assignedLicenses: z.array(microsoft_graph_assignedLicense).describe(
1621
1621
  "The licenses that are assigned to the group. Requires $select to retrieve. Supports $filter (eq). Read-only."
@@ -2003,6 +2003,163 @@ const microsoft_graph_directoryObjectCollectionResponse = z.object({
2003
2003
  value: z.array(microsoft_graph_directoryObject)
2004
2004
  }).partial().passthrough();
2005
2005
  const ReferenceCreate = z.record(z.object({}).partial().passthrough());
2006
+ const microsoft_graph_plannerContainerType = z.enum(["group", "unknownFutureValue", "roster"]);
2007
+ const microsoft_graph_plannerPlanContainer = z.object({
2008
+ containerId: z.string().describe("The identifier of the resource that contains the plan. Optional.").nullish(),
2009
+ type: microsoft_graph_plannerContainerType.optional(),
2010
+ url: z.string().describe("The full canonical URL of the container. Optional.").nullish()
2011
+ }).passthrough();
2012
+ const microsoft_graph_plannerChecklistItems = z.object({}).passthrough();
2013
+ const microsoft_graph_plannerPreviewType = z.enum([
2014
+ "automatic",
2015
+ "noPreview",
2016
+ "checklist",
2017
+ "description",
2018
+ "reference"
2019
+ ]);
2020
+ const microsoft_graph_plannerExternalReferences = z.object({}).passthrough();
2021
+ const microsoft_graph_plannerTaskDetails = z.object({
2022
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
2023
+ checklist: microsoft_graph_plannerChecklistItems.optional(),
2024
+ description: z.string().describe("Description of the task.").nullish(),
2025
+ previewType: microsoft_graph_plannerPreviewType.optional(),
2026
+ references: microsoft_graph_plannerExternalReferences.optional()
2027
+ }).passthrough();
2028
+ const microsoft_graph_plannerAppliedCategories = z.object({}).passthrough();
2029
+ const microsoft_graph_plannerAssignments = z.object({}).passthrough();
2030
+ const microsoft_graph_plannerOrderHintsByAssignee = z.object({}).passthrough();
2031
+ const microsoft_graph_plannerAssignedToTaskBoardTaskFormat = z.object({
2032
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
2033
+ orderHintsByAssignee: microsoft_graph_plannerOrderHintsByAssignee.optional(),
2034
+ unassignedOrderHint: z.string().describe(
2035
+ "Hint value used to order the task on the AssignedTo view of the Task Board when the task isn't assigned to anyone, or if the orderHintsByAssignee dictionary doesn't provide an order hint for the user the task is assigned to. The format is defined as outlined here."
2036
+ ).nullish()
2037
+ }).passthrough();
2038
+ const microsoft_graph_plannerBucketTaskBoardTaskFormat = z.object({
2039
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
2040
+ orderHint: z.string().describe(
2041
+ "Hint used to order tasks in the bucket view of the task board. For details about the supported format, see Using order hints in Planner."
2042
+ ).nullish()
2043
+ }).passthrough();
2044
+ const microsoft_graph_plannerTask = z.object({
2045
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
2046
+ createdDateTime: z.string().regex(
2047
+ /^[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])$/
2048
+ ).datetime({ offset: true }).describe(
2049
+ "Read-only. Date and time at which the task is created. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
2050
+ ).nullish(),
2051
+ title: z.string().describe("Title of the task.").optional(),
2052
+ details: microsoft_graph_plannerTaskDetails.optional(),
2053
+ activeChecklistItemCount: z.number().gte(-2147483648).lte(2147483647).describe("Number of checklist items with value set to false, representing incomplete items.").nullish(),
2054
+ appliedCategories: microsoft_graph_plannerAppliedCategories.optional(),
2055
+ assigneePriority: z.string().describe(
2056
+ "Hint used to order items of this type in a list view. The format is defined as outlined here."
2057
+ ).nullish(),
2058
+ assignments: microsoft_graph_plannerAssignments.optional(),
2059
+ bucketId: z.string().describe(
2060
+ "Bucket ID to which the task belongs. The bucket needs to be in the plan that the task is in. It's 28 characters long and case-sensitive. Format validation is done on the service."
2061
+ ).nullish(),
2062
+ checklistItemCount: z.number().gte(-2147483648).lte(2147483647).describe("Number of checklist items that are present on the task.").nullish(),
2063
+ completedBy: microsoft_graph_identitySet.optional(),
2064
+ completedDateTime: z.string().regex(
2065
+ /^[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])$/
2066
+ ).datetime({ offset: true }).describe(
2067
+ "Read-only. Date and time at which the 'percentComplete' of the task is set to '100'. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
2068
+ ).nullish(),
2069
+ conversationThreadId: z.string().describe(
2070
+ "Thread ID of the conversation on the task. This is the ID of the conversation thread object created in the group."
2071
+ ).nullish(),
2072
+ createdBy: microsoft_graph_identitySet.optional(),
2073
+ dueDateTime: z.string().regex(
2074
+ /^[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])$/
2075
+ ).datetime({ offset: true }).describe(
2076
+ "Date and time at which the task is due. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
2077
+ ).nullish(),
2078
+ hasDescription: z.boolean().describe(
2079
+ "Read-only. Value is true if the details object of the task has a nonempty description and false otherwise."
2080
+ ).nullish(),
2081
+ orderHint: z.string().describe(
2082
+ "Hint used to order items of this type in a list view. The format is defined as outlined here."
2083
+ ).nullish(),
2084
+ percentComplete: z.number().gte(-2147483648).lte(2147483647).describe("Percentage of task completion. When set to 100, the task is considered completed.").nullish(),
2085
+ planId: z.string().describe("Plan ID to which the task belongs.").nullish(),
2086
+ previewType: microsoft_graph_plannerPreviewType.optional(),
2087
+ priority: z.number().gte(-2147483648).lte(2147483647).describe(
2088
+ "Priority of the task. The valid range of values is between 0 and 10, with the increasing value being lower priority (0 has the highest priority and 10 has the lowest priority). Currently, Planner interprets values 0 and 1 as 'urgent', 2, 3 and 4 as 'important', 5, 6, and 7 as 'medium', and 8, 9, and 10 as 'low'. Additionally, Planner sets the value 1 for 'urgent', 3 for 'important', 5 for 'medium', and 9 for 'low'."
2089
+ ).nullish(),
2090
+ referenceCount: z.number().gte(-2147483648).lte(2147483647).describe("Number of external references that exist on the task.").nullish(),
2091
+ startDateTime: z.string().regex(
2092
+ /^[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])$/
2093
+ ).datetime({ offset: true }).describe(
2094
+ "Date and time at which the task starts. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
2095
+ ).nullish(),
2096
+ assignedToTaskBoardFormat: microsoft_graph_plannerAssignedToTaskBoardTaskFormat.optional(),
2097
+ bucketTaskBoardFormat: microsoft_graph_plannerBucketTaskBoardTaskFormat.optional()
2098
+ }).passthrough().passthrough();
2099
+ const microsoft_graph_plannerBucket = z.object({
2100
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
2101
+ name: z.string().describe("Name of the bucket.").optional(),
2102
+ orderHint: z.string().describe(
2103
+ "Hint used to order items of this type in a list view. For details about the supported format, see Using order hints in Planner."
2104
+ ).nullish(),
2105
+ planId: z.string().describe("Plan ID to which the bucket belongs.").nullish(),
2106
+ tasks: z.array(microsoft_graph_plannerTask).describe("Read-only. Nullable. The collection of tasks in the bucket.").optional()
2107
+ }).passthrough();
2108
+ const microsoft_graph_plannerCategoryDescriptions = z.object({
2109
+ category1: z.string().describe("The label associated with Category 1").nullish(),
2110
+ category10: z.string().describe("The label associated with Category 10").nullish(),
2111
+ category11: z.string().describe("The label associated with Category 11").nullish(),
2112
+ category12: z.string().describe("The label associated with Category 12").nullish(),
2113
+ category13: z.string().describe("The label associated with Category 13").nullish(),
2114
+ category14: z.string().describe("The label associated with Category 14").nullish(),
2115
+ category15: z.string().describe("The label associated with Category 15").nullish(),
2116
+ category16: z.string().describe("The label associated with Category 16").nullish(),
2117
+ category17: z.string().describe("The label associated with Category 17").nullish(),
2118
+ category18: z.string().describe("The label associated with Category 18").nullish(),
2119
+ category19: z.string().describe("The label associated with Category 19").nullish(),
2120
+ category2: z.string().describe("The label associated with Category 2").nullish(),
2121
+ category20: z.string().describe("The label associated with Category 20").nullish(),
2122
+ category21: z.string().describe("The label associated with Category 21").nullish(),
2123
+ category22: z.string().describe("The label associated with Category 22").nullish(),
2124
+ category23: z.string().describe("The label associated with Category 23").nullish(),
2125
+ category24: z.string().describe("The label associated with Category 24").nullish(),
2126
+ category25: z.string().describe("The label associated with Category 25").nullish(),
2127
+ category3: z.string().describe("The label associated with Category 3").nullish(),
2128
+ category4: z.string().describe("The label associated with Category 4").nullish(),
2129
+ category5: z.string().describe("The label associated with Category 5").nullish(),
2130
+ category6: z.string().describe("The label associated with Category 6").nullish(),
2131
+ category7: z.string().describe("The label associated with Category 7").nullish(),
2132
+ category8: z.string().describe("The label associated with Category 8").nullish(),
2133
+ category9: z.string().describe("The label associated with Category 9").nullish()
2134
+ }).passthrough();
2135
+ const microsoft_graph_plannerUserIds = z.object({}).passthrough();
2136
+ const microsoft_graph_plannerPlanDetails = z.object({
2137
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
2138
+ categoryDescriptions: microsoft_graph_plannerCategoryDescriptions.optional(),
2139
+ sharedWith: microsoft_graph_plannerUserIds.optional()
2140
+ }).passthrough();
2141
+ const microsoft_graph_plannerPlan = z.object({
2142
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
2143
+ container: microsoft_graph_plannerPlanContainer.optional(),
2144
+ createdBy: microsoft_graph_identitySet.optional(),
2145
+ createdDateTime: z.string().regex(
2146
+ /^[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])$/
2147
+ ).datetime({ offset: true }).describe(
2148
+ "Read-only. Date and time at which the plan is created. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
2149
+ ).nullish(),
2150
+ owner: z.string().describe(
2151
+ "Use the container property instead. ID of the group that owns the plan. After it's set, this property can\u2019t be updated. This property won't return a valid group ID if the container of the plan isn't a group."
2152
+ ).nullish(),
2153
+ title: z.string().describe("Required. Title of the plan.").optional(),
2154
+ buckets: z.array(microsoft_graph_plannerBucket).describe("Read-only. Nullable. Collection of buckets in the plan.").optional(),
2155
+ details: microsoft_graph_plannerPlanDetails.optional(),
2156
+ tasks: z.array(microsoft_graph_plannerTask).describe("Read-only. Nullable. Collection of tasks in the plan.").optional()
2157
+ }).passthrough();
2158
+ const microsoft_graph_plannerPlanCollectionResponse = z.object({
2159
+ "@odata.count": z.number().int().nullable(),
2160
+ "@odata.nextLink": z.string().nullable(),
2161
+ value: z.array(microsoft_graph_plannerPlan)
2162
+ }).partial().passthrough();
2006
2163
  const microsoft_graph_conversationThreadCollectionResponse = z.object({
2007
2164
  "@odata.count": z.number().int().nullable(),
2008
2165
  "@odata.nextLink": z.string().nullable(),
@@ -3881,93 +4038,6 @@ const microsoft_graph_personCollectionResponse = z.object({
3881
4038
  "@odata.nextLink": z.string().nullable(),
3882
4039
  value: z.array(microsoft_graph_person)
3883
4040
  }).partial().passthrough();
3884
- const microsoft_graph_plannerChecklistItems = z.object({}).passthrough();
3885
- const microsoft_graph_plannerPreviewType = z.enum([
3886
- "automatic",
3887
- "noPreview",
3888
- "checklist",
3889
- "description",
3890
- "reference"
3891
- ]);
3892
- const microsoft_graph_plannerExternalReferences = z.object({}).passthrough();
3893
- const microsoft_graph_plannerTaskDetails = z.object({
3894
- id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
3895
- checklist: microsoft_graph_plannerChecklistItems.optional(),
3896
- description: z.string().describe("Description of the task.").nullish(),
3897
- previewType: microsoft_graph_plannerPreviewType.optional(),
3898
- references: microsoft_graph_plannerExternalReferences.optional()
3899
- }).passthrough();
3900
- const microsoft_graph_plannerAppliedCategories = z.object({}).passthrough();
3901
- const microsoft_graph_plannerAssignments = z.object({}).passthrough();
3902
- const microsoft_graph_plannerOrderHintsByAssignee = z.object({}).passthrough();
3903
- const microsoft_graph_plannerAssignedToTaskBoardTaskFormat = z.object({
3904
- id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
3905
- orderHintsByAssignee: microsoft_graph_plannerOrderHintsByAssignee.optional(),
3906
- unassignedOrderHint: z.string().describe(
3907
- "Hint value used to order the task on the AssignedTo view of the Task Board when the task isn't assigned to anyone, or if the orderHintsByAssignee dictionary doesn't provide an order hint for the user the task is assigned to. The format is defined as outlined here."
3908
- ).nullish()
3909
- }).passthrough();
3910
- const microsoft_graph_plannerBucketTaskBoardTaskFormat = z.object({
3911
- id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
3912
- orderHint: z.string().describe(
3913
- "Hint used to order tasks in the bucket view of the task board. For details about the supported format, see Using order hints in Planner."
3914
- ).nullish()
3915
- }).passthrough();
3916
- const microsoft_graph_plannerTask = z.object({
3917
- id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
3918
- createdDateTime: z.string().regex(
3919
- /^[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])$/
3920
- ).datetime({ offset: true }).describe(
3921
- "Read-only. Date and time at which the task is created. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
3922
- ).nullish(),
3923
- title: z.string().describe("Title of the task.").optional(),
3924
- details: microsoft_graph_plannerTaskDetails.optional(),
3925
- activeChecklistItemCount: z.number().gte(-2147483648).lte(2147483647).describe("Number of checklist items with value set to false, representing incomplete items.").nullish(),
3926
- appliedCategories: microsoft_graph_plannerAppliedCategories.optional(),
3927
- assigneePriority: z.string().describe(
3928
- "Hint used to order items of this type in a list view. The format is defined as outlined here."
3929
- ).nullish(),
3930
- assignments: microsoft_graph_plannerAssignments.optional(),
3931
- bucketId: z.string().describe(
3932
- "Bucket ID to which the task belongs. The bucket needs to be in the plan that the task is in. It's 28 characters long and case-sensitive. Format validation is done on the service."
3933
- ).nullish(),
3934
- checklistItemCount: z.number().gte(-2147483648).lte(2147483647).describe("Number of checklist items that are present on the task.").nullish(),
3935
- completedBy: microsoft_graph_identitySet.optional(),
3936
- completedDateTime: z.string().regex(
3937
- /^[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])$/
3938
- ).datetime({ offset: true }).describe(
3939
- "Read-only. Date and time at which the 'percentComplete' of the task is set to '100'. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
3940
- ).nullish(),
3941
- conversationThreadId: z.string().describe(
3942
- "Thread ID of the conversation on the task. This is the ID of the conversation thread object created in the group."
3943
- ).nullish(),
3944
- createdBy: microsoft_graph_identitySet.optional(),
3945
- dueDateTime: z.string().regex(
3946
- /^[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])$/
3947
- ).datetime({ offset: true }).describe(
3948
- "Date and time at which the task is due. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
3949
- ).nullish(),
3950
- hasDescription: z.boolean().describe(
3951
- "Read-only. Value is true if the details object of the task has a nonempty description and false otherwise."
3952
- ).nullish(),
3953
- orderHint: z.string().describe(
3954
- "Hint used to order items of this type in a list view. The format is defined as outlined here."
3955
- ).nullish(),
3956
- percentComplete: z.number().gte(-2147483648).lte(2147483647).describe("Percentage of task completion. When set to 100, the task is considered completed.").nullish(),
3957
- planId: z.string().describe("Plan ID to which the task belongs.").nullish(),
3958
- previewType: microsoft_graph_plannerPreviewType.optional(),
3959
- priority: z.number().gte(-2147483648).lte(2147483647).describe(
3960
- "Priority of the task. The valid range of values is between 0 and 10, with the increasing value being lower priority (0 has the highest priority and 10 has the lowest priority). Currently, Planner interprets values 0 and 1 as 'urgent', 2, 3 and 4 as 'important', 5, 6, and 7 as 'medium', and 8, 9, and 10 as 'low'. Additionally, Planner sets the value 1 for 'urgent', 3 for 'important', 5 for 'medium', and 9 for 'low'."
3961
- ).nullish(),
3962
- referenceCount: z.number().gte(-2147483648).lte(2147483647).describe("Number of external references that exist on the task.").nullish(),
3963
- startDateTime: z.string().regex(
3964
- /^[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])$/
3965
- ).datetime({ offset: true }).describe(
3966
- "Date and time at which the task starts. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
3967
- ).nullish(),
3968
- assignedToTaskBoardFormat: microsoft_graph_plannerAssignedToTaskBoardTaskFormat.optional(),
3969
- bucketTaskBoardFormat: microsoft_graph_plannerBucketTaskBoardTaskFormat.optional()
3970
- }).passthrough().passthrough();
3971
4041
  const microsoft_graph_plannerTaskCollectionResponse = z.object({
3972
4042
  "@odata.count": z.number().int().nullable(),
3973
4043
  "@odata.nextLink": z.string().nullable(),
@@ -4274,71 +4344,6 @@ const microsoft_graph_roomCollectionResponse = z.object({
4274
4344
  "@odata.nextLink": z.string().nullable(),
4275
4345
  value: z.array(microsoft_graph_room)
4276
4346
  }).partial().passthrough();
4277
- const microsoft_graph_plannerBucket = z.object({
4278
- id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
4279
- name: z.string().describe("Name of the bucket.").optional(),
4280
- orderHint: z.string().describe(
4281
- "Hint used to order items of this type in a list view. For details about the supported format, see Using order hints in Planner."
4282
- ).nullish(),
4283
- planId: z.string().describe("Plan ID to which the bucket belongs.").nullish(),
4284
- tasks: z.array(microsoft_graph_plannerTask).describe("Read-only. Nullable. The collection of tasks in the bucket.").optional()
4285
- }).passthrough();
4286
- const microsoft_graph_plannerContainerType = z.enum(["group", "unknownFutureValue", "roster"]);
4287
- const microsoft_graph_plannerPlanContainer = z.object({
4288
- containerId: z.string().describe("The identifier of the resource that contains the plan. Optional.").nullish(),
4289
- type: microsoft_graph_plannerContainerType.optional(),
4290
- url: z.string().describe("The full canonical URL of the container. Optional.").nullish()
4291
- }).passthrough();
4292
- const microsoft_graph_plannerCategoryDescriptions = z.object({
4293
- category1: z.string().describe("The label associated with Category 1").nullish(),
4294
- category10: z.string().describe("The label associated with Category 10").nullish(),
4295
- category11: z.string().describe("The label associated with Category 11").nullish(),
4296
- category12: z.string().describe("The label associated with Category 12").nullish(),
4297
- category13: z.string().describe("The label associated with Category 13").nullish(),
4298
- category14: z.string().describe("The label associated with Category 14").nullish(),
4299
- category15: z.string().describe("The label associated with Category 15").nullish(),
4300
- category16: z.string().describe("The label associated with Category 16").nullish(),
4301
- category17: z.string().describe("The label associated with Category 17").nullish(),
4302
- category18: z.string().describe("The label associated with Category 18").nullish(),
4303
- category19: z.string().describe("The label associated with Category 19").nullish(),
4304
- category2: z.string().describe("The label associated with Category 2").nullish(),
4305
- category20: z.string().describe("The label associated with Category 20").nullish(),
4306
- category21: z.string().describe("The label associated with Category 21").nullish(),
4307
- category22: z.string().describe("The label associated with Category 22").nullish(),
4308
- category23: z.string().describe("The label associated with Category 23").nullish(),
4309
- category24: z.string().describe("The label associated with Category 24").nullish(),
4310
- category25: z.string().describe("The label associated with Category 25").nullish(),
4311
- category3: z.string().describe("The label associated with Category 3").nullish(),
4312
- category4: z.string().describe("The label associated with Category 4").nullish(),
4313
- category5: z.string().describe("The label associated with Category 5").nullish(),
4314
- category6: z.string().describe("The label associated with Category 6").nullish(),
4315
- category7: z.string().describe("The label associated with Category 7").nullish(),
4316
- category8: z.string().describe("The label associated with Category 8").nullish(),
4317
- category9: z.string().describe("The label associated with Category 9").nullish()
4318
- }).passthrough();
4319
- const microsoft_graph_plannerUserIds = z.object({}).passthrough();
4320
- const microsoft_graph_plannerPlanDetails = z.object({
4321
- id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
4322
- categoryDescriptions: microsoft_graph_plannerCategoryDescriptions.optional(),
4323
- sharedWith: microsoft_graph_plannerUserIds.optional()
4324
- }).passthrough();
4325
- const microsoft_graph_plannerPlan = z.object({
4326
- id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
4327
- container: microsoft_graph_plannerPlanContainer.optional(),
4328
- createdBy: microsoft_graph_identitySet.optional(),
4329
- createdDateTime: z.string().regex(
4330
- /^[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])$/
4331
- ).datetime({ offset: true }).describe(
4332
- "Read-only. Date and time at which the plan is created. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z"
4333
- ).nullish(),
4334
- owner: z.string().describe(
4335
- "Use the container property instead. ID of the group that owns the plan. After it's set, this property can\u2019t be updated. This property won't return a valid group ID if the container of the plan isn't a group."
4336
- ).nullish(),
4337
- title: z.string().describe("Required. Title of the plan.").optional(),
4338
- buckets: z.array(microsoft_graph_plannerBucket).describe("Read-only. Nullable. Collection of buckets in the plan.").optional(),
4339
- details: microsoft_graph_plannerPlanDetails.optional(),
4340
- tasks: z.array(microsoft_graph_plannerTask).describe("Read-only. Nullable. Collection of tasks in the plan.").optional()
4341
- }).passthrough();
4342
4347
  const microsoft_graph_plannerBucketCollectionResponse = z.object({
4343
4348
  "@odata.count": z.number().int().nullable(),
4344
4349
  "@odata.nextLink": z.string().nullable(),
@@ -5085,6 +5090,24 @@ const schemas = {
5085
5090
  microsoft_graph_directoryObject,
5086
5091
  microsoft_graph_directoryObjectCollectionResponse,
5087
5092
  ReferenceCreate,
5093
+ microsoft_graph_plannerContainerType,
5094
+ microsoft_graph_plannerPlanContainer,
5095
+ microsoft_graph_plannerChecklistItems,
5096
+ microsoft_graph_plannerPreviewType,
5097
+ microsoft_graph_plannerExternalReferences,
5098
+ microsoft_graph_plannerTaskDetails,
5099
+ microsoft_graph_plannerAppliedCategories,
5100
+ microsoft_graph_plannerAssignments,
5101
+ microsoft_graph_plannerOrderHintsByAssignee,
5102
+ microsoft_graph_plannerAssignedToTaskBoardTaskFormat,
5103
+ microsoft_graph_plannerBucketTaskBoardTaskFormat,
5104
+ microsoft_graph_plannerTask,
5105
+ microsoft_graph_plannerBucket,
5106
+ microsoft_graph_plannerCategoryDescriptions,
5107
+ microsoft_graph_plannerUserIds,
5108
+ microsoft_graph_plannerPlanDetails,
5109
+ microsoft_graph_plannerPlan,
5110
+ microsoft_graph_plannerPlanCollectionResponse,
5088
5111
  microsoft_graph_conversationThreadCollectionResponse,
5089
5112
  reply_to_group_thread_Body,
5090
5113
  microsoft_graph_calendarRoleType,
@@ -5268,16 +5291,6 @@ const schemas = {
5268
5291
  microsoft_graph_website,
5269
5292
  microsoft_graph_person,
5270
5293
  microsoft_graph_personCollectionResponse,
5271
- microsoft_graph_plannerChecklistItems,
5272
- microsoft_graph_plannerPreviewType,
5273
- microsoft_graph_plannerExternalReferences,
5274
- microsoft_graph_plannerTaskDetails,
5275
- microsoft_graph_plannerAppliedCategories,
5276
- microsoft_graph_plannerAssignments,
5277
- microsoft_graph_plannerOrderHintsByAssignee,
5278
- microsoft_graph_plannerAssignedToTaskBoardTaskFormat,
5279
- microsoft_graph_plannerBucketTaskBoardTaskFormat,
5280
- microsoft_graph_plannerTask,
5281
5294
  microsoft_graph_plannerTaskCollectionResponse,
5282
5295
  set_my_presence_Body,
5283
5296
  set_my_status_message_Body,
@@ -5312,13 +5325,6 @@ const schemas = {
5312
5325
  microsoft_graph_workspace,
5313
5326
  microsoft_graph_roomList,
5314
5327
  microsoft_graph_roomCollectionResponse,
5315
- microsoft_graph_plannerBucket,
5316
- microsoft_graph_plannerContainerType,
5317
- microsoft_graph_plannerPlanContainer,
5318
- microsoft_graph_plannerCategoryDescriptions,
5319
- microsoft_graph_plannerUserIds,
5320
- microsoft_graph_plannerPlanDetails,
5321
- microsoft_graph_plannerPlan,
5322
5328
  microsoft_graph_plannerBucketCollectionResponse,
5323
5329
  microsoft_graph_bucketAggregationRange,
5324
5330
  microsoft_graph_bucketAggregationSortProperty,
@@ -7095,7 +7101,7 @@ You can search within a folder hierarchy, a whole drive, or files shared with th
7095
7101
  "Indicates if people external to the organization can send messages to the group. The default value is false. Requires $select to retrieve. Supported only on the Get group API (GET /groups/{ID})."
7096
7102
  ).nullish(),
7097
7103
  assignedLabels: z.array(microsoft_graph_assignedLabel).describe(
7098
- "The list of sensitivity label pairs (label ID, label name) associated with a Microsoft 365 group or a cloud security group. Requires a Microsoft Entra ID P1 license. Requires $select to retrieve. This property can be specified during group creation or update. However, for cloud security groups, it's immutable once set. This property can be updated only in delegated scenarios where the caller requires both the Microsoft Graph permission and a supported administrator role. See Key differences from Microsoft 365 group labeling to learn more about managing this property for Microsoft 365 vs. cloud security groups."
7104
+ "The list of sensitivity label pairs (label ID, label name) associated with a Microsoft 365 group or a cloud security group. Requires a Microsoft Entra ID P1 license. Requires $select to retrieve. This property can be specified during group creation or update. However, for cloud security groups, it's immutable once set. This property can be updated only in delegated scenarios where the caller requires both the Microsoft Graph permission and a supported administrator role. To learn more about managing this property for Microsoft 365 vs. cloud security groups, see Key differences from Microsoft 365 group labeling."
7099
7105
  ).optional(),
7100
7106
  assignedLicenses: z.array(microsoft_graph_assignedLicense).describe(
7101
7107
  "The licenses that are assigned to the group. Requires $select to retrieve. Supports $filter (eq). Read-only."
@@ -7206,7 +7212,7 @@ You can create or update the following types of group: By default, this operatio
7206
7212
  "Indicates if people external to the organization can send messages to the group. The default value is false. Requires $select to retrieve. Supported only on the Get group API (GET /groups/{ID})."
7207
7213
  ).nullish(),
7208
7214
  assignedLabels: z.array(microsoft_graph_assignedLabel).describe(
7209
- "The list of sensitivity label pairs (label ID, label name) associated with a Microsoft 365 group or a cloud security group. Requires a Microsoft Entra ID P1 license. Requires $select to retrieve. This property can be specified during group creation or update. However, for cloud security groups, it's immutable once set. This property can be updated only in delegated scenarios where the caller requires both the Microsoft Graph permission and a supported administrator role. See Key differences from Microsoft 365 group labeling to learn more about managing this property for Microsoft 365 vs. cloud security groups."
7215
+ "The list of sensitivity label pairs (label ID, label name) associated with a Microsoft 365 group or a cloud security group. Requires a Microsoft Entra ID P1 license. Requires $select to retrieve. This property can be specified during group creation or update. However, for cloud security groups, it's immutable once set. This property can be updated only in delegated scenarios where the caller requires both the Microsoft Graph permission and a supported administrator role. To learn more about managing this property for Microsoft 365 vs. cloud security groups, see Key differences from Microsoft 365 group labeling."
7210
7216
  ).optional(),
7211
7217
  assignedLicenses: z.array(microsoft_graph_assignedLicense).describe(
7212
7218
  "The licenses that are assigned to the group. Requires $select to retrieve. Supports $filter (eq). Read-only."
@@ -7618,6 +7624,56 @@ from the default calendar of a group.`,
7618
7624
  ],
7619
7625
  response: z.void()
7620
7626
  },
7627
+ {
7628
+ method: "get",
7629
+ path: "/groups/:groupId/planner/plans",
7630
+ alias: "list-group-planner-plans",
7631
+ description: `Retrieve a list of plannerPlan objects owned by a group object.`,
7632
+ requestFormat: "json",
7633
+ parameters: [
7634
+ {
7635
+ name: "$top",
7636
+ type: "Query",
7637
+ schema: z.number().int().gte(0).describe("Show only the first n items").optional()
7638
+ },
7639
+ {
7640
+ name: "$skip",
7641
+ type: "Query",
7642
+ schema: z.number().int().gte(0).describe("Skip the first n items").optional()
7643
+ },
7644
+ {
7645
+ name: "$search",
7646
+ type: "Query",
7647
+ schema: z.string().describe("Search items by search phrases").optional()
7648
+ },
7649
+ {
7650
+ name: "$filter",
7651
+ type: "Query",
7652
+ schema: z.string().describe("Filter items by property values").optional()
7653
+ },
7654
+ {
7655
+ name: "$count",
7656
+ type: "Query",
7657
+ schema: z.boolean().describe("Include count of items").optional()
7658
+ },
7659
+ {
7660
+ name: "$orderby",
7661
+ type: "Query",
7662
+ schema: z.array(z.string()).describe("Order items by property values").optional()
7663
+ },
7664
+ {
7665
+ name: "$select",
7666
+ type: "Query",
7667
+ schema: z.array(z.string()).describe("Select properties to be returned").optional()
7668
+ },
7669
+ {
7670
+ name: "$expand",
7671
+ type: "Query",
7672
+ schema: z.array(z.string()).describe("Expand related entities").optional()
7673
+ }
7674
+ ],
7675
+ response: z.void()
7676
+ },
7621
7677
  {
7622
7678
  method: "get",
7623
7679
  path: "/groups/:groupId/threads",
@@ -12758,6 +12814,22 @@ Currently, a user can be associated with a team in two different ways:`,
12758
12814
  ],
12759
12815
  response: z.void()
12760
12816
  },
12817
+ {
12818
+ method: "post",
12819
+ path: "/planner/plans",
12820
+ alias: "create-planner-plan",
12821
+ description: `Create a new plannerPlan object.`,
12822
+ requestFormat: "json",
12823
+ parameters: [
12824
+ {
12825
+ name: "body",
12826
+ description: `New navigation property`,
12827
+ type: "Body",
12828
+ schema: microsoft_graph_plannerPlan
12829
+ }
12830
+ ],
12831
+ response: z.void()
12832
+ },
12761
12833
  {
12762
12834
  method: "get",
12763
12835
  path: "/planner/plans/:plannerPlanId",
@@ -12778,6 +12850,22 @@ Currently, a user can be associated with a team in two different ways:`,
12778
12850
  ],
12779
12851
  response: z.void()
12780
12852
  },
12853
+ {
12854
+ method: "patch",
12855
+ path: "/planner/plans/:plannerPlanId",
12856
+ alias: "update-planner-plan",
12857
+ description: `Update the properties of a plannerPlan object.`,
12858
+ requestFormat: "json",
12859
+ parameters: [
12860
+ {
12861
+ name: "body",
12862
+ description: `New navigation property values`,
12863
+ type: "Body",
12864
+ schema: microsoft_graph_plannerPlan
12865
+ }
12866
+ ],
12867
+ response: z.void()
12868
+ },
12781
12869
  {
12782
12870
  method: "get",
12783
12871
  path: "/planner/plans/:plannerPlanId/buckets",
@@ -14864,6 +14952,22 @@ Only the policyViolation property of a chatMessage can be updated in application
14864
14952
  ],
14865
14953
  response: z.void()
14866
14954
  },
14955
+ {
14956
+ method: "post",
14957
+ path: "/teams/:teamId/channels/:channelId/tabs",
14958
+ alias: "create-channel-tab",
14959
+ description: `Add (pin) a tab to the specified channel within a team. The app must be preinstalled in the team and have the configurableTabs property defined in the app manifest.`,
14960
+ requestFormat: "json",
14961
+ parameters: [
14962
+ {
14963
+ name: "body",
14964
+ description: `New navigation property`,
14965
+ type: "Body",
14966
+ schema: microsoft_graph_teamsTab
14967
+ }
14968
+ ],
14969
+ response: z.void()
14970
+ },
14867
14971
  {
14868
14972
  method: "get",
14869
14973
  path: "/teams/:teamId/members",
@@ -86,20 +86,29 @@ function signWhenBodyPresent(target, payload, prefix, suffix) {
86
86
  function signReplyForwardDraft(target, payload, prefix, suffix) {
87
87
  if (!isPlainObject(payload)) return payload;
88
88
  let signed = payload;
89
- if (typeof signed.comment === "string" && signed.comment.trim() !== "") {
90
- signed = { ...signed, comment: signContent(signed.comment, false, prefix, suffix) };
89
+ for (const key of ["comment", "Comment"]) {
90
+ const comment = signed[key];
91
+ if (typeof comment === "string" && comment.trim() !== "") {
92
+ signed = { ...signed, [key]: signContent(comment, false, prefix, suffix) };
93
+ }
91
94
  }
92
- const message = signed.message;
93
- if (isPlainObject(message) && message.body !== void 0) {
94
- signed = { ...signed, message: signItemBodyContainer(target, message, prefix, suffix) };
95
+ for (const key of ["message", "Message"]) {
96
+ const message = signed[key];
97
+ if (isPlainObject(message) && message.body !== void 0) {
98
+ signed = { ...signed, [key]: signItemBodyContainer(target, message, prefix, suffix) };
99
+ }
95
100
  }
96
101
  return signed;
97
102
  }
98
103
  function signSendMail(target, payload, prefix, suffix) {
99
- if (!isPlainObject(payload) || !isPlainObject(payload.message)) {
104
+ const key = isPlainObject(payload) ? ["message", "Message"].find((k) => isPlainObject(payload[k])) : void 0;
105
+ if (!isPlainObject(payload) || key === void 0) {
100
106
  throw new MessageSignoffError(target, "the body has no message object");
101
107
  }
102
- return { ...payload, message: signItemBodyContainer(target, payload.message, prefix, suffix) };
108
+ return {
109
+ ...payload,
110
+ [key]: signItemBodyContainer(target, payload[key], prefix, suffix)
111
+ };
103
112
  }
104
113
  function signGroupThreadReply(target, payload, prefix, suffix) {
105
114
  if (!isPlainObject(payload) || !isPlainObject(payload.post)) {
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.170.1",
4
+ "version": "0.171.0",
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",
@@ -1447,6 +1447,30 @@
1447
1447
  "presets": ["tasks", "work"],
1448
1448
  "scopes": ["Tasks.Read"]
1449
1449
  },
1450
+ {
1451
+ "pathPattern": "/planner/plans",
1452
+ "method": "post",
1453
+ "toolName": "create-planner-plan",
1454
+ "presets": ["tasks", "work"],
1455
+ "scopes": ["Tasks.ReadWrite"],
1456
+ "llmTip": "Body: {\"container\": {\"url\": \"https://graph.microsoft.com/v1.0/groups/{group-id}\"}, \"title\": \"...\"}. For a team, the group id is the team id. The signed-in user must be a member of the group. The container cannot be changed later. Returns the new plan id; to show the plan in a channel, add a Planner tab with create-channel-tab."
1457
+ },
1458
+ {
1459
+ "pathPattern": "/planner/plans/{plannerPlan-id}",
1460
+ "method": "patch",
1461
+ "toolName": "update-planner-plan",
1462
+ "presets": ["tasks", "work"],
1463
+ "scopes": ["Tasks.ReadWrite"],
1464
+ "llmTip": "CRITICAL: Requires If-Match header with ETag from get-planner-plan (use includeHeaders=true)."
1465
+ },
1466
+ {
1467
+ "pathPattern": "/groups/{group-id}/planner/plans",
1468
+ "method": "get",
1469
+ "toolName": "list-group-planner-plans",
1470
+ "presets": ["tasks", "work"],
1471
+ "scopes": ["Tasks.Read"],
1472
+ "llmTip": "Lists the plans owned by a Microsoft 365 group. For a team, the group id is the team id."
1473
+ },
1450
1474
  {
1451
1475
  "pathPattern": "/planner/plans/{plannerPlan-id}/tasks",
1452
1476
  "method": "get",
@@ -1959,6 +1983,14 @@
1959
1983
  "presets": ["teams", "work"],
1960
1984
  "workScopes": ["TeamsTab.Read.All"]
1961
1985
  },
1986
+ {
1987
+ "pathPattern": "/teams/{team-id}/channels/{channel-id}/tabs",
1988
+ "method": "post",
1989
+ "toolName": "create-channel-tab",
1990
+ "presets": ["teams", "work"],
1991
+ "workScopes": ["TeamsTab.Create"],
1992
+ "llmTip": "Body: {\"displayName\": \"...\", \"teamsApp@odata.bind\": \"https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/{teamsAppId}\", \"configuration\": {\"entityId\": ..., \"contentUrl\": ..., \"websiteUrl\": ..., \"removeUrl\": ...}}. Built-in app ids: website com.microsoft.teamspace.tab.web, document library com.microsoft.teamspace.tab.files.sharepoint, Planner com.microsoft.teamspace.tab.planner (see https://learn.microsoft.com/graph/teams-configuring-builtin-tabs). Planner tab for a basic plan (create it first with create-planner-plan): entityId \"planner.v1.{new-guid}_p_{planId}\"; contentUrl \"https://tasks.teams.microsoft.com/teamsui/{tid}/Home/PlannerFrame?page=7&auth_pvr=OrgId&auth_upn={userPrincipalName}&groupId={groupId}&planRoute=/v1/plan/{planId}&subEntityId={subEntityId}&channelId={channelId}&entityId={entityId}&tid={tid}&userObjectId={userObjectId}&sessionId={sessionId}&theme={theme}&mkt={locale}&ringId={ringId}&PlannerRouteHint={tid}&tabVersion=20200228.1_s\"; removeUrl the same with page=13; websiteUrl \"https://planner.cloud.microsoft/webui/v1/plan/{planId}?tid={tenantId}\". Replace only {planId}, {new-guid} and {tenantId} with real values; every other {placeholder} must stay literal, Teams fills it in. A tasks.office.com URL or a missing placeholder renders an error inside the tab."
1993
+ },
1962
1994
  {
1963
1995
  "pathPattern": "/teams/{team-id}/channels/{channel-id}/messages/{chatMessage-id}/setReaction",
1964
1996
  "method": "post",