Files
Claude-SharepointLists/mcp-server/README.md
ang3l12 a4384655d0 README accuracy pass: fix mcp-remote header pattern, add skill install steps
The Desktop config examples showed an inline 'Authorization: Bearer ...' header, which Claude Desktop breaks by splitting args on spaces — replace with the verified env-var pattern (Authorization:${MCP_AUTH_HEADER}, no space). Also: document how the skill is installed/discovered in Claude Code, note the person command in the CLI summary, and correct /health description (it now reports the secret-expiry countdown).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 19:16:38 -06:00

4.7 KiB

sharepoint-lists MCP server

An MCP server exposing Microsoft SharePoint Lists as tools, using app-only (client-credentials) Microsoft Graph auth. It reuses the same core client as the skill (../.claude/skills/sharepoint-lists/scripts/lib/graph.mjs) — one source of truth for the Graph logic.

Transports

Transport Use How the client connects
stdio (default) local Claude apps on the same machine the app launches node index.mjs
Streamable HTTP (--http) hosted in a container, reached over the network client → HTTP POST /mcp (bearer token)

stdio is for same-machine use. To run as a hosted service (e.g. Docker on another box), use the HTTP transport — a stdio client can't attach to a process on a different machine.

Tools

Tool Access Purpose
sharepoint_test read Verify credentials; with a site, list its lists
sharepoint_list_lists read Enumerate lists in a site
sharepoint_get_columns read Column internal names + types (call before writing)
sharepoint_list_items read Query items (filter/select/orderby/top/all)
sharepoint_get_item read Get one item by id
sharepoint_resolve_person read Email → the LookupId person columns store (for writes)
sharepoint_create_item write Create an item
sharepoint_update_item write Update an item (partial)
sharepoint_delete_item write Delete an item (irreversible)

Set SP_READONLY=true to register only the read tools.

Configuration

Credentials come from the environment or mcp-server/.env (git-ignored). See .env.example and ../.claude/skills/sharepoint-lists/references/setup.md.

Var Required Notes
SP_TENANT_ID / SP_CLIENT_ID / SP_CLIENT_SECRET yes app registration
SP_SITE_URL no default site so tools can omit site
SP_SECRET_EXPIRES no client secret's expiry date (YYYY-MM-DD); warns at startup, in /health, and in sharepoint_test when <30 days remain
SP_READONLY no true → read-only tool set
MCP_AUTH_TOKEN HTTP only shared bearer token required on /mcp; empty = unauthenticated
PORT HTTP only listen port (default 3838)

Run locally

cd mcp-server
npm install
cp .env.example .env      # fill in credentials
npm start                 # stdio
npm run start:http        # Streamable HTTP on :3838

Run as a container (Docker Compose)

From the repo root (the build context needs the shared graph.mjs):

# 1. Create mcp-server/.env with SP_* creds + a token:
#    echo "MCP_AUTH_TOKEN=$(openssl rand -hex 32)" >> mcp-server/.env
# 2. Build + start:
docker compose up -d --build
# 3. Check:
curl -s http://localhost:3838/health           # {"ok":true,...}

The service restarts automatically and has a healthcheck. The port is published on all interfaces; restrict it in docker-compose.yml (or via firewall) and rely on MCP_AUTH_TOKEN for auth.

Connect a client

Claude Desktop → remote HTTP server (via mcp-remote)

Desktop speaks stdio, so bridge to the remote HTTP server with mcp-remote in ~/Library/Application Support/Claude/claude_desktop_config.json, then restart Desktop:

{
  "mcpServers": {
    "sharepoint-lists": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "http://192.168.101.12:3838/mcp",
        "--allow-http",
        "--header", "Authorization:${MCP_AUTH_HEADER}"
      ],
      "env": { "MCP_AUTH_HEADER": "Bearer <your MCP_AUTH_TOKEN>" }
    }
  }
}

--allow-http permits the plain-HTTP LAN URL (no TLS). The token must match the container's MCP_AUTH_TOKEN. The header value goes through the env var (with the Bearer prefix) and there is no space after Authorization: — Claude Desktop splits config args on spaces, so an inline Bearer <token> breaks.

Claude Desktop → local stdio (no container)

{
  "mcpServers": {
    "sharepoint-lists": {
      "command": "/opt/homebrew/bin/node",
      "args": ["/absolute/path/to/Claude-SharepointLists/mcp-server/index.mjs"]
    }
  }
}

Claude Code

The repo-root .mcp.json registers the local stdio server automatically.

Security notes

  • App-only auth = the server has full access to the granted SharePoint sites with no per-user check. Anyone who can reach an unauthenticated /mcp has that access — always set MCP_AUTH_TOKEN for the HTTP transport.
  • /health is intentionally unauthenticated (liveness + secret-expiry countdown only; no secrets).
  • Field formats for writes (person/lookup/choice/date) are in ../.claude/skills/sharepoint-lists/references/graph-api.md.