Microsoft Teams MCP服务器
使用Microsoft Graph API计划、重新安排、取消Microsoft Teams面试和管理日历事件的服务器。
特性
- 安排新的Microsoft Teams会议,包括与会者、主题和正文。
- 通过更新现有会议的开始和结束时间来重新安排会议。
- 使用会议ID取消会议。
- 列出支持时区的团队日历事件。
- 检索IANA支持的时区列表,以安排和过滤事件。
先决条件
- Python 3.8或更高版本。
- 具有Microsoft Graph API权限的Microsoft Azure AD应用程序(例如。,
Calendars.ReadWrite,User.Read.All). git和pip安装在您的系统上。- (可选)
uv用于运行服务器(通过安装pip install uv). - (可选)
ngrok用于使用HTTPS公开本地服务器(OpenAI API集成所需)。
安装
使用回购源代码
- 克隆存储库:
git clone https://github.com/alivnavc/Microsoft-Teams-Meetings-MCP-Server.git
cd Microsoft-Teams-Meetings-MCP-Server- 创建并激活虚拟环境:
python -m venv venv
# On Unix/Linux/MacOS:
source venv/bin/activate
# On Windows (Command Prompt):
venv\Scripts\activate
# On Windows (PowerShell):
.\venv\Scripts\Activate.ps1- 安装依赖项:
pip install -r requirements.txt- 配置环境变量:
- 创建一个 .env 项目根目录中的文件。 - 添加您的Microsoft Graph API凭据:
MS_TENANT_ID=your_tenant_id
MS_CLIENT_ID=your_client_id
MS_CLIENT_SECRET=your_client_secret
MS_USER_ID=your_user_id- 运行服务器:
python server.py或者,如果使用 uv:
uv run server.py- 通过Docker部署(可选)
使用.env文件拉取并运行Docker镜像
docker pull alivnavc/microsoft-teams-mcp
docker run -d -p 4200:4200 --name teams-mcp-server --env-file /path/to/.env alivnavc/microsoft-teams-mcp
--env文件/path/to/.env将环境变量从本地.env文件加载到容器中 (将/path/to/.env替换为.env文件的实际路径)
验证容器是否正在运行
docker ps使用PIP
- ```bash
pip install microsoft-teams-mcp==1.1.4
1. 使用以下代码from microsoft_teams_mcp import server server.main({ "MS_TENANT_ID": "Tenant ID", "MS_CLIENT_ID": "Client ID", "MS_CLIENT_SECRET": "Client Secret", "MS_USER_ID": "User Id"
})
Run the command : python filename.py
## Microsoft Graph API的Azure AD安装程序
若要使用Microsoft Graph API,您需要在Microsoft Azure AD中注册应用程序并配置必要的权限。遵循以下步骤(总结自 [MS-Teams-setup.md](https://github.com/InditexTech/mcp-teams-server/blob/master/doc/MS-Teams-setup.md)):
1. **注册Azure AD应用程序**:
- 在Azure门户中创建Microsoft Entra ID应用程序。
- 注意应用程序UUID(设置为 `MS_CLIENT_ID` 在你的 `.env` 文件)。
- 为单租户或多租户配置应用程序:
- 对于单租户,将租户UUID存储在 `MS_TENANT_ID` 并设置 `MS_APP_TYPE=SingleTenant`.
- 对于多租户,请在Azure中相应地调整设置。
1. **添加客户端密码**:
- 为Azure AD应用程序生成客户端密钥。
- 将秘密存储在 `MS_CLIENT_SECRET` 在你的 `.env` 文件。
1. **配置Microsoft Graph API权限**:
- 添加 `Calendars.ReadWrite` 许可(以及可选 `User.Read.All` 用于列出事件)到Azure AD应用程序。
- 确保权限已获得管理员同意。
1. **Azure Bot注册(可选)**:
- 如果与Microsoft Teams渠道集成,请使用相同的方式注册Azure Bot `MS_CLIENT_ID`.
- 将机器人程序连接到Teams频道,并将其配置为使用Microsoft Graph API。
有关详细说明,请参阅 [MS-Teams-setup.md](https://github.com/InditexTech/mcp-teams-server/blob/master/doc/MS-Teams-setup.md).
## 用法
服务器运行在 `http://localhost:4200/mcp/` 默认情况下,在本地运行时。它公开了一个用于与Microsoft团队会议和日历交互的JSON-RPC API。
### 重要说明
- **微软的MCP服务器**:Microsoft提供了一个MCP服务器来管理Teams会议,但发现某些工具(例如,与自定义与会者进行日程安排、重新安排、取消和支持时区的日历事件列表)缺失或不足。该项目是为了解决这些差距而开发的,提供了一个使用以下工具的定制实现。
- **存储事件ID**:使用以下命令安排会议时 `schedule_teams_meeting`,响应包括 `event_id`。将此ID存储在数据库或本地文件(例如JSON或CSV)中,因为重新安排需要它(`reschedule_teams_meeting`)或取消(`cancel_teams_meeting`)会议。例如,您可以保存 `event_id` 以及SQLite数据库或JSON文件中的相关元数据(例如,会议主题、日期),以便于检索。
- **OpenAI API集成**:如果您计划将此服务器与OpenAI API集成,请注意,OpenAI需要HTTPS端点。本地服务器(`http://localhost:4200/mcp/`)不会与OpenAI合作。使用 `ngrok` 使用HTTPS URL公开本地服务器:
1. 安装 `ngrok` (例如,通过 `npm install -g ngrok` 或从以下网址下载 [ngrok.com](https://ngrok.com)).
1. 运行:ngrok http 4200
以生成HTTPS URL(例如。, `https://your-ngrok-subdomain.ngrok.io`).
1. 使用ngrok URL(例如。, `https://your-ngrok-subdomain.ngrok.io/mcp/`)作为OpenAI API集成的端点。
### 在服务器上部署
1. 在服务器上部署应用程序(例如AWS EC2、Azure VM)。
1. 将客户端中的服务器URL更新为服务器的公共IP或域(例如。, `http://your-server-ip:4200/mcp/`).
1. 确保使用Nginx等反向代理为生产启用HTTPS。
1. 使用环境变量保护敏感数据(例如API证书)。
## API使用
服务器使用 `FastMCP` 该框架公开JSON-RPC端点,用于管理Microsoft Teams会议和日历。下面是可用的工具、它们的功能以及如何将它们与示例JSON-RPC有效载荷一起使用。
### 1. `schedule_teams_meeting`
**描述**:使用指定主题、开始/结束时间(UTC,ISO 8601格式)、会议正文和所需与会者安排新的Microsoft Teams会议。
**特性**:
- 使用唯一的加入URL创建团队会议。
- 支持多个具有电子邮件地址和姓名的与会者。
- 允许会议正文为HTML或纯文本。
- 成功调度后返回事件ID和加入URL。 **存储 `event_id` 重新安排或取消会议。**
**用法**:
- **方法**: `tools/call`
- **参数**:
- `subject` (string):会议的标题。
- `body` (string):会议描述(HTML或纯文本)。
- `start_time` (string):ISO 8601 UTC格式的会议开始时间(例如。, `2025-09-10T18:00:00Z`).
- `end_time` (string):ISO 8601 UTC格式的会议结束时间。
- `required_attendees` (list):与会者对象列表,每个对象都有 `email` (有效电子邮件)和 `name` (字符串)。
**有效载荷示例**:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "schedule_teams_meeting", "arguments": { "subject": "Technical Interview - Backend Engineer", "body": "Dear candidate,
Please join the Microsoft Teams meeting for your interview.
Regards, Recruitment Team", "required_attendees": [ { "email": "example@domain.com", "name": "Alice Applicant" } ], "start_time": "2025-09-10T18:00:00Z", "end_time": "2025-09-10T19:00:00Z" } } }
**示例响应**:
{ "jsonrpc": "2.0", "id": 1, "result": { "event_id": "AAMkADg0OWNmYTNjLTJlZmQtNDc2Ny1hNjAyLWNlZDE2MjEzNzAwMQBGAAAAAADbWWPmN-qjQqZ5uOjCatRNBwD4kwMhw138Q6oKJi3U2FGBAAAAAAENAAD4kwMhw138Q6oKJi3U2FGBAAFJIBYCAAA", "join_url": "https://teams.microsoft.com/l/meetup-join/..." } }
### 2. `reschedule_teams_meeting`
**描述**:通过更新现有Microsoft Teams会议的开始和结束时间来重新安排会议。
**特性**:
- 使用现有会议的事件ID更新其开始和结束时间。
- 维护其他会议详细信息(例如,与会者、主题)。
- 成功重新安排后返回事件ID。
- 需要 `event_id` 来自之前安排的会议。
**用法**:
- **方法**: `tools/call`
- **参数**:
- `event_id` (string):要重新安排的会议的Microsoft Graph事件ID。
- `start_time` (string):ISO 8601 UTC格式的新开始时间。
- `end_time` (string):ISO 8601 UTC格式的新结束时间。
**有效载荷示例**:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "reschedule_teams_meeting", "arguments": { "event_id": "AAMkADE1MzJlYTAwLWRkZTMtNDAyMy04ZTk2LTljOTI4OWRjYjg5MABGAAAAAABaL71tdJQET4NwOuYku0EHBwC7MkKjdoRHQ4cHEDY3mToXAAAAAAENAAC7MkKjdoRHQ4cHEDY3mToXAAFPchCuAAA=", "start_time": "2025-09-07T14:00:00Z", "end_time": "2025-09-07T16:00:00Z" } } }
**示例响应**:
{ "jsonrpc": "2.0", "id": 1, "result": { "event_id": "AAMkADE1MzJlYTAwLWRkZTMtNDAyMy04ZTk2LTljOTI4OWRjYjg5MABGAAAAAABaL71tdJQET4NwOuYku0EHBwC7MkKjdoRHQ4cHEDY3mToXAAAAAAENAAC7MkKjdoRHQ4cHEDY3mToXAAFPchCuAAA=", "join_url": "" } }
### 3. `cancel_teams_meeting`
**描述**:使用事件ID取消现有的Microsoft Teams会议。
**特性**:
- 从日历中删除会议。
- 成功取消后返回确认消息。
- 需要 `event_id` 来自之前安排的会议。
**用法**:
- **方法**: `tools/call`
- **参数**:
- `event_id` (string):要取消的会议的Microsoft Graph事件ID。
**有效载荷示例**:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "cancel_teams_meeting", "arguments": { "event_id": "AAMkADg0OWNmYTNjLTJlZmQtNDc2Ny1hNjAyLWNlZDE2MjEzNzAwMQBGAAAAAADbWWPmN-qjQqZ5uOjCatRNBwD4kwMhw138Q6oKJi3U2FGBAAAAAAENAAD4kwMhw138Q6oKJi3U2FGBAAFJIBYCAAA" } } }
**示例响应**:
{ "jsonrpc": "2.0", "id": 1, "result": { "message": "Interview 'AAMkADg0OWNmYTNjLTJlZmQtNDc2Ny1hNjAyLWNlZDE2MjEzNzAwMQBGAAAAAADbWWPmN-qjQqZ5uOjCatRNBwD4kwMhw138Q6oKJi3U2FGBAAAAAAENAAD4kwMhw138Q6oKJi3U2FGBAAFJIBYCAAA' canceled in Teams." } }
### 4. `list_team_calendar_events`
**描述**:列出给定日期范围和时区内指定团队成员的日历事件。
**特性**:
- 检索多个电子邮件地址的事件。
- 支持自定义日期范围和时间与时区转换(IANA时区。, `America/Los_Angeles`).
- 筛选事件,仅包括指定时间窗口内的事件。
- 返回详细的活动信息(主题、开始/结束时间、地点、组织者、与会者、活动ID)。
**用法**:
- **方法**: `tools/call`
- **参数**:
- `emails` (list):用于获取事件的电子邮件地址列表。
- `start_date` (string):开始日期 `YYYY-MM-DD` 格式。
- `end_date` (字符串,可选):结束日期 `YYYY-MM-DD` 格式(默认为 `start_date` 如果没有提供)。
- `start_time` (字符串,可选):开始时间 `HH:MM` 格式(默认为 `00:00`).
- `end_time` (字符串,可选):结束时间 `HH:MM` 格式(默认为 `23:59`).
- `time_zone` (字符串,可选):IANA时区(默认为 `UTC`).
**有效载荷示例**:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "list_team_calendar_events", "arguments": { "emails": ["example@domain.com"], "start_date": "2025-09-07", "time_zone": "America/Los_Angeles" } } }
**示例响应**:
{ "jsonrpc": "2.0", "id": 1, "result": { "status": "success", "start_date": "2025-09-07", "end_date": "2025-09-07", "start_time": "00:00", "end_time": "23:59", "time_zone": "America/Los_Angeles", "events": { "example@domain.com": [ { "subject": "Technical Interview - Backend Engineer", "start": "2025-09-07 11:00", "end": "2025-09-07 12:00", "location": "Microsoft Teams Meeting", "organizer": "Recruitment Team", "event_id": "AAMkADg0OWNmYTNjLTJlZmQtNDc2Ny1hNjAyLWNlZDE2MjEzNzAwMQBGAAAAAADbWWPmN-qjQqZ5uOjCatRNBwD4kwMhw138Q6oKJi3U2FGBAAAAAAENAAD4kwMhw138Q6oKJi3U2FGBAAFJIBYCAAA", "attendees": [ { "emailAddress": { "address": "example@domain.com", "name": "Alice Applicant" }, "type": "required" } ] } ] }, "results": "[...]" } }
### 5. `get_teams_timezones`
**描述**:检索所有IANA支持的时区列表,用于安排或筛选日历事件。
**特性**:
- 返回由支持的IANA时区的完整列表 `pytz` 图书馆。
- 有助于确保其他API调用的有效时区输入(例如。, `list_team_calendar_events`).
**用法**:
- **方法**: `tools/call`
- **参数**:没有。
**有效载荷示例**:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "get_teams_timezones", "arguments": {} } }
**示例响应**:
{ "jsonrpc": "2.0", "id": 1, "result": { "message": "List of IANA-supported time zones. You can also check at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones", "timezones": [ "Africa/Abidjan", "Africa/Accra", "America/Los_Angeles", ... ] } }
### 列出可用工具
检索所有可用工具的列表(例如,发现 `schedule_teams_meeting`, `reschedule_teams_meeting`等),使用 `tools/list` 方法。
**有效载荷示例**:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": { "cursor": "optional-cursor-value" } }
**示例响应**:
{ "jsonrpc": "2.0", "id": 1, "result": { "tools": [ { "name": "schedule_teams_meeting", "description": "Schedule a Microsoft Teams meeting by specifying the subject, start/end times (ISO 8601 UTC), meeting body, and a list of required attendees..." }, { "name": "reschedule_teams_meeting", "description": "Reschedule an existing interview in Microsoft Teams" }, { "name": "cancel_teams_meeting", "description": "Cancel an interview in Microsoft Teams" }, { "name": "list_team_calendar_events", "description": "List calendar events for team members between specified dates and times with timezone support" }, { "name": "get_teams_timezones", "description": "List all IANA-supported time zones (used for scheduling and filtering calendar events)" } ], "next_cursor": null } }
# 将LLM连接到MCP服务器
示例:OpenAI API
from openai import OpenAI
client = OpenAI(api_key="your_api_key_here")
resp = client.responses.create( model="gpt-4.1", tools=[ { "type": "mcp", "server_label": "meetings_scheduler", "server_url": "https://yourdomain.com/mcp/", "require_approval": "never", }, ], input=""" "Schedule a meeting titled 'Project Sync' starting at 2025-09-01T14:00:00Z ending at 2025-09-01T15:00:00Z. The body is 'Discuss project updates'. " Please scheduel and let ,me know . required Attendee name is Naveen and email is example@email.com
""" ) print(resp) print(resp.output_text)
"Schedule a meeting titled 'Project Sync' starting at 2025-09-01T14:00:00Z ending at 2025-09-01T15:00:00Z. The body is 'Discuss project updates'. "
Please scheduel and let ,me know .
required Attendee name is Naveen and email is email@email.com
#could you please give me the event id of the meeting scheduled on August 9th, 2025 PST timezone with email@email.com """
#Can you please reschedule the meeting event id
ET4NwOuYku0EHBwC7MkKjdoRHQ4cHEDY3mToXAAAAAAENAAC7MkKjdoRHQ4cHEDY3mToXAAFPchCwAAA=
to sept 20, 2025 same time.
"""
Can you please cancel the interview event id is
AAMAyMy04ZTk2LTljOTI4OWRjYjg5MABGAAAAAABaL71tdJQET4NwOuYku0EHBwC7MkKjdoRHQ4cHEDY3mToXAAAAAAENAAC7MkKjdoRHQ4cHEDY3mToXAAFPchCwAAA=
## API 文档
有关端点和参数的更多详细信息,请参阅 [Microsoft Graph API文档](https://docs.microsoft.com/en-us/graph/api/overview).
## 贡献
欢迎投稿!我们鼓励您通过添加新工具或增强现有工具来做出贡献,以进一步改进此MCP服务器的功能。请通过GitHub提交问题或拉取请求。看 [贡献.md](CONTRIBUTING.md) 作为指导方针。
## 许可证
该项目根据MIT许可证获得许可。看 [许可证](LICENSE) 了解详情。