EWS Meeting MCP 是一个通过本地部署 Exchange EWS 调度会议的 MCP 服务器与 CLI,主要面向前述严苛的企业场景:受监管团队、内网环境、严格安全审查、老旧 Exchange 部署,以及无法直接授予云端代理广泛 Microsoft 365 权限的组织。它给编码助手和桌面智能体提供安全、结构化的方式,用来读取 Outlook 收件箱消息与可用性、发现会议室、建议会议时段,并仅在显式人工确认后创建、更新或取消会议。
【用途与定位】 许多团队仍通过本地 Exchange/EWS 运行日历基础设施。通用代理可以推理调度,但不应拿到明文密码、猜测参会人地址或在没有可审查检查点的情况下发送会议邀请。本项目不是通用 Outlook 封装,也不是以 Microsoft Graph 为先的日历连接器,而是针对更严格的企业场景:本地 EWS 访问、房间资源、显式人工审批、重复发送保护,以及便于审计的会议生命周期工具。
【主要能力】
- 房间感知调度:查找参会人重叠的可用时间,并按 Exchange 发现或本地策略过滤会议室。
- 人在回路写操作:创建、更新、取消操作需要预览加匹配的 confirmation_id。
- Outlook 显示状态(Show As):创建或更新个人约会时可设置 show_as: "out_of_office"(EWS OOF)。空参会人与会议室不会发送邀请;此功能不配置邮件自动回复。
- 本地优先凭据处理:读取 .env、shell 环境或 macOS Keychain,密码不经过模型。
- 结构化恢复:初始化失败返回机器可读的错误码和面向用户的设置命令。
- 可审计性:生命周期预览、已确认操作、重复确认、进行中状态和结构化错误写入本地 JSONL 审计日志。
- 为智能体准备的说明:MCP 服务器暴露工具描述与初始化指引,仓库还包含一个配套技能(skill)。
【使用方式】
- 配置 EWS:在工作目录创建 .env 或提供等效环境变量。仅在 IT 确认已启用 Basic 认证且端点受 HTTPS 保护时使用 EWS_AUTH_TYPE=BASIC。
- 存储密码:本地开发可用通用的 ACCOUNT_PASSWORD 覆盖,但不要放进 MCP 配置。macOS 上 Keychain 比把密码写进 .env 或 MCP 客户端配置更安全。若省略 ACCOUNT_PASSWORD_KEYCHAIN_ACCOUNT,则使用 EWS_USERNAME。
- 添加 MCP 服务器:支持 npm 安装的 MCP 客户端或本地检出均可。
- 验证设置:第一条命令打印已配置端点和账号(不打印密码),第二条命令验证账号能连接 EWS。
【典型工作流】 读取收件箱邮件时,先搜索已配置收件箱再读取选中邮件;这些邮箱工具是只读的,不会标记已读、发信、移动邮件或改标签。针对周四 Jira 周报自动化,从 Jira 结果撰写报告,然后经由本 MCP 调用专用自我发送邮件工具 ews_send_email_to_self;该工具不接受收件人、to、cc、bcc 参数,收件人取自 EWS_EMAIL,经 Exchange EWS 发送并默认追加配置的 HTML 签名,不会把邮件正文或收件地址写入审计日志。自动化重试请复用同一幂等键;已完成或进行中的键不会再次调用 Exchange。
调度应遵循:先预览再确认。循环会议通过向预览和确认创建调用传入结构化 recurrence 对象来创建。若用户只要求“每周一和周三”这类没有结束日期、次数或明确无结束选择,预览前应先询问。修改已有会议应使用精确日历元数据;当存在多个候选时,代理绝不能凭主题文本推断事件。
【安全与限制】 设计原则是:读取可自动化,每次写入都必须有狭窄的安全闸门。收件箱读取仅限于显式只读搜索与读取工具;会议写入需要预览加显式确认;仅自我发送需配置自我强制加幂等保护。 认证失败快速终止(FailFast):一次无效凭据或账户锁定响应后,该进程内后续所有 EWS 调用被阻止;修复共享 Keychain 项并重启 MCP 后重试。已确认的创建、更新、取消工具必须传 confirm=true 才运行,且需要与预览匹配的 confirmation_id;更新和取消还需从 ews_find_calendar_events 或先前已验证结果取得精确 EWS id 与 changekey。重复确认请求返回 error_code: "duplicate_confirmation" 及先前结果元数据,不再调用 EWS;进行中的确认返回 "confirmation_in_progress",不应盲目重试。预览工具从不保存、移动、删除或发送 Exchange 通知。ews_send_email_to_self 是唯一的邮件写能力,仅限自己发送。若 ews_setup_check 返回 ready: false,代理应原样显示返回的 user_message 或 setup_command 并停止,不应索取参会人邮箱继续调度。
【调度策略】 默认在当前工作目录查找 ews-meeting-policy.json,可用 EWS_MEETING_POLICY_FILE 指向其他文件。若无策略文件则用内置默认:workday 10:00 到 18:00,avoid 12:00-14:00,fallback rooms 为 2-11、2-13、2-14、3-1、3-2、3-4。实时会议室选择优先用 Exchange 房间列表发现,再回退到配置房间。策略房间按别名与默认回退房间合并:匹配别名覆盖默认房间,新别名追加。
【CLI 与显示状态】 npm 包装器默认启动 MCP 服务器,传 --cli 可通过同一包运行 Python CLI。创建会议需 --confirm,否则只打印 dry-run 预览、不调用 EWS。创建和更新的预览/确认工具接受可选的 show_as:创建时省略保持现有 Busy 默认,更新时省略保留已存状态。个人预约使用 attendees: [] 和 rooms: [],并以 SendToNone 保存。调用 ews_create_meeting_preview 后应向用户展示开始/结束、时区偏移、show_as 和邀请行为;显式确认后调用 ews_create_meeting_confirmed 并传相同参数加 confirm: true 与返回的 confirmation_id。预览后更改状态会使该确认失效。查询/验证工具返回存储的 show_as 和原始 legacy_free_busy_status;用 ews_verify_meeting 在保存后读取服务器。此功能只影响日历状态,不影响邮件自动回复。
【开发与参考】 仓库包含 Usage Guide(本地设置、Keychain、调度策略、冒烟检查、CLI 示例、MCP 配置、npm 包装器)和 Agent Guide(工具契约、设置检查、参会人解析、会议室选择、预览-确认流程、审计日志、验证规则),以及 Publishing(npm 包与 GitHub Actions 发布清单)。配套技能供支持技能的代理使用。