# OWA MCP Server MCP (Model Context Protocol) server for any Microsoft Exchange / OWA (Outlook Web Access) deployment. Gives LLM agents access to email, calendar, directory search, folders, availability, and meeting analytics via 30 tools. Works with any on-premise or hosted Exchange server that exposes OWA. ## Quick Start ```bash # Install pip install -e . # Add to your MCP client config with --owa-url # Then use the login tool to paste your session cookies ``` ## Install Add to your MCP client config. Replace `https://owa.example.com` with your OWA URL. **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`): ```json { "mcpServers": { "exchange": { "command": "uvx", "args": [ "exchange-mcp-server", "--owa-url", "https://owa.example.com" ] } } } ``` **Cursor** (`.cursor/mcp.json`): ```json { "mcpServers": { "exchange": { "command": "uvx", "args": [ "exchange-mcp-server", "--owa-url", "https://owa.example.com" ] } } } ``` **Claude Code** (`.mcp.json`): ```json { "mcpServers": { "exchange": { "command": "uvx", "args": [ "exchange-mcp-server", "--owa-url", "https://owa.example.com" ] } } } ``` ## CLI Arguments | Argument | Default | Required | Description | |---|---|---|---| | `--owa-url` | — | Yes | Base URL of the OWA instance (e.g. `https://owa.example.com`) | | `--cookie-file` | `session-cookies.txt` | No | Path to session cookies file | | `--transport` | `stdio` | — | `stdio`, `sse`, or `streamable-http` | | `--token-hash` | — | For HTTP | SHA-256 hash of the bearer token | | `--port` | `8000` | — | HTTP/SSE listener port | | `--host` | `127.0.0.1` | — | HTTP/SSE listener host | | `--enabled-tools` | — | No | Comma-separated whitelist of tool names | | `--disabled-tools` | — | No | Comma-separated blacklist of tool names | ### Tool filtering examples ```bash # Hide only the most dangerous tools exchange-mcp-server --owa-url https://owa.example.com \ --disabled-tools "send_email,delete_email,cancel_meeting" # Allow only email and calendar tools exchange-mcp-server --owa-url https://owa.example.com \ --enabled-tools "get_emails,get_email,send_email,get_calendar_events,create_meeting" # Whitelist a set, then remove one from it exchange-mcp-server --owa-url https://owa.example.com \ --enabled-tools "get_emails,get_email,send_email,delete_email" \ --disabled-tools "delete_email" # → only get_emails, get_email, send_email remain ``` ## HTTP Transport Run the server over HTTP (streamable-http or SSE) instead of stdio. This is useful when the MCP client cannot spawn a local process, or when you want to expose the server on a network. ### Installation ```bash pip install -e ".[http]" # adds uvicorn + sse-starlette ``` ### Start the server ```bash # Compute the token hash once (store only the hash, never the plaintext token) TOKEN_HASH=$(echo -n 'my-secret-token' | sha256sum | cut -d' ' -f1) # stdio (default, for local MCP clients) exchange-mcp-server --owa-url https://owa.example.com # streamable-http (recommended for HTTP) exchange-mcp-server \ --owa-url https://owa.example.com \ --transport streamable-http \ --token-hash "$TOKEN_HASH" \ --port 8000 \ --host 127.0.0.1 # SSE exchange-mcp-server \ --owa-url https://owa.example.com \ --transport sse \ --token-hash "$TOKEN_HASH" \ --port 8000 ``` ### CLI arguments | Argument | Default | Required | Description | |---|---|---|---| | `--owa-url` | — | Yes | Base URL of the OWA instance (e.g. `https://owa.example.com`) | | `--cookie-file` | `session-cookies.txt` | No | Path to session cookies file | | `--transport` | `stdio` | — | `stdio`, `sse`, or `streamable-http` | | `--token-hash` | — | For HTTP | SHA-256 hash of the bearer token | | `--port` | `8000` | — | HTTP/SSE listener port | | `--host` | `127.0.0.1` | — | HTTP/SSE listener host | | `--enabled-tools` | — | No | Comma-separated whitelist of tool names | | `--disabled-tools` | — | No | Comma-separated blacklist of tool names | ### Client configuration (HTTP) ```json { "mcpServers": { "exchange": { "url": "http://127.0.0.1:8000/mcp", "headers": { "Authorization": "Bearer my-secret-token" } } } } ``` ### Authentication The server stores only the SHA-256 hash of your token — the plaintext token never touches the filesystem. Every HTTP request must include: ``` Authorization: Bearer ``` The server hashes the incoming token and compares it with the stored hash. Pass the hash via `--token-hash`: ```bash echo -n 'my-secret-token' | sha256sum # → 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 ``` ### Security notes - Always use a strong random token. - Bind to `127.0.0.1` unless you have a reverse proxy / firewall. - For `streamable-http` the client must send `Accept: text/event-stream`. - The `--token-hash` is required whenever `--transport` is not `stdio`. ## Login The `login` MCP tool accepts session cookies that you copy from your browser. 1. Log into OWA in your browser. 2. Open DevTools (F12) → Application → Cookies → select your OWA domain. 3. Copy all cookies as `name=value` pairs (one per line). 4. Call the `login` tool with the cookies string. Example cookies string: ``` X-OWA-CANARY=abc123 CookieAuth1=def456 ... ``` ``` login(cookies="X-OWA-CANARY=abc123\nCookieAuth1=def456\n...") ``` On success, cookies are saved to `session-cookies.txt` and all tools become usable. When the session expires, repeat the steps. ## Tools (30) ### Email (10) | Tool | Description | |---|---| | `get_emails` | List emails from a folder with filtering | | `get_email` | Get full email content by ID | | `send_email` | Send a new email | | `reply_email` | Reply to an email | | `forward_email` | Forward an email | | `delete_email` | Delete an email | | `move_email` | Move email to another folder | | `mark_email_read` | Mark email as read/unread | | `download_attachments` | Download file attachments from an email | | `get_email_links` | Extract hyperlinks from an email body | ### Calendar (7) | Tool | Description | |---|---| | `get_calendar_events` | Get events in a date range (supports recurring expansion) | | `create_meeting` | Create a meeting with attendees | | `update_meeting` | Update an existing meeting | | `cancel_meeting` | Cancel a meeting and notify attendees | | `respond_to_meeting` | Accept, decline, or tentatively accept | | `download_event_attachments` | Download file attachments from a calendar event | | `get_event_links` | Extract hyperlinks from the event description | ### Directory (1) | Tool | Description | |---|---| | `find_person` | Search people in Active Directory | ### Folders (7) | Tool | Description | |---|---| | `get_folders` | List mail folders with unread counts | | `create_folder` | Create a new mail folder | | `rename_folder` | Rename an existing folder | | `empty_folder` | Empty all items from a folder | | `delete_folder` | Delete a mail folder | | `move_folder` | Move a folder to a different parent | | `check_session` | Check if the OWA session is authenticated | ### Availability (2) | Tool | Description | |---|---| | `find_free_time` | Find free slots in your calendar | | `find_meeting_time` | Find common free slots for multiple people | ### Analytics (2) | Tool | Description | |---|---| | `get_meeting_stats` | Meeting count statistics for multiple people | | `get_meeting_contacts` | Connection matrix — who you meet with most | ### Auth (1) | Tool | Description | |---|---| | `login` | Authenticate to OWA using browser session cookies | ## Files ``` exchange_mcp/ server.py # FastMCP server entry point owa_client.py # OWA HTTP client tools/ email.py # Email tools calendar.py # Calendar tools people.py # Directory search folders.py # Folder management & session check availability.py # Free time / meeting time analytics.py # Meeting stats & contacts auth.py # Login tool pyproject.toml # Package config ```