M365 Graph MCP Server
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
M365 Graph MCP Server
@juvantlabs/m365-graph-mcp-server — Model Context Protocol server
wrapping the Microsoft Graph API for OneDrive, SharePoint, and Calendar
(read + write). Designed to be consumed by Juvant OS agents (or any
MCP-aware client) via npx.
Fulfills the m365-graph role per
docs/adr/0002-mcp-abstract-roles.md
in the handbook (concrete-only — Microsoft Graph is the single
provider). The scope of this server (files + calendar; no mail
send, no Teams chat) follows the threat-model boundary rule in
docs/adr/0003-mcp-server-scope-boundaries.md:
mail and Teams chat have materially different blast radius and would
ship as separate <vendor>-<capability>-mcp-server packages if a
real Juvant OS need surfaces; outbound Teams notifications go through
webhooks (Adaptive Cards), not MCP. Per-company instance config binds
this server in .juvant/config.json.
What's new
v0.7.0 — SharePoint document libraries. New read-only tool
m365-graph:list_sites finds the SharePoint sites you can access;
m365-graph:list_drives takes an optional site_id and returns that
site's document libraries. Their drive IDs work with every drive_id
parameter (list_items, search_files, download_file, upload_file,
create_folder, …). Without site_id, list_drives returns only your
OneDrive drives: Microsoft Graph's /me/drives does not include
SharePoint libraries in business tenants. No new scope:
Sites.ReadWrite.All, already requested, covers site discovery.
v0.6.0 — public-client auth, no client secret. The server now
signs in as an OAuth public client (authorization code + PKCE on a
loopback redirect, device code fallback). Required configuration is
the tenant ID and client ID only, and setup runs straight from npm.
Existing users: see § Migrating from v0.5.x.
Teams meeting transcript support. Two new read-only tools:
m365-graph:list_meeting_transcripts— given a calendar event ID, lists available post-meeting transcripts. Returns transcript IDs to pass toget_transcript.m365-graph:get_transcript— fetches the transcript content, strips VTT timing markers, and returns clean readable text.
Two new delegated scopes required (admin consent — see § Tools):
OnlineMeetings.Read and OnlineMeetingTranscript.Read.All.
Re-run setup after upgrading to acquire them.
See CHANGELOG.md for the full change list.
Related MCP server: Microsoft MCP
Status
Published. v0.4.0 on npm
(@juvantlabs/m365-graph-mcp-server),
released 2026-06-26. 19 tools across files (OneDrive + SharePoint),
Outlook Calendar, and Teams meeting transcripts. v0.4.1 is prepared
on main — adds create_folder (bringing the tool count to 20) and
fixes the consumeConfirmation gc-ordering bug; pending manual tag +
release trigger. Published via npm Trusted Publishing
(OIDC-based auth from GitHub Actions; no static NPM_TOKEN) with
provenance attestation; manual approval gate on the production
GitHub Environment guards the publish step.
Originally generated by
juvantlabs/juvant-tools
scaffold mcp-server on 2026-05-03, conforming to the
mcp-server.md
spec. See CHANGELOG.md for the per-version history.
Install + run
Nothing to clone. Register an Entra app once (§ Setup below), sign in once, then point your MCP client at the npm package:
# 1. One-time sign-in: opens the browser, caches tokens in the OS keychain
M365_TENANT_ID=<tenant-id> M365_CLIENT_ID=<client-id> \
npx -y @juvantlabs/m365-graph-mcp-server@0.8.0 setup
# 2. Register the server with Claude Code (or any MCP client)
claude mcp add m365-graph -s local \
-e M365_TENANT_ID=<tenant-id> \
-e M365_CLIENT_ID=<client-id> \
-- npx -y @juvantlabs/m365-graph-mcp-server@0.8.0Requires Node ≥ 20. The server is a public client: it holds no client secret. The tenant ID and client ID are identifiers, not credentials, so they can live in your MCP client configuration. The only sensitive material on disk is the MSAL token cache, kept in the OS keychain.
Environment variables
Required. Both setup and the server read them from the process
environment only; no file in the current directory is needed. No client
secret: since v0.6.0 a leftover secret variable is ignored and a
one-line deprecation warning is printed on stderr (see § Migrating from
v0.5.x).
Variable | Purpose |
| Microsoft Entra application (client) ID for the registered app. |
| Microsoft Entra tenant ID (UUID). The canonical adoption pattern is single-tenant — see ARCHITECTURE.md § Tenancy model. The regex also accepts |
Optional:
Variable | Purpose |
| Log level for diagnostics on stderr (default |
| Override the per-tenant sandbox directory used by |
| Max raw VTT bytes read from Graph per |
| Max parsed-text characters returned in a single |
CI enforces that every variable documented in this section is actually read from
process.env.<NAME>somewhere insrc/— placeholder names containing<>are skipped. Documenting an env var without wiring it up will fail the build (handbook anti-pattern S2).
OAuth scope minimization is per-tool; see the tool catalog
and ARCHITECTURE.md for the per-tool scope
justifications.
Binding
The Juvant OS adopter binds this server in .juvant/config.json:
{
"m365-graph": {
"provider": "microsoft",
"mcp_server": "npx -y @juvantlabs/m365-graph-mcp-server@0.8.0",
"scope": "rw"
}
}Pinning the version in mcp_server keeps installs reproducible.
Tools
Tool | Purpose | Input | Output | Required scope |
| Finds SharePoint sites the user can access (keyword search; |
|
|
|
| Without |
| without |
|
| Lists immediate children (files + folders) of a folder. Defaults to the drive root. |
|
|
|
| Searches files by name and content within a drive. |
|
|
|
| Downloads a file to a per-tenant local sandbox. Returns the local path; agent reads via a filesystem-aware tool. Streams, capped at 200 MB. With |
|
|
|
| Lists the user's calendars (primary + group / shared). |
|
|
|
| Lists events in a date window. Recurrences are expanded — each occurrence is its own event. |
|
|
|
| Searches events by subject substring (Graph $search isn't supported on Events; subject-only via |
|
|
|
| Fetches full details for a single event — body (capped at 8000 chars), attendees with response statuses, location, recurrence rule, online-meeting join URL when applicable. |
| event summary + |
|
| Uploads a local file to a drive. Auto-routes between single PUT (≤ 4 MB) and resumable upload session (> 4 MB, 10 MB chunks). 200 MB hard cap. |
|
|
|
| Creates a folder in a drive (OneDrive primary by default; SharePoint document library via |
|
|
|
| Creates a new event on the user's primary calendar (or a specified calendar). Sends invitations to attendees by Graph default. |
|
|
|
| Updates an existing event. All fields except |
|
|
|
| Async copy with polling. POSTs to |
|
|
|
| Synchronous move within a drive (PATCH parentReference). Cross-drive moves are not supported here — use copy_file + delete_file for those. |
|
|
|
| Two-phase spec/approval: 1st call returns preview + |
| preview |
|
| Two-phase like delete_file. Cancels a meeting the user organizes (sends cancellation notice to attendees). |
| preview or |
|
| Two-phase. Declines an event the user is invited to (as attendee — distinct from cancel which is for events the user organizes). Sends a decline RSVP unless |
| preview or |
|
| Subject + body content search via the Microsoft Search API (POST |
|
|
|
| List available transcripts for a Teams meeting identified by its calendar event ID. Transcripts are post-meeting only and require recording to have been enabled by the organizer. |
|
|
|
| Fetch the text content of a Teams meeting transcript. VTT timing markers are stripped; returns clean readable text. Long transcripts page via |
|
|
|
¹ Admin consent required. OnlineMeetings.Read and OnlineMeetingTranscript.Read.All must be granted in the Entra app registration under API permissions → Add a permission → Microsoft Graph → Delegated → Grant admin consent. Without admin consent these tools return 403 Forbidden.
That's 5 read + 5 write on files (including SharePoint site discovery), 5 read + 4 write on calendars, 2 read on meeting transcripts — 21 tools total. Read tools exercise delegated Files.Read + Calendars.Read; write tools require Files.ReadWrite + Calendars.ReadWrite; transcript tools require OnlineMeetings.Read + OnlineMeetingTranscript.Read.All (all separately granted + admin-consented in the Entra app).
Setup
1. Register a Microsoft Entra app
Azure Portal → Microsoft Entra ID → App registrations → New registration.
Name:
m365-graph-mcp-server(or your team's convention). Supported account types: single-tenant (see ARCHITECTURE.md § Tenancy model).Redirect URI: platform Public client/native (mobile & desktop), URI
http://localhost. Register. (On an existing app: Authentication → Add a platform → Mobile and desktop applications → custom redirect URIhttp://localhost.) Any port onhttp://localhostis accepted:setuplistens on a free port chosen at run time.Authentication → Allow public client flows: set to Yes only if you will use
setup --device-code(machines without a browser). Leave No otherwise.API permissions → Add a permission → Microsoft Graph → Delegated:
User.Read,Files.ReadWrite,Sites.ReadWrite.All,Calendars.ReadWrite,OnlineMeetings.Read,OnlineMeetingTranscript.Read.All,offline_access. Then Grant admin consent (required for the two transcript scopes, see § Tools).Certificates & secrets: nothing to create. The server never uses a client secret or certificate.
2. Sign in once (populate the keychain)
export M365_TENANT_ID=<tenant-id>
export M365_CLIENT_ID=<client-id>
npx -y @juvantlabs/m365-graph-mcp-server@0.8.0 setupsetup uses the OAuth 2.0 authorization code flow with PKCE: MSAL
starts a one-shot listener on a free port of 127.0.0.1, opens your
default browser at Microsoft's sign-in page (the URL is also printed on
stderr), receives the code on http://localhost:<port> and redeems it
with the PKCE verifier. Tokens are persisted via @napi-rs/keyring
(macOS Keychain / Linux Secret Service / Windows Credential Manager),
keyed by tenant ID, independent of the current directory. After that,
the server uses cached tokens silently and refreshes as needed.
On a machine without a browser, use the device code flow (requires Allow public client flows = Yes on the app):
npx -y @juvantlabs/m365-graph-mcp-server@0.8.0 setup --device-codeBecause the port is chosen at run time, setup can run while the
sibling m365-mail-mcp-server setup is also in progress.
SharePoint document libraries
list_sites { "query": "finance" } → site id
list_drives { "site_id": "<site id>" } → library drive ids
list_items / search_files / download_file / upload_file / create_folder
{ "drive_id": "<library drive id>", ... }3. Register the server with your MCP client
claude mcp add m365-graph -s local \
-e M365_TENANT_ID=<tenant-id> \
-e M365_CLIENT_ID=<client-id> \
-- npx -y @juvantlabs/m365-graph-mcp-server@0.8.0Other MCP clients: spawn npx -y @juvantlabs/m365-graph-mcp-server@0.8.0 over stdio with the same
environment variables.
Migrating from v0.5.x (client secret → public client)
Up to v0.5.x the server used a confidential client with a client secret
and a fixed http://localhost:3000/auth/callback Web redirect. v0.6.0
needs no secret. On your existing app registration:
Authentication → Add a platform → Mobile and desktop applications → custom redirect URI
http://localhost.Set Allow public client flows to Yes only if you will use
setup --device-code.Remove the old Web redirect
http://localhost:3000/auth/callback.Certificates & secrets → delete the client secret.
Remove
M365_CLIENT_SECRETfrom your MCP client configuration and any.env.local(if it is still set, the server ignores it and prints a one-line warning on stderr).Sign in again:
npx -y @juvantlabs/m365-graph-mcp-server@0.8.0 setup. A refresh token cached by v0.5.x was issued to a confidential client and may not be redeemable without the secret; signing in again replaces it in the same keychain entry. Until then, tool calls fail withSilent token acquisition failed: … Re-run … setup.Update the version pin in your MCP client configuration to
0.8.0(or later).
If setup fails with AADSTS7000218 (the request body must contain
client_assertion or client_secret), the app still treats the
redirect as a Web (confidential) client: add the Mobile and desktop
applications platform (step 1); for --device-code, also set
Allow public client flows = Yes.
Local development
npm install
cp .env.example .env.local # tenant ID + client ID; gitignored
npm run setup # = tsx --env-file=.env.local src/index.ts setup
npm run dev # stdio server from source.env.local is only a convenience for the npm run setup / npm run dev scripts in a checkout. The published package never reads it.
Architecture
See ARCHITECTURE.md for design rationale: scope,
OAuth model with @azure/msal-node, token persistence via
@napi-rs/keyring, per-tool scope minimization, filesystem sandboxing
for upload/download tools, and async-op polling for copy / move.
Contributing
See CONTRIBUTING.md. The repo follows the
juvantlabs/handbook
conventions for MCP server repos.
Security
See SECURITY.md for the disclosure process. Per the
handbook security disclosure process,
report vulnerabilities privately via GitHub Security Advisory or
security@juvant.io.
License
MIT. Copyright (c) 2026 Juvant Srls.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Model Context Protocol server for Studex tools, notifications, and profile integrations
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
A Model Context Protocol server for Wix AI tools
Related MCP Servers
- AlicenseBqualityAmaintenanceA Model Context Protocol server that enables interaction with Microsoft 365 services (Excel, Calendar, Mail, OneDrive, Teams, etc.) through the Graph API, allowing AI assistants to manage Microsoft 365 resources via natural language.20388,164 npm1,132MIT
- AlicenseNot gradedqualityDmaintenanceModel Context Protocol servers for Microsoft 365, enabling AI assistants to interact with Calendar, Contacts, OneDrive, Outlook, and SharePoint via the Microsoft Graph API.MIT
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol server for SharePoint file and folder management using Microsoft Graph API. Enables listing, uploading, downloading, and converting documents with markdown-to-DOCX support.-
- FlicenseNot gradedqualityBmaintenanceA Model Context Protocol (MCP) server for interacting with Microsoft 365 and Microsoft Office services through the Graph API.-