@softeria/ms-365-mcp-server 0.105.0 → 0.106.1

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.
@@ -1625,10 +1625,11 @@
1625
1625
  "llmTip": "Gets presence status for a specific user by their user ID or UPN (email). Returns availability and activity. Use list-users to find the user ID first."
1626
1626
  },
1627
1627
  {
1628
- "pathPattern": "/communications/presences",
1628
+ "pathPattern": "/communications/getPresencesByUserId",
1629
1629
  "method": "post",
1630
1630
  "toolName": "get-presences-by-user-id",
1631
1631
  "workScopes": ["Presence.Read.All"],
1632
+ "contentType": "application/json",
1632
1633
  "llmTip": "Gets presence for multiple users in a single call. Body: { ids: ['user-id-1', 'user-id-2', ...] }. Returns array of presence objects. More efficient than calling get-user-presence for each user. Maximum 650 user IDs per request."
1633
1634
  },
1634
1635
  {
@@ -1882,21 +1883,21 @@
1882
1883
  "toolName": "get-mail-tips",
1883
1884
  "scopes": ["Mail.Read"],
1884
1885
  "contentType": "application/json",
1885
- "llmTip": "Looks up MailTips for one or more recipients before sending an email — answers 'is this person on auto-reply / OOF?', 'will my email exceed their mailbox quota?', 'are they an external recipient?', 'is this a mailbox or distribution list?'. Body: { EmailAddresses: ['user@contoso.com', ...] (max 100), MailTipsOptions: 'automaticReplies, mailboxFullStatus, customMailTip, externalMemberCount, totalMemberCount, maxMessageSize, deliveryRestriction, moderationStatus, recipientScope, recipientSuggestions' (comma-separated subset) }. Returns mailTips per recipient with the requested fields populated. Use this to short-circuit urgent emails when a recipient is OOF, or to warn before fanning out to a large DL."
1886
+ "llmTip": "Looks up MailTips for one or more recipients before sending an email — answers 'is this person on auto-reply / OOF?', 'will my email exceed their mailbox quota?', 'are they an external recipient?', 'is this a mailbox or distribution list?'. Body: { EmailAddresses: ['user@contoso.com', ...], MailTipsOptions: 'automaticReplies, mailboxFullStatus, customMailTip, externalMemberCount, totalMemberCount, maxMessageSize, deliveryRestriction, moderationStatus, recipientScope, recipientSuggestions' (comma-separated subset) }. Returns mailTips per recipient with the requested fields populated. Use this to short-circuit urgent emails when a recipient is OOF, or to warn before fanning out to a large DL."
1886
1887
  },
1887
1888
  {
1888
1889
  "pathPattern": "/me/outlook/supportedTimeZones(TimeZoneStandard='{TimeZoneStandard}')",
1889
1890
  "method": "get",
1890
1891
  "toolName": "list-supported-time-zones",
1891
1892
  "scopes": ["User.Read"],
1892
- "llmTip": "Lists time zones the user's mailbox server supports. TimeZoneStandard path parameter must be one of: 'windows' (default — Windows time zone names like 'Pacific Standard Time'), or 'iana' (IANA / Olson names like 'America/Los_Angeles'). Returns timeZoneInformation objects with alias and displayName. Use the result to validate or look up the value before calling update-mailbox-settings to change the user's preferred timeZone — the format must match what the server expects."
1893
+ "llmTip": "Lists time zones the user's mailbox server supports. TimeZoneStandard path parameter must be one of: Windows (default — Windows time zone names like 'Pacific Standard Time'), or Iana (IANA / Olson names like 'America/Los_Angeles'). Note the PascalCase — the values are case-sensitive enums, not lowercase strings. Returns timeZoneInformation objects with alias and displayName. Use the result to validate or look up the value before calling update-mailbox-settings to change the user's preferred timeZone — the format must match what the server expects."
1893
1894
  },
1894
1895
  {
1895
1896
  "pathPattern": "/me/outlook/supportedLanguages()",
1896
1897
  "method": "get",
1897
1898
  "toolName": "list-supported-languages",
1898
1899
  "scopes": ["User.Read"],
1899
- "llmTip": "Lists locales and languages the user's mailbox server supports for the Outlook UI and message rendering. Returns localeInfo objects with locale (e.g. 'en-US'), displayName ('English (United States)'), and nativeName ('English (United States)'). Use this to validate the locale value before calling update-mailbox-settings to change the user's preferred language."
1900
+ "llmTip": "Lists locales and languages the user's mailbox server supports for the Outlook UI and message rendering. Returns localeInfo objects with locale (e.g. 'en-US') and displayName ('English (United States)'). Use this to validate the locale value before calling update-mailbox-settings to change the user's preferred language."
1900
1901
  },
1901
1902
  {
1902
1903
  "pathPattern": "/me/calendar/calendarPermissions",
@@ -1938,35 +1939,35 @@
1938
1939
  "method": "post",
1939
1940
  "toolName": "create-contact-child-folder",
1940
1941
  "scopes": ["Contacts.ReadWrite"],
1941
- "llmTip": "Creates a sub-folder under an existing contact folder. Body: { displayName: 'Sub-folder name' }. Names must be unique among siblings under the same parent. Use list-contact-folders to discover the parent id. The returned contactFolder has its own id usable with update-contact-folder, delete-contact-folder, list-contact-folder-contacts, and create-contact-in-folder — contactFolder ids are mailbox-unique regardless of nesting depth."
1942
+ "llmTip": "Creates a sub-folder under an existing contact folder. Body: { displayName: 'Sub-folder name' }. Use list-contact-folders to discover the parent id. The returned contactFolder has its own id usable with update-contact-folder, delete-contact-folder, list-contact-folder-contacts, and create-contact-in-folder — contactFolder ids are mailbox-unique regardless of nesting depth."
1942
1943
  },
1943
1944
  {
1944
1945
  "pathPattern": "/me/contactFolders",
1945
1946
  "method": "get",
1946
1947
  "toolName": "list-contact-folders",
1947
1948
  "scopes": ["Contacts.Read"],
1948
- "llmTip": "Lists the user's Outlook contact folders (the named buckets that organize contacts). Always includes the built-in 'Contacts' folder; user-created folders also appear. Returns id, displayName, parentFolderId, and wellKnownName ('contacts' for the default). Use this before list-contact-folder-contacts or create-contact-in-folder to discover folder ids. Supports $filter, $top, $orderby."
1949
+ "llmTip": "Lists the user's Outlook contact folders (the named buckets that organize contacts). Always includes the built-in 'Contacts' folder; user-created folders also appear. Returns id, displayName, and parentFolderId. To identify the default folder, match displayName === 'Contacts'. Use this before list-contact-folder-contacts or create-contact-in-folder to discover folder ids. Supports OData query parameters."
1949
1950
  },
