Metadata-Version: 2.4
Name: mcp-microsoft-graph-auth
Version: 0.1.0
Summary: Shared Microsoft Graph auth helpers (Device Code, token cache, BYO client) for MCP servers.
Project-URL: Homepage, https://github.com/XMV-Solutions-GmbH/mcp-microsoft-graph-auth
Project-URL: Repository, https://github.com/XMV-Solutions-GmbH/mcp-microsoft-graph-auth
Project-URL: Issues, https://github.com/XMV-Solutions-GmbH/mcp-microsoft-graph-auth/issues
Project-URL: Changelog, https://github.com/XMV-Solutions-GmbH/mcp-microsoft-graph-auth/blob/main/CHANGELOG.md
Author-email: XMV Solutions GmbH <oss@xmv.de>
Maintainer-email: David Koller <david.koller@xmv.de>
License-Expression: MIT OR Apache-2.0
License-File: LICENSE-APACHE
License-File: LICENSE-MIT
Keywords: device-code,mcp,microsoft-graph,model-context-protocol,oauth
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
Requires-Python: >=3.11
Requires-Dist: cryptography>=42
Requires-Dist: httpx>=0.28
Requires-Dist: keyring>=25
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

<!--
SPDX-License-Identifier: MIT OR Apache-2.0
SPDX-FileCopyrightText: 2026 XMV Solutions GmbH
SPDX-FileContributor: David Koller <david.koller@xmv.de>
-->

# mcp-microsoft-graph-auth

Shared Microsoft Graph authentication helpers for [MCP](https://modelcontextprotocol.io) servers.

[![PyPI version](https://img.shields.io/pypi/v/mcp-microsoft-graph-auth.svg)](https://pypi.org/project/mcp-microsoft-graph-auth/)
[![CI](https://github.com/XMV-Solutions-GmbH/mcp-microsoft-graph-auth/actions/workflows/ci.yml/badge.svg)](https://github.com/XMV-Solutions-GmbH/mcp-microsoft-graph-auth/actions/workflows/ci.yml)
[![Python](https://img.shields.io/pypi/pyversions/mcp-microsoft-graph-auth.svg)](https://pypi.org/project/mcp-microsoft-graph-auth/)
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/License-MIT_OR_Apache--2.0-blue.svg)](LICENSE-MIT)

## Why this exists

[`mcp-server-sharepoint`](https://github.com/XMV-Solutions-GmbH/sharepoint-mcp) and [`mcp-server-outlook`](https://github.com/XMV-Solutions-GmbH/outlook-mcp) (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)

```python
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())
```

## 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](LICENSE-MIT) and [LICENSE-APACHE](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`](docs/RELEASING.md) for release process and [`CHANGELOG.md`](CHANGELOG.md) for what's shipped.
