@softeria/ms-365-mcp-server 0.161.4 → 0.163.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 +14 -8
- package/dist/cli.js +1 -1
- package/dist/endpoints.json +34 -2
- package/dist/generated/client.js +103 -0
- package/dist/lib/attachment-tickets.js +1 -0
- package/dist/lib/attachment-url-config.js +22 -9
- package/dist/server.js +1 -1
- package/package.json +1 -1
- package/src/endpoints.json +34 -2
package/README.md
CHANGED
|
@@ -809,16 +809,21 @@ is refused with the same 404 as any other bad ticket.
|
|
|
809
809
|
|
|
810
810
|
```
|
|
811
811
|
MS365_MCP_ATTACHMENT_URL_BASE=http://m365-mcp:3000 # required
|
|
812
|
-
MS365_MCP_ATTACHMENT_URL_KEY=... #
|
|
813
|
-
MS365_MCP_ATTACHMENT_URL_KEY_ID=1 # optional, default 1
|
|
812
|
+
MS365_MCP_ATTACHMENT_URL_KEY=... # optional (or _KEY_FILE=/path), see below
|
|
813
|
+
MS365_MCP_ATTACHMENT_URL_KEY_ID=1 # optional, default 1; needs a key
|
|
814
814
|
MS365_MCP_ATTACHMENT_URL_TTL_S=120 # optional, default 120, max 300
|
|
815
815
|
```
|
|
816
816
|
|
|
817
817
|
`MS365_MCP_ATTACHMENT_URL_BASE` is deliberately **not** `MS365_MCP_PUBLIC_URL`: that one is
|
|
818
818
|
browser-facing, for OAuth redirects, while this is fetched server-to-server and is
|
|
819
819
|
commonly a container address. A missing or malformed setting fails at startup rather than
|
|
820
|
-
per-request
|
|
821
|
-
|
|
820
|
+
per-request.
|
|
821
|
+
|
|
822
|
+
The signing key is optional. Without one, minted URLs are just `/attachment?t=<ticket>` and
|
|
823
|
+
any HTTP client can fetch them; the ticket alone authorises redemption. Set a key only if
|
|
824
|
+
the fetcher verifies the `dgk`/`dgx`/`dgs` signature (see below), such as a docglean-mcp
|
|
825
|
+
sidecar, which will refuse an unsigned URL. Setting `_KEY_ID` without a key, or a `_KEY_FILE` that is
|
|
826
|
+
empty or unreadable, fails at startup.
|
|
822
827
|
|
|
823
828
|
### Splitting the attachment listener
|
|
824
829
|
|
|
@@ -904,9 +909,10 @@ directly.
|
|
|
904
909
|
`--attachment-host` takes a bare IPv4 address, IPv6 address (bracketed `[::1]` or bare
|
|
905
910
|
`::1`) or hostname. It is refused rather than coerced — `--attachment-host 10.0.0.5:3001`
|
|
906
911
|
is an error naming `--attachment-port`, not a bind to something else. Note that
|
|
907
|
-
`MS365_MCP_ATTACHMENT_URL_BASE`
|
|
908
|
-
the host and the two implementations normalise IPv6 differently); if you
|
|
909
|
-
to an IPv6 address, name it in the base by hostname.
|
|
912
|
+
with a signing key set, `MS365_MCP_ATTACHMENT_URL_BASE` must not be an IPv6 literal (the URL
|
|
913
|
+
signature covers the host and the two implementations normalise IPv6 differently); if you
|
|
914
|
+
bind the listener to an IPv6 address, name it in the base by hostname. Without a key there
|
|
915
|
+
is no such restriction.
|
|
910
916
|
|
|
911
917
|
Point `MS365_MCP_ATTACHMENT_URL_BASE` at the attachment port. The server cannot check this
|
|
912
918
|
for you: the base is usually a container name on a network this process cannot resolve, so
|
|
@@ -915,7 +921,7 @@ base and the bound port are logged at startup, one line apart, for exactly that
|
|
|
915
921
|
|
|
916
922
|
### The signature, and who checks what
|
|
917
923
|
|
|
918
|
-
`dgk`/`dgx`/`dgs`
|
|
924
|
+
This server never checks `dgk`/`dgx`/`dgs` on redemption, and that is deliberate.
|
|
919
925
|
They exist for the fetcher: a document-conversion sidecar that refuses to dial a private
|
|
920
926
|
address unless the URL carries a valid HMAC from an origin it has been configured to trust.
|
|
921
927
|
What authorises redemption _here_ is the ticket. Verifying the signature on the way back in
|
package/dist/cli.js
CHANGED
|
@@ -29,7 +29,7 @@ program.name("ms-365-mcp-server").description("Microsoft 365 MCP Server").versio
|
|
|
29
29
|
"Enable login/logout tools when using HTTP mode (disabled by default in HTTP mode)"
|
|
30
30
|
).option(
|
|
31
31
|
"--enable-attachment-urls",
|
|
32
|
-
"HTTP mode only. Let get-download-url mint a short-TTL, single-use URL served by this server for Graph byte resources that expose no pre-authenticated URL of their own (mail and event attachments, meeting recordings, other $value endpoints). Also adds get-download-url to any --preset that lacks it (except teams-write). Requires MS365_MCP_ATTACHMENT_URL_BASE
|
|
32
|
+
"HTTP mode only. Let get-download-url mint a short-TTL, single-use URL served by this server for Graph byte resources that expose no pre-authenticated URL of their own (mail and event attachments, meeting recordings, other $value endpoints). Also adds get-download-url to any --preset that lacks it (except teams-write). Requires MS365_MCP_ATTACHMENT_URL_BASE; MS365_MCP_ATTACHMENT_URL_KEY (or _KEY_FILE) is optional and adds an HMAC signature for fetchers that verify one"
|
|
33
33
|
).option(
|
|
34
34
|
"--attachment-port <port>",
|
|
35
35
|
"HTTP mode only. Serve the attachment download route on its own listener on this port instead of on the MCP app, so a caller that can fetch attachments cannot also reach /mcp. Requires --enable-attachment-urls, and MS365_MCP_ATTACHMENT_URL_BASE must name this port. A separate port only isolates the two surfaces if they also bind separate interfaces \u2014 see --attachment-host. Equivalent env var: MS365_MCP_ATTACHMENT_PORT."
|
package/dist/endpoints.json
CHANGED
|
@@ -1322,7 +1322,7 @@
|
|
|
1322
1322
|
"toolName": "create-todo-task",
|
|
1323
1323
|
"presets": ["personal", "tasks"],
|
|
1324
1324
|
"scopes": ["Tasks.ReadWrite"],
|
|
1325
|
-
"llmTip": "Creates a new task in a Microsoft To Do list. Body: { title: \"...\" }; optional dueDateTime, reminderDateTime, importance, body (notes), recurrence, categories. Requires todoTaskListId from list-todo-task-lists."
|
|
1325
|
+
"llmTip": "Creates a new task in a Microsoft To Do list. Body: { title: \"...\" }; optional dueDateTime, reminderDateTime, importance, body (notes), recurrence, categories, and checklistItems: [{ displayName: \"...\", isChecked: false }] to create the task's steps inline (isChecked is optional). Requires todoTaskListId from list-todo-task-lists. To change steps after the task exists, use the *-todo-checklist-item tools."
|
|
1326
1326
|
},
|
|
1327
1327
|
{
|
|
1328
1328
|
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}",
|
|
@@ -1330,7 +1330,7 @@
|
|
|
1330
1330
|
"toolName": "update-todo-task",
|
|
1331
1331
|
"presets": ["personal", "tasks"],
|
|
1332
1332
|
"scopes": ["Tasks.ReadWrite"],
|
|
1333
|
-
"llmTip": "Updates a Microsoft To Do task. Use this to mark a to-do item complete or done (body: { status: \"completed\" }), reopen it (status: \"notStarted\"), rename it (title), or change its due date (dueDateTime), reminder (reminderDateTime), importance, or notes (body). Requires todoTaskListId from list-todo-task-lists and todoTaskId from list-todo-tasks."
|
|
1333
|
+
"llmTip": "Updates a Microsoft To Do task. Use this to mark a to-do item complete or done (body: { status: \"completed\" }), reopen it (status: \"notStarted\"), rename it (title), or change its due date (dueDateTime), reminder (reminderDateTime), importance, or notes (body). Requires todoTaskListId from list-todo-task-lists and todoTaskId from list-todo-tasks. Steps (checklistItems) can't be changed here: Graph rejects checklistItems in a PATCH on the task with 400. Use create-todo-checklist-item, update-todo-checklist-item, or delete-todo-checklist-item instead."
|
|
1334
1334
|
},
|
|
1335
1335
|
{
|
|
1336
1336
|
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}",
|
|
@@ -1363,6 +1363,38 @@
|
|
|
1363
1363
|
"scopes": ["Tasks.ReadWrite"],
|
|
1364
1364
|
"llmTip": "Removes a linked resource from a To Do task."
|
|
1365
1365
|
},
|
|
1366
|
+
{
|
|
1367
|
+
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/checklistItems",
|
|
1368
|
+
"method": "get",
|
|
1369
|
+
"toolName": "list-todo-checklist-items",
|
|
1370
|
+
"presets": ["personal", "tasks"],
|
|
1371
|
+
"scopes": ["Tasks.Read"],
|
|
1372
|
+
"llmTip": "Lists the steps (checklist items) of a To Do task. Each item has id, displayName, isChecked, checkedDateTime, and createdDateTime. Graph supports no OData query parameters on this endpoint, so do not pass select, filter, orderby, or top. Requires todoTaskListId from list-todo-task-lists and todoTaskId from list-todo-tasks."
|
|
1373
|
+
},
|
|
1374
|
+
{
|
|
1375
|
+
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/checklistItems",
|
|
1376
|
+
"method": "post",
|
|
1377
|
+
"toolName": "create-todo-checklist-item",
|
|
1378
|
+
"presets": ["personal", "tasks"],
|
|
1379
|
+
"scopes": ["Tasks.ReadWrite"],
|
|
1380
|
+
"llmTip": "Adds a step (checklist item) to an existing To Do task. Body: { displayName: \"...\" }; optional isChecked (defaults to false). Returns the new item with its id. To add steps while creating a task, pass checklistItems in the create-todo-task body instead."
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/checklistItems/{checklistItem-id}",
|
|
1384
|
+
"method": "patch",
|
|
1385
|
+
"toolName": "update-todo-checklist-item",
|
|
1386
|
+
"presets": ["personal", "tasks"],
|
|
1387
|
+
"scopes": ["Tasks.ReadWrite"],
|
|
1388
|
+
"llmTip": "Updates a step (checklist item) of a To Do task. Use this to check a step off (body: { isChecked: true }), uncheck it (isChecked: false), or rename it (displayName). Requires checklistItemId from list-todo-checklist-items."
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/checklistItems/{checklistItem-id}",
|
|
1392
|
+
"method": "delete",
|
|
1393
|
+
"toolName": "delete-todo-checklist-item",
|
|
1394
|
+
"presets": ["personal", "tasks"],
|
|
1395
|
+
"scopes": ["Tasks.ReadWrite"],
|
|
1396
|
+
"llmTip": "Deletes a step (checklist item) from a To Do task. This cannot be undone. Requires checklistItemId from list-todo-checklist-items."
|
|
1397
|
+
},
|
|
1366
1398
|
{
|
|
1367
1399
|
"pathPattern": "/me/planner/tasks",
|
|
1368
1400
|
"method": "get",
|
package/dist/generated/client.js
CHANGED
|
@@ -4148,6 +4148,11 @@ const microsoft_graph_todoTaskCollectionResponse = z.object({
|
|
|
4148
4148
|
"@odata.nextLink": z.string().nullable(),
|
|
4149
4149
|
value: z.array(microsoft_graph_todoTask)
|
|
4150
4150
|
}).partial().passthrough();
|
|
4151
|
+
const microsoft_graph_checklistItemCollectionResponse = z.object({
|
|
4152
|
+
"@odata.count": z.number().int().nullable(),
|
|
4153
|
+
"@odata.nextLink": z.string().nullable(),
|
|
4154
|
+
value: z.array(microsoft_graph_checklistItem)
|
|
4155
|
+
}).partial().passthrough();
|
|
4151
4156
|
const microsoft_graph_linkedResourceCollectionResponse = z.object({
|
|
4152
4157
|
"@odata.count": z.number().int().nullable(),
|
|
4153
4158
|
"@odata.nextLink": z.string().nullable(),
|
|
@@ -5295,6 +5300,7 @@ const schemas = {
|
|
|
5295
5300
|
microsoft_graph_todoTaskList,
|
|
5296
5301
|
microsoft_graph_todoTaskListCollectionResponse,
|
|
5297
5302
|
microsoft_graph_todoTaskCollectionResponse,
|
|
5303
|
+
microsoft_graph_checklistItemCollectionResponse,
|
|
5298
5304
|
microsoft_graph_linkedResourceCollectionResponse,
|
|
5299
5305
|
microsoft_graph_checkInMethod,
|
|
5300
5306
|
microsoft_graph_checkInClaim,
|
|
@@ -12347,6 +12353,103 @@ Currently, a user can be associated with a team in two different ways:`,
|
|
|
12347
12353
|
],
|
|
12348
12354
|
response: z.void()
|
|
12349
12355
|
},
|
|
12356
|
+
{
|
|
12357
|
+
method: "get",
|
|
12358
|
+
path: "/me/todo/lists/:todoTaskListId/tasks/:todoTaskId/checklistItems",
|
|
12359
|
+
alias: "list-todo-checklist-items",
|
|
12360
|
+
description: `Get the checklistItem resources associated to a todoTask from the checklistItems navigation property.`,
|
|
12361
|
+
requestFormat: "json",
|
|
12362
|
+
parameters: [
|
|
12363
|
+
{
|
|
12364
|
+
name: "$top",
|
|
12365
|
+
type: "Query",
|
|
12366
|
+
schema: z.number().int().gte(0).describe("Show only the first n items").optional()
|
|
12367
|
+
},
|
|
12368
|
+
{
|
|
12369
|
+
name: "$skip",
|
|
12370
|
+
type: "Query",
|
|
12371
|
+
schema: z.number().int().gte(0).describe("Skip the first n items").optional()
|
|
12372
|
+
},
|
|
12373
|
+
{
|
|
12374
|
+
name: "$search",
|
|
12375
|
+
type: "Query",
|
|
12376
|
+
schema: z.string().describe("Search items by search phrases").optional()
|
|
12377
|
+
},
|
|
12378
|
+
{
|
|
12379
|
+
name: "$filter",
|
|
12380
|
+
type: "Query",
|
|
12381
|
+
schema: z.string().describe("Filter items by property values").optional()
|
|
12382
|
+
},
|
|
12383
|
+
{
|
|
12384
|
+
name: "$count",
|
|
12385
|
+
type: "Query",
|
|
12386
|
+
schema: z.boolean().describe("Include count of items").optional()
|
|
12387
|
+
},
|
|
12388
|
+
{
|
|
12389
|
+
name: "$orderby",
|
|
12390
|
+
type: "Query",
|
|
12391
|
+
schema: z.array(z.string()).describe("Order items by property values").optional()
|
|
12392
|
+
},
|
|
12393
|
+
{
|
|
12394
|
+
name: "$select",
|
|
12395
|
+
type: "Query",
|
|
12396
|
+
schema: z.array(z.string()).describe("Select properties to be returned").optional()
|
|
12397
|
+
},
|
|
12398
|
+
{
|
|
12399
|
+
name: "$expand",
|
|
12400
|
+
type: "Query",
|
|
12401
|
+
schema: z.array(z.string()).describe("Expand related entities").optional()
|
|
12402
|
+
}
|
|
12403
|
+
],
|
|
12404
|
+
response: z.void()
|
|
12405
|
+
},
|
|
12406
|
+
{
|
|
12407
|
+
method: "post",
|
|
12408
|
+
path: "/me/todo/lists/:todoTaskListId/tasks/:todoTaskId/checklistItems",
|
|
12409
|
+
alias: "create-todo-checklist-item",
|
|
12410
|
+
description: `Create a new checklistItem object.`,
|
|
12411
|
+
requestFormat: "json",
|
|
12412
|
+
parameters: [
|
|
12413
|
+
{
|
|
12414
|
+
name: "body",
|
|
12415
|
+
description: `New navigation property`,
|
|
12416
|
+
type: "Body",
|
|
12417
|
+
schema: microsoft_graph_checklistItem
|
|
12418
|
+
}
|
|
12419
|
+
],
|
|
12420
|
+
response: z.void()
|
|
12421
|
+
},
|
|
12422
|
+
{
|
|
12423
|
+
method: "patch",
|
|
12424
|
+
path: "/me/todo/lists/:todoTaskListId/tasks/:todoTaskId/checklistItems/:checklistItemId",
|
|
12425
|
+
alias: "update-todo-checklist-item",
|
|
12426
|
+
description: `Update the properties of a checklistItem object.`,
|
|
12427
|
+
requestFormat: "json",
|
|
12428
|
+
parameters: [
|
|
12429
|
+
{
|
|
12430
|
+
name: "body",
|
|
12431
|
+
description: `New navigation property values`,
|
|
12432
|
+
type: "Body",
|
|
12433
|
+
schema: microsoft_graph_checklistItem
|
|
12434
|
+
}
|
|
12435
|
+
],
|
|
12436
|
+
response: z.void()
|
|
12437
|
+
},
|
|
12438
|
+
{
|
|
12439
|
+
method: "delete",
|
|
12440
|
+
path: "/me/todo/lists/:todoTaskListId/tasks/:todoTaskId/checklistItems/:checklistItemId",
|
|
12441
|
+
alias: "delete-todo-checklist-item",
|
|
12442
|
+
description: `Delete a checklistItem object.`,
|
|
12443
|
+
requestFormat: "json",
|
|
12444
|
+
parameters: [
|
|
12445
|
+
{
|
|
12446
|
+
name: "If-Match",
|
|
12447
|
+
type: "Header",
|
|
12448
|
+
schema: z.string().describe("ETag").optional()
|
|
12449
|
+
}
|
|
12450
|
+
],
|
|
12451
|
+
response: z.void()
|
|
12452
|
+
},
|
|
12350
12453
|
{
|
|
12351
12454
|
method: "get",
|
|
12352
12455
|
path: "/me/todo/lists/:todoTaskListId/tasks/:todoTaskId/linkedResources",
|
|
@@ -5,6 +5,7 @@ const TICKET_PARAM = "t";
|
|
|
5
5
|
function buildAttachmentUrl(config, ticketId, nowMs = Date.now()) {
|
|
6
6
|
const url = new URL(ATTACHMENT_ROUTE, config.base);
|
|
7
7
|
url.searchParams.set(TICKET_PARAM, ticketId);
|
|
8
|
+
if (!config.key) return url.toString();
|
|
8
9
|
return signUrl(
|
|
9
10
|
url.toString(),
|
|
10
11
|
{ key: config.key, keyId: config.keyId, ttlSeconds: config.ttlSeconds },
|
|
@@ -19,13 +19,20 @@ function pythonStrip(value) {
|
|
|
19
19
|
function readKey(env) {
|
|
20
20
|
const keyFile = env.MS365_MCP_ATTACHMENT_URL_KEY_FILE;
|
|
21
21
|
if (keyFile) {
|
|
22
|
+
let key;
|
|
22
23
|
try {
|
|
23
|
-
|
|
24
|
+
key = pythonStrip(readFileSync(keyFile, "utf8"));
|
|
24
25
|
} catch {
|
|
25
26
|
throw new AttachmentUrlConfigError(
|
|
26
27
|
`MS365_MCP_ATTACHMENT_URL_KEY_FILE could not be read: ${keyFile}`
|
|
27
28
|
);
|
|
28
29
|
}
|
|
30
|
+
if (!key) {
|
|
31
|
+
throw new AttachmentUrlConfigError(
|
|
32
|
+
`MS365_MCP_ATTACHMENT_URL_KEY_FILE is empty: ${keyFile}. Unset it to mint unsigned URLs.`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return key;
|
|
29
36
|
}
|
|
30
37
|
return env.MS365_MCP_ATTACHMENT_URL_KEY ?? "";
|
|
31
38
|
}
|
|
@@ -50,20 +57,26 @@ function loadAttachmentUrlConfig(enabled, env = process.env) {
|
|
|
50
57
|
`MS365_MCP_ATTACHMENT_URL_BASE must be http or https, got ${parsedBase.protocol}`
|
|
51
58
|
);
|
|
52
59
|
}
|
|
53
|
-
if (parsedBase.hostname.startsWith("[")) {
|
|
54
|
-
throw new AttachmentUrlConfigError(
|
|
55
|
-
`MS365_MCP_ATTACHMENT_URL_BASE must not be an IPv6 literal: the URL signature covers the host, and this runtime and the verifying sidecar normalise IPv6 spellings differently, so every minted URL would be refused. Use a hostname (a container or service name) instead of ${parsedBase.hostname}.`
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
60
|
if (parsedBase.search || parsedBase.hash) {
|
|
59
61
|
throw new AttachmentUrlConfigError(
|
|
60
62
|
"MS365_MCP_ATTACHMENT_URL_BASE must not carry a query string or fragment."
|
|
61
63
|
);
|
|
62
64
|
}
|
|
63
65
|
const key = readKey(env);
|
|
64
|
-
if (!key) {
|
|
66
|
+
if (key && !key.trim()) {
|
|
67
|
+
throw new AttachmentUrlConfigError(
|
|
68
|
+
"MS365_MCP_ATTACHMENT_URL_KEY is whitespace only. Set a real key, or unset it to mint unsigned URLs."
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
if (key) {
|
|
72
|
+
if (parsedBase.hostname.startsWith("[")) {
|
|
73
|
+
throw new AttachmentUrlConfigError(
|
|
74
|
+
`MS365_MCP_ATTACHMENT_URL_BASE must not be an IPv6 literal: the URL signature covers the host, and this runtime and the verifying sidecar normalise IPv6 spellings differently, so every minted URL would be refused. Use a hostname (a container or service name) instead of ${parsedBase.hostname}.`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
} else if (env.MS365_MCP_ATTACHMENT_URL_KEY_ID) {
|
|
65
78
|
throw new AttachmentUrlConfigError(
|
|
66
|
-
"
|
|
79
|
+
"MS365_MCP_ATTACHMENT_URL_KEY_ID is set but no signing key is: set MS365_MCP_ATTACHMENT_URL_KEY or MS365_MCP_ATTACHMENT_URL_KEY_FILE, or unset the key id."
|
|
67
80
|
);
|
|
68
81
|
}
|
|
69
82
|
for (let index = 0; index < key.length; index += 1) {
|
|
@@ -92,7 +105,7 @@ function loadAttachmentUrlConfig(enabled, env = process.env) {
|
|
|
92
105
|
}
|
|
93
106
|
return {
|
|
94
107
|
base: parsedBase.origin,
|
|
95
|
-
key,
|
|
108
|
+
key: key || void 0,
|
|
96
109
|
keyId,
|
|
97
110
|
ttlSeconds
|
|
98
111
|
};
|
package/dist/server.js
CHANGED
|
@@ -730,7 +730,7 @@ class MicrosoftGraphServer {
|
|
|
730
730
|
attachmentApp.get(ATTACHMENT_ROUTE, createAttachmentHandler(attachmentDeps));
|
|
731
731
|
attachmentApp.put(ATTACHMENT_ROUTE, createAttachmentUploadHandler(attachmentDeps));
|
|
732
732
|
logger.info(
|
|
733
|
-
` - Attachment URLs: ${attachmentConfig.base}${ATTACHMENT_ROUTE} (ttl ${attachmentConfig.ttlSeconds}s, key id ${attachmentConfig.keyId})`
|
|
733
|
+
` - Attachment URLs: ${attachmentConfig.base}${ATTACHMENT_ROUTE} (ttl ${attachmentConfig.ttlSeconds}s, ${attachmentConfig.key ? `signed, key id ${attachmentConfig.keyId}` : "unsigned"})`
|
|
734
734
|
);
|
|
735
735
|
if (dedicated) {
|
|
736
736
|
logger.info(
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softeria/ms-365-mcp-server",
|
|
3
3
|
"mcpName": "io.github.Softeria/ms-365-mcp-server",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.163.0",
|
|
5
5
|
"description": " A Model Context Protocol (MCP) server for interacting with Microsoft 365 and Office services through the Graph API",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
package/src/endpoints.json
CHANGED
|
@@ -1322,7 +1322,7 @@
|
|
|
1322
1322
|
"toolName": "create-todo-task",
|
|
1323
1323
|
"presets": ["personal", "tasks"],
|
|
1324
1324
|
"scopes": ["Tasks.ReadWrite"],
|
|
1325
|
-
"llmTip": "Creates a new task in a Microsoft To Do list. Body: { title: \"...\" }; optional dueDateTime, reminderDateTime, importance, body (notes), recurrence, categories. Requires todoTaskListId from list-todo-task-lists."
|
|
1325
|
+
"llmTip": "Creates a new task in a Microsoft To Do list. Body: { title: \"...\" }; optional dueDateTime, reminderDateTime, importance, body (notes), recurrence, categories, and checklistItems: [{ displayName: \"...\", isChecked: false }] to create the task's steps inline (isChecked is optional). Requires todoTaskListId from list-todo-task-lists. To change steps after the task exists, use the *-todo-checklist-item tools."
|
|
1326
1326
|
},
|
|
1327
1327
|
{
|
|
1328
1328
|
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}",
|
|
@@ -1330,7 +1330,7 @@
|
|
|
1330
1330
|
"toolName": "update-todo-task",
|
|
1331
1331
|
"presets": ["personal", "tasks"],
|
|
1332
1332
|
"scopes": ["Tasks.ReadWrite"],
|
|
1333
|
-
"llmTip": "Updates a Microsoft To Do task. Use this to mark a to-do item complete or done (body: { status: \"completed\" }), reopen it (status: \"notStarted\"), rename it (title), or change its due date (dueDateTime), reminder (reminderDateTime), importance, or notes (body). Requires todoTaskListId from list-todo-task-lists and todoTaskId from list-todo-tasks."
|
|
1333
|
+
"llmTip": "Updates a Microsoft To Do task. Use this to mark a to-do item complete or done (body: { status: \"completed\" }), reopen it (status: \"notStarted\"), rename it (title), or change its due date (dueDateTime), reminder (reminderDateTime), importance, or notes (body). Requires todoTaskListId from list-todo-task-lists and todoTaskId from list-todo-tasks. Steps (checklistItems) can't be changed here: Graph rejects checklistItems in a PATCH on the task with 400. Use create-todo-checklist-item, update-todo-checklist-item, or delete-todo-checklist-item instead."
|
|
1334
1334
|
},
|
|
1335
1335
|
{
|
|
1336
1336
|
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}",
|
|
@@ -1363,6 +1363,38 @@
|
|
|
1363
1363
|
"scopes": ["Tasks.ReadWrite"],
|
|
1364
1364
|
"llmTip": "Removes a linked resource from a To Do task."
|
|
1365
1365
|
},
|
|
1366
|
+
{
|
|
1367
|
+
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/checklistItems",
|
|
1368
|
+
"method": "get",
|
|
1369
|
+
"toolName": "list-todo-checklist-items",
|
|
1370
|
+
"presets": ["personal", "tasks"],
|
|
1371
|
+
"scopes": ["Tasks.Read"],
|
|
1372
|
+
"llmTip": "Lists the steps (checklist items) of a To Do task. Each item has id, displayName, isChecked, checkedDateTime, and createdDateTime. Graph supports no OData query parameters on this endpoint, so do not pass select, filter, orderby, or top. Requires todoTaskListId from list-todo-task-lists and todoTaskId from list-todo-tasks."
|
|
1373
|
+
},
|
|
1374
|
+
{
|
|
1375
|
+
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/checklistItems",
|
|
1376
|
+
"method": "post",
|
|
1377
|
+
"toolName": "create-todo-checklist-item",
|
|
1378
|
+
"presets": ["personal", "tasks"],
|
|
1379
|
+
"scopes": ["Tasks.ReadWrite"],
|
|
1380
|
+
"llmTip": "Adds a step (checklist item) to an existing To Do task. Body: { displayName: \"...\" }; optional isChecked (defaults to false). Returns the new item with its id. To add steps while creating a task, pass checklistItems in the create-todo-task body instead."
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/checklistItems/{checklistItem-id}",
|
|
1384
|
+
"method": "patch",
|
|
1385
|
+
"toolName": "update-todo-checklist-item",
|
|
1386
|
+
"presets": ["personal", "tasks"],
|
|
1387
|
+
"scopes": ["Tasks.ReadWrite"],
|
|
1388
|
+
"llmTip": "Updates a step (checklist item) of a To Do task. Use this to check a step off (body: { isChecked: true }), uncheck it (isChecked: false), or rename it (displayName). Requires checklistItemId from list-todo-checklist-items."
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
"pathPattern": "/me/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/checklistItems/{checklistItem-id}",
|
|
1392
|
+
"method": "delete",
|
|
1393
|
+
"toolName": "delete-todo-checklist-item",
|
|
1394
|
+
"presets": ["personal", "tasks"],
|
|
1395
|
+
"scopes": ["Tasks.ReadWrite"],
|
|
1396
|
+
"llmTip": "Deletes a step (checklist item) from a To Do task. This cannot be undone. Requires checklistItemId from list-todo-checklist-items."
|
|
1397
|
+
},
|
|
1366
1398
|
{
|
|
1367
1399
|
"pathPattern": "/me/planner/tasks",
|
|
1368
1400
|
"method": "get",
|