1950
1951
  {
1951
1952
  "pathPattern": "/me/contactFolders",
1952
1953
  "method": "post",
1953
1954
  "toolName": "create-contact-folder",
1954
1955
  "scopes": ["Contacts.ReadWrite"],
1955
- "llmTip": "Creates a new contact folder under the user's mailbox root. Body: { displayName: 'Family' }. Returns the created contactFolder with its id. Folder names must be unique among siblings. To create a sub-folder, POST to /me/contactFolders/{parent-id}/childFolders instead not currently exposed."
1956
+ "llmTip": "Creates a new contact folder under the user's mailbox root. Body: { displayName: 'Family' }. Returns the created contactFolder with its id. To create a sub-folder under an existing folder, use create-contact-child-folder."
1956
1957
  },
1957
1958
  {
1958
1959
  "pathPattern": "/me/contactFolders/{contactFolder-id}",
1959
1960
  "method": "patch",
1960
1961
  "toolName": "update-contact-folder",
1961
1962
  "scopes": ["Contacts.ReadWrite"],
1962
- "llmTip": "Renames a contact folder. Body: { displayName: 'New name' }. Only displayName is writable. The default 'Contacts' folder cannot be renamed — Graph returns an error. Get the folder id via list-contact-folders."
1963
+ "llmTip": "Updates a contact folder. Body: { displayName?: 'New name', parentFolderId?: '<id>' } both displayName (rename) and parentFolderId (move) are writable. The default 'Contacts' folder may not be renameable. Get the folder id via list-contact-folders."
1963
1964
  },
1964
1965
  {
1965
1966
  "pathPattern": "/me/contactFolders/{contactFolder-id}",
1966
1967
  "method": "delete",
1967
1968
  "toolName": "delete-contact-folder",
1968
1969
  "scopes": ["Contacts.ReadWrite"],
1969
- "llmTip": "Deletes a contact folder and ALL contacts in it (cascades). The default 'Contacts' folder cannot be deleted — Graph returns an error. Get the folder id via list-contact-folders. Operation is irreversible."
1970
+ "llmTip": "Deletes a contact folder. The default 'Contacts' folder cannot be deleted — Graph returns an error. The folder (and its contents) typically lands in Deleted Items rather than being permanently removed. Get the folder id via list-contact-folders."
1970
1971
  },
1971
1972
  {
1972
1973
  "pathPattern": "/me/contactFolders/{contactFolder-id}/contacts",
@@ -2009,14 +2010,14 @@
2009
2010
  "method": "delete",
2010
2011
  "toolName": "delete-todo-task-list",
2011
2012
  "scopes": ["Tasks.ReadWrite"],
2012
- "llmTip": "Deletes a Microsoft To Do task list and ALL of its tasks (cascades). Built-in lists cannot be deleted — the API returns an error for those. Get list ids via list-todo-task-lists. Operation is irreversible."
2013
+ "llmTip": "Deletes a Microsoft To Do task list. Built-in lists (Flagged emails, the default Tasks list) cannot be deleted — the API returns an error for those. Get list ids via list-todo-task-lists."
2013
2014
  },
2014
2015
  {
2015
2016
  "pathPattern": "/me/onenote/pages",
2016
2017
  "method": "get",
2017
2018
  "toolName": "list-onenote-pages",
2018
2019
  "scopes": ["Notes.Read"],
2019
- "llmTip": "Lists all OneNote pages across every notebook and section the user has access to — transverse alternative to walking notebooks → sections → pages. Default returns top 20 ordered by lastModifiedTime desc. Supports $search='query' for full-text search across page titles and bodies, $filter (e.g. lastModifiedTime gt 2026-01-01), $top (max 100), $select, and $expand=parentNotebook,parentSection. Use $search before bouncing through list-onenote-notebooks / list-all-onenote-sections / list-onenote-section-pages when you only have a topic in mind."
2020
+ "llmTip": "Lists all OneNote pages across every notebook and section the user has access to — transverse alternative to walking notebooks → sections → pages. Default returns top 20 ordered by lastModifiedTime desc. Supports $filter (e.g. lastModifiedTime gt 2026-01-01, or contains(tolower(title), 'topic') for title search), $top (max 100), $select, and $expand=parentNotebook,parentSection. Use this instead of bouncing through list-onenote-notebooks / list-all-onenote-sections / list-onenote-section-pages when you have a topic in mind."
2020
2021
  },
