@softeria/ms-365-mcp-server 0.104.0 → 0.106.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.
@@ -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
  {
@@ -2010,5 +2011,88 @@
2010
2011
  "toolName": "delete-todo-task-list",
2011
2012
  "scopes": ["Tasks.ReadWrite"],
2012
2013
  "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."
2014
+ },
2015
+ {
2016
+ "pathPattern": "/me/onenote/pages",
2017
+ "method": "get",
2018
+ "toolName": "list-onenote-pages",
2019
+ "scopes": ["Notes.Read"],
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 $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."
2021
+ },
2022
+ {
2023
+ "pathPattern": "/me/onenote/sectionGroups",
2024
+ "method": "get",
2025
+ "toolName": "list-onenote-section-groups",
2026
+ "scopes": ["Notes.Read"],
2027
+ "llmTip": "Lists all OneNote section groups (subfolders inside notebooks that contain their own sections and nested section groups) for the user. A section group is a folder-like container — many notebooks use them to organize sections by theme. Default sort is name asc. Supports $expand=sections,sectionGroups,parentNotebook,parentSectionGroup to traverse the full hierarchy. Pair with list-onenote-notebooks for a complete picture of the user's notebook structure."
2028
+ },
2029
+ {
2030
+ "pathPattern": "/me/onenote/notebooks/getNotebookFromWebUrl",
2031
+ "method": "post",
2032
+ "toolName": "get-onenote-notebook-from-web-url",
2033
+ "workScopes": ["Notes.Read"],
2034
+ "contentType": "application/json",
2035
+ "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."
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 ('Available' | 'Busy' | 'DoNotDisturb' | 'BeRightBack' | 'Away' | 'Offline'), activity ('Available' | 'InACall' | 'InAMeeting' | 'Presenting' | 'Busy' | 'Away' | 'OffWork' | 'Offline'), expirationDuration (ISO 8601 duration like 'PT1H' — defaults to PT5M, max PT24H) }. 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 ('Available' | 'Busy' | 'DoNotDisturb' | 'BeRightBack' | 'Away' | 'Offline'), activity (same values), expirationDuration (ISO 8601 duration like 'PT2H' — omit for indefinite). Requires at least one active presence session (Teams client signed in or set-my-presence call). 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
+ "llmTip": "Clears any preferred (sticky) presence override set via set-my-user-preferred-presence. The user's visible status returns to their actual activity (e.g. Available when free, InAMeeting when in a call). No request body."
2067
+ },
2068
+ {
2069
+ "pathPattern": "/me/presence/setStatusMessage",
2070
+ "method": "post",
2071
+ "toolName": "set-my-status-message",
2072
+ "workScopes": ["Presence.ReadWrite"],
2073
+ "contentType": "application/json",
2074
+ "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."
2075
+ },
2076
+ {
2077
+ "pathPattern": "/me/teamwork/associatedTeams",
2078
+ "method": "get",
2079
+ "toolName": "list-my-associated-teams",
2080
+ "workScopes": ["Team.ReadBasic.All"],
2081
+ "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."
2082
+ },
2083
+ {
2084
+ "pathPattern": "/me/teamwork/installedApps",
2085
+ "method": "get",
2086
+ "toolName": "list-my-installed-teams-apps",
2087
+ "workScopes": ["TeamsAppInstallation.ReadForUser"],
2088
+ "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."
2089
+ },
2090
+ {
2091
+ "pathPattern": "/me/teamwork/sendActivityNotification",
2092
+ "method": "post",
2093
+ "toolName": "send-my-activity-notification",
2094
+ "workScopes": ["TeamsActivity.Send"],
2095
+ "contentType": "application/json",
2096
+ "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?: <click-through URL when source=text> }, activityType: <one of the activity types declared in the calling app's Teams manifest>, previewText: { content: 'short preview' }, templateParameters?: [{ name, value }] (substituted into the manifest's localized notification template), teamsAppId?: <required when caller is not a Teams app — fetch via list-my-installed-teams-apps>, chainId?, iconId? }. Use to ping the user with 'action required' notifications from agentic workflows. activityType must exist in the Teams app manifest — see https://learn.microsoft.com/graph/teams-send-activityfeednotifications."
2013
2097
  }
2014
2098
  ]
@@ -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(),
@@ -3341,11 +3342,37 @@ const microsoft_graph_onenoteSectionCollectionResponse = z.object({
3341
3342
  "@odata.nextLink": z.string().nullable(),
3342
3343
  value: z.array(microsoft_graph_onenoteSection)
3343
3344
  }).partial().passthrough();
3345
+ const microsoft_graph_CopyNotebookModel = z.object({
3346
+ createdBy: z.string().nullish(),
3347
+ createdByIdentity: microsoft_graph_identitySet.optional(),
3348
+ createdTime: z.string().regex(
3349
+ /^[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])$/
3350
+ ).datetime({ offset: true }).nullish(),
3351
+ id: z.string().nullish(),
3352
+ isDefault: z.boolean().nullish(),
3353
+ isShared: z.boolean().nullish(),
3354
+ lastModifiedBy: z.string().nullish(),
3355
+ lastModifiedByIdentity: microsoft_graph_identitySet.optional(),
3356
+ lastModifiedTime: z.string().regex(
3357
+ /^[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])$/
3358
+ ).datetime({ offset: true }).nullish(),
3359
+ links: microsoft_graph_notebookLinks.optional(),
3360
+ name: z.string().nullish(),
3361
+ sectionGroupsUrl: z.string().nullish(),
3362
+ sectionsUrl: z.string().nullish(),
3363
+ self: z.string().nullish(),
3364
+ userRole: microsoft_graph_onenoteUserRole.optional()
3365
+ }).passthrough();
3344
3366
  const microsoft_graph_onenotePageCollectionResponse = z.object({
3345
3367
  "@odata.count": z.number().int().nullable(),
3346
3368
  "@odata.nextLink": z.string().nullable(),
3347
3369
  value: z.array(microsoft_graph_onenotePage)
3348
3370
  }).partial().passthrough();
3371
+ const microsoft_graph_sectionGroupCollectionResponse = z.object({
3372
+ "@odata.count": z.number().int().nullable(),
3373
+ "@odata.nextLink": z.string().nullable(),
3374
+ value: z.array(microsoft_graph_sectionGroup)
3375
+ }).partial().passthrough();
3349
3376
  const microsoft_graph_allowedLobbyAdmitterRoles = z.enum([
3350
3377
  "organizerAndCoOrganizersAndPresenters",
3351
3378
  "organizerAndCoOrganizers",
@@ -3754,6 +3781,55 @@ const microsoft_graph_plannerTaskCollectionResponse = z.object({
3754
3781
  "@odata.nextLink": z.string().nullable(),
3755
3782
  value: z.array(microsoft_graph_plannerTask)
3756
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();
3757
3833
  const microsoft_graph_wellknownListName = z.enum([
3758
3834
  "none",
3759
3835
  "defaultList",
@@ -4597,6 +4673,8 @@ const schemas = {
4597
4673
  microsoft_graph_chatMessageCollectionResponse,
4598
4674
  microsoft_graph_chatMessageHostedContentCollectionResponse,
4599
4675
  microsoft_graph_pinnedChatMessageInfoCollectionResponse,
4676
+ get_presences_by_user_id_Body,
4677
+ BaseCollectionPaginationCountResponse,
4600
4678
  microsoft_graph_outOfOfficeSettings,
4601
4679
  microsoft_graph_dateTimeTimeZone,
4602
4680
  microsoft_graph_presenceStatusMessage,
@@ -4643,7 +4721,6 @@ const schemas = {
4643
4721
  microsoft_graph_sensitivityLabelAssignment,
4644
4722
  microsoft_graph_extractSensitivityLabelsResult,
4645
4723
  share_drive_item_Body,
4646
- BaseCollectionPaginationCountResponse,
4647
4724
  ReferenceNumeric,
4648
4725
  create_drive_item_preview_Body,
4649
4726
  microsoft_graph_itemPreviewInfo,
@@ -4883,7 +4960,9 @@ const schemas = {
4883
4960
  microsoft_graph_notebook,
4884
4961
  microsoft_graph_notebookCollectionResponse,
4885
4962
  microsoft_graph_onenoteSectionCollectionResponse,
4963
+ microsoft_graph_CopyNotebookModel,
4886
4964
  microsoft_graph_onenotePageCollectionResponse,
4965
+ microsoft_graph_sectionGroupCollectionResponse,
4887
4966
  microsoft_graph_allowedLobbyAdmitterRoles,
4888
4967
  microsoft_graph_onlineMeetingPresenters,
4889
4968
  microsoft_graph_meetingLiveShareOptions,
@@ -4929,6 +5008,14 @@ const schemas = {
4929
5008
  microsoft_graph_plannerBucketTaskBoardTaskFormat,
4930
5009
  microsoft_graph_plannerTask,
4931
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,
4932
5019
  microsoft_graph_wellknownListName,
4933
5020
  microsoft_graph_taskStatus,
4934
5021
  microsoft_graph_attachmentBase,
@@ -5434,16 +5521,16 @@ const endpoints = makeApi([
5434
5521
  },
5435
5522
  {
5436
5523
  method: "post",
5437
- path: "/communications/presences",
5524
+ path: "/communications/getPresencesByUserId",
5438
5525
  alias: "get-presences-by-user-id",
5439
- description: `Create new navigation property to presences for communications`,
5526
+ description: `Get the presence information for multiple users.`,
5440
5527
  requestFormat: "json",
5441
5528
  parameters: [
5442
5529
  {
5443
5530
  name: "body",
5444
- description: `New navigation property`,
5531
+ description: `Action parameters`,
5445
5532
  type: "Body",
5446
- schema: microsoft_graph_presence
5533
+ schema: get_presences_by_user_id_Body
5447
5534
  }
5448
5535
  ],
5449
5536
  response: z.void()
@@ -10333,6 +10420,72 @@ resource.`,
10333
10420
  ],
10334
10421
  response: z.void()
10335
10422
  },
10423
+ {
10424
+ method: "post",
10425
+ path: "/me/onenote/notebooks/getNotebookFromWebUrl",
10426
+ alias: "get-onenote-notebook-from-web-url",
10427
+ description: `Retrieve the properties and relationships of a notebook object by using its URL path. The location can be user notebooks on Microsoft 365, group notebooks, or SharePoint site-hosted team notebooks on Microsoft 365.`,
10428
+ requestFormat: "json",
10429
+ parameters: [
10430
+ {
10431
+ name: "body",
10432
+ description: `Action parameters`,
10433
+ type: "Body",
10434
+ schema: z.object({ webUrl: z.string().nullable() }).partial().passthrough()
10435
+ }
10436
+ ],
10437
+ response: z.void()
10438
+ },
10439
+ {
10440
+ method: "get",
10441
+ path: "/me/onenote/pages",
10442
+ alias: "list-onenote-pages",
10443
+ description: `Retrieve a list of page objects.`,
10444
+ requestFormat: "json",
10445
+ parameters: [
10446
+ {
10447
+ name: "$top",
10448
+ type: "Query",
10449
+ schema: z.number().int().gte(0).describe("Show only the first n items").optional()
10450
+ },
10451
+ {
10452
+ name: "$skip",
10453
+ type: "Query",
10454
+ schema: z.number().int().gte(0).describe("Skip the first n items").optional()
10455
+ },
10456
+ {
10457
+ name: "$search",
10458
+ type: "Query",
10459
+ schema: z.string().describe("Search items by search phrases").optional()
10460
+ },
10461
+ {
10462
+ name: "$filter",
10463
+ type: "Query",
10464
+ schema: z.string().describe("Filter items by property values").optional()
10465
+ },
10466
+ {
10467
+ name: "$count",
10468
+ type: "Query",
10469
+ schema: z.boolean().describe("Include count of items").optional()
10470
+ },
10471
+ {
10472
+ name: "$orderby",
10473
+ type: "Query",
10474
+ schema: z.array(z.string()).describe("Order items by property values").optional()
10475
+ },
10476
+ {
10477
+ name: "$select",
10478
+ type: "Query",
10479
+ schema: z.array(z.string()).describe("Select properties to be returned").optional()
10480
+ },
10481
+ {
10482
+ name: "$expand",
10483
+ type: "Query",
10484
+ schema: z.array(z.string()).describe("Expand related entities").optional()
10485
+ }
10486
+ ],
10487
+ response: z.void()
10488
+ },
10336
10489
  {
10337
10490
  method: "post",
10338
10491
  path: "/me/onenote/pages",
@@ -10372,6 +10525,56 @@ resource.`,
10372
10525
  requestFormat: "json",
10373
10526
  response: z.void()
10374
10527
  },
10528
+ {
10529
+ method: "get",
10530
+ path: "/me/onenote/sectionGroups",
10531
+ alias: "list-onenote-section-groups",
10532
+ description: `Retrieve a list of sectionGroup objects.`,
10533
+ requestFormat: "json",
10534
+ parameters: [
10535
+ {
10536
+ name: "$top",
10537
+ type: "Query",
10538
+ schema: z.number().int().gte(0).describe("Show only the first n items").optional()
10539
+ },
10540
+ {
10541
+ name: "$skip",
10542
+ type: "Query",
10543
+ schema: z.number().int().gte(0).describe("Skip the first n items").optional()
10544
+ },
10545
+ {
10546
+ name: "$search",
10547
+ type: "Query",
10548
+ schema: z.string().describe("Search items by search phrases").optional()
10549
+ },
10550
+ {
10551
+ name: "$filter",
10552
+ type: "Query",
10553
+ schema: z.string().describe("Filter items by property values").optional()
10554
+ },
10555
+ {
10556
+ name: "$count",
10557
+ type: "Query",
10558
+ schema: z.boolean().describe("Include count of items").optional()
10559
+ },
10560
+ {
10561
+ name: "$orderby",
10562
+ type: "Query",
10563
+ schema: z.array(z.string()).describe("Order items by property values").optional()
10564
+ },
10565
+ {
10566
+ name: "$select",
10567
+ type: "Query",
10568
+ schema: z.array(z.string()).describe("Select properties to be returned").optional()
10569
+ },
10570
+ {
10571
+ name: "$expand",
10572
+ type: "Query",
10573
+ schema: z.array(z.string()).describe("Expand related entities").optional()
10574
+ }
10575
+ ],
10576
+ response: z.void()
10577
+ },
10375
10578
  {
10376
10579
  method: "get",
10377
10580
  path: "/me/onenote/sections",
@@ -11227,6 +11430,78 @@ getting the user's mailbox settings.`,
11227
11430
  ],
11228
11431
  response: z.void()
11229
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
+ },
11230
11505
  {
11231
11506
  method: "post",
11232
11507
  path: "/me/sendMail",
@@ -11243,6 +11518,123 @@ getting the user's mailbox settings.`,
11243
11518
  ],
11244
11519
  response: z.void()
11245
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
+ },
11246
11638
  {
11247
11639
  method: "get",
11248
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.104.0",
3
+ "version": "0.106.0",
4
4
  "description": " A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Office services through the Graph API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -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
  {
@@ -2010,5 +2011,88 @@
2010
2011
  "toolName": "delete-todo-task-list",
2011
2012
  "scopes": ["Tasks.ReadWrite"],
2012
2013
  "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."
2014
+ },
2015
+ {
2016
+ "pathPattern": "/me/onenote/pages",
2017
+ "method": "get",
2018
+ "toolName": "list-onenote-pages",
2019
+ "scopes": ["Notes.Read"],
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 $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."
2021
+ },
2022
+ {
2023
+ "pathPattern": "/me/onenote/sectionGroups",
2024
+ "method": "get",
2025
+ "toolName": "list-onenote-section-groups",
2026
+ "scopes": ["Notes.Read"],
2027
+ "llmTip": "Lists all OneNote section groups (subfolders inside notebooks that contain their own sections and nested section groups) for the user. A section group is a folder-like container — many notebooks use them to organize sections by theme. Default sort is name asc. Supports $expand=sections,sectionGroups,parentNotebook,parentSectionGroup to traverse the full hierarchy. Pair with list-onenote-notebooks for a complete picture of the user's notebook structure."
2028
+ },
2029
+ {
2030
+ "pathPattern": "/me/onenote/notebooks/getNotebookFromWebUrl",
2031
+ "method": "post",
2032
+ "toolName": "get-onenote-notebook-from-web-url",
2033
+ "workScopes": ["Notes.Read"],
2034
+ "contentType": "application/json",
2035
+ "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."
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 ('Available' | 'Busy' | 'DoNotDisturb' | 'BeRightBack' | 'Away' | 'Offline'), activity ('Available' | 'InACall' | 'InAMeeting' | 'Presenting' | 'Busy' | 'Away' | 'OffWork' | 'Offline'), expirationDuration (ISO 8601 duration like 'PT1H' — defaults to PT5M, max PT24H) }. 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 ('Available' | 'Busy' | 'DoNotDisturb' | 'BeRightBack' | 'Away' | 'Offline'), activity (same values), expirationDuration (ISO 8601 duration like 'PT2H' — omit for indefinite). Requires at least one active presence session (Teams client signed in or set-my-presence call). 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
+ "llmTip": "Clears any preferred (sticky) presence override set via set-my-user-preferred-presence. The user's visible status returns to their actual activity (e.g. Available when free, InAMeeting when in a call). No request body."
2067
+ },
2068
+ {
2069
+ "pathPattern": "/me/presence/setStatusMessage",
2070
+ "method": "post",
2071
+ "toolName": "set-my-status-message",
2072
+ "workScopes": ["Presence.ReadWrite"],
2073
+ "contentType": "application/json",
2074
+ "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."
2075
+ },
2076
+ {
2077
+ "pathPattern": "/me/teamwork/associatedTeams",
2078
+ "method": "get",
2079
+ "toolName": "list-my-associated-teams",
2080
+ "workScopes": ["Team.ReadBasic.All"],
2081
+ "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."
2082
+ },
2083
+ {
2084
+ "pathPattern": "/me/teamwork/installedApps",
2085
+ "method": "get",
2086
+ "toolName": "list-my-installed-teams-apps",
2087
+ "workScopes": ["TeamsAppInstallation.ReadForUser"],
2088
+ "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."
2089
+ },
2090
+ {
2091
+ "pathPattern": "/me/teamwork/sendActivityNotification",
2092
+ "method": "post",
2093
+ "toolName": "send-my-activity-notification",
2094
+ "workScopes": ["TeamsActivity.Send"],
2095
+ "contentType": "application/json",
2096
+ "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?: <click-through URL when source=text> }, activityType: <one of the activity types declared in the calling app's Teams manifest>, previewText: { content: 'short preview' }, templateParameters?: [{ name, value }] (substituted into the manifest's localized notification template), teamsAppId?: <required when caller is not a Teams app — fetch via list-my-installed-teams-apps>, chainId?, iconId? }. Use to ping the user with 'action required' notifications from agentic workflows. activityType must exist in the Teams app manifest — see https://learn.microsoft.com/graph/teams-send-activityfeednotifications."
2013
2097
  }
2014
2098
  ]