# ποΈ sharepoint-mcp
### **The MCP Server that gives your AI agent a brain for Microsoft SharePoint**
[](https://github.com/ravikant1918/sharepoint-mcp/actions/workflows/ci.yml)
[](https://pypi.org/project/sharepoint-mcp/)
[](https://pypi.org/project/sharepoint-mcp/)
[](https://opensource.org/licenses/MIT)
[](https://github.com/ravikant1918/sharepoint-mcp#-docker)
[](https://modelcontextprotocol.io)
A production-grade **Model Context Protocol (MCP) server** for **Microsoft SharePoint**.
Connect **Claude Desktop**, **VS Code Copilot**, **Cursor**, **Continue**, or any MCP-compatible AI agent
to your SharePoint β read files, manage folders, and reason over your organisation's knowledge.
[π Docs](docs/) Β· [πΊοΈ Roadmap](docs/roadmap.md) Β· [π Bugs](https://github.com/ravikant1918/sharepoint-mcp/issues) Β· [π‘ Features](https://github.com/ravikant1918/sharepoint-mcp/issues/new?template=feature_request.yml)
---
## π Table of Contents
- [Why sharepoint-mcp?](#-why-sharepoint-mcp)
- [What Your Agent Can Do](#-what-your-agent-can-do)
- [Features](#-features)
- [Quickstart](#-quickstart)
- [Docker](#-docker)
- [Transport Modes](#-transport-modes)
- [Integrations](#-integrations) β Claude Desktop Β· VS Code Copilot Β· Cursor
- [All 14 Tools](#οΈ-all-14-tools)
- [Configuration Reference](#οΈ-full-configuration-reference)
- [Limitations](#οΈ-limitations)
- [Troubleshooting](#-troubleshooting)
- [Development](#-development)
- [Documentation](#-documentation)
- [Contributing](#-contributing)
- [Security](#-security)
---
## π§ Why sharepoint-mcp?
> Most AI agents only know what's in their training data.
> **sharepoint-mcp** gives your agent _live access_ to your organisation's real knowledge.
| Without sharepoint-mcp | With sharepoint-mcp |
| ---------------------------------- | --------------------------------------- |
| π€· Agent guesses or hallucinates | Agent reads the actual document |
| π You copy-paste content manually | Agent fetches files automatically |
| π Knowledge locked in SharePoint | Knowledge flows into your AI workflow |
| π Static, one-shot answers | Agent reasons, rewrites, and saves back |
---
## π What Your Agent Can Do
### π Understand Any Document
```
You: "Summarise the Q3 report in the Finance folder"
Agent: β Get_Document_Content("Finance", "Q3_Report.pdf")
β Reads full extracted text
β Returns a sharp, accurate summary
```
### βοΈ Read β Reason β Write
```
You: "Translate the proposal to French and save it"
Agent: β Get_Document_Content β translate β Upload_Document
```
### ποΈ Navigate Your Library
```
You: "What files are in the Legal/Contracts folder?"
Agent: β List_SharePoint_Documents("Legal/Contracts")
```
### π Supported File Formats
| π Format | π€ What the Agent Gets |
| -------------------------------------------- | ----------------------------- |
| **PDF** | Full text from every page |
| **Word** `.docx` `.doc` | Complete document content |
| **Excel** `.xlsx` `.xls` | All sheets as structured text |
| **Text, JSON, Markdown, HTML, YAML, Python** | Raw content as-is |
| **Images, ZIP, binaries** | File type + Base64 |
---
## β¨ Features
| | Feature | Description |
| --- | -------------------------- | ------------------------------------------------------ |
| π | **Dual API Support** | Choose Office365 REST or Microsoft Graph API |
| π | **Folder Management** | List, create, delete, get full recursive tree |
| π | **Document Management** | Upload, download, update, delete, search, read content |
| π·οΈ | **Metadata Management** | Read and update SharePoint list-item fields |
| π | **Smart Parsing** | Auto-detects PDF / Word / Excel / text |
| π | **KQL Search** | Native SharePoint KQL search for semantic file finding |
| π | **Flexible Library Scope** | Scope to a subfolder or access the entire library root |
| π | **Auto-Retry** | Exponential backoff on SharePoint 429/503 throttling |
| π | **Dual Transport** | `stdio` for desktop Β· `http` for Docker/remote |
| πͺ΅ | **Structured Logging** | JSON in production Β· coloured console in dev |
| π³ | **Docker-Ready** | Single command: `docker compose up -d` |
| π‘οΈ | **Non-Root Container** | Runs as unprivileged user inside Docker |
| π©Ί | **Health Check** | Live `/health` endpoint with real SharePoint check |
| π€ | **CI/CD** | Tested on Python 3.10 Β· 3.11 Β· 3.12 Β· 3.13 |
---
## β‘ Quickstart
### 1οΈβ£ Install
```bash
pip install sharepoint-mcp
```
Or from source:
```bash
git clone https://github.com/ravikant1918/sharepoint-mcp.git
cd sharepoint-mcp && pip install -e .
```
### 2οΈβ£ Configure
```bash
cp .env.example .env
# Open .env and fill in your Azure AD credentials
```
```env
SHP_ID_APP=your-azure-app-client-id
SHP_ID_APP_SECRET=your-azure-app-secret
SHP_TENANT_ID=your-tenant-id
SHP_SITE_URL=https://your-tenant.sharepoint.com/sites/your-site
SHP_API_TYPE=office365 # or "graph" / "graphql" for Microsoft Graph API
```
> π **New to Azure AD?** Follow the [step-by-step guide β](docs/azure-setup.md)
> π **Choose Your API**: SharePoint MCP supports both **Office365 REST API** (default) and **Microsoft Graph API**. See [API Configuration Guide β](docs/api-configuration.md)
#### Optional: Scope to a subfolder
By default, the server accesses your **entire document library root**. To restrict operations to a specific subfolder:
```env
# Only operate within this subfolder (omit for full library access)
SHP_DOC_LIBRARY=mcp_server
# Library name (only needed if your org renamed "Shared Documents")
# Graph API auto-detects the default drive β this is only for Office365 REST API
# SHP_LIBRARY_NAME=Shared Documents
```
### 3οΈβ£ Run
```bash
# π Interactive testing with MCP Inspector
npx @modelcontextprotocol/inspector -- sharepoint-mcp
# βΆοΈ Run directly
sharepoint-mcp
```
---
## π³ Docker
The fastest way to deploy for remote or cloud use.
### π Usage Scenarios
#### Scenario A: Pull Latest Version from DockerHub (Recommended)
Use this for production deployments with the latest stable release:
```bash
# Step 1: Clone repository
git clone https://github.com/ravikant1918/sharepoint-mcp.git
cd sharepoint-mcp
# Step 2: Create .env file with your SharePoint credentials
cp .env.example .env
# Edit .env and fill in:
# SHP_ID_APP=your-app-id
# SHP_ID_APP_SECRET=your-secret
# SHP_TENANT_ID=your-tenant-id
# SHP_SITE_URL=https://yourcompany.sharepoint.com/sites/yoursite
# Step 3: Start container (pulls from DockerHub automatically)
docker compose up -d
# Step 4: Verify it's running
docker compose ps
curl http://localhost:8000/health
# View logs
docker compose logs -f
# Stop container
docker compose down
```
**What happens:** Pulls `ravikant1918/sharepoint-mcp:latest` from DockerHub with automatic architecture detection (Intel/ARM).
---
#### Scenario B: Use Specific Version
Lock to a specific version for stability or testing:
```bash
# Step 1: Set version via environment variable
SHAREPOINT_MCP_VERSION=v1.0.1 docker compose up -d
# Or add to .env file
echo "SHAREPOINT_MCP_VERSION=v1.0.1" >> .env
docker compose up -d
```
**What happens:** Pulls `ravikant1918/sharepoint-mcp:v1.0.1` instead of `latest`.
---
#### Scenario C: Build Locally from Source
Use this for development or when you've made local code changes:
```bash
# Step 1: Clone and setup
git clone https://github.com/ravikant1918/sharepoint-mcp.git
cd sharepoint-mcp
cp .env.example .env
# Edit .env with your credentials
# Step 2: Build from local Dockerfile and start
docker compose up -d --build
# Step 3: Rebuild after code changes
docker compose down
docker compose up -d --build
```
**What happens:** Builds image from local `Dockerfile`, tags as `ravikant1918/sharepoint-mcp:latest`, and starts container.
---
#### Scenario D: Use Custom Image/Fork
If you've forked the repo and published to your own DockerHub:
```bash
# Use your custom image
SHAREPOINT_MCP_IMAGE=myusername/sharepoint-mcp \
SHAREPOINT_MCP_VERSION=dev \
docker compose up -d
# Or add to .env
echo "SHAREPOINT_MCP_IMAGE=myusername/sharepoint-mcp" >> .env
echo "SHAREPOINT_MCP_VERSION=dev" >> .env
docker compose up -d
```
**What happens:** Pulls from your custom registry/repository.
---
### π§ Common Commands
```bash
# Start in detached mode
docker compose up -d
# Start with live logs
docker compose up
# View logs
docker compose logs -f
# Stop container
docker compose down
# Restart container
docker compose restart
# Pull latest image
docker compose pull
# Rebuild and restart
docker compose up -d --build
# Remove everything (including volumes)
docker compose down -v
```
> **Using Podman?** Just replace `docker` with `podman` β fully compatible.
### Docker Environment Variables
| Variable | Default | Description |
| ------------ | --------- | ------------------- |
| `TRANSPORT` | `http` | `stdio` or `http` |
| `HTTP_HOST` | `0.0.0.0` | Bind address |
| `HTTP_PORT` | `8000` | Port |
| `LOG_FORMAT` | `json` | `json` or `console` |
---
## π Transport Modes
| Mode | Best For | Set With |
| ------- | ---------------------------------------------------- | ----------------------------- |
| `stdio` | Claude Desktop, Cursor, MCP Inspector | `TRANSPORT=stdio` _(default)_ |
| `http` | Docker, remote agents, VS Code Copilot, REST clients | `TRANSPORT=http` |
---
## π Integrations
### π€ Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"sharepoint": {
"command": "sharepoint-mcp",
"env": {
"SHP_ID_APP": "your-app-id",
"SHP_ID_APP_SECRET": "your-app-secret",
"SHP_SITE_URL": "https://your-tenant.sharepoint.com/sites/your-site",
"SHP_TENANT_ID": "your-tenant-id",
"SHP_DOC_LIBRARY": "my-subfolder"
}
}
}
}
```
> π‘ Omit `SHP_DOC_LIBRARY` to access the full library root. If your org uses Office365 REST API and renamed the default library, also set `SHP_LIBRARY_NAME`.
### π» VS Code Copilot (Agent Mode)
1. Start the server via Docker or `TRANSPORT=http sharepoint-mcp`
2. Create `.vscode/mcp.json` in your workspace:
```json
{
"servers": {
"sharepoint": {
"url": "http://localhost:8000/mcp/",
"type": "http"
}
}
}
```
3. Open Copilot Chat β switch to **Agent mode** β your 14 SharePoint tools are available.
> β οΈ **Trailing slash matters** β the URL must end with `/mcp/` (not `/mcp`).
### β¨οΈ Cursor / Continue
Add to your MCP config (uses stdio transport):
```json
{
"mcpServers": {
"sharepoint": {
"command": "sharepoint-mcp",
"env": {
"SHP_ID_APP": "your-app-id",
"SHP_ID_APP_SECRET": "your-app-secret",
"SHP_SITE_URL": "https://your-tenant.sharepoint.com/sites/your-site",
"SHP_TENANT_ID": "your-tenant-id"
}
}
}
}
```
---
## π οΈ All 14 Tools
### π Folder Management
| Tool | What It Does |
| ------------------------- | ---------------------------------------- |
| `List_SharePoint_Folders` | π List all sub-folders in a directory |
| `Get_SharePoint_Tree` | π³ Get full recursive folder + file tree |
| `Create_Folder` | β Create a new folder |
| `Delete_Folder` | ποΈ Delete an empty folder |
### π Document Management
| Tool | What It Does |
| --------------------------- | -------------------------------------------------- |
| `List_SharePoint_Documents` | π List all files with metadata |
| `Search_SharePoint` | π Search documents using KQL queries |
| `Get_Document_Content` | π Read & parse file content (PDF/Word/Excel/text) |
| `Upload_Document` | β¬οΈ Upload file as string or Base64 |
| `Upload_Document_From_Path` | π Upload a local file directly |
| `Update_Document` | βοΈ Overwrite existing file content |
| `Delete_Document` | ποΈ Permanently delete a file |
| `Download_Document` | β¬οΈ Download file to local filesystem |
### π·οΈ Metadata Management
| Tool | What It Does |
| ---------------------- | -------------------------------------- |
| `Get_File_Metadata` | π Get all SharePoint list-item fields |
| `Update_File_Metadata` | βοΈ Update metadata fields |
---
## βοΈ Full Configuration Reference
| Variable | Required | Default | Description |
| --------------------------- | -------- | ------------------------ | ----------------------------------------------------------- |
| `SHP_ID_APP` | β
| | Azure AD app client ID |
| `SHP_ID_APP_SECRET` | β
| | Azure AD client secret |
| `SHP_TENANT_ID` | β
| | Microsoft tenant ID |
| `SHP_SITE_URL` | β
| | SharePoint site URL |
| `SHP_API_TYPE` | | `office365` | `office365`, `graph`, or `graphql` |
| `SHP_LIBRARY_NAME` | | `Shared Documents` | Library name (Office365 REST only; Graph auto-detects) |
| `SHP_DOC_LIBRARY` | | _(empty = full library)_ | Subfolder scope (e.g. `mcp_server`). Empty = entire library |
| `SHP_MAX_DEPTH` | | `15` | Max tree depth |
| `SHP_MAX_FOLDERS_PER_LEVEL` | | `100` | Folders per batch |
| `SHP_LEVEL_DELAY` | | `0.5` | Delay (s) between tree levels |
| `TRANSPORT` | | `stdio` | `stdio` or `http` |
| `HTTP_HOST` | | `0.0.0.0` | HTTP bind host |
| `HTTP_PORT` | | `8000` | HTTP port |
| `LOG_LEVEL` | | `INFO` | `DEBUG` `INFO` `WARNING` `ERROR` |
| `LOG_FORMAT` | | `console` | `console` or `json` |
---
## β οΈ Limitations
| Limitation | Details |
| --------------- | ----------------------------------------------------------------------------------------------------- |
| **Single site** | Connects to one SharePoint site per server instance (multi-site planned for v2.0) |
| **Sync client** | Uses synchronous SharePoint REST API calls (async client planned for v1.3) |
| **No sharing** | Cannot create sharing links yet (planned for v1.1) |
| **Large files** | Very large files may hit memory limits during content extraction |
| **Rate limits** | SharePoint throttling (429/503) is handled with auto-retry, but sustained bulk operations may be slow |
---
## π§ Troubleshooting
### Authentication Errors
**Problem:** `Missing or invalid SharePoint credentials`
**Solution:** Verify all 4 required environment variables are set:
```bash
echo $SHP_ID_APP $SHP_ID_APP_SECRET $SHP_TENANT_ID $SHP_SITE_URL
```
### Connection Issues (HTTP Transport)
**Problem:** Agent can't connect to the MCP server
**Solution:**
1. Ensure the server is running: `curl http://localhost:8000/mcp/`
2. Check the URL ends with `/mcp/` (trailing slash required)
3. Verify the port is not blocked by a firewall
### Docker Container Unhealthy
**Problem:** `podman ps` / `docker ps` shows `(unhealthy)`
**Solution:** Check container logs for errors:
```bash
docker logs sharepoint-mcp
```
### Debug Logging
Enable verbose output by setting `LOG_LEVEL=DEBUG`:
```bash
LOG_LEVEL=DEBUG sharepoint-mcp
```
For Docker, add to your `.env` file or `docker-compose.yml`:
```env
LOG_LEVEL=DEBUG
LOG_FORMAT=console
```
### Permission Errors
**Problem:** `Access denied` from SharePoint
**Solution:**
1. Verify the Azure AD app has the required API permissions
2. Ensure admin consent has been granted (if required by your org)
3. Confirm `SHP_SITE_URL` points to a site your app has access to
---
## π§ͺ Development
```bash
git clone https://github.com/ravikant1918/sharepoint-mcp.git
cd sharepoint-mcp
pip install -e ".[dev]"
make test # run all tests
make inspect # π launch MCP Inspector
make check # quick import sanity check
make clean # π§Ή remove caches
```
---
## π Documentation
| π Doc | π Description |
| --------------------------------------------- | ------------------------------- |
| [β‘ Getting Started](docs/getting-started.md) | Full setup guide |
| [βοΈ Configuration](docs/configuration.md) | All environment variables |
| [π οΈ Tools Reference](docs/tools-reference.md) | Detailed tool parameters |
| [ποΈ Architecture](docs/architecture.md) | Design and layer diagram |
| [π Azure Setup](docs/azure-setup.md) | Azure AD app registration guide |
| [πΊοΈ Roadmap](docs/roadmap.md) | Planned features |
| [π
Changelog](docs/changelog.md) | Version history |
---
## π€ Contributing
Contributions are welcome! Please read [docs/contributing.md](docs/contributing.md) and our [Code of Conduct](CODE_OF_CONDUCT.md).
1. π΄ Fork the repo
2. πΏ Create a branch: `git checkout -b feat/my-tool`
3. β
Add tests: `make test`
4. π¬ Open a Pull Request
---
## π Security
Found a vulnerability? Please **do not** open a public issue.
Report privately via [GitHub Security Advisories](https://github.com/ravikant1918/sharepoint-mcp/security/advisories/new) or see [SECURITY.md](SECURITY.md).
---
**MIT License Β© 2026 [Ravi Kant](https://github.com/ravikant1918)**
β If this project helps you, please star it on GitHub!