2021
2022
  {
2022
2023
  "pathPattern": "/me/onenote/sectionGroups",
@@ -2031,6 +2032,68 @@
2031
2032
  "toolName": "get-onenote-notebook-from-web-url",
2032
2033
  "workScopes": ["Notes.Read"],
2033
2034
  "contentType": "application/json",
2034
- "llmTip": "Resolves a OneNote notebook from its web URL (the link a user copies from OneNote / SharePoint / Teams). Body: { webUrl: 'https://...' }. Returns a CopyNotebookModel with the notebook's id, displayName, sectionsUrl, sectionGroupsUrl, and isShared — you can then list its sections via list-onenote-notebook-sections. Accepts user notebooks, group notebooks, and SharePoint-hosted team notebooks. Personal Microsoft accounts are not supported."
2035
+ "llmTip": "Resolves a OneNote notebook from its web URL (the link a user copies from OneNote / SharePoint / Teams). Body: { webUrl: 'https://...' }. Returns a notebook object with id, displayName, sectionsUrl, sectionGroupsUrl, and isShared — you can then list its sections via list-onenote-notebook-sections. Accepts user notebooks, group notebooks, and SharePoint-hosted team notebooks. Personal Microsoft accounts are not supported."
2036
+ },
2037
+ {
2038
+ "pathPattern": "/me/presence/setPresence",
2039
+ "method": "post",
2040
+ "toolName": "set-my-presence",
2041
+ "workScopes": ["Presence.ReadWrite"],
2042
+ "contentType": "application/json",
2043
+ "llmTip": "Sets the user's presence session as an application. Body: { sessionId (your app's client/session id, required), availability + activity (must be one of these documented combos: Available/Available, Busy/InACall, Busy/InAConferenceCall, Away/Away, DoNotDisturb/Presenting), expirationDuration (ISO 8601 duration like 'PT1H' — defaults to PT5M, valid range PT5M–PT4H) }. Note: if the user also wants to override their *visible* status regardless of activity, prefer set-my-user-preferred-presence. clear-my-presence ends the session."
2044
+ },
2045
+ {
2046
+ "pathPattern": "/me/presence/clearPresence",
2047
+ "method": "post",
2048
+ "toolName": "clear-my-presence",
2049
+ "workScopes": ["Presence.ReadWrite"],
2050
+ "contentType": "application/json",
2051
+ "llmTip": "Ends the application's presence session for the current user. Body: { sessionId } — must match the sessionId used in set-my-presence. If this was the user's only presence session, their status returns to Offline."
2052
+ },
2053
+ {
2054
+ "pathPattern": "/me/presence/setUserPreferredPresence",
2055
+ "method": "post",
2056
+ "toolName": "set-my-user-preferred-presence",
2057
+ "workScopes": ["Presence.ReadWrite"],
2058
+ "contentType": "application/json",
2059
+ "llmTip": "Sets the user's preferred (sticky) availability and activity — the value Teams clients display regardless of underlying activity. Body: { availability + activity (must be one of these documented combos: Available/Available, Busy/Busy, DoNotDisturb/DoNotDisturb, BeRightBack/BeRightBack, Away/Away, Offline/OffWork), expirationDuration (ISO 8601 duration like 'PT2H' — if omitted, defaults to 1 day for DoNotDisturb/Busy and 7 days for other availability values; not 'indefinite'). Requires at least one active presence session (Teams client signed in or set-my-presence call) — otherwise the user appears Offline. Use this for 'put me in Do Not Disturb for 2 hours' workflows. clear-my-user-preferred-presence reverts to actual presence."
2060
+ },
2061
+ {
2062
+ "pathPattern": "/me/presence/clearUserPreferredPresence",
2063
+ "method": "post",
2064
+ "toolName": "clear-my-user-preferred-presence",
2065
+ "workScopes": ["Presence.ReadWrite"],
2066
+ "contentType": "application/json",
2067
+ "llmTip": "Clears any preferred (sticky) presence override set via set-my-user-preferred-presence. The user's visible status returns to their actual activity. Body: {} (an empty JSON object — required, not 'no body')."
2068
+ },
2069
+ {
2070
+ "pathPattern": "/me/presence/setStatusMessage",
2071
+ "method": "post",
2072
+ "toolName": "set-my-status-message",
2073
+ "workScopes": ["Presence.ReadWrite"],
2074
+ "contentType": "application/json",
2075
+ "llmTip": "Sets the user's Teams status message (the free-text note shown next to their name, e.g. 'Heads-down on Q3 plan'). Body: { statusMessage: { message: { content: 'text or HTML', contentType: 'text' | 'html' }, expiryDateTime: { dateTime: '2026-05-06T17:00:00', timeZone: 'UTC' } (optional) } }. Pass an empty object {} or message.content='' to clear. expiryDateTime is optional — omit for no expiration."
2076
+ },
2077
+ {
2078
+ "pathPattern": "/me/teamwork/associatedTeams",
2079
+ "method": "get",
2080
+ "toolName": "list-my-associated-teams",
2081
+ "workScopes": ["Team.ReadBasic.All"],
2082
+ "llmTip": "Lists Teams the current user is associated with — both joined teams and host teams of shared channels the user is a direct member of. Returns associatedTeamInfo objects with id, displayName, and tenantId. Broader than list-joined-teams because it includes shared-channel host teams."
2083
+ },
2084
+ {
2085
+ "pathPattern": "/me/teamwork/installedApps",
2086
+ "method": "get",
2087
+ "toolName": "list-my-installed-teams-apps",
2088
+ "workScopes": ["TeamsAppInstallation.ReadForUser"],
2089
+ "llmTip": "Lists Teams apps installed in the current user's personal scope (the apps pinned to the user's Teams sidebar / accessible without joining a team or chat). Use $expand=teamsApp,teamsAppDefinition for full app metadata (displayName, version, distributionMethod). Useful before send-my-activity-notification to discover the user's own teamsAppId."
2090
+ },
2091
+ {
2092
+ "pathPattern": "/me/teamwork/sendActivityNotification",
2093
+ "method": "post",
2094
+ "toolName": "send-my-activity-notification",
2095
+ "workScopes": ["TeamsActivity.Send"],
2096
+ "contentType": "application/json",
2097
+ "llmTip": "Sends a Teams activity feed notification to the current user (the badge + entry in their Activity tab). Body: { topic: { source: 'entityUrl' | 'text', value: <Graph URL or plain text>, webUrl: <required when source='text', click-through URL> }, activityType: <must be declared in the calling Teams app's manifest, OR the reserved 'systemDefault' which provides free-form Actor+Reason text>, previewText: { content: 'short preview' }, templateParameters?: [{ name, value }] (substituted into the manifest's localized notification template), teamsAppId?: <optional disambiguator when multiple installed apps share a Microsoft Entra app ID — fetch via list-my-installed-teams-apps>, chainId?, iconId? }. Use to ping the user with 'action required' notifications from agentic workflows. See https://learn.microsoft.com/graph/teams-send-activityfeednotifications."
2035
2098
  }
2036
2099
  ]
@@ -432,6 +432,8 @@ const microsoft_graph_pinnedChatMessageInfoCollectionResponse = z.object({
432
432
  "@odata.nextLink": z.string().nullable(),
433
433
  value: z.array(microsoft_graph_pinnedChatMessageInfo)
434
434
  }).partial().passthrough();
