@softeria/ms-365-mcp-server 0.64.0 → 0.66.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.
package/README.md CHANGED
@@ -553,6 +553,8 @@ Parent directories are created automatically. Files are written with `0600` perm
553
553
 
554
554
  > **Security note**: File-based token storage writes sensitive credentials to disk. Ensure the chosen directory has appropriate access controls. The OS credential store (keytar) is preferred when available.
555
555
 
556
+ > **Hosted/sandboxed environments** (e.g. Anthropic Cowork): Set `MS365_MCP_TOKEN_CACHE_PATH` and `MS365_MCP_SELECTED_ACCOUNT_PATH` to a persistent mount so tokens survive between sessions.
557
+
556
558
  ## Azure Key Vault Integration
557
559
 
558
560
  For production deployments, you can store secrets in Azure Key Vault instead of environment variables. This is particularly useful for Azure Container Apps with managed identity.
@@ -348,6 +348,25 @@
348
348
  "supportsExpandExtendedProperties": true,
349
349
  "llmTip": "Returns expanded recurring event instances (not just seriesMaster) within a date range for a specific calendar. Requires startDateTime and endDateTime query parameters in ISO 8601 format (e.g., 2024-01-01T00:00:00Z). Each instance includes seriesMasterId and type (occurrence/exception) fields for recurring event linkage. Use fetchAllPages=true to retrieve all results when there are many events. To find Teams meetings, use $filter=isOnlineMeeting eq true. Teams meetings include a joinWebUrl property needed for transcript access via list-online-meetings."
350
350
  },
