# SharePoint MCP connector

Connecting SharePoint to Elaichi lets Claude, ChatGPT, Cursor, or any MCP client search your SharePoint sites, read and publish site pages, and find and download files from document libraries, all as the person who signed in.

Source: https://elaichi.ai/connectors/sharepoint/

## Facts

| | |
| --- | --- |
| Application | SharePoint |
| Category | Cloud Storage |
| AI tools | 97 |
| Authentication | Connects over OAuth |
| Needs your own OAuth app | No |
| MCP endpoint | https://api.elaichi.ai/mcp |
| Works with | Claude, ChatGPT, Cursor, any MCP client, and the Elaichi Agent |
| Tools advertised by name | No. 97 tools is past the 30-tool threshold, so clients use `search_tools` and `execute_tool` |

## What you can ask once SharePoint is connected

- List the site pages published on our intranet site this week.
- Create a news page on the Marketing site from our template.
- Which SharePoint sites has Support added pages to recently?

## Connect SharePoint in Elaichi

This happens once for the organization, before any client is involved.

1. Open Connections, choose Add connection, and pick SharePoint.
2. Optionally set Share with, then press Connect.
3. Approve it in SharePoint. SharePoint's own window opens. Whoever approves it decides what this connection can reach.

Credentials are vaulted and nobody, including the AI, reads them back. The connection becomes a toolbox immediately, so you can curate which SharePoint tools are exposed, rename them, or freeze arguments before anyone points a client at it.

## Connect SharePoint to Claude

Endpoint: https://api.elaichi.ai/mcp

1. Open Customize, then Connectors.
2. Press Add.
3. Name it, paste the MCP server URL, then Continue.
4. Sign in and approve.

On Team and Enterprise, an Owner adds it once. Everyone else turns it on for themselves.

## Connect SharePoint to ChatGPT

Endpoint: https://api.elaichi.ai/mcp

1. Open Plugins, then press the + button.
2. Name it and paste the endpoint into Server URL.
3. Leave Authentication on OAuth, then tick the risk acknowledgement.
4. Press Create, then sign in and approve.

Works on the web today. The plugin directory lives at chatgpt.com/plugins.

## Connect SharePoint to Cursor

Endpoint: https://api.elaichi.ai/mcp

1. Open `~/.cursor/mcp.json`.
2. Add the endpoint under `mcpServers`.
3. Reload Cursor, then sign in and approve.

Set up per machine, so repeat it on each computer you work from.

## Connect SharePoint to any MCP client

Endpoint: https://api.elaichi.ai/mcp

1. Add the endpoint as a remote MCP server.
2. Sign in and approve.

The Elaichi Agent already has these tools, with nothing to set up.

## What the consent screen decides

Only Read is granted by default, which is not enough to call a SharePoint tool. Over MCP there is no trusted place to confirm a write in the moment, so the consent screen is the standing approval rather than a formality. Grant Read and Run tools. Think hard before granting Delete, which reaches into connected apps and cannot be undone.

## What teams do with SharePoint through Elaichi

### Publish the weekly announcement page

Internal communications. Start a new site page from your standard template, add the sections and web parts, and publish it to the intranet without opening the page editor.

### Find the current version of a policy

HR. Search every site and document library for the travel policy or employee handbook, confirm which copy is current, and download it for the person asking.

### Pull the right collateral before a call

Sales. Ask for the latest case study or pricing sheet in the sales site's document library and have it downloaded and ready before the meeting starts.

### Keep help pages current after a change

Support. When a process changes, update the relevant site page on the support intranet and publish the new version once the team has agreed the wording.

### Take stock of every site and page

Operations. List all SharePoint sites, their pages, and their document libraries to see what exists, what is duplicated, and what nobody has touched in a year.

### Retire pages and files when a project closes

Project management. Delete stale site pages and out-of-date files from the project site so people stop finding old plans in search.

## Frequently asked questions

### How do I connect SharePoint to Claude?

Connect SharePoint in Elaichi first: you sign in with your normal Microsoft account and approve access, and there is no OAuth application to register and no client ID or secret to generate. Then open Claude, go to Customize, then Connectors, then Add, and paste https://api.elaichi.ai/mcp. Claude will ask you to sign in to Elaichi, and SharePoint is then available in your conversations.

### Does SharePoint work with ChatGPT and Cursor as well as Claude?

