# Microsoft Graph API Setup Guide
Complete guide to configure Microsoft Graph API access for the msgraph-mcp server.
## Table of Contents
1. [Prerequisites](#prerequisites)
2. [Azure AD App Registration](#azure-ad-app-registration)
3. [Configure API Permissions](#configure-api-permissions)
4. [Create Client Secret](#create-client-secret)
5. [Get Your Credentials](#get-your-credentials)
6. [Configure the MCP Server](#configure-the-mcp-server)
7. [Test Your Setup](#test-your-setup)
8. [Troubleshooting](#troubleshooting)
---
## Prerequisites
### Required Access
- **Azure AD Admin Access**: You need Global Administrator or Application Administrator role
- **Microsoft 365 Tenant**: Access to a Microsoft 365 organization
- **Claude Code**: Claude Code CLI installed and configured
### What You'll Need
- Azure Portal account (https://portal.azure.com)
- 15-20 minutes for setup
- Admin consent capability for your M365 tenant
---
## Azure AD App Registration
### Step 1: Access Azure Portal
1. Navigate to **Azure Portal**: https://portal.azure.com
2. Sign in with your Microsoft 365 admin account
3. Search for "**Azure Active Directory**" or "**Microsoft Entra ID**" in the top search bar
4. Click on **Azure Active Directory**
### Step 2: Register a New Application
1. In the left sidebar, click **App registrations**
2. Click **+ New registration** at the top
3. Fill in the application details:
| Field | Value |
|-------|-------|
| **Name** | `M365 Graph MCP` (or your preferred name) |
| **Supported account types** | **Accounts in this organizational directory only (Single tenant)** |
| **Redirect URI** | Leave blank (not needed for MCP server) |
4. Click **Register**
### Step 3: Note Your Application IDs
After registration, you'll see the **Overview** page. **SAVE THESE VALUES**:
- **Application (client) ID**: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
- **Directory (tenant) ID**: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
**Important**: Keep these values handy - you'll need them for configuration.
---
## Configure API Permissions
### Step 1: Access API Permissions
1. In your app registration, click **API permissions** in the left sidebar
2. You'll see `User.Read` (delegated) by default - we'll add application permissions
### Step 2: Add Microsoft Graph Permissions
Click **+ Add a permission**, then:
1. Select **Microsoft Graph**
2. Choose **Application permissions** (NOT Delegated permissions)
3. Search and select the following permissions:
#### Required Permissions
| Permission | Purpose | Category |
|------------|---------|----------|
| `Sites.Read.All` | Read SharePoint sites and content | SharePoint |
| `Files.Read.All` | Read all files in all site collections | SharePoint/OneDrive |
| `Mail.Read` | Read mail in all mailboxes | Outlook |
| `ChannelMessage.Read.All` | Read all channel messages | Teams |
| `Chat.Read.All` | Read all chat messages | Teams |
| `Calendars.Read` | Read calendars in all mailboxes | Calendar |
| `User.Read.All` | Read all users' full profiles | Directory |
| `Group.Read.All` | Read all groups | Teams/Groups |
#### How to Add Each Permission
For **each** permission above:
1. Click **+ Add a permission**
2. Select **Microsoft Graph**
3. Select **Application permissions**
4. Search for the permission name (e.g., `Sites.Read.All`)
5. Check the checkbox next to the permission
6. Click **Add permissions** at the bottom
Repeat until all 8 permissions are added.
### Step 3: Grant Admin Consent
**CRITICAL STEP**: Application permissions require admin consent.
1. After adding all permissions, click **✓ Grant admin consent for [Your Organization]**
2. Click **Yes** to confirm
3. Verify that all permissions show **Granted for [Your Organization]** in green
**Why Admin Consent?**
- Application permissions access data across all users
- Requires admin approval for security reasons
- Without consent, API calls will fail with "Insufficient privileges"
---
## Create Client Secret
### Step 1: Access Certificates & Secrets
1. In your app registration, click **Certificates & secrets** in the left sidebar
2. Under **Client secrets**, click **+ New client secret**
### Step 2: Create the Secret
1. **Description**: Enter a meaningful name (e.g., `msgraph-mcp-secret`)
2. **Expires**: Choose expiration period
- **Recommended**: `24 months` (maximum for most tenants)
- **6 months**: If your organization requires frequent rotation
- **Custom**: If you need a specific date
3. Click **Add**
### Step 3: Copy the Secret Value
**CRITICAL**: The secret value is shown ONLY ONCE.
1. After creation, you'll see the secret with a **Value** column
2. Click the **Copy** icon next to the Value
3. **Save this value immediately** in a secure location
**Important Notes**:
- The secret is visible only immediately after creation
- If you lose it, you must create a new secret
- Treat this like a password - never commit to git or share publicly
- The secret expires - set a calendar reminder to renew before expiration
**Secret Format**: `abc~defGHI1234567890-_XYZabc123`
---
## Get Your Credentials
You should now have **three** pieces of information:
### 1. Client ID (Application ID)
- **Location**: App registration → Overview
- **Format**: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
- **Example**: `8637b5cc-de74-44b2-aa77-40c56842370b`
### 2. Tenant ID (Directory ID)
- **Location**: App registration → Overview
- **Format**: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
- **Example**: `dd6e92ae-a64d-498c-a43b-61d1b30d6955`
### 3. Client Secret (Secret Value)
- **Location**: App registration → Certificates & secrets (copied when created)
- **Format**: `abc~defGHI1234567890-_XYZabc123`
- **Security**: NEVER commit to git, share, or expose publicly
---
## Configure the MCP Server
### Step 1: Install the MCP Server
```bash
# Clone or download the repository
git clone https://github.com/eesb99/msgraph-mcp.git
cd msgraph-mcp
# Install Python dependencies
pip install -r requirements.txt
```
Or if installing to Claude's MCP directory:
```bash
# Create directory
mkdir -p ~/.claude/mcp-servers/msgraph-mcp
cd ~/.claude/mcp-servers/msgraph-mcp
# Clone repository
git clone https://github.com/eesb99/msgraph-mcp.git .
# Install dependencies
pip install -r requirements.txt
```
### Step 2: Configure Environment Variables
You have two options for storing credentials:
#### Option A: Environment Variables (Recommended for Testing)
Create a `.env` file in the msgraph-mcp directory:
```bash
# Create .env file (will be gitignored)
cat > .env << 'EOF'
AZURE_CLIENT_ID=your-client-id-here
AZURE_TENANT_ID=your-tenant-id-here
AZURE_CLIENT_SECRET=your-client-secret-here
EOF
```
Replace the placeholder values with your actual credentials.
**Security Note**: The `.env` file is automatically excluded by `.gitignore`.
#### Option B: Claude Code Configuration (Recommended for Production)
Edit your Claude Code configuration file `~/.claude.json`:
```json
{
"mcpServers": {
"msgraph-mcp": {
"type": "stdio",
"command": "python3",
"args": ["/Users/YOUR_USERNAME/.claude/mcp-servers/msgraph-mcp/server.py"],
"env": {
"AZURE_CLIENT_ID": "your-client-id-here",
"AZURE_TENANT_ID": "your-tenant-id-here",
"AZURE_CLIENT_SECRET": "your-client-secret-here"
}
}
}
}
```
**Replace**:
- `YOUR_USERNAME` with your actual username
- `your-client-id-here` with your Application (client) ID
- `your-tenant-id-here` with your Directory (tenant) ID
- `your-client-secret-here` with your Client secret value
**Path Note**: Adjust the path in `args` to match where you installed msgraph-mcp.
### Step 3: Verify Configuration File Permissions
Ensure your configuration files have restricted permissions:
```bash
# Secure .claude.json (contains secrets)
chmod 600 ~/.claude.json
# Secure .env if using Option A
chmod 600 ~/.claude/mcp-servers/msgraph-mcp/.env
```
This prevents other users on your system from reading your credentials.
---
## Test Your Setup
### Step 1: Restart Claude Code
After configuring credentials, restart Claude Code to load the MCP server:
```bash
# Exit Claude Code
# Restart Claude Code
```
### Step 2: Test Connection
In Claude Code, run the following test:
```python
# Test basic connectivity
result = msgraph.test_connection()
print(result)
```
**Expected Output**:
```json
{
"status": "success",
"message": "Successfully authenticated with Microsoft Graph API",
"token_acquired": true
}
```
### Step 3: Test Each Service
#### Test SharePoint Access
```python
# Search for sites
result = msgraph.search_sites("SharePoint", limit=5)
print(result)
```
#### Test User Directory Access
```python
# List users
result = msgraph.list_users(limit=5)
print(result)
```
#### Test Outlook Access
```python
# List recent emails for a user
result = msgraph.list_recent_emails("user@yourdomain.com", limit=5)
print(result)
```
#### Test Teams Access
```python
# List teams
result = msgraph.list_teams(limit=10)
print(result)
```
#### Test Calendar Access
```python
# List upcoming events
result = msgraph.list_events("user@yourdomain.com", days_ahead=7)
print(result)
```
### Step 4: Verify Read-Only Access
The MCP server has **read-only** permissions. Attempting write operations will fail:
```python
# This should fail (no write permissions)
# msgraph does not expose write functions
```
---
## Troubleshooting
### Common Issues and Solutions
#### Issue 1: "Insufficient privileges to complete the operation"
**Cause**: Admin consent not granted
**Solution**:
1. Go to Azure Portal → App registrations → Your app
2. Click **API permissions**
3. Verify all permissions show "Granted for [Organization]"
4. If not, click "Grant admin consent" and approve
#### Issue 2: "AADSTS7000215: Invalid client secret provided"
**Cause**: Client secret is incorrect or expired
**Solution**:
1. Check that your client secret is copied correctly (no extra spaces)
2. Go to Azure Portal → App registrations → Certificates & secrets
3. Check if the secret is expired
4. If expired, create a new secret and update your configuration
#### Issue 3: "AADSTS700016: Application not found"
**Cause**: Client ID or Tenant ID is incorrect
**Solution**:
1. Go to Azure Portal → App registrations → Your app → Overview
2. Verify your Application (client) ID
3. Verify your Directory (tenant) ID
4. Update your configuration with correct values
#### Issue 4: "ModuleNotFoundError: No module named 'msal'"
**Cause**: Python dependencies not installed
**Solution**:
```bash
cd ~/.claude/mcp-servers/msgraph-mcp
pip install -r requirements.txt
```
#### Issue 5: "Connection timeout" or "Network error"
**Cause**: Firewall or proxy blocking Microsoft Graph API
**Solution**:
1. Verify internet connectivity
2. Check if your network allows HTTPS connections to `*.microsoft.com` and `*.microsoftonline.com`
3. If behind a corporate proxy, configure proxy settings:
```bash
export HTTPS_PROXY=http://proxy.company.com:8080
```
#### Issue 6: MCP server not loading in Claude Code
**Cause**: Configuration error in ~/.claude.json
**Solution**:
1. Validate JSON syntax in ~/.claude.json (use jsonlint.com)
2. Check that the path to server.py is correct and absolute
3. Verify Python 3 is available: `which python3`
4. Check Claude Code logs for error messages
### Verify Token Acquisition
If experiencing authentication issues, enable debug logging:
```python
# Add to your test script
import logging
logging.basicConfig(level=logging.DEBUG)
result = msgraph.test_connection()
```
Look for:
- Token acquisition success/failure
- Specific error codes (AADSTS*)
- Network connectivity issues
### Check Permission Scope
Verify your app has the correct permissions:
```bash
# Use Microsoft Graph Explorer
# Visit: https://developer.microsoft.com/graph/graph-explorer
# Try a test query with your token
GET https://graph.microsoft.com/v1.0/me
```
If Graph Explorer works but MCP doesn't, the issue is likely in the MCP configuration.
---
## Security Best Practices
### Credential Management
1. **Never commit secrets**:
- Use `.gitignore` to exclude `.env` files
- Never hardcode credentials in source code
- Use environment variables or secure vaults
2. **Rotate secrets regularly**:
- Set calendar reminders before expiration
- Create new secret before old one expires
- Update configuration atomically
3. **Limit access**:
- Use principle of least privilege
- Grant only required permissions
- Review permissions periodically
### Monitoring and Auditing
1. **Azure AD Sign-in Logs**:
- Monitor app authentication attempts
- Review unusual access patterns
- Set up alerts for failed authentications
2. **Audit Logs**:
- Review which data the app accesses
- Monitor for unexpected behavior
- Regular security reviews
### Token Security
- Tokens are cached in memory (never written to disk)
- Automatic token refresh before expiration
- Tokens are never exposed to Claude or logged
- Each token has 1-hour validity (automatically managed)
---
## Advanced Configuration
### Custom Token Cache Location
By default, tokens are cached in memory. To use persistent cache:
```python
# Not recommended for security reasons, but available if needed
# Add to server.py configuration
TOKEN_CACHE_PATH = "/secure/path/token_cache.bin"
```
### Custom Timeout Settings
Adjust API timeout in `graph_client.py`:
```python
# Default: 30 seconds
TIMEOUT = 30
```
### Multiple Tenants
To access multiple Microsoft 365 tenants, create separate MCP server instances:
```json
{
"mcpServers": {
"msgraph-tenant1": {
"type": "stdio",
"command": "python3",
"args": ["/path/to/msgraph-mcp/server.py"],
"env": {
"AZURE_CLIENT_ID": "tenant1-client-id",
"AZURE_TENANT_ID": "tenant1-tenant-id",
"AZURE_CLIENT_SECRET": "tenant1-secret"
}
},
"msgraph-tenant2": {
"type": "stdio",
"command": "python3",
"args": ["/path/to/msgraph-mcp/server.py"],
"env": {
"AZURE_CLIENT_ID": "tenant2-client-id",
"AZURE_TENANT_ID": "tenant2-tenant-id",
"AZURE_CLIENT_SECRET": "tenant2-secret"
}
}
}
}
```
---
## Next Steps
After successful setup:
1. **Explore API Functions**: See [README.md](README.md) for all available functions
2. **Build Workflows**: Create custom scripts using the msgraph module
3. **Monitor Usage**: Review Azure AD logs periodically
4. **Plan Secret Rotation**: Set calendar reminders before secret expiration
## Getting Help
- **Issues**: https://github.com/eesb99/msgraph-mcp/issues
- **Microsoft Graph Docs**: https://learn.microsoft.com/graph/
- **Azure AD Docs**: https://learn.microsoft.com/azure/active-directory/
---
**Last Updated**: 2025-12-17
**Version**: 1.0.0