Skip to main content

mcp-microsoft-graph-auth

Shared Microsoft Graph authentication helpers for MCP servers.

PyPI version CI Python License: MIT OR Apache-2.0

Why this exists

mcp-server-sharepoint and mcp-server-outlook (and likely future siblings — Teams, OneDrive, …) all need the same auth machinery against Microsoft Graph: OAuth Device Code flow, token cache with sensible storage backends, optional service-principal mode, multi-profile support.

This library factors that machinery out so each MCP server adds only what's specific to its API surface (scopes + tool names), not yet another reimplementation of Device Code + token storage.

What's in the box

  • device_code — primitives for the OAuth 2.0 Device Code flow against Microsoft Identity v2.0 (request_device_code, poll_for_token, refresh_access_token).
  • service_principal — client-credentials grant for unattended automation (CI runners, scheduled jobs).
  • token_store — three pluggable storage backends:
    • OS keyring (macOS Keychain / Windows Credential Locker / Linux Secret Service) when available.
    • Plain file mode 0600 (~/.cache/<your-app>/<profile>/token.json) — same convention as gh auth, aws configure.
    • Encrypted file with passphrase (Fernet + Scrypt KDF) for paranoid setups or shared CI cache.
  • tokens — CachedToken dataclass with sensible JSON serialisation.
  • login_session — LoginSession + LoginSessionRegistry for MCP-tool-driven login flows (the in-process state your *_login_begin / *_login_status tools share).

Public API contract

The library is prefix-agnostic: it does not read environment variables on its own. Each consumer (an MCP server) is responsible for reading its own env-var conventions and passing values explicitly. This keeps the library reusable by any MCP server without env-var collisions.

Minimal sketch (subject to v0.1.0 release)

from mcp_microsoft_graph_auth import (
    request_device_code,
    poll_for_token,
    refresh_access_token,
    CachedToken,
    PlainFileTokenStore,
)

# Initiate Device Code flow
device_code, challenge = request_device_code(
    client_id="<your-app-id>",
    tenant="organizations",  # or a specific tenant GUID
    scopes=("Files.ReadWrite.All", "Sites.ReadWrite.All", "User.Read", "offline_access"),
)
print(f"Open {challenge.verification_uri} and enter code {challenge.user_code}")

# Poll until the user completes sign-in
token = poll_for_token(
    device_code=device_code,
    client_id="<your-app-id>",
    interval=challenge.interval,
)

# Persist for later
store = PlainFileTokenStore(base_dir="~/.cache/my-mcp-server")
store.set("default", token.to_json().encode())

UX guidance for relaying the verification URL + user code

When an MCP server wraps the Device Code flow as a tool (e.g. sp_login_begin returns {verification_url, user_code, ...}), the tool's description should tell the agent how to render those two values to the user. Mobile / smartphone agent UIs are strict about both shape and ordering:

  • user_code first, alone in its own one-line code block, with no labels like Code: and no whitespace padding. Long-press / tap-and-hold copy then yields just the code.
  • verification_url second, on its own line as a plain Markdown auto-link, not inside a code block (code blocks suppress link rendering, so on mobile the user can't tap it).

Why this ordering: the user's optimal workflow is copy the code → click the link → paste the code into the page that just opened. With the code first, the clipboard is loaded before the user leaves the chat. URL-first would force a chat-↔-browser ping-pong.

Recommended verbatim phrasing for the tool's MCP description:

When surfacing the result to the user, render user_code FIRST in its own code block (no labels, no whitespace) and verification_url SECOND as a plain auto-link (not in a code block). The user copies the code first, then clicks the link, and pastes into the page that opens — minimises app-switching on mobile.

The CLI fallback (mcp-server-<svc> login) prints URL: / Code: labels in URL-then-Code order because terminals don't have rich rendering — that format is correct for stderr and wrong to relay verbatim into chat.

Compatibility

  • Python 3.11+
  • Microsoft Identity v2.0 endpoints
  • Tested on Linux + macOS (Windows should work; not yet covered by CI)

License

Dual-licensed under MIT or Apache-2.0 at your option. See LICENSE-MIT and LICENSE-APACHE.

Status

Pre-1.0. The public API is stable enough for use by mcp-server-sharepoint and mcp-server-outlook — the two consumers driving its design. External consumption is welcome but expect occasional breaking changes until v1.0.

See docs/RELEASING.md for release process and CHANGELOG.md for what's shipped.

Metadata

Release files for mcp-microsoft-graph-auth 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-microsoft-graph-auth 0.1.2
File Size Uploaded
mcp_microsoft_graph_auth-0.1.2.tar.gz 104.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-microsoft-graph-auth 0.1.2
File Interpreter ABI Platform
mcp_microsoft_graph_auth-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 131.3 kB

Release files / mcp_microsoft_graph_auth-0.1.2.tar.gz

Download URL mcp_microsoft_graph_auth-0.1.2.tar.gz
Size 104.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c8ea70229e2ad27fb3119d27b73986736354124270cc0c10534b75b8d6d7a149
BLAKE2b-256 checksum
How to use checksums
a5151162e4ac811d81482a9078e903116b8dd39f34baecde5c47cf45b5903a93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mcp_microsoft_graph_auth-0.1.2-py3-none-any.whl

Download URL mcp_microsoft_graph_auth-0.1.2-py3-none-any.whl
Size 27.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
20cb4e62c7c2f9ac867d92c980addd3dfdb6af60d4048c79ebf6cd40b5c6a023
BLAKE2b-256 checksum
How to use checksums
a1220df51a4ae4deb3ce3d5c3eb19c73774843f568fa6ef2897595e5a0eea8cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page