351
+ {
352
+ "pathPattern": "/me/calendar/getSchedule",
353
+ "method": "post",
354
+ "toolName": "get-schedule",
355
+ "workScopes": ["Calendars.Read"]
356
+ },
357
+ {
358
+ "pathPattern": "/users/{user-id}/calendar/events",
359
+ "method": "get",
360
+ "toolName": "list-shared-calendar-events",
361
+ "workScopes": ["Calendars.Read.Shared"]
362
+ },
363
+ {
364
+ "pathPattern": "/users/{user-id}/calendarView",
365
+ "method": "get",
366
+ "toolName": "get-shared-calendar-view",
367
+ "workScopes": ["Calendars.Read.Shared"],
368
+ "supportsTimezone": true
369
+ },
351
370
  {
352
371
  "pathPattern": "/me/calendars/{calendar-id}/events/{event-id}/instances",
353
372
  "method": "get",
@@ -1346,6 +1346,68 @@ const microsoft_graph_conversationThreadCollectionResponse = z.object({
1346
1346
  value: z.array(microsoft_graph_conversationThread)
1347
1347
  }).partial().passthrough();
1348
1348
  const reply_to_group_thread_Body = z.object({ Post: microsoft_graph_post }).partial().passthrough();
1349
+ const get_schedule_Body = z.object({
1350
+ Schedules: z.array(z.string().nullable()),
1351
+ EndTime: z.union([microsoft_graph_dateTimeTimeZone, z.object({}).partial().passthrough()]),
1352
+ StartTime: z.union([microsoft_graph_dateTimeTimeZone, z.object({}).partial().passthrough()]),
1353
+ AvailabilityViewInterval: z.number().gte(-2147483648).lte(2147483647).nullable()
1354
+ }).partial().passthrough();
1355
+ const BaseCollectionPaginationCountResponse = z.object({ "@odata.count": z.number().int().nullable(), "@odata.nextLink": z.string().nullable() }).partial().passthrough();
1356
+ const microsoft_graph_freeBusyError = z.object({
1357
+ message: z.string().describe("Describes the error.").nullish(),
1358
+ responseCode: z.string().describe(
1359
+ "The response code from querying for the availability of the user, distribution list, or resource."
1360
+ ).nullish()
1361
+ }).passthrough();
1362
+ const microsoft_graph_freeBusyStatus = z.enum([
1363
+ "unknown",
1364
+ "free",
1365
+ "tentative",
1366
+ "busy",
1367
+ "oof",
1368
+ "workingElsewhere"
1369
+ ]);
1370
+ const microsoft_graph_scheduleItem = z.object({
1371
+ end: microsoft_graph_dateTimeTimeZone.optional(),
1372
+ isPrivate: z.boolean().describe(
1373
+ "The sensitivity of the corresponding event. True if the event is marked private, false otherwise. Optional."
1374
+ ).nullish(),
1375
+ location: z.string().describe("The location where the corresponding event is held or attended from. Optional.").nullish(),
1376
+ start: microsoft_graph_dateTimeTimeZone.optional(),
1377
+ status: microsoft_graph_freeBusyStatus.optional(),
1378
+ subject: z.string().describe("The corresponding event's subject line. Optional.").nullish()
1379
+ }).passthrough();
1380
+ const microsoft_graph_dayOfWeek = z.enum([
1381
+ "sunday",
1382
+ "monday",
1383
+ "tuesday",
1384
+ "wednesday",
1385
+ "thursday",
1386
+ "friday",
1387
+ "saturday"
1388
+ ]);
1389
+ const microsoft_graph_timeZoneBase = z.object({
1390
+ name: z.string().describe(
1391
+ "The name of a time zone. It can be a standard time zone name such as 'Hawaii-Aleutian Standard Time', or 'Customized Time Zone' for a custom time zone."
1392
+ ).nullish()
1393
+ }).passthrough();
1394
+ const microsoft_graph_workingHours = z.object({
1395
+ daysOfWeek: z.array(z.union([microsoft_graph_dayOfWeek, z.object({}).partial().passthrough()])).describe("The days of the week on which the user works.").optional(),
1396
+ endTime: z.string().regex(/^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$/).describe("The time of the day that the user stops working.").nullish(),
1397
+ startTime: z.string().regex(/^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$/).describe("The time of the day that the user starts working.").nullish(),
1398
+ timeZone: microsoft_graph_timeZoneBase.optional()
1399
+ }).passthrough();
1400
+ const microsoft_graph_scheduleInformation = z.object({
1401
+ availabilityView: z.string().describe(
1402
+ "Represents a merged view of availability of all the items in scheduleItems. The view consists of time slots. Availability during each time slot is indicated with: 0= free or working elswhere, 1= tentative, 2= busy, 3= out of office.Note: Working elsewhere is set to 0 instead of 4 for backward compatibility. For details, see the Q&A and Exchange 2007 and Exchange 2010 do not use the WorkingElsewhere value."
1403
+ ).nullish(),
1404
+ error: microsoft_graph_freeBusyError.optional(),
1405
+ scheduleId: z.string().describe(
1406
+ "An SMTP address of the user, distribution list, or resource, identifying an instance of scheduleInformation."
1407
+ ).nullish(),
1408
+ scheduleItems: z.array(microsoft_graph_scheduleItem).describe("Contains the items that describe the availability of the user or resource.").optional(),
1409
+ workingHours: microsoft_graph_workingHours.optional()
1410
+ }).passthrough();
1349
1411
  const microsoft_graph_onlineMeetingProviderType = z.enum([
1350
1412
  "unknown",
1351
1413
  "skypeForBusiness",
@@ -1442,14 +1504,6 @@ const microsoft_graph_location = z.object({
1442
1504
  uniqueId: z.string().describe("For internal use only.").nullish(),
1443
1505
  uniqueIdType: microsoft_graph_locationUniqueIdType.optional()
1444
1506
  }).passthrough();
1445
- const microsoft_graph_freeBusyStatus = z.enum([
1446
- "unknown",
1447
- "free",
1448
- "tentative",
1449
- "busy",
1450
- "oof",
1451
- "workingElsewhere"
1452
- ]);
1453
1507
  const microsoft_graph_sensitivity = z.enum(["normal", "personal", "private", "confidential"]);
1454
1508
  const microsoft_graph_importance = z.enum(["low", "normal", "high"]);
1455
1509
  const microsoft_graph_attendeeType = z.enum(["required", "optional", "resource"]);
@@ -1479,15 +1533,6 @@ const microsoft_graph_attendee = z.object({
1479
1533
  proposedNewTime: microsoft_graph_timeSlot.optional(),
1480
1534
  status: microsoft_graph_responseStatus.optional()
1481
1535
  }).passthrough();
1482
- const microsoft_graph_dayOfWeek = z.enum([
1483
- "sunday",
1484
- "monday",
1485
- "tuesday",
1486
- "wednesday",
1487
- "thursday",
1488
- "friday",
1489
- "saturday"
1490
- ]);
1491
1536
  const microsoft_graph_weekIndex = z.enum(["first", "second", "third", "fourth", "last"]);
1492
1537
  const microsoft_graph_recurrencePatternType = z.enum([
1493
1538
  "daily",
@@ -2506,17 +2551,6 @@ const microsoft_graph_userPurpose = z.enum([
2506
2551
  "others",
2507
2552
  "unknownFutureValue"
2508
2553
  ]);
2509
- const microsoft_graph_timeZoneBase = z.object({
2510
- name: z.string().describe(
2511
- "The name of a time zone. It can be a standard time zone name such as 'Hawaii-Aleutian Standard Time', or 'Customized Time Zone' for a custom time zone."
2512
- ).nullish()
2513
- }).passthrough();
2514
- const microsoft_graph_workingHours = z.object({
2515
- daysOfWeek: z.array(z.union([microsoft_graph_dayOfWeek, z.object({}).partial().passthrough()])).describe("The days of the week on which the user works.").optional(),
2516
- endTime: z.string().regex(/^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$/).describe("The time of the day that the user stops working.").nullish(),
2517
- startTime: z.string().regex(/^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$/).describe("The time of the day that the user starts working.").nullish(),
2518
- timeZone: microsoft_graph_timeZoneBase.optional()
2519
- }).passthrough();
2520
2554
  const microsoft_graph_mailboxSettings = z.object({
2521
2555
  archiveFolder: z.string().describe("Folder ID of an archive folder for the user.").nullish(),
2522
2556
  automaticRepliesSetting: microsoft_graph_automaticRepliesSetting.optional(),
@@ -3621,7 +3655,6 @@ const microsoft_graph_searchRequest = z.object({
3621
3655
  ).optional()
3622
3656
  }).passthrough();
3623
3657
  const search_query_Body = z.object({ requests: z.array(microsoft_graph_searchRequest) }).partial().passthrough();
3624
- const BaseCollectionPaginationCountResponse = z.object({ "@odata.count": z.number().int().nullable(), "@odata.nextLink": z.string().nullable() }).partial().passthrough();
3625
3658
  const microsoft_graph_searchBucket = z.object({
3626
3659
  aggregationFilterToken: z.string().describe(
3627
3660
  "A token containing the encoded filter to aggregate search matches by the specific key value. To use the filter, pass the token as part of the aggregationFilter property in a searchRequest object, in the format '{field}:/'{aggregationFilterToken}/''. See an example."
@@ -3937,6 +3970,15 @@ const schemas = {
3937
3970
  microsoft_graph_conversationCollectionResponse,
3938
3971
  microsoft_graph_conversationThreadCollectionResponse,
3939
3972
  reply_to_group_thread_Body,
3973
+ get_schedule_Body,
3974
+ BaseCollectionPaginationCountResponse,
3975
+ microsoft_graph_freeBusyError,
3976
+ microsoft_graph_freeBusyStatus,
3977
+ microsoft_graph_scheduleItem,
3978
+ microsoft_graph_dayOfWeek,
3979
+ microsoft_graph_timeZoneBase,
3980
+ microsoft_graph_workingHours,
3981
+ microsoft_graph_scheduleInformation,
3940
3982
  microsoft_graph_onlineMeetingProviderType,
3941
3983
  microsoft_graph_calendarColor,
3942
3984
  microsoft_graph_calendarRoleType,
@@ -3947,7 +3989,6 @@ const schemas = {
3947
3989
  microsoft_graph_locationType,
3948
3990
  microsoft_graph_locationUniqueIdType,
3949
3991
  microsoft_graph_location,
3950
- microsoft_graph_freeBusyStatus,
3951
3992
  microsoft_graph_sensitivity,
3952
3993
  microsoft_graph_importance,
3953
3994
  microsoft_graph_attendeeType,
@@ -3955,7 +3996,6 @@ const schemas = {
3955
3996
  microsoft_graph_responseType,
3956
3997
  microsoft_graph_responseStatus,
3957
3998
  microsoft_graph_attendee,
3958
- microsoft_graph_dayOfWeek,
3959
3999
  microsoft_graph_weekIndex,
3960
4000
  microsoft_graph_recurrencePatternType,
3961
4001
  microsoft_graph_recurrencePattern,
@@ -4045,8 +4085,6 @@ const schemas = {
4045
4085
  microsoft_graph_delegateMeetingMessageDeliveryOptions,
4046
4086
  microsoft_graph_localeInfo,
4047
4087
  microsoft_graph_userPurpose,
4048
- microsoft_graph_timeZoneBase,
4049
- microsoft_graph_workingHours,
4050
4088
  microsoft_graph_mailboxSettings,
4051
4089
  microsoft_graph_messageRuleActions,
4052
4090
  microsoft_graph_messageActionFlag,
@@ -4157,7 +4195,6 @@ const schemas = {
4157
4195
  microsoft_graph_sortProperty,
4158
4196
  microsoft_graph_searchRequest,
4159
4197
  search_query_Body,
4160
- BaseCollectionPaginationCountResponse,
4161
4198
  microsoft_graph_searchBucket,
4162
4199
  microsoft_graph_searchAggregation,
4163
4200
  microsoft_graph_entity,
@@ -5041,6 +5078,22 @@ const endpoints = makeApi([
5041
5078
  ],
5042
5079
  response: z.void()
5043
5080
  },
5081
+ {
5082
+ method: "post",
5083
+ path: "/me/calendar/getSchedule",
5084
+ alias: "get-schedule",
5085
+ description: `Get the free/busy availability information for a collection of users, distributions lists, or resources (rooms or equipment) for a specified time period.`,
5086
+ requestFormat: "json",
5087
+ parameters: [
5088
+ {
5089
+ name: "body",
5090
+ description: `Action parameters`,
5091
+ type: "Body",
5092
+ schema: get_schedule_Body
5093
+ }
5094
+ ],
5095
+ response: z.void()
5096
+ },
5044
5097
  {
5045
5098
  method: "get",
5046
5099
  path: "/me/calendars",
@@ -9369,6 +9422,120 @@ To monitor future changes, call the delta API by using the @odata.deltaLink in t
9369
9422
  ],
9370
9423
  response: z.void()
9371
9424
  },
9425
+ {
9426
+ method: "get",
9427
+ path: "/users/:userId/calendar/events",
9428
+ alias: "list-shared-calendar-events",
9429
+ description: `The events in the calendar. Navigation property. Read-only.`,
9430
+ requestFormat: "json",
9431
+ parameters: [
9432
+ {
9433
+ name: "$top",
9434
+ type: "Query",
9435
+ schema: z.number().int().gte(0).describe("Show only the first n items").optional()
9436
+ },
9437
+ {
9438
+ name: "$skip",
9439
+ type: "Query",
9440
+ schema: z.number().int().gte(0).describe("Skip the first n items").optional()
9441
+ },
9442
+ {
9443
+ name: "$search",
9444
+ type: "Query",
9445
+ schema: z.string().describe("Search items by search phrases").optional()
9446
+ },
9447
+ {
9448
+ name: "$filter",
9449
+ type: "Query",
9450
+ schema: z.string().describe("Filter items by property values").optional()
9451
+ },
9452
+ {
9453
+ name: "$count",
9454
+ type: "Query",
9455
+ schema: z.boolean().describe("Include count of items").optional()
9456
+ },
9457
+ {
9458
+ name: "$orderby",
9459
+ type: "Query",
9460
+ schema: z.array(z.string()).describe("Order items by property values").optional()
9461
+ },
9462
+ {
9463
+ name: "$select",
9464
+ type: "Query",
9465
+ schema: z.array(z.string()).describe("Select properties to be returned").optional()
9466
+ },
9467
+ {
9468
+ name: "$expand",
9469
+ type: "Query",
9470
+ schema: z.array(z.string()).describe("Expand related entities").optional()
9471
+ }
9472
+ ],
9473
+ response: z.void()
9474
+ },
9475
+ {
9476
+ method: "get",
9477
+ path: "/users/:userId/calendarView",
9478
+ alias: "get-shared-calendar-view",
9479
+ description: `The calendar view for the calendar. Read-only. Nullable.`,
9480
+ requestFormat: "json",
9481
+ parameters: [
9482
+ {
9483
+ name: "startDateTime",
9484
+ type: "Query",
9485
+ schema: z.string().describe(
9486
+ "The start date and time of the time range, represented in ISO 8601 format. For example, 2019-11-08T19:00:00-08:00"
9487
+ )
9488
+ },
9489
+ {
9490
+ name: "endDateTime",
9491
+ type: "Query",
9492
+ schema: z.string().describe(
9493
+ "The end date and time of the time range, represented in ISO 8601 format. For example, 2019-11-08T20:00:00-08:00"
9494
+ )
9495
+ },
9496
+ {
9497
+ name: "$top",
9498
+ type: "Query",
9499
+ schema: z.number().int().gte(0).describe("Show only the first n items").optional()
9500
+ },
9501
+ {
9502
+ name: "$skip",
9503
+ type: "Query",
9504
+ schema: z.number().int().gte(0).describe("Skip the first n items").optional()
9505
+ },
9506
+ {
9507
+ name: "$search",
9508
+ type: "Query",
9509
+ schema: z.string().describe("Search items by search phrases").optional()
9510
+ },
9511
+ {
9512
+ name: "$filter",
9513
+ type: "Query",
9514
+ schema: z.string().describe("Filter items by property values").optional()
9515
+ },
9516
+ {
9517
+ name: "$count",
9518
+ type: "Query",
9519
+ schema: z.boolean().describe("Include count of items").optional()
9520
+ },
9521
+ {
9522
+ name: "$orderby",
9523
+ type: "Query",
9524
+ schema: z.array(z.string()).describe("Order items by property values").optional()
9525
+ },
9526
+ {
9527
+ name: "$select",
9528
+ type: "Query",
9529
+ schema: z.array(z.string()).describe("Select properties to be returned").optional()
9530
+ },
9531
+ {
9532
+ name: "$expand",
9533
+ type: "Query",
9534
+ schema: z.array(z.string()).describe("Expand related entities").optional()
9535
+ }
9536
+ ],
9537
+ response: z.void()
9538
+ },
9372
9539
  {
9373
9540
  method: "get",
9374
9541
  path: "/users/:userId/directReports",
@@ -1,10 +1,10 @@
1
- 2026-04-05 09:28:30 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
2
- 2026-04-05 09:28:30 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
3
- 2026-04-05 09:28:30 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
4
- 2026-04-05 09:28:30 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me/messages
5
- 2026-04-05 09:28:30 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me/calendar
6
- 2026-04-05 09:28:32 INFO: Using environment variables for secrets
7
- 2026-04-05 09:28:32 INFO: Using environment variables for secrets
8
- 2026-04-05 09:28:32 INFO: Using environment variables for secrets
9
- 2026-04-05 09:28:32 INFO: Using environment variables for secrets
10
- 2026-04-05 09:28:32 INFO: Using environment variables for secrets
1
+ 2026-04-05 10:06:38 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
2
+ 2026-04-05 10:06:38 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
3
+ 2026-04-05 10:06:38 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
4
+ 2026-04-05 10:06:38 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me/messages
5
+ 2026-04-05 10:06:38 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me/calendar
6
+ 2026-04-05 10:06:40 INFO: Using environment variables for secrets
7
+ 2026-04-05 10:06:40 INFO: Using environment variables for secrets
8
+ 2026-04-05 10:06:40 INFO: Using environment variables for secrets
9
+ 2026-04-05 10:06:40 INFO: Using environment variables for secrets
10
+ 2026-04-05 10:06:40 INFO: Using environment variables for secrets
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softeria/ms-365-mcp-server",
3
- "version": "0.64.0",
3
+ "version": "0.66.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",
@@ -348,6 +348,25 @@
348
348
  "supportsExpandExtendedProperties": true,
349
349
  "llmTip": "Returns expanded recurring event instances (not just seriesMaster) within a date range for a specific calendar. Requires startDateTime and endDateTime query parameters in ISO 8601 format (e.g., 2024-01-01T00:00:00Z). Each instance includes seriesMasterId and type (occurrence/exception) fields for recurring event linkage. Use fetchAllPages=true to retrieve all results when there are many events. To find Teams meetings, use $filter=isOnlineMeeting eq true. Teams meetings include a joinWebUrl property needed for transcript access via list-online-meetings."
350
350
  },
351
+ {
352
+ "pathPattern": "/me/calendar/getSchedule",
353
+ "method": "post",
354
+ "toolName": "get-schedule",
355
+ "workScopes": ["Calendars.Read"]
356
+ },
357
+ {
358
+ "pathPattern": "/users/{user-id}/calendar/events",
359
+ "method": "get",
360
+ "toolName": "list-shared-calendar-events",
361
+ "workScopes": ["Calendars.Read.Shared"]
362
+ },
363
+ {
364
+ "pathPattern": "/users/{user-id}/calendarView",
365
+ "method": "get",
366
+ "toolName": "get-shared-calendar-view",
367
+ "workScopes": ["Calendars.Read.Shared"],
368
+ "supportsTimezone": true
369
+ },
351
370
  {
352
371
  "pathPattern": "/me/calendars/{calendar-id}/events/{event-id}/instances",
353
372
  "method": "get",