@softeria/ms-365-mcp-server 0.88.0 → 0.88.2
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 +4 -0
- package/dist/__tests__/graph-tools.test.js +46 -0
- package/dist/endpoints.json +4 -2
- package/dist/graph-tools.js +2 -7
- package/package.json +1 -1
- package/src/endpoints.json +4 -2
package/README.md
CHANGED
|
@@ -622,6 +622,10 @@ After cloning the repository, you may need to generate the client code from the
|
|
|
622
622
|
npm run generate
|
|
623
623
|
```
|
|
624
624
|
|
|
625
|
+
## Related Projects
|
|
626
|
+
|
|
627
|
+
- [ms-365-admin-mcp-server](https://github.com/okapi-ca/ms-365-admin-mcp-server) by [@okapi-ca](https://github.com/okapi-ca): companion server for admin/daemon scenarios using application permissions (client credentials flow), covering security alerts, audit logs, service health, and usage reports.
|
|
628
|
+
|
|
625
629
|
## Support
|
|
626
630
|
|
|
627
631
|
If you're having problems or need help:
|
|
@@ -395,4 +395,50 @@ describe("graph-tools", () => {
|
|
|
395
395
|
expect(tool.schema["timezone"]).toBeUndefined();
|
|
396
396
|
});
|
|
397
397
|
});
|
|
398
|
+
describe("outlook.body-content-type Prefer header", () => {
|
|
399
|
+
it('should set Prefer: outlook.body-content-type="text" on GET requests', async () => {
|
|
400
|
+
const endpoint = makeEndpoint({ method: "get" });
|
|
401
|
+
const config = makeConfig({ method: "get" });
|
|
402
|
+
mockEndpoints.push(endpoint);
|
|
403
|
+
mockEndpointsJson = [config];
|
|
404
|
+
const graphClient = createMockGraphClient([
|
|
405
|
+
{ content: [{ type: "text", text: JSON.stringify({ value: [] }) }] }
|
|
406
|
+
]);
|
|
407
|
+
const server = createMockServer();
|
|
408
|
+
const { registerGraphTools } = await loadModule();
|
|
409
|
+
registerGraphTools(server, graphClient);
|
|
410
|
+
await server.tools.get("test-tool").handler({});
|
|
411
|
+
const [, options] = graphClient.graphRequest.mock.calls[0];
|
|
412
|
+
expect(options.headers["Prefer"]).toContain('outlook.body-content-type="text"');
|
|
413
|
+
});
|
|
414
|
+
it("should NOT set Prefer: outlook.body-content-type on POST requests", async () => {
|
|
415
|
+
const endpoint = makeEndpoint({
|
|
416
|
+
alias: "create-reply-draft",
|
|
417
|
+
method: "post",
|
|
418
|
+
path: "/me/messages/:messageId/createReply",
|
|
419
|
+
parameters: [
|
|
420
|
+
{ name: "messageId", type: "Path", schema: z.string() },
|
|
421
|
+
{ name: "body", type: "Body", schema: z.any() }
|
|
422
|
+
]
|
|
423
|
+
});
|
|
424
|
+
const config = makeConfig({
|
|
425
|
+
toolName: "create-reply-draft",
|
|
426
|
+
method: "post",
|
|
427
|
+
pathPattern: "/me/messages/{message-id}/createReply"
|
|
428
|
+
});
|
|
429
|
+
mockEndpoints.push(endpoint);
|
|
430
|
+
mockEndpointsJson = [config];
|
|
431
|
+
const graphClient = createMockGraphClient([{ content: [{ type: "text", text: "{}" }] }]);
|
|
432
|
+
const server = createMockServer();
|
|
433
|
+
const { registerGraphTools } = await loadModule();
|
|
434
|
+
registerGraphTools(server, graphClient);
|
|
435
|
+
await server.tools.get("create-reply-draft").handler({
|
|
436
|
+
messageId: "AAMk123",
|
|
437
|
+
body: { Message: { body: { contentType: "html", content: "<p>hi</p>" } } }
|
|
438
|
+
});
|
|
439
|
+
const [, options] = graphClient.graphRequest.mock.calls[0];
|
|
440
|
+
const prefer = options.headers["Prefer"];
|
|
441
|
+
expect(prefer === void 0 || !prefer.includes("outlook.body-content-type")).toBe(true);
|
|
442
|
+
});
|
|
443
|
+
});
|
|
398
444
|
});
|
package/dist/endpoints.json
CHANGED
|
@@ -190,13 +190,15 @@
|
|
|
190
190
|
"pathPattern": "/me/messages/{message-id}/createReply",
|
|
191
191
|
"method": "post",
|
|
192
192
|
"toolName": "create-reply-draft",
|
|
193
|
-
"scopes": ["Mail.ReadWrite"]
|
|
193
|
+
"scopes": ["Mail.ReadWrite"],
|
|
194
|
+
"llmTip": "For HTML replies pass Message.body.contentType: 'html' with Message.body.content as HTML. Note: supplying Message.body replaces the whole draft body, so the original quoted history is not included. Specifying both 'comment' and Message.body returns 400. Signatures are added by the Outlook client only, not via Graph."
|
|
194
195
|
},
|
|
195
196
|
{
|
|
196
197
|
"pathPattern": "/me/messages/{message-id}/createReplyAll",
|
|
197
198
|
"method": "post",
|
|
198
199
|
"toolName": "create-reply-all-draft",
|
|
199
|
-
"scopes": ["Mail.ReadWrite"]
|
|
200
|
+
"scopes": ["Mail.ReadWrite"],
|
|
201
|
+
"llmTip": "For HTML replies pass Message.body.contentType: 'html' with Message.body.content as HTML. Note: supplying Message.body replaces the whole draft body, so the original quoted history is not included. Specifying both 'comment' and Message.body returns 400. Signatures are added by the Outlook client only, not via Graph."
|
|
200
202
|
},
|
|
201
203
|
{
|
|
202
204
|
"pathPattern": "/me/messages/{message-id}/send",
|
package/dist/graph-tools.js
CHANGED
|
@@ -142,7 +142,7 @@ async function executeGraphTool(tool, config, graphClient, params, authManager)
|
|
|
142
142
|
logger.info(`Setting timezone preference: outlook.timezone="${params.timezone}"`);
|
|
143
143
|
}
|
|
144
144
|
const bodyFormat = process.env.MS365_MCP_BODY_FORMAT || "text";
|
|
145
|
-
if (bodyFormat !== "html") {
|
|
145
|
+
if (bodyFormat !== "html" && tool.method.toUpperCase() === "GET") {
|
|
146
146
|
preferValues.push(`outlook.body-content-type="${bodyFormat}"`);
|
|
147
147
|
}
|
|
148
148
|
if (preferValues.length > 0) {
|
|
@@ -221,13 +221,8 @@ async function executeGraphTool(tool, config, graphClient, params, authManager)
|
|
|
221
221
|
while (nextLink && pageCount < maxPages && allItems.length < maxItems) {
|
|
222
222
|
logger.info(`Fetching page ${pageCount + 1} from: ${nextLink}`);
|
|
223
223
|
const url = new URL(nextLink);
|
|
224
|
-
const nextPath = url.pathname.replace("/v1.0", "");
|
|
224
|
+
const nextPath = url.pathname.replace("/v1.0", "") + url.search;
|
|
225
225
|
const nextOptions = { ...options };
|
|
226
|
-
const nextQueryParams = {};
|
|
227
|
-
for (const [key, value] of url.searchParams.entries()) {
|
|
228
|
-
nextQueryParams[key] = value;
|
|
229
|
-
}
|
|
230
|
-
nextOptions.queryParams = nextQueryParams;
|
|
231
226
|
const nextResponse = await graphClient.graphRequest(nextPath, nextOptions);
|
|
232
227
|
if (nextResponse?.content?.[0]?.text) {
|
|
233
228
|
const nextJsonResponse = JSON.parse(nextResponse.content[0].text);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softeria/ms-365-mcp-server",
|
|
3
|
-
"version": "0.88.
|
|
3
|
+
"version": "0.88.2",
|
|
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",
|
package/src/endpoints.json
CHANGED
|
@@ -190,13 +190,15 @@
|
|
|
190
190
|
"pathPattern": "/me/messages/{message-id}/createReply",
|
|
191
191
|
"method": "post",
|
|
192
192
|
"toolName": "create-reply-draft",
|
|
193
|
-
"scopes": ["Mail.ReadWrite"]
|
|
193
|
+
"scopes": ["Mail.ReadWrite"],
|
|
194
|
+
"llmTip": "For HTML replies pass Message.body.contentType: 'html' with Message.body.content as HTML. Note: supplying Message.body replaces the whole draft body, so the original quoted history is not included. Specifying both 'comment' and Message.body returns 400. Signatures are added by the Outlook client only, not via Graph."
|
|
194
195
|
},
|
|
195
196
|
{
|
|
196
197
|
"pathPattern": "/me/messages/{message-id}/createReplyAll",
|
|
197
198
|
"method": "post",
|
|
198
199
|
"toolName": "create-reply-all-draft",
|
|
199
|
-
"scopes": ["Mail.ReadWrite"]
|
|
200
|
+
"scopes": ["Mail.ReadWrite"],
|
|
201
|
+
"llmTip": "For HTML replies pass Message.body.contentType: 'html' with Message.body.content as HTML. Note: supplying Message.body replaces the whole draft body, so the original quoted history is not included. Specifying both 'comment' and Message.body returns 400. Signatures are added by the Outlook client only, not via Graph."
|
|
200
202
|
},
|
|
201
203
|
{
|
|
202
204
|
"pathPattern": "/me/messages/{message-id}/send",
|