Skip to main content
Glama
nhatho0001

Outlook Email MCP Server

by nhatho0001
README.md
# Outlook Email MCP Server

MCP Server cho Claude Desktop để đọc và quản lý email Microsoft 365 / Outlook qua Microsoft Graph API.

## Tính năng

| Tool | Mô tả |
|------|-------|
| `auth_login` | Bắt đầu đăng nhập — trả về URL và mã xác thực |
| `auth_confirm` | Hoàn tất đăng nhập sau khi xác thực trong browser |
| `auth_status` | Kiểm tra trạng thái đăng nhập hiện tại |
| `auth_logout` | Đăng xuất, xóa token đã lưu |
| `list_emails` | Liệt kê email theo folder |
| `read_email` | Đọc nội dung đầy đủ một email |
| `search_emails` | Tìm kiếm email với nhiều điều kiện |
| `create_draft` | Tạo email nháp mới |
| `list_drafts` | Liệt kê tất cả email nháp |
| `update_draft` | Sửa nội dung email nháp |
| `delete_draft` | Xóa email nháp |
| `send_draft` | Gửi email nháp đã tạo |
| `send_email` | Soạn và gửi email ngay |
| `mark_email_as_read` | Đánh dấu email đã đọc / chưa đọc |
| `list_attachments` | Liệt kê file đính kèm của một email |
| `read_attachment` | Đọc nội dung file đính kèm (text/xlsx/pdf/docx/ảnh) |
| `read_sharepoint_excel` | Đọc nội dung file Excel từ SharePoint Online |
| `filter_sharepoint_excel` | Đọc file Excel từ SharePoint, chỉ lấy các dòng khớp filter |

---

## Yêu cầu

