MCP-Local-SharePoint-Server-Setup
README.md
# Corporate SharePoint MCP — Finance Pilot M005L
This milestone keeps the MCP service local and read-only while using a OneDrive shortcut to expose an approved SharePoint folder under the signed-in Windows user's existing SharePoint access.
## Added in M005L
- `sharepoint_list_folder` (filters local OneDrive clutter such as `desktop.ini`)
- `sharepoint_inspect_excel`
- `sharepoint_read_excel_range`
- `.xlsx` only for this milestone
- 100 MiB (configurable with `EXCEL_MAX_FILE_SIZE_MB`) workbook cap
- range requests capped at 100 rows × 30 columns
- Excel opened using `openpyxl` read-only mode with cached formula values (`data_only=True`)
- all file paths must resolve beneath `SHAREPOINT_SYNC_ROOT`
- no create/update/delete/move/rename tools
## Install/update dependencies
```powershell
pip install -r .\requirements.txt
```
## Run tests
```powershell
$env:PYTHONPATH = "$PWD\src"
pytest -q
```
## Run server
```powershell
python -m sharepoint_mcp.server
```
## Test the real synced workbook
In a second PowerShell window:
```powershell
.\.venv\Scripts\Activate.ps1
$env:PYTHONPATH = "$PWD\src"
python .\scripts\test_excel_reader.py
```
The script expects `SalesDelivery Note.xlsx` in the configured root. It inspects the workbook, reads `A1:J10` from the first worksheet, and confirms `../` remains blocked.
## M006L - Safe document discovery
This milestone adds `sharepoint_search_files`, a recursive metadata-only search
inside `SHAREPOINT_SYNC_ROOT`.
It searches:
- file names
- approved-root-relative paths
It deliberately does **not** open file contents during discovery. This avoids
hydrating or parsing large OneDrive-backed workbooks simply to locate them.
Example:
```text
sharepoint_search_files(
query="sales delivery",
extension="xlsx",
max_results=10
)
```
The tool:
- remains read-only
- blocks `../` traversal
- ignores `desktop.ini`, `Thumbs.db`, and temporary `~$` Office files
- caps a request at 50 returned results
- caps one scan at 10,000 files
- returns relative paths rather than exposing the full local Windows path
Run:
```powershell
pytest -q tests
python .\scripts\test_document_search.py
```
## M007L - Content-aware Excel querying
Adds two read-only tools:
- `sharepoint_get_excel_columns`
- `sharepoint_find_excel_rows`
The first discovers every named header in a worksheet. The second scans a
bounded number of rows and returns matching records using one named business
column.
Safety limits:
- SharePoint sync root sandbox still enforced
- `.xlsx` only
- workbook opened read-only
- at most 500,000 rows scanned per request
- at most 100 matching rows returned
- at most 20 returned columns
- no edit, rename, move, delete, or upload capability
Example:
```text
sharepoint_find_excel_rows(
relative_path="SalesDelivery Note.xlsx",
sheet_name="Data",
column_name="Packing Slip",
search_value="GRP0000124",
match_mode="equals",
return_columns_csv="Product Id,Packing Slip,Quantity"
)
```
Live test:
```powershell
pytest -q tests
python .\scripts\test_excel_content_query.py
```
## M007.1 - Query completeness and continuation
This patch prevents a partial worksheet scan from being mistaken for a complete
answer.
`sharepoint_find_excel_rows` now returns:
- `scan_complete`
- `next_start_row`
- `worksheet_max_row`
The default scan allowance is now 500,000 rows, enough to cover the current
443,759-row Finance workbook in one call. If a future worksheet exceeds the
bounded scan or the result cap is reached, Claude can continue with
`start_row=next_start_row`.
The reader also narrows the streamed Excel column window to only the filter
column and requested output columns, reducing unnecessary work on wide sheets.
Run:
```powershell
pytest -q tests
python .\scripts\test_excel_content_query.py
```
## M008L - Multi-condition Finance queries and aggregations
Adds:
- `sharepoint_query_excel`
- `sharepoint_aggregate_excel`
Multi-condition filters are passed as a bounded JSON array, for example:
```json
[
{"column":"Business Unit","operator":"equals","value":"Dean"},
{"column":"Delivery Date","operator":"gte","value":"2026-01-01"},
{"column":"Delivery Date","operator":"lte","value":"2026-12-31"}
]
```
Supported filter operators:
- equals / not_equals
- contains / starts_with / ends_with
- gt / gte / lt / lte
- is_blank / is_not_blank
Aggregations:
- count
- sum
- avg
- min
- max
- optional group_by_column
Guardrails:
- maximum 8 filter conditions
- maximum 500,000 scanned rows
- maximum 100 returned query rows
- maximum 20 returned columns
- maximum 100 aggregation groups
- aggregations refuse partial scans
- strict SharePoint sync-root sandbox
- `.xlsx` only
- read-only; no write/delete/move/upload tools
Run:
```powershell
pytest -q tests
python .\scripts\test_finance_multiquery.py
```
## M009L - Claude Desktop local connection
Adds a dedicated local stdio transport entry point:
```text
python -m sharepoint_mcp.desktop
```
The HTTP development server remains available separately:
```text
python -m sharepoint_mcp.server
```
Claude Desktop should launch the stdio process itself, so port 8000 is not
required for the Desktop connection.
Generate a machine-specific config snippet:
```powershell
$env:PYTHONPATH = "$PWD\\src"
python .\\scripts\\show_claude_desktop_config.py
```
The generated JSON contains local executable/folder paths and read-only pilot
settings only. It does not include Entra secrets.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues