diff --git a/backend/mcp-bundles/softeria-ms-365-mcp-server/dist/endpoints.json b/backend/mcp-bundles/softeria-ms-365-mcp-server/dist/endpoints.json index 53a00c79..149e3905 100644 --- a/backend/mcp-bundles/softeria-ms-365-mcp-server/dist/endpoints.json +++ b/backend/mcp-bundles/softeria-ms-365-mcp-server/dist/endpoints.json @@ -500,6 +500,27 @@ "scopes": ["Files.ReadWrite"], "llmTip": "Shares a file or folder with specific users. Body: { recipients: [{ email: 'user@example.com' }], roles: ['read'], sendInvitation: true, message: 'Please review this file.' }. Roles: 'read', 'write', 'owner'. Set requireSignIn to true to require authentication." }, + { + "pathPattern": "/drives/{drive-id}/items/{driveItem-id}/createLink", + "method": "post", + "toolName": "create-drive-item-share-link", + "scopes": ["Files.ReadWrite"], + "llmTip": "Create a shareable link for a file or folder WITHOUT sending an email invitation. Body: { type: 'view' | 'edit' | 'embed', scope: 'anonymous' | 'organization' | 'users', password?: string, expirationDateTime?: ISO-8601, retainInheritedPermissions?: boolean }. Returns a permission with link.webUrl. Pair with share-drive-item when you want to grant explicit access; use this when you only need a URL to paste into a doc/email/chat without triggering OneDrive notifications." + }, + { + "pathPattern": "/drives/{drive-id}/items/{driveItem-id}/copy", + "method": "post", + "toolName": "copy-drive-item", + "scopes": ["Files.ReadWrite"], + "llmTip": "Asynchronously copy a file or folder to a new location and/or name. Body: { parentReference: { driveId: '...', id: '...' }, name?: 'New Name.xlsx' }. Returns 202 Accepted with a Location header pointing at a monitor URL for the async job. Ideal for duplicating templates (e.g. clone an Armhr Census Template per prospect), bulk file provisioning, or preserving an immutable snapshot of a working file." + }, + { + "pathPattern": "/drives/{drive-id}/items/{driveItem-id}/preview", + "method": "post", + "toolName": "create-drive-item-preview", + "scopes": ["Files.Read"], + "llmTip": "Generate a short-lived embeddable preview URL for a file (Office docs, PDFs, images). Body: { page?: number | string, zoom?: number, viewer?: 'onedrive' | 'office' }. Returns getUrl (interactive) and postUrl (form-post). Useful for surfacing inline previews in summary emails or chat messages without needing the recipient to open the file." + }, { "pathPattern": "/drives/{drive-id}/items/{driveItem-id}/permissions", "method": "get", @@ -1715,5 +1736,26 @@ "toolName": "reauthorize-subscription", "scopes": [], "llmTip": "Reauthorizes a subscription after receiving a 'reauthorizationRequired' lifecycle notification from Microsoft Graph. No body required. Must be called within the reauthorizationRequiredDateTime window (typically 48h) to avoid subscription expiry." + }, + { + "pathPattern": "/drives/{drive-id}/items/{driveItem-id}/extractSensitivityLabels", + "method": "post", + "toolName": "extract-drive-item-sensitivity-labels", + "workScopes": ["Files.Read.All"], + "llmTip": "Returns the Microsoft Information Protection (MIP) sensitivity labels assigned to a file. No request body. Response: { value: { labels: [{ sensitivityLabelId, assignmentMethod, tenantId }] } }. Use list-sensitivity-labels to map sensitivityLabelId to a human-readable name. Not supported for personal Microsoft accounts. May return 423 Locked if the file is double-key-encrypted or decryption is deferred." + }, + { + "pathPattern": "/me/dataSecurityAndGovernance/sensitivityLabels", + "method": "get", + "toolName": "list-sensitivity-labels", + "workScopes": ["SensitivityLabel.Read"], + "llmTip": "Lists Microsoft Information Protection (MIP) sensitivity labels available to the signed-in user. Use to map label IDs (returned by extract-drive-item-sensitivity-labels) to human-readable names. Not supported for personal Microsoft accounts." + }, + { + "pathPattern": "/me/dataSecurityAndGovernance/sensitivityLabels/{sensitivityLabel-id}", + "method": "get", + "toolName": "get-sensitivity-label", + "workScopes": ["SensitivityLabel.Read"], + "llmTip": "Gets a single MIP sensitivity label by id. Use list-sensitivity-labels to find ids. Not supported for personal Microsoft accounts." } ] diff --git a/backend/mcp-bundles/softeria-ms-365-mcp-server/dist/index.js b/backend/mcp-bundles/softeria-ms-365-mcp-server/dist/index.js index c0d2799a..3ccf2199 100755 --- a/backend/mcp-bundles/softeria-ms-365-mcp-server/dist/index.js +++ b/backend/mcp-bundles/softeria-ms-365-mcp-server/dist/index.js @@ -103813,30 +103813,24 @@ var microsoft_graph_driveItemCollectionResponse = external_exports.object({ "@odata.nextLink": external_exports.string().nullable(), value: external_exports.array(microsoft_graph_driveItem) }).partial().passthrough(); -var create_upload_session_Body = external_exports.object({ item: external_exports.object({}).partial().passthrough() }).partial().passthrough(); -var microsoft_graph_uploadSession = external_exports.object({ +var copy_drive_item_Body = external_exports.object({ + name: external_exports.string().nullable(), + parentReference: external_exports.union([microsoft_graph_itemReference, external_exports.object({}).partial().passthrough()]), + childrenOnly: external_exports.boolean().nullable().default(false), + includeAllVersionHistory: external_exports.boolean().nullable().default(false) +}).partial().passthrough(); +var create_drive_item_share_link_Body = external_exports.object({ + type: external_exports.string().nullable(), + scope: external_exports.string().nullable(), expirationDateTime: external_exports.string().regex( /^[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])$/ - ).datetime({ offset: true }).describe( - "The date and time in UTC that the upload session expires. The complete file must be uploaded before this expiration time is reached. Each fragment uploaded during the session extends the expiration time." - ).nullish(), - nextExpectedRanges: external_exports.array(external_exports.string().nullable()).describe( - "A collection of byte ranges that the server is missing for the file. These ranges are zero indexed and of the format 'start-end' (for example '0-26' to indicate the first 27 bytes of the file). When uploading files as Outlook attachments, instead of a collection of ranges, this property always indicates a single value '{start}', the location in the file where the next upload should begin." - ).optional(), - uploadUrl: external_exports.string().describe("The URL endpoint that accepts PUT requests for byte ranges of the file.").nullish() -}).passthrough(); -var BaseDeltaFunctionResponse = external_exports.object({ "@odata.nextLink": external_exports.string().nullable(), "@odata.deltaLink": external_exports.string().nullable() }).partial().passthrough(); -var share_drive_item_Body = external_exports.object({ - requireSignIn: external_exports.boolean().nullable().default(false), - roles: external_exports.array(external_exports.string().nullable()), - sendInvitation: external_exports.boolean().nullable().default(false), + ).datetime({ offset: true }).nullable(), + password: external_exports.string().nullable(), message: external_exports.string().nullable(), recipients: external_exports.array(external_exports.object({}).partial().passthrough()), retainInheritedPermissions: external_exports.boolean().nullable().default(false), - expirationDateTime: external_exports.string().nullable(), - password: external_exports.string().nullable() + sendNotification: external_exports.boolean().nullable().default(false) }).partial().passthrough(); -var BaseCollectionPaginationCountResponse = external_exports.object({ "@odata.count": external_exports.number().int().nullable(), "@odata.nextLink": external_exports.string().nullable() }).partial().passthrough(); var microsoft_graph_sharePointGroupIdentity = external_exports.object({ displayName: external_exports.string().describe( "The display name of the identity.For drive items, the display name might not always be available or up to date. For example, if a user changes their display name the API might show the new value in a future response, but the items associated with the user don't show up as changed when using delta." @@ -103917,6 +103911,56 @@ var microsoft_graph_permission = external_exports.object({ "A unique token that can be used to access this shared item via the shares API. Read-only." ).nullish() }).passthrough(); +var create_upload_session_Body = external_exports.object({ item: external_exports.object({}).partial().passthrough() }).partial().passthrough(); +var microsoft_graph_uploadSession = external_exports.object({ + expirationDateTime: external_exports.string().regex( + /^[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])$/ + ).datetime({ offset: true }).describe( + "The date and time in UTC that the upload session expires. The complete file must be uploaded before this expiration time is reached. Each fragment uploaded during the session extends the expiration time." + ).nullish(), + nextExpectedRanges: external_exports.array(external_exports.string().nullable()).describe( + "A collection of byte ranges that the server is missing for the file. These ranges are zero indexed and of the format 'start-end' (for example '0-26' to indicate the first 27 bytes of the file). When uploading files as Outlook attachments, instead of a collection of ranges, this property always indicates a single value '{start}', the location in the file where the next upload should begin." + ).optional(), + uploadUrl: external_exports.string().describe("The URL endpoint that accepts PUT requests for byte ranges of the file.").nullish() +}).passthrough(); +var BaseDeltaFunctionResponse = external_exports.object({ "@odata.nextLink": external_exports.string().nullable(), "@odata.deltaLink": external_exports.string().nullable() }).partial().passthrough(); +var microsoft_graph_sensitivityLabelAssignmentMethod = external_exports.enum([ + "standard", + "privileged", + "auto", + "unknownFutureValue" +]); +var microsoft_graph_sensitivityLabelAssignment = external_exports.object({ + assignmentMethod: microsoft_graph_sensitivityLabelAssignmentMethod.optional(), + sensitivityLabelId: external_exports.string().describe("The unique identifier for the sensitivity label assigned to the file.").optional(), + tenantId: external_exports.string().describe( + "The unique identifier for the tenant that hosts the file when this label is applied." + ).optional() +}).passthrough(); +var microsoft_graph_extractSensitivityLabelsResult = external_exports.object({ + labels: external_exports.array(microsoft_graph_sensitivityLabelAssignment).describe("List of sensitivity labels assigned to a file.").optional() +}).passthrough(); +var share_drive_item_Body = external_exports.object({ + requireSignIn: external_exports.boolean().nullable().default(false), + roles: external_exports.array(external_exports.string().nullable()), + sendInvitation: external_exports.boolean().nullable().default(false), + message: external_exports.string().nullable(), + recipients: external_exports.array(external_exports.object({}).partial().passthrough()), + retainInheritedPermissions: external_exports.boolean().nullable().default(false), + expirationDateTime: external_exports.string().nullable(), + password: external_exports.string().nullable() +}).partial().passthrough(); +var BaseCollectionPaginationCountResponse = external_exports.object({ "@odata.count": external_exports.number().int().nullable(), "@odata.nextLink": external_exports.string().nullable() }).partial().passthrough(); +var ReferenceNumeric = external_exports.enum(["-INF", "INF", "NaN"]); +var create_drive_item_preview_Body = external_exports.object({ + page: external_exports.string().nullable(), + zoom: external_exports.union([external_exports.number(), external_exports.string(), ReferenceNumeric]) +}).partial().passthrough(); +var microsoft_graph_itemPreviewInfo = external_exports.object({ + getUrl: external_exports.string().nullish(), + postParameters: external_exports.string().nullish(), + postUrl: external_exports.string().nullish() +}).passthrough(); var microsoft_graph_permissionCollectionResponse = external_exports.object({ "@odata.count": external_exports.number().int().nullable(), "@odata.nextLink": external_exports.string().nullable(), @@ -105025,6 +105069,67 @@ var microsoft_graph_contactCollectionResponse = external_exports.object({ "@odata.nextLink": external_exports.string().nullable(), value: external_exports.array(microsoft_graph_contact) }).partial().passthrough(); +var microsoft_graph_labelActionSource = external_exports.enum([ + "manual", + "automatic", + "recommended", + "none", + "unknownFutureValue" +]); +var microsoft_graph_usageRights = external_exports.enum([ + "unknown", + "docEdit", + "edit", + "comment", + "export", + "forward", + "owner", + "print", + "reply", + "replyAll", + "view", + "extract", + "viewRightsData", + "editRightsData", + "objModel", + "accessDenied", + "userDefinedProtectionTypeNotSupportedException", + "encryptedProtectionTypeNotSupportedException", + "purviewClaimsChallengeNotSupportedException", + "exception", + "labelNotFoundException", + "unknownFutureValue" +]); +var microsoft_graph_usageRightsIncluded = external_exports.object({ + id: external_exports.string().describe("The unique identifier for an entity. Read-only.").optional(), + ownerEmail: external_exports.string().describe("The email of owner label rights.").nullish(), + userEmail: external_exports.string().describe("The email of user with label user rights.").nullish(), + value: microsoft_graph_usageRights.optional() +}).passthrough(); +var microsoft_graph_sensitivityLabel = external_exports.lazy( + () => external_exports.object({ + id: external_exports.string().describe("The unique identifier for an entity. Read-only.").optional(), + actionSource: microsoft_graph_labelActionSource.optional(), + autoTooltip: external_exports.string().nullish(), + description: external_exports.string().nullish(), + displayName: external_exports.string().nullish(), + hasProtection: external_exports.boolean().nullish(), + isDefault: external_exports.boolean().nullish(), + isEndpointProtectionEnabled: external_exports.boolean().nullish(), + isScopedToUser: external_exports.boolean().nullish(), + locale: external_exports.string().nullish(), + name: external_exports.string().nullish(), + priority: external_exports.number().gte(-2147483648).lte(2147483647).nullish(), + toolTip: external_exports.string().nullish(), + rights: microsoft_graph_usageRightsIncluded.optional(), + sublabels: external_exports.array(microsoft_graph_sensitivityLabel).optional() + }).passthrough() +); +var microsoft_graph_sensitivityLabelCollectionResponse = external_exports.object({ + "@odata.count": external_exports.number().int().nullable(), + "@odata.nextLink": external_exports.string().nullable(), + value: external_exports.array(microsoft_graph_sensitivityLabel) +}).partial().passthrough(); var microsoft_graph_storagePlanInformation = external_exports.object({ upgradeAvailable: external_exports.boolean().describe("Indicates whether there are higher storage quota plans available. Read-only.").nullish() }).passthrough(); @@ -106054,7 +106159,6 @@ var microsoft_graph_timeConstraint = external_exports.object({ activityDomain: microsoft_graph_activityDomain.optional(), timeSlots: external_exports.array(microsoft_graph_timeSlot).optional() }).passthrough(); -var ReferenceNumeric = external_exports.enum(["-INF", "INF", "NaN"]); var find_meeting_times_Body = external_exports.object({ attendees: external_exports.array(microsoft_graph_attendeeBase), locationConstraint: external_exports.union([ @@ -108005,6 +108109,39 @@ var endpoints2 = makeApi([ ], response: external_exports.void() }, + { + method: "post", + path: "/drives/:driveId/items/:driveItemId/copy", + alias: "copy-drive-item", + description: `Invoke action copy`, + requestFormat: "json", + parameters: [ + { + name: "body", + description: `Action parameters`, + type: "Body", + schema: copy_drive_item_Body + } + ], + response: external_exports.void() + }, + { + method: "post", + path: "/drives/:driveId/items/:driveItemId/createLink", + alias: "create-drive-item-share-link", + description: `Create a link to share a driveItem driveItem. The createLink action creates a new sharing link if the specified link type doesn't already exist for the calling application. +If a sharing link of the specified type already exists for the app, the existing sharing link is returned. DriveItem resources inherit sharing permissions from their ancestors.`, + requestFormat: "json", + parameters: [ + { + name: "body", + description: `Action parameters`, + type: "Body", + schema: create_drive_item_share_link_Body + } + ], + response: external_exports.void() + }, { method: "post", path: "/drives/:driveId/items/:driveItemId/createUploadSession", @@ -108075,6 +108212,14 @@ Items with this property set should be removed from your local state.`, ], response: external_exports.void() }, + { + method: "post", + path: "/drives/:driveId/items/:driveItemId/extractSensitivityLabels", + alias: "extract-drive-item-sensitivity-labels", + description: `Invoke action extractSensitivityLabels`, + requestFormat: "json", + response: external_exports.void() + }, { method: "post", path: "/drives/:driveId/items/:driveItemId/invite", @@ -108156,6 +108301,22 @@ Items with this property set should be removed from your local state.`, ], response: external_exports.void() }, + { + method: "post", + path: "/drives/:driveId/items/:driveItemId/preview", + alias: "create-drive-item-preview", + description: `Invoke action preview`, + requestFormat: "json", + parameters: [ + { + name: "body", + description: `Action parameters`, + type: "Body", + schema: create_drive_item_preview_Body + } + ], + response: external_exports.void() + }, { method: "get", path: "/drives/:driveId/items/:driveItemId/versions", @@ -110174,6 +110335,76 @@ or from some other calendar of the user.`, ], response: external_exports.void() }, + { + method: "get", + path: "/me/dataSecurityAndGovernance/sensitivityLabels", + alias: "list-sensitivity-labels", + description: `Get sensitivityLabels from me`, + requestFormat: "json", + parameters: [ + { + name: "$top", + type: "Query", + schema: external_exports.number().int().gte(0).describe("Show only the first n items").optional() + }, + { + name: "$skip", + type: "Query", + schema: external_exports.number().int().gte(0).describe("Skip the first n items").optional() + }, + { + name: "$search", + type: "Query", + schema: external_exports.string().describe("Search items by search phrases").optional() + }, + { + name: "$filter", + type: "Query", + schema: external_exports.string().describe("Filter items by property values").optional() + }, + { + name: "$count", + type: "Query", + schema: external_exports.boolean().describe("Include count of items").optional() + }, + { + name: "$orderby", + type: "Query", + schema: external_exports.array(external_exports.string()).describe("Order items by property values").optional() + }, + { + name: "$select", + type: "Query", + schema: external_exports.array(external_exports.string()).describe("Select properties to be returned").optional() + }, + { + name: "$expand", + type: "Query", + schema: external_exports.array(external_exports.string()).describe("Expand related entities").optional() + } + ], + response: external_exports.void() + }, + { + method: "get", + path: "/me/dataSecurityAndGovernance/sensitivityLabels/:sensitivityLabelId", + alias: "get-sensitivity-label", + description: `Get sensitivityLabels from me`, + requestFormat: "json", + parameters: [ + { + name: "$select", + type: "Query", + schema: external_exports.array(external_exports.string()).describe("Select properties to be returned").optional() + }, + { + name: "$expand", + type: "Query", + schema: external_exports.array(external_exports.string()).describe("Expand related entities").optional() + } + ], + response: external_exports.void() + }, { method: "get", path: "/me/directReports", @@ -115516,13 +115747,8 @@ async function executeGraphTool(tool, config2, graphClient, params, authManager) while (nextLink && pageCount < maxPages && allItems.length < maxItems) { logger_default.info(`Fetching page ${pageCount + 1} from: ${nextLink}`); const url2 = new URL(nextLink); - const nextPath = url2.pathname.replace("/v1.0", ""); + const nextPath = url2.pathname.replace("/v1.0", "") + url2.search; const nextOptions = { ...options }; - const nextQueryParams = {}; - for (const [key, value] of url2.searchParams.entries()) { - nextQueryParams[key] = value; - } - nextOptions.queryParams = nextQueryParams; const nextResponse = await graphClient.graphRequest(nextPath, nextOptions); if (nextResponse?.content?.[0]?.text) { const nextJsonResponse = JSON.parse(nextResponse.content[0].text); diff --git a/backend/mcp-bundles/softeria-ms-365-mcp-server/package.json b/backend/mcp-bundles/softeria-ms-365-mcp-server/package.json index f634ff74..c6377f84 100644 --- a/backend/mcp-bundles/softeria-ms-365-mcp-server/package.json +++ b/backend/mcp-bundles/softeria-ms-365-mcp-server/package.json @@ -1 +1 @@ -{"name":"@softeria/ms-365-mcp-server","version":"0.88.1"} \ No newline at end of file +{"name":"@softeria/ms-365-mcp-server","version":"0.90.0"} \ No newline at end of file