Microsoft SharePoint
<!-- BEGIN:skill-intro -->
Agent-callable tools for Microsoft SharePoint Online, over the
Microsoft Graph API v1.0 (
https://graph.microsoft.com/v1.0/sites/...
): find sites and document libraries; browse, search, upload, download, move, copy, and share files and folders; manage SharePoint lists and list items; and author and publish site pages. 32 scripts across sites, drives, files & folders, sharing & permissions, lists, list items, and pages. Read-only navigation tools resolve the ids (
,
,
,
, column internal names) that the write tools require — a site is addressed by an opaque composite id you get from
/
, never constructed by hand.
<!-- legal:disclaimer -->
Independent, unofficial connector for Microsoft SharePoint. Not affiliated with, endorsed by, or sponsored by Microsoft SharePoint. "Microsoft SharePoint" is a trademark of its owner, used only to identify the service this connector works with.
<!-- /legal:disclaimer -->
<!-- END:skill-intro -->
When to use this
<!-- BEGIN:skill-use-cases -->
- An agent needs to find or read SharePoint content — search sites, list a site's document libraries, browse or search files and folders, or read a file's / list-item's / page's details.
- An agent needs to work with files — create folders, upload text or binary files, move / copy / rename, export to PDF or HTML, or share (links and per-person grants) and manage permissions.
- An agent needs to work with lists — list a site's lists, discover a list's columns, create lists, and create / read / update / delete list items.
- An agent needs to author pages — create a draft site page (optionally with text body content) and publish it.
<!-- END:skill-use-cases -->
Setup
This is an
agentskills.io skill.
If the connector has not been installed as a skill yet, install it first with
npx skills add zapier/connectors --skill microsoft-sharepoint
(or your harness's own skill-install mechanism), then continue here. Installing the skill copies these files, not dependencies. Before running the CLI, a local MCP server, or
auth commands, run
here once. Importing the published package as a dependency in your own project instead? That
already resolves everything — see
.
The connector runs on Node.js 22.18+. Pick the reference that matches how you're running it, and load it before doing anything else:
| You have... | Load |
|---|
An MCP-aware client — tools may already be loaded (e.g. mcp__microsoft-sharepoint__<tool>
), or you can register a local server yourself (or guide the user to) | |
| Terminal / subprocess access (you can run ) | |
| Only your own code, importing this package as a dependency | |
| No tool access, no terminal, no ability to import this package — you write your own code that calls the Microsoft SharePoint API directly (e.g. a code-execution sandbox) | references/use-as-recipe.md
|
Scripts
<!-- BEGIN:skill-connections-note? -->
All scripts use the single connection
, except
, which needs no connection (it polls a pre-authenticated monitor URL).
<!-- END:skill-connections-note -->
<!-- BEGIN:skill-scripts-table -->
| Script | Script name | Connections | Description |
|---|
| | | Search sites by keyword; the primary site-discovery entry point. |
| | | Get a site by composite id, , or . |
| | | List a site's document libraries to resolve a . |
scripts/listFolderItems.ts
| | | List the direct children of a folder or a drive root. |
| | | Search files and folders by name/content within a drive. |
| | | Get a file or folder's metadata (with a download URL) by id. |
| | | Create a folder at the root or inside another folder. |
scripts/uploadTextFile.ts
| | | Create a small text file from string content. |
| | | Upload a binary file from a source URL (handles large files). |
| | | Replace an existing file's contents from a source URL. |
| | | Move / rename an item within the same document library. |
| | | Copy a file/folder to another folder or drive (async). |
| | (none) | Poll the status of an async copy started by . |
| | | Delete a file or folder (moves it to the recycle bin). |
| | | Download a file converted to PDF / HTML / JPG / GLB. |
scripts/createSharingLink.ts
| | | Create a shareable link (view/edit/embed) to an item. |
| | | Grant named people read/write access to an item. |
scripts/listItemPermissions.ts
| | | List the permissions on a file or folder. |
scripts/removeItemPermission.ts
| | | Revoke a permission from a file or folder. |
| | | List a site's lists (also serves single-list lookup). |
| | | Create a new list in a site. |
| | | List a list's column definitions (internal field names). |
| | | List or filter items in a list, with column values. |
| | | Get a single list item with its column values. |
scripts/createListItem.ts
| | | Create a new item in a list. |
scripts/updateListItem.ts
| | | Update column values on an existing list item. |
scripts/deleteListItem.ts
| | | Delete a list item (hard delete, not the recycle bin). |
| | | List a site's pages to resolve a . |
| | | Get a single site page by id. |
| | | Create a draft site page, optionally with text content. |
| | | Publish a draft site page. |
| | | Delete a site page (moves it to the recycle bin). |
<!-- END:skill-scripts-table -->
<!-- BEGIN:disambiguation-and-refusals? -->
Disambiguation & refusals
Disambiguation before a write. Before writing to something you looked up by name — a site from
, a list from
, or a list item from
— count the
exact case-insensitive name matches:
- Exactly one match — act on it. Don't over-ask; a single unambiguous match is the answer.
- Two or more that tie — stop. List the tied candidates with a distinguishing field (, , or ) and ask which one the user means. Don't pick arbitrarily, and don't write to all of them. Site names in particular collide across departments (e.g. two "Marketing" sites).
Unsupported operations — say so and stop; don't fake it with another tool. This catalog deliberately does not:
- Move a file across libraries or sites (no native move). is same-library only. The only way to relocate across libraries/sites is → () → , which is lossy: the copy gets a new id and URL, its sharing links and permissions don't carry over, and a half-failed copy can lose the file. You may perform this relocation when asked to move a file elsewhere, but never present it as a plain "move": warn the user first that it's a copy-then-delete, tell them the file's URL/id changes and sharing links & permissions won't carry over, confirm the copy succeeded via before deleting the original, and report the new location. Never silently copy-delete and report a completed move.
- Edit an existing page's body, or add non-text web parts (images, embeds, quick-links, multi-column layouts). authors a single text web part on a new page; editing an existing page's content and rich web parts are out of scope. Do not delete the page and recreate it to simulate an edit — that changes the page's id/URL and loses its version history, comments, and permissions. Tell the user in-place body editing isn't supported and stop.
- Enumerate every site in the tenant. There is no "list all sites" — a delegated token can't. Use (keyword) or with a known path.
- Manage content types, site columns, term-store metadata, or triggers (new-file / new-item notifications). These aren't exposed.
- Write person/group or multi-value lookup columns on list items. Those column types are read-only here.
If asked for any of these, tell the user it's unsupported and stop — don't reach for an unrelated tool to approximate it.
<!-- END:disambiguation-and-refusals -->
Auth
Every shape passes auth as one connection
selector, not the secret — a
string. Every connector accepts
(Zapier-managed auth — routes through Zapier's auth, retries, and governance layer); some also accept one or more direct-token resolvers (naming and count vary per connector) — check this connector's own resolvers rather than assuming. The
prefix is optional; a bare value goes to the first resolver that claims it — a UUID-shaped bare value always claims
. Each script declares the connections it needs and the resolvers each accepts. The exact syntax for passing a connection (and how to see this connector's resolver list) differs by shape — see the reference you loaded above.
Checking what's already configured first? Don't dump environment values to do it —
or
prints the value along with the name, leaking a live credential into the transcript if one is set. Check names only (
env | cut -d= -f1 | grep -i <name>
) or test a known name directly (
).
<!-- BEGIN:skill-auth-notes? operational behavior that differs by WHICH resolver is used — a safety gate only one path enforces, scopes/permissions that differ between resolvers, a billing/plan difference tied to the auth path, or a feature only available (or unavailable) on one resolver. Not for describing how to obtain or pass a credential — that's references/use-without-zapier.md's job. Leave this region empty (unfilled) if every resolver behaves identically. -->
<!-- END:skill-auth-notes -->
No connection yet? Pick one — and follow the reference's own flow to obtain it; never just ask the user for a connection id or token as if they already have one memorized:
| Load |
|---|
| Pass the credential directly | references/use-without-zapier.md
|
| Route it through a Zapier connection | references/use-with-zapier.md
|
Output format
Every script returns a
envelope:
- — the script's result (the shape its declares; see the reference you loaded above for how to inspect a script's exact schema in your shape).
meta.outputDataValidation
— what validating did:
{ skipped: false, droppedPaths: null }
— validated, nothing removed.
{ skipped: false, droppedPaths: [...], instruction }
— validated, but those paths were stripped from : fields the script returned from the API that the doesn't declare. If you need them, re-run with output validation skipped.
- — validation was bypassed; is the raw, unchecked script output.
Reading dropped fields / . To receive the raw, unvalidated result, opt out of output validation (the exact syntax differs by shape — see the reference you loaded above). Input validation is never skipped.
Trimming the result / . To shrink a large result down to the fields you need, pass a jq expression that post-processes
(again, exact syntax per shape). The jq runs against
only, NOT the
envelope, so write it rooted at
(run the script's
— or your shape's equivalent — to see its output schema). The transformed value replaces
,
is preserved, and the result is NOT re-validated against the output schema.
<!-- BEGIN:skill-references-table -->
References
Load the matching reference file before working in that area:
| Reference | Covers | Load it when |
|---|
| microsoft-sharepoint-api-gotchas.md | Graph permission scopes, error envelope (403/404/429), pagination, site/drive addressing, short-lived download URLs, async copy, resumable uploads, same-drive move, delete semantics, sharing links/invites/permissions, list-item column values (LookupId, 12-lookup limit, multi-value), and site-page draft/publish/type-cast rules. | A call errors unexpectedly (403/404/429, name conflict), you're resolving a site or drive id, working with list-item column values, or creating/publishing site pages. |
<!-- END:skill-references-table -->