Step-by-step guide to install and configure the EWS MCP Server.
What you get: 42 base tools plus 4 optional AI tools covering email (incl. reply/forward drafts), calendar, contacts, directory (GAL), tasks, folders (incl. ID-based references), attachments, and out-of-office. All base tools support
target_mailboxvia impersonation.
- Python 3.11 or higher
- Microsoft Exchange account (Office 365 or on-premises)
- Exchange Web Services (EWS) enabled
- Docker 20.10+
- Docker Compose 2.0+
- Azure AD tenant with admin access
- Permissions to register applications
git clone <repository-url>
cd ews-mcp-server# Copy example environment file
cp .env.example .env
# Edit .env with your credentials
nano .env # or use your preferred editorSee Configuration section for details.
# Build Docker image
docker build -t ews-mcp-server .
# Run with docker-compose (recommended)
docker-compose up -d
# Or run directly
docker run -d --name ews-mcp-server --env-file .env ews-mcp-server
# View logs
docker-compose logs -fgit clone <repository-url>
cd ews-mcp-server# Make script executable (Linux/Mac)
chmod +x scripts/setup.sh
# Run setup
./scripts/setup.shOr manually:
# Create virtual environment
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate # Linux/Mac
# or
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
# For development
pip install -r requirements-dev.txt# Copy example environment file
cp .env.example .env
# Edit with your credentials
nano .env# Activate virtual environment if not already active
source venv/bin/activate
# Run server
python -m src.main- Go to Azure Portal
- Navigate to Azure Active Directory → App registrations
- Click New registration
- Name:
EWS MCP Server - Supported account types: Accounts in this organizational directory only
- Redirect URI: Leave blank
- Name:
- Click Register
-
Go to API permissions
-
Click Add a permission
-
Select APIs my organization uses
-
Search for Office 365 Exchange Online
-
Select Application permissions
-
Add these permissions:
full_access_as_app(for full access)
Or specific permissions:
Mail.ReadWriteMail.SendCalendars.ReadWriteContacts.ReadWriteTasks.ReadWrite
-
Click Add permissions
-
Click Grant admin consent for [Your Organization]
-
Confirm by clicking Yes
- Go to Certificates & secrets
- Click New client secret
- Description:
EWS MCP Server Secret - Expires: Select duration (recommend: 24 months)
- Click Add
- Copy the secret VALUE immediately (you won't see it again!)
From the Overview page, copy:
- Application (client) ID
- Directory (tenant) ID
Update your .env file:
# Exchange Server
EWS_SERVER_URL=https://outlook.office365.com/EWS/Exchange.asmx
EWS_EMAIL=your.email@company.com
EWS_AUTODISCOVER=true
# OAuth2 Authentication
EWS_AUTH_TYPE=oauth2
EWS_CLIENT_ID=<your-client-id>
EWS_CLIENT_SECRET=<your-client-secret>
EWS_TENANT_ID=<your-tenant-id>Update your .env file:
# Exchange Server
EWS_SERVER_URL=https://mail.company.com/EWS/Exchange.asmx
EWS_EMAIL=user@company.com
EWS_AUTODISCOVER=false
# Basic Authentication
EWS_AUTH_TYPE=basic
EWS_USERNAME=user@company.com
EWS_PASSWORD=your-passwordNote: Basic authentication is being deprecated by Microsoft. Use OAuth2 when possible.
Update your .env file:
# Exchange Server
EWS_SERVER_URL=https://mail.company.com/EWS/Exchange.asmx
EWS_EMAIL=DOMAIN\username
EWS_AUTODISCOVER=false
# NTLM Authentication
EWS_AUTH_TYPE=ntlm
EWS_USERNAME=DOMAIN\username
EWS_PASSWORD=your-passwordmacOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Linux:
~/.config/Claude/claude_desktop_config.json{
"mcpServers": {
"ews": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--env-file",
"/absolute/path/to/ews-mcp/.env",
"ews-mcp-server"
]
}
}
}Important: Replace /absolute/path/to/ews-mcp/.env with the actual absolute path.
{
"mcpServers": {
"ews": {
"command": "python",
"args": ["-m", "src.main"],
"cwd": "/absolute/path/to/ews-mcp",
"env": {
"EWS_SERVER_URL": "https://outlook.office365.com/EWS/Exchange.asmx",
"EWS_EMAIL": "your.email@company.com",
"EWS_AUTH_TYPE": "oauth2",
"EWS_CLIENT_ID": "your-client-id",
"EWS_CLIENT_SECRET": "your-secret",
"EWS_TENANT_ID": "your-tenant",
"LOG_LEVEL": "INFO"
}
}
}
}Completely quit and restart Claude Desktop application.
In Claude Desktop, type:
Can you check my unread emails?
If working, Claude will use the EWS MCP Server to fetch your emails.
# From Python
python -c "
from src.config import settings
from src.auth import AuthHandler
from src.ews_client import EWSClient
auth = AuthHandler(settings)
client = EWSClient(settings, auth)
if client.test_connection():
print('✓ Connection successful!')
print(f'Inbox count: {client.account.inbox.total_count}')
else:
print('✗ Connection failed')
"# Activate virtual environment
source venv/bin/activate
# Run tests
pytest
# Run with coverage
pytest --cov=src# Docker
docker-compose logs -f
# Local
tail -f logs/ews-mcp.logSolution:
# Ensure virtual environment is activated
source venv/bin/activate
# Reinstall dependencies
pip install -r requirements.txtSolutions:
- Verify all credentials are correct
- Check OAuth2 app permissions
- Ensure admin consent granted
- Try basic auth for testing
Solutions:
- Verify EWS_SERVER_URL is correct
- Check network connectivity
- Try autodiscovery:
EWS_AUTODISCOVER=true - Test with curl:
curl https://outlook.office365.com/EWS/Exchange.asmx
Solutions:
- Verify configuration file location
- Check JSON syntax (use a JSON validator)
- Ensure paths are absolute, not relative
- Restart Claude Desktop completely
- Check Docker container is running:
docker ps | grep ews-mcp
# In .env file
# Disable specific features
ENABLE_EMAIL=true
ENABLE_CALENDAR=true
ENABLE_CONTACTS=true
ENABLE_TASKS=true# Connection settings
CONNECTION_POOL_SIZE=10
REQUEST_TIMEOUT=30
# Caching (future feature)
ENABLE_CACHE=true
CACHE_TTL=300RATE_LIMIT_ENABLED=true
RATE_LIMIT_REQUESTS_PER_MINUTE=25# Log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_LEVEL=INFO
# Audit logging
ENABLE_AUDIT_LOG=true- Review API Documentation for available tools
- Check Usage Examples for common patterns
- Read Troubleshooting Guide for common issues
- See Deployment Guide for production deployment
- Never commit .env file - It's in .gitignore
- Rotate secrets regularly - Especially OAuth2 client secrets
- Use OAuth2 when possible - More secure than basic auth
- Limit permissions - Only grant needed permissions
- Monitor access logs - Enable audit logging
- Use HTTPS only - Never use HTTP for Exchange
- Secure the host - Keep OS and dependencies updated
For issues during setup:
- Check Troubleshooting Guide
- Enable DEBUG logging:
LOG_LEVEL=DEBUG - Review logs for detailed errors
- Create GitHub issue with:
- Steps to reproduce
- Error messages (redact credentials)
- Environment details