feat(outlook): 添加 Outlook MCP 集成支持并优化分页功能

- 新增 NANO_OUTLOOK_MCP_URL 和 NANO_OUTLOOK_MCP_SERVER_ID 环境变量配置
- 实现 Outlook 邮件和日历的分页查询功能,添加安全参数验证
- 为 app-instance 创建脚本添加 Outlook MCP 服务器 ID 参数
- 更新前端 Outlook 页面实现邮件列表和日历事件的分页浏览
- 添加 Git 忽略文件配置和 Docker 挂载路径修复

BREAKING CHANGE: Outlook 集成现在需要配置 MCP URL 和服务器 ID 环境变量
This commit is contained in:
2026-03-16 17:01:58 +08:00
parent 04501fea22
commit b3767dd4ab
20 changed files with 1671 additions and 83 deletions

View File

@ -16,6 +16,7 @@ HOST_PORT=""
PUBLIC_URL=""
AUTHZ_BASE_URL=""
AUTHZ_OUTLOOK_MCP_URL=""
OUTLOOK_MCP_SERVER_ID="${OUTLOOK_MCP_SERVER_ID:-outlook_mcp}"
BACKEND_ID=""
CLIENT_ID=""
CLIENT_SECRET=""
@ -60,6 +61,8 @@ Optional:
--authz-base-url <url> AuthZ service base URL.
--authz-outlook-mcp-url <url>
Managed Outlook MCP URL for AuthZ mode.
--outlook-mcp-server-id <id>
Default Outlook MCP server id. Default: outlook_mcp
--backend-id <id> Pre-assigned backend id.
--client-id <id> Pre-assigned AuthZ client id.
--client-secret <secret> Pre-assigned AuthZ client secret.
@ -133,6 +136,7 @@ render_config_json() {
API_BASE="$API_BASE" \
AUTHZ_BASE_URL="$AUTHZ_BASE_URL" \
AUTHZ_OUTLOOK_MCP_URL="$AUTHZ_OUTLOOK_MCP_URL" \
OUTLOOK_MCP_SERVER_ID="$OUTLOOK_MCP_SERVER_ID" \
BACKEND_ID="$BACKEND_ID" \
CLIENT_ID="$CLIENT_ID" \
CLIENT_SECRET="$CLIENT_SECRET" \
@ -145,12 +149,48 @@ from pathlib import Path
target = Path(os.environ["TARGET_PATH"])
provider = os.environ["PROVIDER"]
outlook_mcp_url = os.environ["AUTHZ_OUTLOOK_MCP_URL"].strip()
outlook_server_id = os.environ["OUTLOOK_MCP_SERVER_ID"].strip() or "outlook_mcp"
provider_cfg = {"apiKey": os.environ["API_KEY"]}
api_base = os.environ["API_BASE"].strip()
if api_base:
provider_cfg["apiBase"] = api_base
outlook_tool_names = [
"auth_status",
"mail_list_folders",
"mail_list_messages",
"mail_search_messages",
"mail_get_message",
"mail_send_email",
"mail_reply_to_message",
"mail_forward_message",
"mail_move_message",
"mail_delta_sync",
"calendar_list_events",
"calendar_create_event",
"calendar_update_event",
"calendar_get_schedule",
"calendar_find_meeting_times",
"calendar_delta_sync",
]
default_mcp_servers = {}
if outlook_mcp_url:
default_mcp_servers[outlook_server_id] = {
"command": "",
"args": [],
"env": {},
"url": outlook_mcp_url,
"headers": {},
"authMode": "oauth_backend_token",
"authAudience": f"mcp:{outlook_server_id}",
"authScopes": ["list_tools", *[f"tool:{name}" for name in outlook_tool_names]],
"toolTimeout": 60,
"sensitive": True,
}
data = {
"agents": {
"defaults": {
@ -163,12 +203,13 @@ data = {
},
"tools": {
"restrictToWorkspace": True,
"mcpServers": default_mcp_servers,
},
"authz": {
"enabled": bool(os.environ["AUTHZ_BASE_URL"].strip()),
"baseUrl": os.environ["AUTHZ_BASE_URL"].strip() or "http://127.0.0.1:19090",
"requestTimeoutSeconds": 10,
"outlookMcpUrl": os.environ["AUTHZ_OUTLOOK_MCP_URL"].strip(),
"outlookMcpUrl": outlook_mcp_url,
},
"backend_identity": {
"backendId": os.environ["BACKEND_ID"].strip(),
@ -281,6 +322,10 @@ while [[ $# -gt 0 ]]; do
AUTHZ_OUTLOOK_MCP_URL="${2:-}"
shift 2
;;
--outlook-mcp-server-id)
OUTLOOK_MCP_SERVER_ID="${2:-}"
shift 2
;;
--backend-id)
BACKEND_ID="${2:-}"
shift 2
@ -448,6 +493,7 @@ RUN_ARGS=(
-e "APP_PUBLIC_PORT=8080"
-e "APP_FRONTEND_PORT=3000"
-e "APP_BACKEND_PORT=18080"
-e "NANOBOT_OUTLOOK_MCP_SERVER_ID=${OUTLOOK_MCP_SERVER_ID}"
--label "nano.instance.id=${INSTANCE_ID}"
--label "nano.instance.slug=${INSTANCE_SLUG}"
--label "nano.instance.public_url=${PUBLIC_URL}"