@softeria/ms-365-mcp-server 0.47.0 → 0.47.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/dist/auth.js +50 -27
- package/dist/endpoints.json +49 -0
- package/dist/generated/client.js +215 -0
- package/logs/mcp-server.log +10 -10
- package/package.json +1 -1
- package/src/endpoints.json +49 -0
package/dist/auth.js
CHANGED
|
@@ -48,6 +48,30 @@ function ensureParentDir(filePath) {
|
|
|
48
48
|
const dir = path.dirname(filePath);
|
|
49
49
|
fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
50
50
|
}
|
|
51
|
+
function wrapCache(data) {
|
|
52
|
+
return JSON.stringify({ _cacheEnvelope: true, data, savedAt: Date.now() });
|
|
53
|
+
}
|
|
54
|
+
function unwrapCache(raw) {
|
|
55
|
+
try {
|
|
56
|
+
const parsed = JSON.parse(raw);
|
|
57
|
+
if (parsed._cacheEnvelope && typeof parsed.data === "string") {
|
|
58
|
+
return { data: parsed.data, savedAt: parsed.savedAt };
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
return { data: raw };
|
|
63
|
+
}
|
|
64
|
+
function pickNewest(keytarRaw, fileRaw) {
|
|
65
|
+
if (!keytarRaw && !fileRaw) return void 0;
|
|
66
|
+
if (keytarRaw && !fileRaw) return unwrapCache(keytarRaw).data;
|
|
67
|
+
if (!keytarRaw && fileRaw) return unwrapCache(fileRaw).data;
|
|
68
|
+
const kt = unwrapCache(keytarRaw);
|
|
69
|
+
const file = unwrapCache(fileRaw);
|
|
70
|
+
if (kt.savedAt === void 0 && file.savedAt === void 0) return kt.data;
|
|
71
|
+
if (kt.savedAt !== void 0 && file.savedAt === void 0) return kt.data;
|
|
72
|
+
if (kt.savedAt === void 0 && file.savedAt !== void 0) return file.data;
|
|
73
|
+
return kt.savedAt >= file.savedAt ? kt.data : file.data;
|
|
74
|
+
}
|
|
51
75
|
function createMsalConfig(secrets) {
|
|
52
76
|
const cloudEndpoints = getCloudEndpoints(secrets.cloudType);
|
|
53
77
|
return {
|
|
@@ -126,24 +150,21 @@ class AuthManager {
|
|
|
126
150
|
}
|
|
127
151
|
async loadTokenCache() {
|
|
128
152
|
try {
|
|
129
|
-
let
|
|
153
|
+
let keytarRaw;
|
|
130
154
|
try {
|
|
131
155
|
const kt = await getKeytar();
|
|
132
156
|
if (kt) {
|
|
133
|
-
|
|
134
|
-
if (cachedData) {
|
|
135
|
-
cacheData = cachedData;
|
|
136
|
-
}
|
|
157
|
+
keytarRaw = await kt.getPassword(SERVICE_NAME, TOKEN_CACHE_ACCOUNT) ?? void 0;
|
|
137
158
|
}
|
|
138
159
|
} catch (keytarError) {
|
|
139
|
-
logger.warn(
|
|
140
|
-
`Keychain access failed, falling back to file storage: ${keytarError.message}`
|
|
141
|
-
);
|
|
160
|
+
logger.warn(`Keychain access failed: ${keytarError.message}`);
|
|
142
161
|
}
|
|
162
|
+
let fileRaw;
|
|
143
163
|
const cachePath = getTokenCachePath();
|
|
144
|
-
if (
|
|
145
|
-
|
|
164
|
+
if (existsSync(cachePath)) {
|
|
165
|
+
fileRaw = readFileSync(cachePath, "utf8");
|
|
146
166
|
}
|
|
167
|
+
const cacheData = pickNewest(keytarRaw, fileRaw);
|
|
147
168
|
if (cacheData) {
|
|
148
169
|
this.msalApp.getTokenCache().deserialize(cacheData);
|
|
149
170
|
}
|
|
@@ -154,24 +175,23 @@ class AuthManager {
|
|
|
154
175
|
}
|
|
155
176
|
async loadSelectedAccount() {
|
|
156
177
|
try {
|
|
157
|
-
let
|
|
178
|
+
let keytarRaw;
|
|
158
179
|
try {
|
|
159
180
|
const kt = await getKeytar();
|
|
160
181
|
if (kt) {
|
|
161
|
-
|
|
162
|
-
if (cachedData) {
|
|
163
|
-
selectedAccountData = cachedData;
|
|
164
|
-
}
|
|
182
|
+
keytarRaw = await kt.getPassword(SERVICE_NAME, SELECTED_ACCOUNT_KEY) ?? void 0;
|
|
165
183
|
}
|
|
166
184
|
} catch (keytarError) {
|
|
167
185
|
logger.warn(
|
|
168
|
-
`Keychain access failed for selected account
|
|
186
|
+
`Keychain access failed for selected account: ${keytarError.message}`
|
|
169
187
|
);
|
|
170
188
|
}
|
|
189
|
+
let fileRaw;
|
|
171
190
|
const accountPath = getSelectedAccountPath();
|
|
172
|
-
if (
|
|
173
|
-
|
|
191
|
+
if (existsSync(accountPath)) {
|
|
192
|
+
fileRaw = readFileSync(accountPath, "utf8");
|
|
174
193
|
}
|
|
194
|
+
const selectedAccountData = pickNewest(keytarRaw, fileRaw);
|
|
175
195
|
if (selectedAccountData) {
|
|
176
196
|
const parsed = JSON.parse(selectedAccountData);
|
|
177
197
|
this.selectedAccountId = parsed.accountId;
|
|
@@ -183,15 +203,15 @@ class AuthManager {
|
|
|
183
203
|
}
|
|
184
204
|
async saveTokenCache() {
|
|
185
205
|
try {
|
|
186
|
-
const
|
|
206
|
+
const stamped = wrapCache(this.msalApp.getTokenCache().serialize());
|
|
187
207
|
try {
|
|
188
208
|
const kt = await getKeytar();
|
|
189
209
|
if (kt) {
|
|
190
|
-
await kt.setPassword(SERVICE_NAME, TOKEN_CACHE_ACCOUNT,
|
|
210
|
+
await kt.setPassword(SERVICE_NAME, TOKEN_CACHE_ACCOUNT, stamped);
|
|
191
211
|
} else {
|
|
192
212
|
const cachePath = getTokenCachePath();
|
|
193
213
|
ensureParentDir(cachePath);
|
|
194
|
-
fs.writeFileSync(cachePath,
|
|
214
|
+
fs.writeFileSync(cachePath, stamped, { mode: 384 });
|
|
195
215
|
}
|
|
196
216
|
} catch (keytarError) {
|
|
197
217
|
logger.warn(
|
|
@@ -199,7 +219,7 @@ class AuthManager {
|
|
|
199
219
|
);
|
|
200
220
|
const cachePath = getTokenCachePath();
|
|
201
221
|
ensureParentDir(cachePath);
|
|
202
|
-
fs.writeFileSync(cachePath,
|
|
222
|
+
fs.writeFileSync(cachePath, stamped, { mode: 384 });
|
|
203
223
|
}
|
|
204
224
|
} catch (error) {
|
|
205
225
|
logger.error(`Error saving token cache: ${error.message}`);
|
|
@@ -207,15 +227,15 @@ class AuthManager {
|
|
|
207
227
|
}
|
|
208
228
|
async saveSelectedAccount() {
|
|
209
229
|
try {
|
|
210
|
-
const
|
|
230
|
+
const stamped = wrapCache(JSON.stringify({ accountId: this.selectedAccountId }));
|
|
211
231
|
try {
|
|
212
232
|
const kt = await getKeytar();
|
|
213
233
|
if (kt) {
|
|
214
|
-
await kt.setPassword(SERVICE_NAME, SELECTED_ACCOUNT_KEY,
|
|
234
|
+
await kt.setPassword(SERVICE_NAME, SELECTED_ACCOUNT_KEY, stamped);
|
|
215
235
|
} else {
|
|
216
236
|
const accountPath = getSelectedAccountPath();
|
|
217
237
|
ensureParentDir(accountPath);
|
|
218
|
-
fs.writeFileSync(accountPath,
|
|
238
|
+
fs.writeFileSync(accountPath, stamped, { mode: 384 });
|
|
219
239
|
}
|
|
220
240
|
} catch (keytarError) {
|
|
221
241
|
logger.warn(
|
|
@@ -223,7 +243,7 @@ class AuthManager {
|
|
|
223
243
|
);
|
|
224
244
|
const accountPath = getSelectedAccountPath();
|
|
225
245
|
ensureParentDir(accountPath);
|
|
226
|
-
fs.writeFileSync(accountPath,
|
|
246
|
+
fs.writeFileSync(accountPath, stamped, { mode: 384 });
|
|
227
247
|
}
|
|
228
248
|
} catch (error) {
|
|
229
249
|
logger.error(`Error saving selected account: ${error.message}`);
|
|
@@ -524,5 +544,8 @@ export {
|
|
|
524
544
|
buildScopesFromEndpoints,
|
|
525
545
|
auth_default as default,
|
|
526
546
|
getSelectedAccountPath,
|
|
527
|
-
getTokenCachePath
|
|
547
|
+
getTokenCachePath,
|
|
548
|
+
pickNewest,
|
|
549
|
+
unwrapCache,
|
|
550
|
+
wrapCache
|
|
528
551
|
};
|
package/dist/endpoints.json
CHANGED
|
@@ -658,6 +658,55 @@
|
|
|
658
658
|
"toolName": "list-team-members",
|
|
659
659
|
"workScopes": ["TeamMember.Read.All"]
|
|
660
660
|
},
|
|
661
|
+
{
|
|
662
|
+
"pathPattern": "/teams/{team-id}/tags",
|
|
663
|
+
"method": "get",
|
|
664
|
+
"toolName": "list-team-tags",
|
|
665
|
+
"workScopes": ["TeamworkTag.Read"],
|
|
666
|
+
"llmTip": "List all tags in a team. Returns tag id, displayName, memberCount, and tagType (standard or scheduled). Use list-joined-teams to find the team ID first."
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"pathPattern": "/teams/{team-id}/tags",
|
|
670
|
+
"method": "post",
|
|
671
|
+
"toolName": "create-team-tag",
|
|
672
|
+
"workScopes": ["TeamworkTag.ReadWrite"],
|
|
673
|
+
"llmTip": "Create a new tag in a team. Body requires displayName (max 40 chars) and an optional members array (max 25 at creation, each with a userId). Use list-team-members to find user IDs. Add more members individually with add-team-tag-member after creation."
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}",
|
|
677
|
+
"method": "get",
|
|
678
|
+
"toolName": "get-team-tag",
|
|
679
|
+
"workScopes": ["TeamworkTag.Read"],
|
|
680
|
+
"llmTip": "Get details of a specific tag including displayName, memberCount, and tagType. Use list-team-tags to find the tag ID."
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}",
|
|
684
|
+
"method": "patch",
|
|
685
|
+
"toolName": "update-team-tag",
|
|
686
|
+
"workScopes": ["TeamworkTag.ReadWrite"],
|
|
687
|
+
"llmTip": "Update a tag's displayName (max 40 chars). Use list-team-tags to find the tag ID."
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}",
|
|
691
|
+
"method": "delete",
|
|
692
|
+
"toolName": "delete-team-tag",
|
|
693
|
+
"workScopes": ["TeamworkTag.ReadWrite"],
|
|
694
|
+
"llmTip": "Permanently delete a tag from a team. This action is irreversible. Use list-team-tags to find the tag ID."
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}/members",
|
|
698
|
+
"method": "get",
|
|
699
|
+
"toolName": "list-team-tag-members",
|
|
700
|
+
"workScopes": ["TeamworkTag.Read"],
|
|
701
|
+
"llmTip": "List all members of a specific tag. Returns member id, displayName, tenantId, and userId. Use list-team-tags to find the tag ID."
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}/members/{teamworkTagMember-id}",
|
|
705
|
+
"method": "delete",
|
|
706
|
+
"toolName": "remove-team-tag-member",
|
|
707
|
+
"workScopes": ["TeamworkTag.ReadWrite"],
|
|
708
|
+
"llmTip": "Remove a member from a tag. Use list-team-tag-members to find the member ID."
|
|
709
|
+
},
|
|
661
710
|
{
|
|
662
711
|
"pathPattern": "/chats/{chat-id}/messages/{chatMessage-id}/replies",
|
|
663
712
|
"method": "get",
|
package/dist/generated/client.js
CHANGED
|
@@ -3559,6 +3559,34 @@ const microsoft_graph_conversationMemberCollectionResponse = z.object({
|
|
|
3559
3559
|
"@odata.nextLink": z.string().nullable(),
|
|
3560
3560
|
value: z.array(microsoft_graph_conversationMember)
|
|
3561
3561
|
}).partial().passthrough();
|
|
3562
|
+
const microsoft_graph_teamworkTagType = z.enum(["standard", "unknownFutureValue"]);
|
|
3563
|
+
const microsoft_graph_teamworkTagMember = z.object({
|
|
3564
|
+
id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
|
|
3565
|
+
displayName: z.string().describe("The member's display name.").nullish(),
|
|
3566
|
+
tenantId: z.string().describe("The ID of the tenant that the tag member is a part of.").nullish(),
|
|
3567
|
+
userId: z.string().describe("The user ID of the member.").nullish()
|
|
3568
|
+
}).passthrough();
|
|
3569
|
+
const microsoft_graph_teamworkTag = z.object({
|
|
3570
|
+
id: z.string().describe("The unique identifier for an entity. Read-only.").optional(),
|
|
3571
|
+
description: z.string().describe(
|
|
3572
|
+
"The description of the tag as it appears to the user in Microsoft Teams. A teamworkTag can't have more than 200 teamworkTagMembers."
|
|
3573
|
+
).nullish(),
|
|
3574
|
+
displayName: z.string().describe("The name of the tag as it appears to the user in Microsoft Teams.").nullish(),
|
|
3575
|
+
memberCount: z.number().gte(-2147483648).lte(2147483647).describe("The number of users assigned to the tag.").nullish(),
|
|
3576
|
+
tagType: microsoft_graph_teamworkTagType.optional(),
|
|
3577
|
+
teamId: z.string().describe("ID of the team in which the tag is defined.").nullish(),
|
|
3578
|
+
members: z.array(microsoft_graph_teamworkTagMember).describe("Users assigned to the tag.").optional()
|
|
3579
|
+
}).passthrough();
|
|
3580
|
+
const microsoft_graph_teamworkTagCollectionResponse = z.object({
|
|
3581
|
+
"@odata.count": z.number().int().nullable(),
|
|
3582
|
+
"@odata.nextLink": z.string().nullable(),
|
|
3583
|
+
value: z.array(microsoft_graph_teamworkTag)
|
|
3584
|
+
}).partial().passthrough();
|
|
3585
|
+
const microsoft_graph_teamworkTagMemberCollectionResponse = z.object({
|
|
3586
|
+
"@odata.count": z.number().int().nullable(),
|
|
3587
|
+
"@odata.nextLink": z.string().nullable(),
|
|
3588
|
+
value: z.array(microsoft_graph_teamworkTagMember)
|
|
3589
|
+
}).partial().passthrough();
|
|
3562
3590
|
const microsoft_graph_userCollectionResponse = z.object({
|
|
3563
3591
|
"@odata.count": z.number().int().nullable(),
|
|
3564
3592
|
"@odata.nextLink": z.string().nullable(),
|
|
@@ -3919,6 +3947,11 @@ const schemas = {
|
|
|
3919
3947
|
BaseDeltaFunctionResponse,
|
|
3920
3948
|
microsoft_graph_channelCollectionResponse,
|
|
3921
3949
|
microsoft_graph_conversationMemberCollectionResponse,
|
|
3950
|
+
microsoft_graph_teamworkTagType,
|
|
3951
|
+
microsoft_graph_teamworkTagMember,
|
|
3952
|
+
microsoft_graph_teamworkTag,
|
|
3953
|
+
microsoft_graph_teamworkTagCollectionResponse,
|
|
3954
|
+
microsoft_graph_teamworkTagMemberCollectionResponse,
|
|
3922
3955
|
microsoft_graph_userCollectionResponse
|
|
3923
3956
|
};
|
|
3924
3957
|
const endpoints = makeApi([
|
|
@@ -7924,6 +7957,188 @@ To monitor future changes, call the delta API by using the @odata.deltaLink in t
|
|
|
7924
7957
|
],
|
|
7925
7958
|
response: z.void()
|
|
7926
7959
|
},
|
|
7960
|
+
{
|
|
7961
|
+
method: "get",
|
|
7962
|
+
path: "/teams/:teamId/tags",
|
|
7963
|
+
alias: "list-team-tags",
|
|
7964
|
+
description: `Get a list of the tag objects and their properties.`,
|
|
7965
|
+
requestFormat: "json",
|
|
7966
|
+
parameters: [
|
|
7967
|
+
{
|
|
7968
|
+
name: "$top",
|
|
7969
|
+
type: "Query",
|
|
7970
|
+
schema: z.number().int().gte(0).describe("Show only the first n items").optional()
|
|
7971
|
+
},
|
|
7972
|
+
{
|
|
7973
|
+
name: "$skip",
|
|
7974
|
+
type: "Query",
|
|
7975
|
+
schema: z.number().int().gte(0).describe("Skip the first n items").optional()
|
|
7976
|
+
},
|
|
7977
|
+
{
|
|
7978
|
+
name: "$search",
|
|
7979
|
+
type: "Query",
|
|
7980
|
+
schema: z.string().describe("Search items by search phrases").optional()
|
|
7981
|
+
},
|
|
7982
|
+
{
|
|
7983
|
+
name: "$filter",
|
|
7984
|
+
type: "Query",
|
|
7985
|
+
schema: z.string().describe("Filter items by property values").optional()
|
|
7986
|
+
},
|
|
7987
|
+
{
|
|
7988
|
+
name: "$count",
|
|
7989
|
+
type: "Query",
|
|
7990
|
+
schema: z.boolean().describe("Include count of items").optional()
|
|
7991
|
+
},
|
|
7992
|
+
{
|
|
7993
|
+
name: "$orderby",
|
|
7994
|
+
type: "Query",
|
|
7995
|
+
schema: z.array(z.string()).describe("Order items by property values").optional()
|
|
7996
|
+
},
|
|
7997
|
+
{
|
|
7998
|
+
name: "$select",
|
|
7999
|
+
type: "Query",
|
|
8000
|
+
schema: z.array(z.string()).describe("Select properties to be returned").optional()
|
|
8001
|
+
},
|
|
8002
|
+
{
|
|
8003
|
+
name: "$expand",
|
|
8004
|
+
type: "Query",
|
|
8005
|
+
schema: z.array(z.string()).describe("Expand related entities").optional()
|
|
8006
|
+
}
|
|
8007
|
+
],
|
|
8008
|
+
response: z.void()
|
|
8009
|
+
},
|
|
8010
|
+
{
|
|
8011
|
+
method: "post",
|
|
8012
|
+
path: "/teams/:teamId/tags",
|
|
8013
|
+
alias: "create-team-tag",
|
|
8014
|
+
description: `Create a standard tag for members in a team.`,
|
|
8015
|
+
requestFormat: "json",
|
|
8016
|
+
parameters: [
|
|
8017
|
+
{
|
|
8018
|
+
name: "body",
|
|
8019
|
+
description: `New navigation property`,
|
|
8020
|
+
type: "Body",
|
|
8021
|
+
schema: microsoft_graph_teamworkTag
|
|
8022
|
+
}
|
|
8023
|
+
],
|
|
8024
|
+
response: z.void()
|
|
8025
|
+
},
|
|
8026
|
+
{
|
|
8027
|
+
method: "get",
|
|
8028
|
+
path: "/teams/:teamId/tags/:teamworkTagId",
|
|
8029
|
+
alias: "get-team-tag",
|
|
8030
|
+
description: `Read the properties and relationships of a tag object.`,
|
|
8031
|
+
requestFormat: "json",
|
|
8032
|
+
parameters: [
|
|
8033
|
+
{
|
|
8034
|
+
name: "$select",
|
|
8035
|
+
type: "Query",
|
|
8036
|
+
schema: z.array(z.string()).describe("Select properties to be returned").optional()
|
|
8037
|
+
},
|
|
8038
|
+
{
|
|
8039
|
+
name: "$expand",
|
|
8040
|
+
type: "Query",
|
|
8041
|
+
schema: z.array(z.string()).describe("Expand related entities").optional()
|
|
8042
|
+
}
|
|
8043
|
+
],
|
|
8044
|
+
response: z.void()
|
|
8045
|
+
},
|
|
8046
|
+
{
|
|
8047
|
+
method: "patch",
|
|
8048
|
+
path: "/teams/:teamId/tags/:teamworkTagId",
|
|
8049
|
+
alias: "update-team-tag",
|
|
8050
|
+
description: `Update the properties of a tag object.`,
|
|
8051
|
+
requestFormat: "json",
|
|
8052
|
+
parameters: [
|
|
8053
|
+
{
|
|
8054
|
+
name: "body",
|
|
8055
|
+
description: `New navigation property values`,
|
|
8056
|
+
type: "Body",
|
|
8057
|
+
schema: microsoft_graph_teamworkTag
|
|
8058
|
+
}
|
|
8059
|
+
],
|
|
8060
|
+
response: z.void()
|
|
8061
|
+
},
|
|
8062
|
+
{
|
|
8063
|
+
method: "delete",
|
|
8064
|
+
path: "/teams/:teamId/tags/:teamworkTagId",
|
|
8065
|
+
alias: "delete-team-tag",
|
|
8066
|
+
description: `Delete a tag object permanently.`,
|
|
8067
|
+
requestFormat: "json",
|
|
8068
|
+
parameters: [
|
|
8069
|
+
{
|
|
8070
|
+
name: "If-Match",
|
|
8071
|
+
type: "Header",
|
|
8072
|
+
schema: z.string().describe("ETag").optional()
|
|
8073
|
+
}
|
|
8074
|
+
],
|
|
8075
|
+
response: z.void()
|
|
8076
|
+
},
|
|
8077
|
+
{
|
|
8078
|
+
method: "get",
|
|
8079
|
+
path: "/teams/:teamId/tags/:teamworkTagId/members",
|
|
8080
|
+
alias: "list-team-tag-members",
|
|
8081
|
+
description: `Get a list of the members of a standard tag in a team and their properties.`,
|
|
8082
|
+
requestFormat: "json",
|
|
8083
|
+
parameters: [
|
|
8084
|
+
{
|
|
8085
|
+
name: "$top",
|
|
8086
|
+
type: "Query",
|
|
8087
|
+
schema: z.number().int().gte(0).describe("Show only the first n items").optional()
|
|
8088
|
+
},
|
|
8089
|
+
{
|
|
8090
|
+
name: "$skip",
|
|
8091
|
+
type: "Query",
|
|
8092
|
+
schema: z.number().int().gte(0).describe("Skip the first n items").optional()
|
|
8093
|
+
},
|
|
8094
|
+
{
|
|
8095
|
+
name: "$search",
|
|
8096
|
+
type: "Query",
|
|
8097
|
+
schema: z.string().describe("Search items by search phrases").optional()
|
|
8098
|
+
},
|
|
8099
|
+
{
|
|
8100
|
+
name: "$filter",
|
|
8101
|
+
type: "Query",
|
|
8102
|
+
schema: z.string().describe("Filter items by property values").optional()
|
|
8103
|
+
},
|
|
8104
|
+
{
|
|
8105
|
+
name: "$count",
|
|
8106
|
+
type: "Query",
|
|
8107
|
+
schema: z.boolean().describe("Include count of items").optional()
|
|
8108
|
+
},
|
|
8109
|
+
{
|
|
8110
|
+
name: "$orderby",
|
|
8111
|
+
type: "Query",
|
|
8112
|
+
schema: z.array(z.string()).describe("Order items by property values").optional()
|
|
8113
|
+
},
|
|
8114
|
+
{
|
|
8115
|
+
name: "$select",
|
|
8116
|
+
type: "Query",
|
|
8117
|
+
schema: z.array(z.string()).describe("Select properties to be returned").optional()
|
|
8118
|
+
},
|
|
8119
|
+
{
|
|
8120
|
+
name: "$expand",
|
|
8121
|
+
type: "Query",
|
|
8122
|
+
schema: z.array(z.string()).describe("Expand related entities").optional()
|
|
8123
|
+
}
|
|
8124
|
+
],
|
|
8125
|
+
response: z.void()
|
|
8126
|
+
},
|
|
8127
|
+
{
|
|
8128
|
+
method: "delete",
|
|
8129
|
+
path: "/teams/:teamId/tags/:teamworkTagId/members/:teamworkTagMemberId",
|
|
8130
|
+
alias: "remove-team-tag-member",
|
|
8131
|
+
description: `Delete a member from a standard tag in a team.`,
|
|
8132
|
+
requestFormat: "json",
|
|
8133
|
+
parameters: [
|
|
8134
|
+
{
|
|
8135
|
+
name: "If-Match",
|
|
8136
|
+
type: "Header",
|
|
8137
|
+
schema: z.string().describe("ETag").optional()
|
|
8138
|
+
}
|
|
8139
|
+
],
|
|
8140
|
+
response: z.void()
|
|
8141
|
+
},
|
|
7927
8142
|
{
|
|
7928
8143
|
method: "get",
|
|
7929
8144
|
path: "/users",
|
package/logs/mcp-server.log
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
2026-03-25
|
|
2
|
-
2026-03-25
|
|
3
|
-
2026-03-25
|
|
4
|
-
2026-03-25
|
|
5
|
-
2026-03-25
|
|
6
|
-
2026-03-25
|
|
7
|
-
2026-03-25
|
|
8
|
-
2026-03-25
|
|
9
|
-
2026-03-25
|
|
10
|
-
2026-03-25
|
|
1
|
+
2026-03-25 16:38:47 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
|
|
2
|
+
2026-03-25 16:38:47 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
|
|
3
|
+
2026-03-25 16:38:47 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me
|
|
4
|
+
2026-03-25 16:38:48 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me/messages
|
|
5
|
+
2026-03-25 16:38:48 INFO: [GRAPH CLIENT] Final URL being sent to Microsoft: https://graph.microsoft.com/v1.0/me/calendar
|
|
6
|
+
2026-03-25 16:38:49 INFO: Using environment variables for secrets
|
|
7
|
+
2026-03-25 16:38:49 INFO: Using environment variables for secrets
|
|
8
|
+
2026-03-25 16:38:49 INFO: Using environment variables for secrets
|
|
9
|
+
2026-03-25 16:38:49 INFO: Using environment variables for secrets
|
|
10
|
+
2026-03-25 16:38:49 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.47.
|
|
3
|
+
"version": "0.47.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
|
@@ -658,6 +658,55 @@
|
|
|
658
658
|
"toolName": "list-team-members",
|
|
659
659
|
"workScopes": ["TeamMember.Read.All"]
|
|
660
660
|
},
|
|
661
|
+
{
|
|
662
|
+
"pathPattern": "/teams/{team-id}/tags",
|
|
663
|
+
"method": "get",
|
|
664
|
+
"toolName": "list-team-tags",
|
|
665
|
+
"workScopes": ["TeamworkTag.Read"],
|
|
666
|
+
"llmTip": "List all tags in a team. Returns tag id, displayName, memberCount, and tagType (standard or scheduled). Use list-joined-teams to find the team ID first."
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"pathPattern": "/teams/{team-id}/tags",
|
|
670
|
+
"method": "post",
|
|
671
|
+
"toolName": "create-team-tag",
|
|
672
|
+
"workScopes": ["TeamworkTag.ReadWrite"],
|
|
673
|
+
"llmTip": "Create a new tag in a team. Body requires displayName (max 40 chars) and an optional members array (max 25 at creation, each with a userId). Use list-team-members to find user IDs. Add more members individually with add-team-tag-member after creation."
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}",
|
|
677
|
+
"method": "get",
|
|
678
|
+
"toolName": "get-team-tag",
|
|
679
|
+
"workScopes": ["TeamworkTag.Read"],
|
|
680
|
+
"llmTip": "Get details of a specific tag including displayName, memberCount, and tagType. Use list-team-tags to find the tag ID."
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}",
|
|
684
|
+
"method": "patch",
|
|
685
|
+
"toolName": "update-team-tag",
|
|
686
|
+
"workScopes": ["TeamworkTag.ReadWrite"],
|
|
687
|
+
"llmTip": "Update a tag's displayName (max 40 chars). Use list-team-tags to find the tag ID."
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}",
|
|
691
|
+
"method": "delete",
|
|
692
|
+
"toolName": "delete-team-tag",
|
|
693
|
+
"workScopes": ["TeamworkTag.ReadWrite"],
|
|
694
|
+
"llmTip": "Permanently delete a tag from a team. This action is irreversible. Use list-team-tags to find the tag ID."
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}/members",
|
|
698
|
+
"method": "get",
|
|
699
|
+
"toolName": "list-team-tag-members",
|
|
700
|
+
"workScopes": ["TeamworkTag.Read"],
|
|
701
|
+
"llmTip": "List all members of a specific tag. Returns member id, displayName, tenantId, and userId. Use list-team-tags to find the tag ID."
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"pathPattern": "/teams/{team-id}/tags/{teamworkTag-id}/members/{teamworkTagMember-id}",
|
|
705
|
+
"method": "delete",
|
|
706
|
+
"toolName": "remove-team-tag-member",
|
|
707
|
+
"workScopes": ["TeamworkTag.ReadWrite"],
|
|
708
|
+
"llmTip": "Remove a member from a tag. Use list-team-tag-members to find the member ID."
|
|
709
|
+
},
|
|
661
710
|
{
|
|
662
711
|
"pathPattern": "/chats/{chat-id}/messages/{chatMessage-id}/replies",
|
|
663
712
|
"method": "get",
|