Skip to main content

Graph MCP

An MCP server that connects Claude to Microsoft Teams, Outlook Calendar, and Mail through the Microsoft Graph API.

What it does

Gives Claude access to 41 tools:

Category Tools
Auth Check status, login (browser OAuth), logout
Chats List chats, read/send messages, create chats, list members
Teams & Channels List teams, list channels, read/send messages, list members, read/send replies
Calendar List calendars, list/get events, create/update/delete events
Mail List emails, read email, search emails, send email, reply, list/get attachments
Meetings Find meeting by Join URL, list/get transcripts, list recordings, get recording URL
Files Browse OneDrive folders, search files, get content, upload files, create sharing links
Users Search organization directory
Presence Get/set your presence, get another user's presence
Search Search messages across all chats and channels

Prerequisites

You need an Azure App Registration:

  1. Go to Azure Portal > App registrations > New registration

  2. Set platform to Mobile and desktop applications

  3. Set redirect URI to http://localhost:3000/auth/callback

  4. Mark as Public client (no client secret needed)

  5. Under API permissions, add these delegated permissions:

    • offline_access, openid, profile, User.Read
    • User.ReadBasic.All
    • Chat.Read, Chat.ReadWrite, ChatMessage.Send
    • ChannelMessage.Read.All, ChannelMessage.Send
    • Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMember.Read.All
    • Calendars.ReadWrite
    • Mail.Read, Mail.Send
    • Presence.Read, Presence.Read.All, Presence.ReadWrite
    • OnlineMeetings.Read, OnlineMeetingTranscript.Read.All, OnlineMeetingRecording.Read.All
    • Files.ReadWrite.All

Install

pip install graph-mcp

Or from a cloned repo:

pip install -e .

Setup

graph-mcp setup

This asks for your Azure Client ID and Tenant ID, then gives you the exact command:

claude mcp add graph -e AZURE_CLIENT_ID=your-id -e AZURE_TENANT_ID=your-tenant -- /path/to/graph-mcp

Paste it, start Claude Code, and ask Claude to log in. It opens your browser for OAuth sign-in — that's it.

Message and email formatting

The Teams message tools (graph_send_chat_message, graph_send_channel_message, and graph_reply_to_channel_message) and outbound mail tools (graph_send_mail, graph_reply_mail) default to HTML mode. When is_html=true, pass explicit HTML and it will be sent as-is. Markdown is not converted automatically.

Use Teams/Graph-compatible HTML for formatted messages:

<p><strong>Status update</strong></p>
<ul>
  <li>Use <code>&lt;strong&gt;</code> for bold text.</li>
  <li>Use <code>&lt;pre&gt;&lt;code&gt;</code> for multi-line code blocks.</li>
  <li>Use placeholder text like <code>YOUR_NAME</code>, not <code>&lt;your-name&gt;</code>.</li>
</ul>

Use is_html=false for plain text bodies. Plain text is sent as exact text and is not formatted.

For email, the same rule applies: use explicit HTML when is_html=true, or plain text when is_html=false.

These tools also support optional top-level Graph API mentions, either in raw Graph format or a simplified shape such as:

[
  {
    "name": "Jane Smith",
    "user_id": "ef1c916a-3135-4417-ba27-8eb7bd084193"
  }
]

Use the corresponding <at id="0">Jane Smith</at> tag in the HTML body to trigger a real Teams mention.

How it works

Claude Code  ──stdio──>  graph-mcp  ──HTTPS──>  Microsoft Graph API
                              │
                         ~/.graph-mcp/
                           tokens.enc  (encrypted)
                           .key        (auto-generated)
  • Auth: OAuth2 Authorization Code flow with PKCE. Login opens your browser, a local callback server captures the token. No secrets stored in config.
  • Token persistence: Tokens are encrypted with Fernet and stored in ~/.graph-mcp/tokens.enc. The encryption key is auto-generated on first use. Logins survive server restarts.
  • Token refresh: Access tokens are refreshed automatically before they expire. You only need to log in again if the refresh token itself expires.
  • Rate limiting: Sliding window counter with exponential backoff. Respects Retry-After headers on 429 responses.

Configuration

All configuration is passed via environment variables (set in the MCP config's env block):

Variable Required Default Description
AZURE_CLIENT_ID Yes — From your Azure App Registration
AZURE_TENANT_ID No common Your Azure tenant ID, or common for multi-tenant
GRAPH_REDIRECT_URI No http://localhost:3000/auth/callback Must match Azure app registration
GRAPH_TOKEN_ENCRYPTION_KEY No auto-generated Fernet key for token encryption
GRAPH_DEBUG No false Enable verbose logging

Troubleshooting

"Approval required" error during login Your Azure app is requesting scopes that aren't registered or need admin consent. Check the API permissions in the Azure portal match the list above.

403 Forbidden on specific tools The endpoint needs a permission that's not in your Azure app registration, or requires admin consent.

Login works but tools say "not authenticated" Restart the MCP server (claude mcp restart graph) — it may be running an old version.

Disclaimer

This project is an independent open-source effort and is not affiliated with, endorsed by, or sponsored by Microsoft Corporation. Microsoft, Microsoft Teams, Outlook, Microsoft 365, Microsoft Graph, and Azure are trademarks of the Microsoft group of companies.

This software is provided "as is", without warranty of any kind. Use it at your own risk. The authors accept no liability for any damages, data loss, or security issues arising from the use of this software. You are responsible for complying with your organization's policies and Microsoft's API Terms of Use when using this tool.

This software accesses Microsoft services on your behalf using your own credentials and Azure app registration. Data retrieved from Microsoft Graph (emails, messages, calendar events, etc.) is passed to the LLM that invoked the tool. Be mindful of your organization's data handling policies when using this with cloud-hosted AI models.

License

MIT — see LICENSE.

Metadata

Release files for graph-mcp 0.5.1

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

Source distribution (sdist)

Source distribution for graph-mcp 0.5.1
File Size Uploaded Provenance
graph_mcp-0.5.1.tar.gz 20.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for graph-mcp 0.5.1
File Interpreter ABI Platform
graph_mcp-0.5.1-py3-none-any.whl Python 3 none any Details

Total release size: 48.8 kB

Release files / graph_mcp-0.5.1.tar.gz

Download URL graph_mcp-0.5.1.tar.gz
Size 20.7 kB
Tags Source
SHA-256 checksum
How to use checksums
324dd80b735a0aeeab3721d3314e75499f5164430b7b7bc1d819f0dcedd91f5c
BLAKE2b-256 checksum
How to use checksums
89c098395b139acbe28fd5ec92d30bd7554c958e4f2a22788e1ac618c7094909
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 10, 2026.

Transparency log

Release files / graph_mcp-0.5.1-py3-none-any.whl

Download URL graph_mcp-0.5.1-py3-none-any.whl
Size 28.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fe37cd593749aaa501f4ab0193fb360c9a643718ed8be11e644336a9145c63e6
BLAKE2b-256 checksum
How to use checksums
f16bbc09ab9a8e886fb12a5d26688d70ca32ee18b3e9db455255f6d8c60068bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 10, 2026.

Transparency log

Security for graph-mcp 0.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for graph_mcp-0.5.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 10, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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