435
+ const get_presences_by_user_id_Body = z.object({ ids: z.array(z.string()) }).partial().passthrough();
436
+ const BaseCollectionPaginationCountResponse = z.object({ "@odata.count": z.number().int().nullable(), "@odata.nextLink": z.string().nullable() }).partial().passthrough();
435
437
  const microsoft_graph_outOfOfficeSettings = z.object({
436
438
  isOutOfOffice: z.boolean().describe(
437
439
  "If true, either of the following is met:The current time falls within the out-of-office window configured in Outlook or Teams.An event marked as 'Show as Out of Office' appears on the user's calendar.Otherwise, false."
@@ -900,7 +902,6 @@ const share_drive_item_Body = z.object({
900
902
  expirationDateTime: z.string().nullable(),
901
903
  password: z.string().nullable()
902
904
  }).partial().passthrough();
903
- const BaseCollectionPaginationCountResponse = z.object({ "@odata.count": z.number().int().nullable(), "@odata.nextLink": z.string().nullable() }).partial().passthrough();
904
905
  const ReferenceNumeric = z.enum(["-INF", "INF", "NaN"]);
905
906
  const create_drive_item_preview_Body = z.object({
906
907
  page: z.string().nullable(),
@@ -3780,6 +3781,55 @@ const microsoft_graph_plannerTaskCollectionResponse = z.object({
3780
3781
  "@odata.nextLink": z.string().nullable(),
3781
3782
  value: z.array(microsoft_graph_plannerTask)
3782
3783
  }).partial().passthrough();
3784
+ const set_my_presence_Body = z.object({
3785
+ sessionId: z.string().nullable(),
3786
+ availability: z.string(),
3787
+ activity: z.string(),
3788
+ expirationDuration: z.string().regex(/^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$/).nullable()
3789
+ }).partial().passthrough();
3790
+ const set_my_status_message_Body = z.object({
3791
+ statusMessage: z.union([
3792
+ microsoft_graph_presenceStatusMessage,
3793
+ z.object({}).partial().passthrough()
3794
+ ])
3795
+ }).partial().passthrough();
3796
+ const set_my_user_preferred_presence_Body = z.object({
3797
+ availability: z.string(),
3798
+ activity: z.string(),
3799
+ expirationDuration: z.string().regex(/^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$/).nullable()
3800
+ }).partial().passthrough();
3801
+ const microsoft_graph_associatedTeamInfo = z.object({
3802
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
3803
+ displayName: z.string().describe("The name of the team.").nullish(),
3804
+ tenantId: z.string().describe("The ID of the Microsoft Entra tenant.").nullish(),
3805
+ team: microsoft_graph_team.describe("[Note: Simplified from 30 properties to 25 most common ones]").optional()
3806
+ }).passthrough();
3807
+ const microsoft_graph_associatedTeamInfoCollectionResponse = z.object({
3808
+ "@odata.count": z.number().int().nullable(),
3809
+ "@odata.nextLink": z.string().nullable(),
3810
+ value: z.array(microsoft_graph_associatedTeamInfo)
3811
+ }).partial().passthrough();
3812
+ const microsoft_graph_userScopeTeamsAppInstallation = z.object({
3813
+ id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
3814
+ consentedPermissionSet: microsoft_graph_teamsAppPermissionSet.optional(),
3815
+ teamsApp: microsoft_graph_teamsApp.optional(),
3816
+ teamsAppDefinition: microsoft_graph_teamsAppDefinition.optional(),
3817
+ chat: microsoft_graph_chat.optional()
3818
+ }).passthrough();
3819
+ const microsoft_graph_userScopeTeamsAppInstallationCollectionResponse = z.object({
3820
+ "@odata.count": z.number().int().nullable(),
3821
+ "@odata.nextLink": z.string().nullable(),
3822
+ value: z.array(microsoft_graph_userScopeTeamsAppInstallation)
3823
+ }).partial().passthrough();
3824
+ const send_my_activity_notification_Body = z.object({
3825
+ topic: z.object({}).partial().passthrough(),
3826
+ activityType: z.string().nullable(),
3827
+ chainId: z.number().nullable(),
3828
+ previewText: z.union([microsoft_graph_itemBody, z.object({}).partial().passthrough()]),
3829
+ teamsAppId: z.string().nullable(),
3830
+ templateParameters: z.array(z.object({}).partial().passthrough()),
3831
+ iconId: z.string().nullable()
3832
+ }).partial().passthrough();
3783
3833
  const microsoft_graph_wellknownListName = z.enum([
3784
3834
  "none",
3785
3835
  "defaultList",
@@ -4623,6 +4673,8 @@ const schemas = {
4623
4673
  microsoft_graph_chatMessageCollectionResponse,
4624
4674
  microsoft_graph_chatMessageHostedContentCollectionResponse,
4625
4675
  microsoft_graph_pinnedChatMessageInfoCollectionResponse,
4676
+ get_presences_by_user_id_Body,
4677
+ BaseCollectionPaginationCountResponse,
4626
4678
  microsoft_graph_outOfOfficeSettings,
4627
4679
  microsoft_graph_dateTimeTimeZone,
4628
4680
  microsoft_graph_presenceStatusMessage,
@@ -4669,7 +4721,6 @@ const schemas = {
4669
4721
  microsoft_graph_sensitivityLabelAssignment,
4670
4722
  microsoft_graph_extractSensitivityLabelsResult,
4671
4723
  share_drive_item_Body,
4672
- BaseCollectionPaginationCountResponse,
4673
4724
  ReferenceNumeric,
4674
4725
  create_drive_item_preview_Body,
4675
4726
  microsoft_graph_itemPreviewInfo,
@@ -4957,6 +5008,14 @@ const schemas = {
4957
5008
  microsoft_graph_plannerBucketTaskBoardTaskFormat,
4958
5009
  microsoft_graph_plannerTask,
4959
5010
  microsoft_graph_plannerTaskCollectionResponse,
5011
+ set_my_presence_Body,
5012
+ set_my_status_message_Body,
5013
+ set_my_user_preferred_presence_Body,
5014
+ microsoft_graph_associatedTeamInfo,
5015
+ microsoft_graph_associatedTeamInfoCollectionResponse,
5016
+ microsoft_graph_userScopeTeamsAppInstallation,
5017
+ microsoft_graph_userScopeTeamsAppInstallationCollectionResponse,
5018
+ send_my_activity_notification_Body,
4960
5019
  microsoft_graph_wellknownListName,
4961
5020
  microsoft_graph_taskStatus,
4962
5021
  microsoft_graph_attachmentBase,
@@ -5462,16 +5521,16 @@ const endpoints = makeApi([
5462
5521
  },
5463
5522
  {
5464
5523
  method: "post",
5465
- path: "/communications/presences",
5524
+ path: "/communications/getPresencesByUserId",
5466
5525
  alias: "get-presences-by-user-id",
5467
- description: `Create new navigation property to presences for communications`,
5526
+ description: `Get the presence information for multiple users.`,
5468
5527
  requestFormat: "json",
5469
5528
  parameters: [
5470
5529
  {
5471
5530
  name: "body",
5472
- description: `New navigation property`,
5531
+ description: `Action parameters`,
5473
5532
  type: "Body",
5474
- schema: microsoft_graph_presence
5533
+ schema: get_presences_by_user_id_Body
5475
5534
  }
5476
5535
  ],
5477
5536
  response: z.void()
@@ -11371,6 +11430,78 @@ getting the user's mailbox settings.`,
11371
11430
  ],
11372
11431
  response: z.void()
11373
11432
  },
11433
+ {
11434
+ method: "post",
11435
+ path: "/me/presence/clearPresence",
11436
+ alias: "clear-my-presence",
11437
+ description: `Clear the application's presence session for a user. If it is the user's only presence session, the user's presence will change to Offline/Offline. For details about presences sessions, see presence: setPresence.`,
11438
+ requestFormat: "json",
11439
+ parameters: [
11440
+ {
11441
+ name: "body",
11442
+ description: `Action parameters`,
11443
+ type: "Body",
11444
+ schema: z.object({ sessionId: z.string().nullable() }).partial().passthrough()
11445
+ }
11446
+ ],
11447
+ response: z.void()
11448
+ },
11449
+ {
11450
+ method: "post",
11451
+ path: "/me/presence/clearUserPreferredPresence",
11452
+ alias: "clear-my-user-preferred-presence",
11453
+ description: `Clear the preferred availability and activity status for a user.`,
11454
+ requestFormat: "json",
11455
+ response: z.void()
11456
+ },
11457
+ {
11458
+ method: "post",
11459
+ path: "/me/presence/setPresence",
11460
+ alias: "set-my-presence",
11461
+ description: `Set the state of a user's presence session as an application. For more information about presence sessions, states permutations, and timeouts, see Manage presence state using the Microsoft Graph API.`,
11462
+ requestFormat: "json",
11463
+ parameters: [
11464
+ {
11465
+ name: "body",
11466
+ description: `Action parameters`,
11467
+ type: "Body",
11468
+ schema: set_my_presence_Body
11469
+ }
11470
+ ],
11471
+ response: z.void()
11472
+ },
11473
+ {
11474
+ method: "post",
11475
+ path: "/me/presence/setStatusMessage",
11476
+ alias: "set-my-status-message",
11477
+ description: `Set a presence status message for a user. An optional expiration date and time can be supplied.`,
11478
+ requestFormat: "json",
11479
+ parameters: [
11480
+ {
11481
+ name: "body",
11482
+ description: `Action parameters`,
11483
+ type: "Body",
11484
+ schema: set_my_status_message_Body
11485
+ }
11486
+ ],
11487
+ response: z.void()
11488
+ },
11489
+ {
11490
+ method: "post",
11491
+ path: "/me/presence/setUserPreferredPresence",
11492
+ alias: "set-my-user-preferred-presence",
11493
+ description: `Set the preferred availability and activity status for a user. If the preferred presence of a user is set, the user's presence shows as the preferred status. Preferred presence takes effect only when at least one presence session exists for the user. Otherwise, the user's presence shows as Offline. A presence session is created as a result of a successful setPresence operation, or if the user is signed in on a Microsoft Teams client. For more details, see presence sessions and time-out and expiration.`,
11494
+ requestFormat: "json",
11495
+ parameters: [
11496
+ {
11497
+ name: "body",
11498
+ description: `Action parameters`,
11499
+ type: "Body",
11500
+ schema: set_my_user_preferred_presence_Body
11501
+ }
11502
+ ],
11503
+ response: z.void()
11504
+ },
11374
11505
  {
11375
11506
  method: "post",
11376
11507
  path: "/me/sendMail",
@@ -11387,6 +11518,123 @@ getting the user's mailbox settings.`,
11387
11518
  ],
11388
11519
  response: z.void()
11389
11520
  },
11521
+ {
11522
+ method: "get",
11523
+ path: "/me/teamwork/associatedTeams",
11524
+ alias: "list-my-associated-teams",
11525
+ description: `Get the list of teams in Microsoft Teams that a user is associated with.
11526
+ Currently, a user can be associated with a team in two different ways:`,
11527
+ requestFormat: "json",
11528
+ parameters: [
11529
+ {
11530
+ name: "$top",
11531
+ type: "Query",
11532
+ schema: z.number().int().gte(0).describe("Show only the first n items").optional()
11533
+ },
11534
+ {
11535
+ name: "$skip",
11536
+ type: "Query",
11537
+ schema: z.number().int().gte(0).describe("Skip the first n items").optional()
11538
+ },
11539
+ {
11540
+ name: "$search",
11541
+ type: "Query",
11542
+ schema: z.string().describe("Search items by search phrases").optional()
11543
+ },
11544
+ {
11545
+ name: "$filter",
11546
+ type: "Query",
11547
+ schema: z.string().describe("Filter items by property values").optional()
11548
+ },
11549
+ {
11550
+ name: "$count",
11551
+ type: "Query",
11552
+ schema: z.boolean().describe("Include count of items").optional()
11553
+ },
11554
+ {
11555
+ name: "$orderby",
11556
+ type: "Query",
11557
+ schema: z.array(z.string()).describe("Order items by property values").optional()
11558
+ },
11559
+ {
11560
+ name: "$select",
11561
+ type: "Query",
11562
+ schema: z.array(z.string()).describe("Select properties to be returned").optional()
11563
+ },
11564
+ {
11565
+ name: "$expand",
11566
+ type: "Query",
11567
+ schema: z.array(z.string()).describe("Expand related entities").optional()
11568
+ }
11569
+ ],
11570
+ response: z.void()
11571
+ },
11572
+ {
11573
+ method: "get",
11574
+ path: "/me/teamwork/installedApps",
11575
+ alias: "list-my-installed-teams-apps",
11576
+ description: `The apps installed in the personal scope of this user.`,
11577
+ requestFormat: "json",
11578
+ parameters: [
11579
+ {
11580
+ name: "$top",
11581
+ type: "Query",
11582
+ schema: z.number().int().gte(0).describe("Show only the first n items").optional()
11583
+ },
11584
+ {
11585
+ name: "$skip",
11586
+ type: "Query",
11587
+ schema: z.number().int().gte(0).describe("Skip the first n items").optional()
11588
+ },
11589
+ {
11590
+ name: "$search",
11591
+ type: "Query",
11592
+ schema: z.string().describe("Search items by search phrases").optional()
11593
+ },
11594
+ {
11595
+ name: "$filter",
11596
+ type: "Query",
11597
+ schema: z.string().describe("Filter items by property values").optional()
11598
+ },
11599
+ {
11600
+ name: "$count",
11601
+ type: "Query",
11602
+ schema: z.boolean().describe("Include count of items").optional()
11603
+ },
11604
+ {
11605
+ name: "$orderby",
11606
+ type: "Query",
11607
+ schema: z.array(z.string()).describe("Order items by property values").optional()
11608
+ },
11609
+ {
11610
+ name: "$select",
11611
+ type: "Query",
11612
+ schema: z.array(z.string()).describe("Select properties to be returned").optional()
11613
+ },
11614
+ {
11615
+ name: "$expand",
11616
+ type: "Query",
11617
+ schema: z.array(z.string()).describe("Expand related entities").optional()
11618
+ }
11619
+ ],
11620
+ response: z.void()
11621
+ },
11622
+ {
11623
+ method: "post",
11624
+ path: "/me/teamwork/sendActivityNotification",
11625
+ alias: "send-my-activity-notification",
11626
+ description: `Send an activity feed notification to a user. For more information, see sending Teams activity notifications.`,
11627
+ requestFormat: "json",
11628
+ parameters: [
11629
+ {
11630
+ name: "body",
11631
+ description: `Action parameters`,
11632
+ type: "Body",
11633
+ schema: send_my_activity_notification_Body
11634
+ }
11635
+ ],
11636
+ response: z.void()
11637
+ },
11390
11638
  {
11391
11639
  method: "get",
11392
11640
  path: "/me/todo/lists",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softeria/ms-365-mcp-server",
3
- "version": "0.105.0",
3
+ "version": "0.106.1",
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",
@@ -1625,10 +1625,11 @@
1625
1625
  "llmTip": "Gets presence status for a specific user by their user ID or UPN (email). Returns availability and activity. Use list-users to find the user ID first."
1626
1626
  },
1627
1627
  {
1628
- "pathPattern": "/communications/presences",
1628
+ "pathPattern": "/communications/getPresencesByUserId",
1629
1629
  "method": "post",
1630
1630
  "toolName": "get-presences-by-user-id",
1631
1631
  "workScopes": ["Presence.Read.All"],
1632
+ "contentType": "application/json",
1632
1633
  "llmTip": "Gets presence for multiple users in a single call. Body: { ids: ['user-id-1', 'user-id-2', ...] }. Returns array of presence objects. More efficient than calling get-user-presence for each user. Maximum 650 user IDs per request."
1633
1634
  },
1634
1635
  {
@@ -1882,21 +1883,21 @@
1882
1883
  "toolName": "get-mail-tips",
1883
1884
  "scopes": ["Mail.Read"],
1884
1885
  "contentType": "application/json",
1885
- "llmTip": "Looks up MailTips for one or more recipients before sending an email — answers 'is this person on auto-reply / OOF?', 'will my email exceed their mailbox quota?', 'are they an external recipient?', 'is this a mailbox or distribution list?'. Body: { EmailAddresses: ['user@contoso.com', ...] (max 100), MailTipsOptions: 'automaticReplies, mailboxFullStatus, customMailTip, externalMemberCount, totalMemberCount, maxMessageSize, deliveryRestriction, moderationStatus, recipientScope, recipientSuggestions' (comma-separated subset) }. Returns mailTips per recipient with the requested fields populated. Use this to short-circuit urgent emails when a recipient is OOF, or to warn before fanning out to a large DL."
1886
+ "llmTip": "Looks up MailTips for one or more recipients before sending an email — answers 'is this person on auto-reply / OOF?', 'will my email exceed their mailbox quota?', 'are they an external recipient?', 'is this a mailbox or distribution list?'. Body: { EmailAddresses: ['user@contoso.com', ...], MailTipsOptions: 'automaticReplies, mailboxFullStatus, customMailTip, externalMemberCount, totalMemberCount, maxMessageSize, deliveryRestriction, moderationStatus, recipientScope, recipientSuggestions' (comma-separated subset) }. Returns mailTips per recipient with the requested fields populated. Use this to short-circuit urgent emails when a recipient is OOF, or to warn before fanning out to a large DL."
1886
1887
  },
1887
1888
  {
1888
1889
  "pathPattern": "/me/outlook/supportedTimeZones(TimeZoneStandard='{TimeZoneStandard}')",
1889
1890
  "method": "get",
1890
1891
  "toolName": "list-supported-time-zones",
1891
1892
  "scopes": ["User.Read"],
1892
- "llmTip": "Lists time zones the user's mailbox server supports. TimeZoneStandard path parameter must be one of: 'windows' (default — Windows time zone names like 'Pacific Standard Time'), or 'iana' (IANA / Olson names like 'America/Los_Angeles'). Returns timeZoneInformation objects with alias and displayName. Use the result to validate or look up the value before calling update-mailbox-settings to change the user's preferred timeZone — the format must match what the server expects."
1893
+ "llmTip": "Lists time zones the user's mailbox server supports. TimeZoneStandard path parameter must be one of: Windows (default — Windows time zone names like 'Pacific Standard Time'), or Iana (IANA / Olson names like 'America/Los_Angeles'). Note the PascalCase — the values are case-sensitive enums, not lowercase strings. Returns timeZoneInformation objects with alias and displayName. Use the result to validate or look up the value before calling update-mailbox-settings to change the user's preferred timeZone — the format must match what the server expects."
1893
1894
  },
1894
1895
  {
1895
1896
  "pathPattern": "/me/outlook/supportedLanguages()",
1896
1897
  "method": "get",
1897
1898
  "toolName": "list-supported-languages",
1898
1899
  "scopes": ["User.Read"],
1899
- "llmTip": "Lists locales and languages the user's mailbox server supports for the Outlook UI and message rendering. Returns localeInfo objects with locale (e.g. 'en-US'), displayName ('English (United States)'), and nativeName ('English (United States)'). Use this to validate the locale value before calling update-mailbox-settings to change the user's preferred language."
1900
+ "llmTip": "Lists locales and languages the user's mailbox server supports for the Outlook UI and message rendering. Returns localeInfo objects with locale (e.g. 'en-US') and displayName ('English (United States)'). Use this to validate the locale value before calling update-mailbox-settings to change the user's preferred language."
1900
1901
  },
1901
1902
  {
1902
1903
  "pathPattern": "/me/calendar/calendarPermissions",
@@ -1938,35 +1939,35 @@
1938
1939
  "method": "post",
1939
1940
  "toolName": "create-contact-child-folder",
1940
1941
  "scopes": ["Contacts.ReadWrite"],
1941
- "llmTip": "Creates a sub-folder under an existing contact folder. Body: { displayName: 'Sub-folder name' }. Names must be unique among siblings under the same parent. Use list-contact-folders to discover the parent id. The returned contactFolder has its own id usable with update-contact-folder, delete-contact-folder, list-contact-folder-contacts, and create-contact-in-folder — contactFolder ids are mailbox-unique regardless of nesting depth."
1942
+ "llmTip": "Creates a sub-folder under an existing contact folder. Body: { displayName: 'Sub-folder name' }. Use list-contact-folders to discover the parent id. The returned contactFolder has its own id usable with update-contact-folder, delete-contact-folder, list-contact-folder-contacts, and create-contact-in-folder — contactFolder ids are mailbox-unique regardless of nesting depth."
1942
1943
  },
1943
1944
  {
1944
1945
  "pathPattern": "/me/contactFolders",
1945
1946
  "method": "get",
1946
1947
  "toolName": "list-contact-folders",
1947
1948
  "scopes": ["Contacts.Read"],
1948
- "llmTip": "Lists the user's Outlook contact folders (the named buckets that organize contacts). Always includes the built-in 'Contacts' folder; user-created folders also appear. Returns id, displayName, parentFolderId, and wellKnownName ('contacts' for the default). Use this before list-contact-folder-contacts or create-contact-in-folder to discover folder ids. Supports $filter, $top, $orderby."
1949
+ "llmTip": "Lists the user's Outlook contact folders (the named buckets that organize contacts). Always includes the built-in 'Contacts' folder; user-created folders also appear. Returns id, displayName, and parentFolderId. To identify the default folder, match displayName === 'Contacts'. Use this before list-contact-folder-contacts or create-contact-in-folder to discover folder ids. Supports OData query parameters."
1949
1950
  },
1950
1951
  {
1951
1952
  "pathPattern": "/me/contactFolders",
1952
1953
  "method": "post",
1953
1954
  "toolName": "create-contact-folder",
1954
1955
  "scopes": ["Contacts.ReadWrite"],
1955
- "llmTip": "Creates a new contact folder under the user's mailbox root. Body: { displayName: 'Family' }. Returns the created contactFolder with its id. Folder names must be unique among siblings. To create a sub-folder, POST to /me/contactFolders/{parent-id}/childFolders instead not currently exposed."
1956
+ "llmTip": "Creates a new contact folder under the user's mailbox root. Body: { displayName: 'Family' }. Returns the created contactFolder with its id. To create a sub-folder under an existing folder, use create-contact-child-folder."
1956
1957
  },
1957
1958
  {
1958
1959
  "pathPattern": "/me/contactFolders/{contactFolder-id}",
1959
1960
  "method": "patch",
1960
1961
  "toolName": "update-contact-folder",
1961
1962
  "scopes": ["Contacts.ReadWrite"],
1962
- "llmTip": "Renames a contact folder. Body: { displayName: 'New name' }. Only displayName is writable. The default 'Contacts' folder cannot be renamed — Graph returns an error. Get the folder id via list-contact-folders."
1963
+ "llmTip": "Updates a contact folder. Body: { displayName?: 'New name', parentFolderId?: '<id>' } both displayName (rename) and parentFolderId (move) are writable. The default 'Contacts' folder may not be renameable. Get the folder id via list-contact-folders."
1963
1964
  },
1964
1965
  {
1965
1966
  "pathPattern": "/me/contactFolders/{contactFolder-id}",
1966
1967
  "method": "delete",
1967
1968
  "toolName": "delete-contact-folder",
1968
1969
  "scopes": ["Contacts.ReadWrite"],
1969
- "llmTip": "Deletes a contact folder and ALL contacts in it (cascades). The default 'Contacts' folder cannot be deleted — Graph returns an error. Get the folder id via list-contact-folders. Operation is irreversible."
1970
+ "llmTip": "Deletes a contact folder. The default 'Contacts' folder cannot be deleted — Graph returns an error. The folder (and its contents) typically lands in Deleted Items rather than being permanently removed. Get the folder id via list-contact-folders."
1970
1971
  },
1971
1972
  {
1972
1973
  "pathPattern": "/me/contactFolders/{contactFolder-id}/contacts",
@@ -2009,14 +2010,14 @@
2009
2010
  "method": "delete",
2010
2011
  "toolName": "delete-todo-task-list",
2011
2012
  "scopes": ["Tasks.ReadWrite"],
2012
- "llmTip": "Deletes a Microsoft To Do task list and ALL of its tasks (cascades). Built-in lists cannot be deleted — the API returns an error for those. Get list ids via list-todo-task-lists. Operation is irreversible."
2013
+ "llmTip": "Deletes a Microsoft To Do task list. Built-in lists (Flagged emails, the default Tasks list) cannot be deleted — the API returns an error for those. Get list ids via list-todo-task-lists."
2013
2014
  },
2014
2015
  {
2015
2016
  "pathPattern": "/me/onenote/pages",
2016
2017
  "method": "get",
2017
2018
  "toolName": "list-onenote-pages",
2018
2019
  "scopes": ["Notes.Read"],
2019
- "llmTip": "Lists all OneNote pages across every notebook and section the user has access to — transverse alternative to walking notebooks → sections → pages. Default returns top 20 ordered by lastModifiedTime desc. Supports $search='query' for full-text search across page titles and bodies, $filter (e.g. lastModifiedTime gt 2026-01-01), $top (max 100), $select, and $expand=parentNotebook,parentSection. Use $search before bouncing through list-onenote-notebooks / list-all-onenote-sections / list-onenote-section-pages when you only have a topic in mind."
2020
+ "llmTip": "Lists all OneNote pages across every notebook and section the user has access to — transverse alternative to walking notebooks → sections → pages. Default returns top 20 ordered by lastModifiedTime desc. Supports $filter (e.g. lastModifiedTime gt 2026-01-01, or contains(tolower(title), 'topic') for title search), $top (max 100), $select, and $expand=parentNotebook,parentSection. Use this instead of bouncing through list-onenote-notebooks / list-all-onenote-sections / list-onenote-section-pages when you have a topic in mind."
2020
2021
  },
2021
2022
  {
2022
2023
  "pathPattern": "/me/onenote/sectionGroups",
@@ -2031,6 +2032,68 @@
2031
2032
  "toolName": "get-onenote-notebook-from-web-url",
2032
2033
  "workScopes": ["Notes.Read"],
2033
2034
  "contentType": "application/json",
2034
- "llmTip": "Resolves a OneNote notebook from its web URL (the link a user copies from OneNote / SharePoint / Teams). Body: { webUrl: 'https://...' }. Returns a CopyNotebookModel with the notebook's id, displayName, sectionsUrl, sectionGroupsUrl, and isShared — you can then list its sections via list-onenote-notebook-sections. Accepts user notebooks, group notebooks, and SharePoint-hosted team notebooks. Personal Microsoft accounts are not supported."
2035
+ "llmTip": "Resolves a OneNote notebook from its web URL (the link a user copies from OneNote / SharePoint / Teams). Body: { webUrl: 'https://...' }. Returns a notebook object with id, displayName, sectionsUrl, sectionGroupsUrl, and isShared — you can then list its sections via list-onenote-notebook-sections. Accepts user notebooks, group notebooks, and SharePoint-hosted team notebooks. Personal Microsoft accounts are not supported."
2036
+ },
2037
+ {
2038
+ "pathPattern": "/me/presence/setPresence",
2039
+ "method": "post",
2040
+ "toolName": "set-my-presence",
2041
+ "workScopes": ["Presence.ReadWrite"],
2042
+ "contentType": "application/json",
2043
+ "llmTip": "Sets the user's presence session as an application. Body: { sessionId (your app's client/session id, required), availability + activity (must be one of these documented combos: Available/Available, Busy/InACall, Busy/InAConferenceCall, Away/Away, DoNotDisturb/Presenting), expirationDuration (ISO 8601 duration like 'PT1H' — defaults to PT5M, valid range PT5M–PT4H) }. Note: if the user also wants to override their *visible* status regardless of activity, prefer set-my-user-preferred-presence. clear-my-presence ends the session."
2044
+ },
2045
+ {
2046
+ "pathPattern": "/me/presence/clearPresence",
2047
+ "method": "post",
2048
+ "toolName": "clear-my-presence",
2049
+ "workScopes": ["Presence.ReadWrite"],
2050
+ "contentType": "application/json",
2051
+ "llmTip": "Ends the application's presence session for the current user. Body: { sessionId } — must match the sessionId used in set-my-presence. If this was the user's only presence session, their status returns to Offline."
2052
+ },
2053
+ {
2054
+ "pathPattern": "/me/presence/setUserPreferredPresence",
2055
+ "method": "post",
2056
+ "toolName": "set-my-user-preferred-presence",
2057
+ "workScopes": ["Presence.ReadWrite"],
2058
+ "contentType": "application/json",
2059
+ "llmTip": "Sets the user's preferred (sticky) availability and activity — the value Teams clients display regardless of underlying activity. Body: { availability + activity (must be one of these documented combos: Available/Available, Busy/Busy, DoNotDisturb/DoNotDisturb, BeRightBack/BeRightBack, Away/Away, Offline/OffWork), expirationDuration (ISO 8601 duration like 'PT2H' — if omitted, defaults to 1 day for DoNotDisturb/Busy and 7 days for other availability values; not 'indefinite'). Requires at least one active presence session (Teams client signed in or set-my-presence call) — otherwise the user appears Offline. Use this for 'put me in Do Not Disturb for 2 hours' workflows. clear-my-user-preferred-presence reverts to actual presence."
2060
+ },
2061
+ {
2062
+ "pathPattern": "/me/presence/clearUserPreferredPresence",
2063
+ "method": "post",
2064
+ "toolName": "clear-my-user-preferred-presence",
2065
+ "workScopes": ["Presence.ReadWrite"],
2066
+ "contentType": "application/json",
2067
+ "llmTip": "Clears any preferred (sticky) presence override set via set-my-user-preferred-presence. The user's visible status returns to their actual activity. Body: {} (an empty JSON object — required, not 'no body')."
2068
+ },
2069
+ {
2070
+ "pathPattern": "/me/presence/setStatusMessage",
2071
+ "method": "post",
2072
+ "toolName": "set-my-status-message",
2073
+ "workScopes": ["Presence.ReadWrite"],
2074
+ "contentType": "application/json",
2075
+ "llmTip": "Sets the user's Teams status message (the free-text note shown next to their name, e.g. 'Heads-down on Q3 plan'). Body: { statusMessage: { message: { content: 'text or HTML', contentType: 'text' | 'html' }, expiryDateTime: { dateTime: '2026-05-06T17:00:00', timeZone: 'UTC' } (optional) } }. Pass an empty object {} or message.content='' to clear. expiryDateTime is optional — omit for no expiration."
2076
+ },
2077
+ {
2078
+ "pathPattern": "/me/teamwork/associatedTeams",
2079
+ "method": "get",
2080
+ "toolName": "list-my-associated-teams",
2081
+ "workScopes": ["Team.ReadBasic.All"],
2082
+ "llmTip": "Lists Teams the current user is associated with — both joined teams and host teams of shared channels the user is a direct member of. Returns associatedTeamInfo objects with id, displayName, and tenantId. Broader than list-joined-teams because it includes shared-channel host teams."
2083
+ },
2084
+ {
2085
+ "pathPattern": "/me/teamwork/installedApps",
2086
+ "method": "get",
2087
+ "toolName": "list-my-installed-teams-apps",
2088
+ "workScopes": ["TeamsAppInstallation.ReadForUser"],
2089
+ "llmTip": "Lists Teams apps installed in the current user's personal scope (the apps pinned to the user's Teams sidebar / accessible without joining a team or chat). Use $expand=teamsApp,teamsAppDefinition for full app metadata (displayName, version, distributionMethod). Useful before send-my-activity-notification to discover the user's own teamsAppId."
2090
+ },
2091
+ {
2092
+ "pathPattern": "/me/teamwork/sendActivityNotification",
2093
+ "method": "post",
2094
+ "toolName": "send-my-activity-notification",
2095
+ "workScopes": ["TeamsActivity.Send"],
2096
+ "contentType": "application/json",
2097
+ "llmTip": "Sends a Teams activity feed notification to the current user (the badge + entry in their Activity tab). Body: { topic: { source: 'entityUrl' | 'text', value: <Graph URL or plain text>, webUrl: <required when source='text', click-through URL> }, activityType: <must be declared in the calling Teams app's manifest, OR the reserved 'systemDefault' which provides free-form Actor+Reason text>, previewText: { content: 'short preview' }, templateParameters?: [{ name, value }] (substituted into the manifest's localized notification template), teamsAppId?: <optional disambiguator when multiple installed apps share a Microsoft Entra app ID — fetch via list-my-installed-teams-apps>, chainId?, iconId? }. Use to ping the user with 'action required' notifications from agentic workflows. See https://learn.microsoft.com/graph/teams-send-activityfeednotifications."
2035
2098
  }
2036
2099
  ]