Yes. Once SharePoint is connected in Elaichi, the same endpoint, https://api.elaichi.ai/mcp, works in Claude, ChatGPT, Cursor, any other MCP client, and the Elaichi Agent. You connect SharePoint once and every client you use picks it up.

### What can an AI agent actually do with my SharePoint data?

Through Elaichi, an AI agent can search across your SharePoint sites, list sites, site pages, and document libraries, read a page, and find and download files. It can also create a site page from a template, add sections and web parts, update and publish pages, and delete pages or files when asked. SharePoint has a lot of capabilities, so short concrete asks such as "find the Q3 sales deck in the Marketing site" get better results than long paragraphs.

### Does connecting SharePoint give the AI access to every site and library?

No. The AI works inside the SharePoint permissions of the person who signed in, so it can only see the sites, pages, and files that person can already open. Elaichi can narrow that further, for example to search and reading only, but it can never grant access to a SharePoint site the person does not have.

### Can my team share one SharePoint connection?

Yes. One person connects SharePoint in Elaichi and shares it with a team, and nobody else has to handle a password or sign-in secret. Each teammate still signs in to Elaichi as themselves, so every search, download, or page change in SharePoint is recorded against the person who did it.

### Can I stop an agent from deleting or changing things in SharePoint?

Yes. Restrictions in Elaichi work per action, so you can allow searching and reading SharePoint pages and files while blocking deleting files, deleting pages, or publishing changes. A blocked action is never shown to Claude, ChatGPT, or Cursor at all, so no prompt, however worded, can reach it.

### What happens to a SharePoint connection when someone leaves?

When you offboard someone in Elaichi, their access to SharePoint through every AI client ends at once. If they had shared a SharePoint connection with a team, it keeps working for everyone else. Disconnecting SharePoint once in Elaichi removes it from Claude, ChatGPT, Cursor, and every other client in one step.

## All 97 SharePoint tools

Every tool below is callable through https://api.elaichi.ai/mcp once SharePoint is connected, subject to the toolbox it is in and the restrictions on the caller.

