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

@ -2312,6 +2312,11 @@ def _register_routes(app: FastAPI) -> None:
server_id = req.id.strip()
if not server_id:
raise HTTPException(status_code=400, detail="Server id is required")
auth_mode = (req.auth_mode or "none").strip().lower() or "none"
auth_audience = (req.auth_audience or "").strip()
auth_scopes = [str(item).strip() for item in list(req.auth_scopes or []) if str(item).strip()]
if auth_mode == "oauth_backend_token" and not auth_audience:
auth_audience = f"mcp:{server_id}"
config.tools.mcp_servers[server_id] = MCPServerConfig(
command=req.command,
@ -2319,9 +2324,9 @@ def _register_routes(app: FastAPI) -> None:
env=req.env,
url=req.url,
headers=req.headers,
auth_mode=req.auth_mode,
auth_audience=req.auth_audience,
auth_scopes=req.auth_scopes,
auth_mode=auth_mode,
auth_audience=auth_audience,
auth_scopes=auth_scopes,
tool_timeout=req.tool_timeout,
sensitive=req.sensitive,
)
@ -2460,6 +2465,56 @@ def _register_routes(app: FastAPI) -> None:
except Exception as exc: # noqa: BLE001
raise HTTPException(status_code=400, detail=str(exc)) from exc
@app.get("/api/integrations/outlook/messages")
async def get_outlook_messages(
folder: str = "inbox",
top: int = 20,
skip: int = 0,
unread_only: bool = False,
):
from nanobot.web.outlook import OutlookIntegrationError, list_messages
config: Config = app.state.config
if not folder.strip():
raise HTTPException(status_code=400, detail="folder is required")
try:
return await list_messages(
config,
folder=folder.strip(),
top=top,
skip=skip,
unread_only=unread_only,
)
except OutlookIntegrationError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
except Exception as exc: # noqa: BLE001
raise HTTPException(status_code=400, detail=str(exc)) from exc
@app.get("/api/integrations/outlook/events")
async def get_outlook_events(
start_time: str,
end_time: str,
top: int = 20,
skip: int = 0,
):
from nanobot.web.outlook import OutlookIntegrationError, list_events
config: Config = app.state.config
if not start_time.strip() or not end_time.strip():
raise HTTPException(status_code=400, detail="start_time and end_time are required")
try:
return await list_events(
config,
start_time=start_time.strip(),
end_time=end_time.strip(),
top=top,
skip=skip,
)
except OutlookIntegrationError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
except Exception as exc: # noqa: BLE001
raise HTTPException(status_code=400, detail=str(exc)) from exc
@app.get("/api/integrations/outlook/message-detail")
async def get_outlook_message_detail(message_id: str, changekey: str | None = None):
from nanobot.web.outlook import OutlookIntegrationError, get_message_detail