- Python 3.11 trở lên (nếu dùng `uv` ở Bước 3 - Cách 1, không cần cài Python trước — `uv` tự tải)
- [Claude Desktop](https://claude.ai/download)
- Tài khoản Microsoft 365 hoặc Outlook.com
- Quyền truy cập [Azure Portal](https://portal.azure.com) (để đăng ký app)

---

## Hướng dẫn cài đặt

### Bước 1: Tải source code

Tải hoặc clone repo này về máy, ví dụ vào thư mục:
```
C:\Projects\mcp-server\
```

> Ghi nhớ đường dẫn này — bạn sẽ dùng ở Bước 4.

---

### Bước 2: Đăng ký Azure App

> Bước này chỉ làm **một lần duy nhất**. Nếu đã có `AZURE_CLIENT_ID`, bỏ qua.

1. Truy cập [portal.azure.com](https://portal.azure.com) và đăng nhập
2. Tìm **"App registrations"** → nhấn **"New registration"**
3. Điền thông tin:
   - **Name**: `M365 MCP Server` (hoặc tên bất kỳ)
   - **Supported account types**: chọn theo nhu cầu:
     - `Accounts in any organizational directory and personal Microsoft accounts` — nếu muốn dùng cả tài khoản cá nhân lẫn tổ chức
     - `Accounts in this organizational directory only` — nếu chỉ dùng trong nội bộ tổ chức
   - **Redirect URI**: để **trống**
4. Nhấn **Register**
5. Sau khi tạo xong, copy **Application (client) ID** — đây là `AZURE_CLIENT_ID`

#### Cấp quyền API

6. Vào tab **"API permissions"** → **"Add a permission"** → **"Microsoft Graph"** → **"Delegated permissions"**
7. Tìm và thêm các quyền sau:
   - `Mail.Read`
   - `Mail.ReadWrite`
   - `Mail.Send`
   - `User.Read`
   - `Sites.Read.All` — cần cho `read_sharepoint_excel` / `filter_sharepoint_excel`
   - `Files.Read.All` — cần cho `read_sharepoint_excel` / `filter_sharepoint_excel`
   - `offline_access`
8. Nhấn **"Grant admin consent for [tên tổ chức]"** nếu bạn là admin *(tùy chọn — xem phần Troubleshooting nếu không có quyền này)*

> Nếu app đã tạo trước đó và chỉ có 4 quyền đầu, quay lại **"API permissions"** để bổ sung `Sites.Read.All`/`Files.Read.All`, nếu không 2 tool SharePoint sẽ báo lỗi 403.

#### Bật Device Code Flow

9. Vào tab **"Authentication"**
10. Kéo xuống phần **"Advanced settings"**
11. Bật **"Allow public client flows"** → **Yes**
12. Nhấn **Save**

---

### Bước 3: Cài đặt dependencies

Mở terminal, điều hướng vào thư mục project:

```bash
cd "C:\Projects\mcp-server"
```

#### Cách 1: Dùng `uv` (Khuyên dùng — tự quản lý virtual env)

**Cài `uv` (nếu máy chưa có):**

Windows (PowerShell):
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

macOS / Linux:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Hoặc nếu máy đã có sẵn Python + pip:
```bash
pip install uv
```

> Sau khi cài xong, **đóng và mở lại terminal** để PATH được cập nhật, rồi kiểm tra bằng `uv --version`.
> `uv` tự quản lý phiên bản Python — không cần cài Python 3.11 riêng, `uv sync` bên dưới sẽ tự tải nếu máy chưa có.

**Cài dependencies:**

```bash
uv sync
```

#### Cách 2: Dùng `pip` thông thường

```bash
pip install "mcp[cli]" msal httpx python-dotenv html2text openpyxl pypdf python-docx
```

---

### Bước 4: Tạo file `.env`

Trong thư mục project, copy file mẫu:

```bash
# Windows
copy .env.example .env

# macOS / Linux
cp .env.example .env
```

Mở file `.env` và điền `AZURE_CLIENT_ID` lấy từ Bước 2:

```
AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_TENANT_ID=common
```

**Giá trị `AZURE_TENANT_ID`:**

| Giá trị | Dùng khi |
|---------|----------|
| `common` | Tài khoản cá nhân (Outlook.com) hoặc hỗn hợp |
| `organizations` | Chỉ tài khoản tổ chức (work/school) |
| `<tenant-id>` | Giới hạn đúng một tổ chức cụ thể |

---

### Bước 5: Cấu hình Claude Desktop

Mở file cấu hình Claude Desktop:

- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`

Thêm vào trong `mcpServers` (thay đường dẫn bằng đường dẫn thực tế trên máy bạn):

#### Cách 1: Dùng `uv` (Khuyên dùng)

```json
{
  "mcpServers": {
    "outlook-email": {
      "command": "uv",
      "args": [
        "--directory",
        "C:\\Projects\\mcp-server",
        "run",
        "server.py"
      ]
    }
  }
}
```

#### Cách 2: Dùng `python` trực tiếp

```json
{
  "mcpServers": {
    "outlook-email": {
      "command": "python",
      "args": [
        "C:\\Projects\\mcp-server\\server.py"
      ]
    }
  }
}
```

> **Lưu ý Windows**: Dùng `\\` thay vì `\` trong đường dẫn JSON.

**Restart Claude Desktop** sau khi lưu file config.

---

### Bước 6: Đăng nhập lần đầu

Sau khi restart Claude Desktop:

1. Mở cuộc trò chuyện mới
2. Kiểm tra biểu tượng MCP tools xuất hiện (icon công cụ)
3. Yêu cầu Claude gọi tool `auth_login`:
   > "Hãy đăng nhập vào Outlook email cho tôi"

4. Claude sẽ trả về **URL và mã xác thực** ngay trong chat, ví dụ:
   ```
   1. Mở trình duyệt và truy cập: https://login.microsoft.com/device
   2. Nhập mã xác thực: ABCD1234
   3. Đăng nhập bằng tài khoản Microsoft của bạn
   4. Sau khi xác thực xong, gọi auth_confirm
   ```

5. Thực hiện theo hướng dẫn trong chat, sau đó yêu cầu Claude gọi `auth_confirm`:
   > "Tôi đã xác thực xong, hãy xác nhận đăng nhập"

6. Claude thông báo đăng nhập thành công.

> Token được lưu tại `~/.outlook-mcp-tokens.json` và tự động refresh — **có hiệu lực 90 ngày**.

---

## Sử dụng

Sau khi đăng nhập, bạn có thể dùng ngôn ngữ tự nhiên:

```
"Kiểm tra xem tôi đã đăng nhập chưa"
"Liệt kê 10 email mới nhất trong inbox"
"Tìm email từ boss@company.com"
"Tạo email nháp gửi cho colleague@company.com với tiêu đề Meeting tomorrow"
"Gửi email cho client@example.com nội dung cảm ơn hợp tác"
"Đánh dấu email vừa đọc là chưa đọc"
```

---

## Troubleshooting

### "Need admin approval" khi đăng nhập

Tài khoản tổ chức (work/school) yêu cầu admin của tổ chức phải grant consent cho app.

**Nếu bạn là admin:**
1. Azure Portal → **Enterprise Applications** → tìm app → **Permissions** → **Grant admin consent**

**Nếu bạn không phải admin:**
- Nhờ IT admin của tổ chức vào Azure Portal, tìm app theo tên, và grant consent
- Hoặc admin nhấn **"Have an admin account? Sign in with that account"** ngay trên màn hình lỗi

**Giới hạn người dùng (tùy chọn cho admin):**
- Azure Portal → **Enterprise Applications** → tên app → **Properties** → bật **"Assignment required"**
- Sau đó vào **Users and groups** → chỉ add những người được phép dùng

---

### MCP server không xuất hiện trong Claude Desktop

- Kiểm tra đường dẫn trong `claude_desktop_config.json` có đúng không
- Đảm bảo đã restart Claude Desktop hoàn toàn (thoát hẳn, không chỉ đóng cửa sổ)
- Chạy thử `python server.py` trong terminal để kiểm tra lỗi

### Lỗi sau khi gọi `auth_confirm`

- Đảm bảo bạn đã **hoàn thành xác thực trên browser** trước khi gọi `auth_confirm`
- Mã xác thực hết hạn sau ~15 phút — nếu quá thời gian, gọi lại `auth_login` để lấy mã mới

### Token hết hạn

Token tự động refresh. Nếu bị lỗi xác thực sau 90 ngày, gọi lại `auth_login` để đăng nhập mới.

---

## Cấu trúc dự án

```
mcp-server/
├── server.py           # Entry point
├── config.py           # Cấu hình và constants
├── pyproject.toml      # Dependencies
├── .env                # Biến môi trường (KHÔNG commit file này)
├── .env.example        # File mẫu
├── auth/               # Xác thực Microsoft
│   ├── device_flow.py  # MSAL Device Code Flow
│   ├── token_cache.py  # Lưu trữ token
│   ├── tools.py        # MCP tools: login/confirm/status/logout
│   └── __init__.py
├── graph/              # Microsoft Graph API client
│   ├── client.py       # HTTP client, pagination
│   └── __init__.py
├── mail/               # Email operations
│   ├── list_emails.py
│   ├── read_email.py
│   ├── search_emails.py
│   ├── drafts.py       # create/list/update/delete/send draft
│   ├── send_email.py
│   ├── mark_as_read.py
│   ├── attachments.py  # list_attachments, read_attachment
│   ├── folder_utils.py
│   └── __init__.py
├── sharepoint/         # Đọc file Excel từ SharePoint Online
│   ├── read_excel.py
│   ├── filter_excel.py
│   ├── excel_common.py # helper resolve URL / download / parse JSON dùng chung
│   └── __init__.py
└── utils/              # Tiện ích dùng chung
    ├── html_sanitizer.py
    └── formatting.py
```

---

## Mở rộng

Để thêm tính năng mới (ví dụ Calendar):

1. Tạo thư mục `calendar_tools/` với các file tương tự `mail/`
   (không đặt tên `calendar/` — trùng tên module chuẩn của Python, sẽ gây lỗi import)
2. Viết `calendar_tools/__init__.py` với hàm `register_calendar_tools(mcp)`
3. Thêm vào `server.py`:
   ```python
   from calendar_tools import register_calendar_tools
   register_calendar_tools(mcp)
   ```
4. Thêm package vào `pyproject.toml` → `[tool.hatch.build.targets.wheel] packages`

Không cần thay đổi file nào khác.

TDQS

A3.7/5.0

Scored across 17 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: authentication tools are separate from email operations, and email operations cover separate actions (create, list, read, update, delete, send, search). There is no overlap between tools.

Naming Consistency5/5

All tools use snake_case with a consistent verb_noun pattern (e.g., create_draft, list_emails, send_email). The authentication tools follow the auth_ prefix pattern, maintaining consistency within the subset.

Tool Count4/5

17 tools is slightly above the typical well-scoped range but still reasonable for a comprehensive email server. Each tool serves a specific function without redundancy, though the inclusion of read_sharepoint_excel feels a bit out of place.

Completeness3/5

The tool set covers core email workflows (send, draft, read, search, list) but lacks important operations like deleting non-draft emails, replying/forwarding, and moving emails between folders. These gaps could lead to agent failures in common scenarios.

Maintenance

ActivityStale
ResponsivenessNo issues