- **List all SharePoint sites** (List). List all available SharePoint sites in an organization. Returns: id, createdDateTime, description, displayName, eTag, isPersonalSite, lastModifiedDateTime, name, root, sharepointIds, siteCollection, webUrl.
- **Get single SharePoint site by ID** (Get). Get a single SharePoint site by its id. Returns: id, createdDateTime, description, displayName, isPersonalSite, lastModifiedDateTime, name, sharepointIds, siteCollection, webUrl, 2XX. Required: id.
- **SharePoint sites using path** (Action). Get a SharePoint site by its hostname and server-relative URL path. Returns: id, createdDateTime, description, displayName, isPersonalSite, lastModifiedDateTime, name, sharepointIds, siteCollection, webUrl. Required: hostname, server_relative_path.
- **List all SharePoint base site pages** (List). List SharePoint site pages (baseSitePage objects) from the site pages list in a site. Returns: id, name, createdDateTime, lastModifiedDateTime, webUrl. Results are sorted alphabetically by name in ascending order and returned with pagination. Required: site_id.
- **Get single SharePoint base site page by ID** (Get). Get metadata for a specific SharePoint base site page by its id within a site. Returns: id, name, createdDateTime, lastModifiedDateTime, webUrl, eTag. Required: site_id, id.
- **List all SharePoint site pages** (List). List the modern site pages on a SharePoint site. The microsoft.graph.sitePage cast in the path filters the pages collection to site pages specifically. Returns id, name, title, pageLayout, promotionKind, webUrl and publishingState. Required: site_id.
- **Get single SharePoint site page by ID** (Get). Get one modern site page by id. Pass $expand=canvasLayout to include the page content structure and its web parts. Required: site_id, id.
- **Create a SharePoint site page** (Create). Create a modern page on a SharePoint site. "@odata.type" must be "#microsoft.graph.sitePage" and "name" must end in .aspx. The page is created as a DRAFT and is not visible to site visitors until you call site-pages.publish. Required: site_id, @odata.type, name.
- **Update a SharePoint site page by ID** (Update). Update a modern site page - title, layout, comment settings or canvasLayout content. Editing a published page creates a new draft version; call site-pages.publish to make the change live. Required: site_id, id.
- **SharePoint site pages publish** (Publish). Publish a modern site page, making the current draft visible to site visitors. Takes no body. A newly created or edited page stays in draft until this is called. Returns an empty 204 on success. Required: site_id, id.
- **SharePoint site pages create from template** (Create). Create a site page from an existing page template. BETA endpoint - Microsoft may change it without notice, so prefer site-pages.create for stable work. The new page is a draft until published. Required: site_id. PREREQUISITE: the site must already hold at least one page template, otherwise this returns 404. Templates are created in the SharePoint page editor (Save as template); none exist in a fresh site.
- **Delete a SharePoint site page by ID** (Delete). Delete a site page. Note the path has no microsoft.graph.sitePage cast - deletion is done on the base pages collection. Returns an empty 204 on success. Required: site_id, id.
- **List all SharePoint horizontal sections** (List). List horizontal sections from the canvas layout of a SharePoint site page. Returns: id, columns, isPersonalSite, displayName, name, createdDateTime, lastModifiedDateTime, webUrl. Required: site_id, page_id.
- **Create a SharePoint horizontal section** (Create). Add a horizontal section to a SharePoint page canvas layout. The body needs an id (the section position, as a string, e.g. "1"), plus layout and emphasis - a body without id fails with 400 "Empty Payload. JSON content expected." or "One of the provided arguments is not acceptable." Sections are the rows of a modern page; web parts are placed inside them afterwards. Verified working with {"id":"9","layout":"oneColumn","emphasis":"none"}. Required: site_id, page_id, id.
- **List all SharePoint web parts** (List). List web parts on a SharePoint site page. Returns each web part with id, @odata.type, webPartType, data, and innerHtml. Required: site_id, page_id.
- **SharePoint web parts create vertical** (Create). Create a new web part in the vertical section of a SharePoint page's canvas layout. Returns the created web part with id, @odata.type, webPartType, data, and innerHtml. Required: site_id, page_id. PREREQUISITE: the page canvas must already contain a vertical section, otherwise this returns 404. No method in this integration creates one - add it in the SharePoint page editor first. For the ordinary case use web-parts.create-horizontal, which works against the horizontal sections that new pages have by default.
- **SharePoint web parts create horizontal** (Create). Create a new web part in a specific column of a horizontal section on a SharePoint site page. Returns: id, @odata.type.type. Required: site_id, page_id, horizontal_section_id, horizontal_section_column_id.
- **SharePoint web parts download** (Download). Download binary content referenced by a web part, by pre-authenticated URL. Like drive-items.download this takes no ids: pass base as the URL origin and path as the pathname plus query string, both taken from the pre-authenticated URL in the web part payload (typically a driveItem @microsoft.graph.downloadUrl). Anything else returns 500 "Invalid URL string". Required: base, path.
- **List all SharePoint drives** (List). List drives (document libraries) under a SharePoint site. Returns: id, name, createdDateTime, description, eTag, lastModifiedDateTime, webUrl. Required: site_id.
- **List all SharePoint drive items** (List). List the CHILDREN of a folder in a document library, with listItem expanded. Despite the resource name this is a folder listing, not a flat item list: item_id must be a FOLDER id, and passing a file id returns 422 "Children cannot be listed from an item that is not a folder". item_id defaults to "root", so omit it to list the library root. Required: site_id, drive_id.
- **Get single SharePoint drive item by ID** (Get). Get a driveItem from a site's DEFAULT document library. The path resolves /sites/{site_id}/drive, so the id must be a driveItem id from that default drive - passing a site id, a list id or an item from a different drive returns 400 "The provided drive id appears to be malformed, or does not exist". To read an item from a specific (non-default) drive, use drive-items-v2.get with drive_id instead. Required: site_id, id.
- **SharePoint drive items download** (Download). Download a driveItem's binary content by pre-authenticated URL. This tool does not take a drive or item id: it takes the download URL, split in two. Read the item first (drive-items-v2.get) to obtain its "@microsoft.graph.downloadUrl", then pass base as that URL's origin (e.g. https://contoso.sharepoint.com) and path as its pathname plus query string. Passing anything else returns 500 "Invalid URL string". Verified working when split from a live downloadUrl. Required: base, path.
- **Delete a SharePoint drive item by ID** (Delete). Delete a SharePoint drive item by id. Returns an empty 204 response on success. Required: drive_id, id.
- **List all SharePoint search** (List). Run a Microsoft Search query across SharePoint content. This is a POST that requires a body: {"requests":[{"entityTypes":["driveItem"],"query":{"queryString":"..."}}]}. An empty or malformed body returns 500 "Value cannot be null. (Parameter 'source')". Note also that Microsoft Search is permission-gated - raw POST /v1.0/search/query returns 400 "The call failed, please try again." on a connection without search entitlement, independent of the body, so a correct request can still fail on tenant configuration. Required: requests.
- **List all SharePoint lists** (List). List all SharePoint lists on a site. Returns each list's id, displayName, description, webUrl and its list facet (template, hidden, contentTypesEnabled). Use the returned id as list_id for list-items and list-columns. Required: site_id.
- **Get single SharePoint list by ID** (Get). Get one SharePoint list by id, including its template and settings. Required: site_id, id.
- **Create a SharePoint list** (Create). Create a new SharePoint list on a site. displayName is required; set list.template to choose the type ("genericList" for a normal list, "documentLibrary" for a library). You may define columns inline in the same call. Required: site_id, displayName.
- **Create a SharePoint list column** (Create). Add a column to a SharePoint list. "name" is required and becomes the key used in list item fields. Declare the column type by setting exactly one type facet - text, number, boolean, dateTime, choice, currency, lookup, personOrGroup, hyperlinkOrPicture, geolocation or term - to an object (an empty object accepts the defaults). Required: site_id, list_id, name.
- **List all SharePoint list columns** (List). List the column definitions of a SharePoint list. Call this before reading or writing list-items: each column's "name" is the exact key to use in a list item's fields object, and "required"/"readOnly" tell you which keys you must or must not send. Required: site_id, list_id.
- **Get single SharePoint list column by ID** (Get). Get a single column definition from a SharePoint list, including its type facet and validation rules. Required: site_id, list_id, id.
- **Update a SharePoint list column by ID** (Update). Update a column definition on a SharePoint list. Send only the properties you want to change. The column type facet generally cannot be changed after creation; displayName, description, required, indexed, hidden and defaultValue can. Required: site_id, list_id, id.
- **Delete a SharePoint list column by ID** (Delete). Delete a column from a SharePoint list. This permanently removes the column and its values from every item in the list. Columns with isDeletable false cannot be removed. Returns an empty 204 on success. Required: site_id, list_id, id.
- **List all SharePoint list items** (List). List the items in a SharePoint list. Column values are NOT returned by default - pass $expand=fields to include them, optionally narrowed with $expand=fields($select=Name,Status). Discover the available field names with list-columns.list. Required: site_id, list_id.
- **Get single SharePoint list item by ID** (Get). Get one item from a SharePoint list. Pass $expand=fields to include the column values. The id is the item's numeric id within the list (e.g. "1"), not a GUID. Required: site_id, list_id, id.
- **Create a SharePoint list item** (Create). Create an item in a SharePoint list. The body must be {"fields": { ... }} where the keys are column names from list-columns.list - call that first to learn the names and which are required. "Title" is the default column on a generic list. Required: site_id, list_id, fields.
- **Update a SharePoint list item by ID** (Update). Update the column values of a SharePoint list item. This targets the item's fields resource, so the body is the bare fieldValueSet - name/value pairs at the top level, NOT wrapped in a "fields" object (that is only for create). Send only the columns you want to change. Returns the updated fieldValueSet. Required: site_id, list_id, id.
- **Delete a SharePoint list item by ID** (Delete). Delete an item from a SharePoint list. The item goes to the site recycle bin. Returns an empty 204 on success. Required: site_id, list_id, id.
- **List all SharePoint site permissions** (List). List permissions. Required: site_id.
- **Create a SharePoint site permission** (Create). Create permission. Required: site_id.
- **Create a SharePoint list item permission** (Create). Create new navigation property to permissions for sites. Required: site_id, list_id, item_id.
- **List all SharePoint site members** (List). List user profile items from the User Information List in a SharePoint site, with field values expanded. Returns: id, createdDateTime, eTag, lastModifiedDateTime, name, webUrl, fields. Required: site_id.
- **List all SharePoint sub sites** (List). List the collection of subsites defined under a parent SharePoint site. Returns: id, displayName, name, createdDateTime, lastModifiedDateTime, webUrl, isPersonalSite. Required: site_id.
- **List all SharePoint organization** (List). List organizations (tenant details) in SharePoint via Microsoft Graph. Returns: id, displayName, businessPhones, preferredLanguage, createdDateTime.
- **SharePoint drive item export download** (Export). Download the content of a specific drive item in SharePoint, optionally converting it to a specified format. Returns the file content as a binary stream. Required: site_id, drive_id, item_id, format.
- **List all SharePoint drive item permissions** (List). List permissions for a SharePoint drive item. Returns each permission object including its id and resource-type-specific attributes from the microsoft.graph.permission schema. Required: drive_id, item_id.
- **Update a SharePoint drive item permission by ID** (Update). Update a sharing permission on a SharePoint drive item. Returns the updated permission including id, roles, grantedTo, and link. ONLY DIRECT PERMISSIONS ARE PATCHABLE: a driveItem's default permissions are inherited from the site's SharePoint groups (Owners / Members / Visitors) and Graph rejects a PATCH on those with 403 Access denied - this is by design, not a request defect. Use drive-item-permissions.list first and target a permission that carries a link object or was granted directly to a user; change site-group membership in SharePoint itself. The body replaces roles wholesale: send ["read"] for view-only or ["write"] for edit. Required: drive_id, item_id, id.
- **Delete a SharePoint drive item permission by ID** (Delete). Delete a sharing permission from a SharePoint drive item. Returns an empty 204 response on success. Required: drive_id, item_id, id.
- **Get single SharePoint drive item permission by ID** (Get). Get a specific permission on a SharePoint drive item by id. Returns: id, attributes. Required: drive_id, item_id, id.
- **SharePoint drive item invite send** (Invite). Send a sharing invitation for a SharePoint drive item to specified recipients, optionally including a custom message and role assignments. Returns a collection of permissions including value (array of permission objects with id, roles, and grantedTo). Required: drive_id, item_id. TENANT GATE: external and link-based sharing must be enabled for the tenant and the library. Where it is not, Graph returns 400 even for a well-formed body - verified with sendInvitation false, so no mail was emitted. Check the SharePoint admin sharing policy before treating a 400 here as a request defect.
- **List all SharePoint role assignments** (List). List the users in a SharePoint site group, via the SharePoint REST API rather than Graph. The identifiers are SharePoint-specific: site_name is the site path segment (for example "Notion" from /sites/Notion) and group_id is the NUMERIC SharePoint site-group id from /_api/web/sitegroups - NOT an Entra group GUID. Note also that /_api/ is the SharePoint REST surface and the connection Graph OAuth token is not accepted there, so this returns 401 on a Graph-only connection regardless of the identifiers. Required: site_name, group_id.
- **List all SharePoint get all sites** (List). List every SharePoint site in the tenant. IMPORTANT: /sites/getAllSites requires the Sites.Read.All APPLICATION permission and an app-only token - a delegated (user) connection returns 403 Access denied no matter which site permissions the user holds. To enumerate sites with a delegated connection use sites.list or get the root site with root-site.list and walk sub-sites.list instead. Takes no parameters.
- **List all SharePoint list sites** (List). List all available SharePoint sites in an organization. Supports $search to find sites matching given keywords, plus $filter, $count, $orderby, $select, and $expand query options; for listing sites across all geographies use getAllSites instead. Returns: id, displayName, name, webUrl, createdDateTime, lastModifiedDateTime, isPersonalSite, description, eTag, root, sharepointIds, siteCollection.
- **List all SharePoint group members** (List). List members of a group in SharePoint. Returns: id, businessPhones, displayName, givenName, jobTitle, mail, mobilePhone, officeLocation, preferredLanguage, surname, userPrincipalName. Required: group_id.
- **List all SharePoint groups** (List). List the Microsoft 365 groups in the tenant. Takes NO required parameters - call it bare. Earlier versions of this tool declared site_id, store_id, site-id, store-id and group-id as required; none of them appear in the request path, so Graph rejected the call with 400 "Unrecognized query argument specified". Verified returning 19 groups with no parameters at all. Use $select/$filter/$top to narrow the result. The group id returned here is what group-members.list, group-sites.list and planner-plans.list ($filter=owner eq) expect.
- **Get single SharePoint group by ID** (Get). Get a single Microsoft 365 group by id. The ONLY parameter needed is the group id, passed as the path id. Earlier versions also demanded site_id, store_id, site-id, store-id and group-id; none appear in the path and Graph rejects them with 400 "Unrecognized query argument specified". Verified working with the id alone. Required: id.
- **List all SharePoint group endpoints** (List). List the endpoints registered on a Microsoft 365 group - the resources provisioned for it by services such as Microsoft Teams. Returns id, capability, providerId, providerName, providerResourceId, uri and deletedDateTime for each endpoint. Required: group_id. Uses the Graph /beta endpoint. Note that this method declares no response_path, so the raw response is Graph's envelope {"@odata.context":..., "value":[...]} rather than a bare array; the fields documented here describe each object inside value. Most groups return an empty value array - verified across 6 groups, 2 of which had a single Microsoft Teams endpoint.
- **List all SharePoint group sites** (List). Get the root SharePoint site of a Microsoft 365 group. Requires the Sites.Read.All permission in addition to group read access; with a delegated connection that lacks it, this returns 403 Access denied even when groups.list succeeds. Required: group_id (the Entra group id, from groups.list).
- **List all SharePoint me** (List). Get the current authenticated user's profile in SharePoint via the Microsoft Graph /me endpoint. Returns: displayName, id, token_type, scope, expires_in, ext_expires_in, access_token, refresh_token. No required parameters.
- **List all SharePoint root site** (List). Get the root SharePoint site within a tenant. Returns the site object including its id, displayName, name, webUrl, createdDateTime, lastModifiedDateTime, and isPersonalSite.
- **SharePoint drive item download download** (Download). Download the content of a SharePoint drive item file as a binary stream. Returns the file's binary content stream (application/octet-stream). Required: site_id, drive_id, item_id.
- **Get single SharePoint drive items v 2 by ID** (Get). Get a single SharePoint drive item by id. Returns: id, name, createdDateTime, lastModifiedDateTime, webUrl, isPersonalSite, displayName. Required: drive_id, id.
- **List all SharePoint drive items v 2** (List). List children of a SharePoint drive item, expanding listItem data for each child. Returns: id, name, createdDateTime, description, eTag, lastModifiedDateTime, webUrl. Required: drive_id. Defaults to listing root children when item_id is omitted.
- **Update a SharePoint drive items v 2 by ID** (Update). Update a SharePoint drive item by id. Returns: id, name, createdDateTime, description, eTag, lastModifiedDateTime, webUrl. Required: drive_id, id.
- **Create a SharePoint drive item child** (Create). Create a new child item (such as a folder or file) under a parent SharePoint drive item. Returns: id, name, displayName, description, eTag, webUrl, createdDateTime, lastModifiedDateTime, isPersonalSite, root, sharepointIds, siteCollection, analytics, contentTypes, drive, drives, items, lists, operations, permissions, sites, columns, onenote, termStore, termStores. Required: drive_id,…
- **SharePoint drive item content upload by site path** (Upload). Upload file content to a SharePoint site's default drive by specifying the parent folder path and file name. Returns the driveItem object including id, name, createdDateTime, lastModifiedDateTime, eTag, and webUrl. Required: site_id, parent_id, file_name.
- **Create a SharePoint drive item content** (Create). Upload new file content to a SharePoint drive by specifying the parent item and file name. Returns the driveItem object including id, name, createdDateTime, lastModifiedDateTime, eTag, and webUrl. Required: drive_id, parent_id, file_name.
- **Update a SharePoint drive item content by ID** (Update). Replace the content of an existing SharePoint driveItem by id. Returns the driveItem object including id, name, createdDateTime, lastModifiedDateTime, eTag, and webUrl. Required: drive_id, id.
- **Create a SharePoint drive item upload session** (Create). Create an upload session in SharePoint to begin a resumable file upload for a new drive item under a parent folder. Returns: uploadUrl, expirationDateTime, nextExpectedRanges. Required: drive_id, item_id, file_name. NOTE ON ETAGS: this method also sends an If-Match header from the optional etag query param. Creating a session for a NEW file name succeeds without it, but pointing it at a name that already exists and omitting etag returns 412 - pass the existing item's eTag in that case.
- **SharePoint drive item upload sessions create for item** (Upload). Create an upload session in SharePoint to update the content of an existing drive item via resumable chunked upload. Returns: uploadUrl, expirationDateTime, nextExpectedRanges. VERIFIED behaviour: with a correct etag this returns an uploadUrl; with a stale etag, or with etag omitted entirely, it fails with 412 "ETag does not match current item's value" - the method always sends If-Match, so etag is effectively required even though it is a query parameter. PUT the file bytes to the returned uploadUrl in ranges; the session is not the upload itself. Required: drive_id, item_id, etag.
- **List all SharePoint drive item version** (List). List versions of a drive item in a SharePoint document library. Returns: id, lastModifiedDateTime, createdDateTime, displayName, name, webUrl, isPersonalSite, eTag, description, root, sharepointIds, siteCollection. Required: site_id, drive_id, item_id.
- **Get single SharePoint share by ID** (Get). Resolve a sharing link to the driveItem it points at, with children expanded. The id is NOT a site, drive or item id - it must be either a sharing token, or a sharing URL encoded as "u!" followed by the base64url of the URL (standard base64 with + replaced by -, / replaced by _, and trailing = stripped). A link to a site rather than a file or folder returns 400 "Share url does not point to a drive item". Required: id.
- **Create a SharePoint site item content** (Create). Upload binary file content to create or replace a file in a SharePoint site, addressing it by site, parent item, and file name. Returns: id, name, createdDateTime, lastModifiedDateTime, webUrl, isPersonalSite, displayName. Required: site_id, parent_id, file_name.
- **Create a SharePoint ensure user** (Create). Resolve a user on a SharePoint site via the SharePoint REST API, creating the site user entry if it does not exist. TWO THINGS TO KNOW. First, this method builds its own base URL from a truto_base query parameter - pass truto_base as the site URL (e.g. https://contoso.sharepoint.com/sites/TeamA); omit it and the request resolves against the Graph host and fails with 404 "Invalid version: _api". Second, /_api/ is the SharePoint REST surface rather than Graph, and the connection Graph OAuth token is not accepted there - the call returns 401 even with truto_base set. The same limitation applies to role-assignments.list. Required: truto_base, and logonName in the body.
- **List all SharePoint subscriptions** (List). List active Microsoft Graph subscriptions in SharePoint. Returns: id, applicationId, changeType, clientState, creatorId, encryptionCertificate, encryptionCertificateId, expirationDateTime, includeResourceData, latestSupportedTlsVersion, lifecycleNotificationUrl, notificationQueryOptions, notificationUrl, notificationUrlAppId, resource.
- **Get single SharePoint subscription by ID** (Get). Get a Microsoft Graph change-notification subscription by id. The id must be the subscription GUID returned by subscriptions.list or subscriptions.create - it is NOT a site, drive, list or item id. Passing anything else returns 400 "SubscriptionId Guid format is invalid or contained all zeros". Required: id.
- **Create a SharePoint subscription** (Create). Create a Microsoft Graph subscription to receive change notifications when SharePoint data changes. Returns the created subscription including id, changeType, resource, notificationUrl, and expirationDateTime. Required: changeType, notificationUrl, resource, expirationDateTime.
- **Update a SharePoint subscription by ID** (Update). Update a Microsoft Graph subscription's expirationDateTime for renewal and/or notificationUrl for delivery. Returns the updated subscription including id, changeType, resource, notificationUrl, and expirationDateTime. Required: id.
- **Delete a SharePoint subscription by ID** (Delete). Delete a Microsoft Graph subscription by id to stop receiving change notifications. Returns an empty 204 response on success. Required: id.
- **SharePoint subscriptions reauthorize** (Action). Reauthorize a Microsoft Graph subscription when you receive a reauthorizationRequired challenge. Returns an empty 204 response on success. Required: id.
- **List all SharePoint drive items delta** (List). Track incremental changes to items under the root of a SharePoint drive using a delta query. Returns: value, @odata.nextLink, @odata.deltaLink, id, isPersonalSite, displayName, name, createdDateTime, lastModifiedDateTime, webUrl.nextLink, @odata.deltaLink. Required: drive_id.
- **List all SharePoint site drive items delta** (List). Track changes to a site's default document library (delta query). Returns the changed driveItems in value, plus a deltaLink carrying the token for the next call. delta_token is effectively REQUIRED: the method always appends token={{query.delta_token}}, so leaving it out sends the unsubstituted placeholder and Graph rejects the call with 400 "One of the provided arguments is not acceptable". Pass delta_token=latest for a starting cursor without enumerating the library (VERIFIED: returns 200 with an empty set), or the token from the previous deltaLink to get only subsequent changes. Required: site_id, delta_token.
- **List all SharePoint planner plans** (List). List Microsoft Planner plans. Graph rejects this collection unbound: you MUST pass $filter on the owner property, e.g. $filter=owner eq '<group-id>' - without it the call fails with 405 "This entity set must be queried with a filter on owner property". It also needs Planner read access to that group: with a connection lacking the Tasks.Read permission this returns 403 "You do not have the required permissions to access this item" even with a valid owner filter. To list the signed-in user's plans instead, use GET /me/planner/plans, which needs no filter. Required: $filter.
- **Get single SharePoint planner plan by ID** (Get). Get one Planner plan by id. The response carries an @odata.etag - keep it, update and delete require it. Required: id.
- **Create a SharePoint planner plan** (Create). Create a Planner plan. A plan must belong to a Microsoft 365 group - set container.containerId to the group id. title is required. The signed-in user must be a member of that group. Required: title, container.
- **Update a SharePoint planner plan by ID** (Update). Update a Planner plan (in practice, its title). Requires the etag query param, taken from the @odata.etag of a prior get - Planner sends it as If-Match and returns 409 Conflict if it is stale (400 if the param is omitted). Send only the fields you are changing. Required: id, etag.
- **Delete a SharePoint planner plan by ID** (Delete). Delete a Planner plan. This permanently removes the plan and every bucket and task in it. Requires the etag query param (sent as If-Match); a stale etag returns 409 Conflict, and omitting the param returns 400. Returns an empty 204 on success. Required: id, etag.
- **List all SharePoint planner buckets** (List). List the buckets (board columns) of a Planner plan. Buckets are how a Planner board is divided; a task's bucketId must reference one of these. Required: plan_id.
- **Get single SharePoint planner bucket by ID** (Get). Get one Planner bucket by id. Note the path is /planner/buckets/{id} - buckets are addressed globally, not under their plan. Keep the returned @odata.etag for update and delete. Required: id.
- **Create a SharePoint planner bucket** (Create). Create a bucket in a Planner plan. name and planId are required. Set orderHint to " !" to place it first on the board, or omit it to append. Required: name, planId.
- **Update a SharePoint planner bucket by ID** (Update). Update a Planner bucket - rename it or move it on the board via orderHint. Requires the etag query param from a prior read (sent as If-Match); 409 Conflict if stale, 400 if omitted. Required: id, etag.
- **Delete a SharePoint planner bucket by ID** (Delete). Delete a Planner bucket. Tasks in the bucket are NOT deleted - they become unbucketed in the same plan. Requires the etag query param (sent as If-Match). Returns an empty 204 on success. Required: id, etag.
- **List all SharePoint planner tasks** (List). List Microsoft Planner tasks. Graph rejects this collection unbound: you MUST pass $filter on planId, e.g. $filter=planId eq '<plan-id>' - without it the call fails with 405 "This entity set cannot be queried without a filter on planId". To list the signed-in user's assigned tasks instead, use GET /me/planner/tasks. Task descriptions and checklists live on a separate details entity, not here. Required: $filter.
- **Get single SharePoint planner task by ID** (Get). Get one Planner task by id. Returns the task fields only - the description, checklist and references are on the separate task details entity. Keep the returned @odata.etag for update and delete. Required: id.
- **Create a SharePoint planner task** (Create). Create a Planner task. planId and title are required; bucketId is optional but must reference a bucket in the same plan. Assign people by keying assignments on their user id. percentComplete 0/50/100 maps to Not started / In progress / Completed. Required: planId, title.
- **Update a SharePoint planner task by ID** (Update). Update a Planner task - retitle it, move buckets, set progress, reassign or change dates. Requires the etag query param, taken from the @odata.etag of a prior read; Planner sends it as If-Match and returns 409 Conflict if it is stale (400 if the param is omitted). Send only the fields you are changing. Required: id, etag.
- **Delete a SharePoint planner task by ID** (Delete). Delete a Planner task. Requires the etag query param (sent as If-Match); a stale etag returns 409 Conflict, and omitting the param returns 400. Returns an empty 204 on success. Required: id, etag.
- **List all SharePoint users** (List). List the users in the Microsoft Entra tenant. Takes no required parameters - call it bare. Returns id, displayName, givenName, surname, userPrincipalName, mail, jobTitle, businessPhones, mobilePhone, officeLocation and preferredLanguage for each user; use $select to request other user properties. Verified returning 23 users with no parameters. $select, $top, $filter, $orderby, $search, $count and $expand all work on this endpoint; $skip does not - Graph rejects it with "'$skip' is not supported by the service", so page with $top and let Truto follow @odata.nextLink.
