MCP 集成(AI 工具访问)
Canopy 内置了一个 MCP 服务器(Model Context Protocol),允许 AI 工具(如 Claude Desktop、GitHub Copilot、Cursor 和 VS Code)直接查询并更新您的 EA 数据。AI 工具还可以上传工件(电子表格、BPMN 图、DrawIO 图、自由文档),并将其转化为符合现有元模型的卡片、关系和图表。用户通过现有的 SSO 提供商进行身份验证,每个操作都遵循其个人权限。
此功能是可选的,不会自动启动。它要求 SSO 已配置、MCP 配置文件在 Docker Compose 中已激活,并且管理员在设置界面中启用了它。
工作原理
AI 工具(Claude、Copilot 等)
│
│ MCP 协议(HTTP + SSE)
▼
Canopy MCP 服务器(:8001,内部)
│
│ OAuth 2.1 + PKCE
│ 委托给 SSO 提供商
▼
Canopy 后端(:8000)
│
│ 按用户 RBAC
▼
PostgreSQL
- 用户将 MCP 服务器 URL 添加到其 AI 工具中。
- 首次连接时,AI 工具会打开浏览器窗口进行 SSO 身份验证。
- 登录后,MCP 服务器会颁发自己的访问令牌(基于用户的 Canopy JWT)。该令牌会在到期前大约一小时被主动刷新。
- AI 工具将使用此令牌进行所有后续请求。
- 每个查询都通过 Canopy 的正常权限系统——用户只能看到他们有权访问的数据。
前提条件
启用 MCP 之前,您必须具备:
- 已配置且正常运行的 SSO —— MCP 将身份验证委托给您的 SSO 提供商(Microsoft Entra ID、Google Workspace、Okta 或通用 OIDC)。请参阅认证与 SSO 指南。
- 具有公共域名的 HTTPS —— OAuth 流程需要稳定的重定向 URI。请将 Canopy 部署在 TLS 终止反向代理(Caddy、Traefik、Cloudflare Tunnel 等)后面。
设置
步骤 1:启动 MCP 服务
MCP 服务器是一个可选启用的 Docker Compose 配置文件。在启动命令中添加 --profile mcp:
docker compose --profile mcp up -d
这会在后端和前端旁边启动一个轻量级 Python 容器(端口 8001,仅限内部)。Nginx 会自动将 /mcp/ 请求代理到该服务——如果容器未运行,请求会得到一个干净的 502 响应,而不会导致边缘代理崩溃。
步骤 2:配置环境变量
将以下内容添加到您的 .env 文件中:
CANOPY_PUBLIC_URL=https://your-domain.example.com
MCP_PUBLIC_URL=https://your-domain.example.com/mcp
| 变量 | 默认值 | 描述 |
|---|---|---|
CANOPY_URL | http://backend:8000 | MCP 容器所访问的内部后端 URL(Docker 服务名——很少需要更改)。 |
CANOPY_PUBLIC_URL | http://localhost:8920 | 您的 Canopy 实例的公共 URL。 |
MCP_PUBLIC_URL | http://localhost:8920/mcp | MCP 服务器的公共 URL(用于 OAuth 重定向 URI 和元数据)。 |
MCP_PORT | 8001 | MCP 容器的内部端口(很少需要更改)。 |
步骤 3:将 OAuth 重定向 URI 添加到 SSO 应用
在 SSO 提供商的应用注册中(与您为 Canopy 登录设置的相同),添加此重定向 URI:
https://your-domain.example.com/mcp/oauth/callback
这是用户从 AI 工具连接时 OAuth 认证流程所必需的。
步骤 4:在管理设置中启用 MCP
- 前往管理区域的设置,并选择 AI 选项卡。
- 滚动到 **MCP 集成(AI 工具访问)**部分。
- 切换开关以启用 MCP。
- 界面将显示 MCP 服务器 URL 和设置说明,供您与团队共享。
如果未配置 SSO,开关将被禁用。请先设置 SSO。
连接 AI 工具
启用 MCP 后,将 MCP 服务器 URL 分享给您的团队。每个用户将其添加到自己的 AI 工具中:
Claude Desktop
- 打开设置 > 连接器 > 添加自定义连接器。
- 输入 MCP 服务器 URL:
https://your-domain.example.com/mcp - 点击连接 —— 浏览器窗口将打开进行 SSO 登录。
- 认证后,Claude 即可查询并更新您的 EA 数据。
VS Code(GitHub Copilot / Cursor)
添加到工作区的 .vscode/mcp.json:
{
"servers": {
"canopy": {
"type": "http",
"url": "https://your-domain.example.com/mcp/mcp"
}
}
}
双重 /mcp/mcp 是有意为之——第一个 /mcp/ 是 Nginx 代理路径,第二个是 MCP 协议端点。
本地测试(stdio 模式)
对于不需要 SSO/HTTPS 的本地开发或测试,可以在 stdio 模式下运行 MCP 服务器——Claude Desktop 会将其直接作为本地进程启动。
1. 安装 MCP 服务器包:
pip install ./mcp-server
2. 添加到 Claude Desktop 配置(claude_desktop_config.json):
{
"mcpServers": {
"canopy": {
"command": "python",
"args": ["-m", "canopy_mcp", "--stdio"],
"env": {
"CANOPY_URL": "http://localhost:8000",
"CANOPY_PASSWORD": "your-password"
}
}
}
}
在此模式下,服务器会直接使用邮箱/密码进行身份验证(无需 OAuth),并在后台自动刷新 Canopy JWT。
可用功能
MCP 服务器共提供 47 个工具:涵盖九个集群的 30 个读取工具,以及 17 个写入工具(13 个附加型,4 个破坏性)。每个工具都携带 ToolAnnotations(readOnlyHint / destructiveHint / idempotentHint),因此像 Claude Desktop 这样的连接器可以在用户批准调用之前,在 其界面上呈现该操作的破坏性程度。
写入操作的演练安全机制
每个写入工具默认使用 dry_run=true。在此模式下,后端会运行每一个校验器和解析器,构建完整计划,然后回滚事务,因此不会持久化任何内容。AI 工具会将预览返回给用户;只有在用户明确确认后,才应再次以 dry_run=false 调用该工具进行提交。这可以防止过于热心的代理在解读错误的电子表格基础上,悄悄创建数百张卡片。
对于较大规模的提交,还有第二道关卡:任何超过 MCP_BATCH_CONFIRMATION_THRESHOLD(默认 20 行)的提交,都必须回传由上一次演练所颁发的一次性 confirm_token。该令牌的有效期为 15 分钟。这一规则会被强制执行两次——一次是在调用后端之前由 MCP 封装层执行,另一次是在提交端点上由后端自身执行——因此即便客户端跳过了演练步骤,也无法悄悄提交一个未经审查的大批量变更。
变更批次(审计轨迹)
每次写入调用——无论是否为演练——都会在触碰任何数据之前先创建一条 mutation_batches 记录,其发出的每个事件(卡片创建、关系创建/更新、评论发布……)都会被打上该批次 ID、调用的工具名称以及已认证用户的标记。get_change_history 工具可以根据批次 ID 还原该批次逐个事件的完整差异,rollback_batch 则可以撤销某个批次的写入操作(见下文)。这意味着任何由 MCP 驱动的更改,都可以精确追溯到究竟是谁在何时运行了哪个工具——这与通过 Web 界面执行的同一操作是可以区分的。
读取工具
服务器提供分布在九个集群中的 30 个读取工具。
卡片与元模型
| 工具 | 描述 |
|---|---|
search_cards | 按类型、状态或自由文本搜索和筛选卡片 |
get_card | 通过 UUID 获取卡片的完整详细信息 |
get_card_relations | 获取连接到卡片的所有关系 |
get_card_hierarchy | 获取卡片的祖先与子级 |
list_card_types | 列出元模型中的所有卡片类型,包括字段与配置 |
get_relation_types | 列出关系类型,可按卡片类型筛选 |
resolve_card_refs | 在批量导入前预校验基于名称的卡片引用(例如「Sales / Customer Mgmt / CRM」)——显示已解析 / 存在歧义 / 缺失的匹配结果 |
analyze_impact | 多跳影响分析——从某张卡片出发沿关系图向外遍历最多 3 跳,按深度分组,并可选按关系类型和卡片类型筛选 |
仪表盘
| 工具 | 描述 |
|---|---|
get_dashboard | KPI 仪表盘(计数、数据质量、审批、活动) |
get_landscape | 某一类型的卡片按相关类型分组 |
GRC — 风险登记册
| 工具 | 描述 |
|---|---|
list_risks | 分页可筛选的 EA 风险列表(TOGAF G 阶段) |
get_risk | 单条风险详情,含关联卡片与审计轨迹 |
get_risk_metrics | KPI 指标 + 初始与残余 4×4 概率 × 影响矩阵 |
get_card_risks | 当前与某卡片关联的所有风险 |
GRC — 合规
| 工具 | 描述 |
|---|---|
list_compliance_findings | 按法规分组的合规发现(EU AI Act、GDPR、NIS2、DORA、SOC 2、ISO 27001) |
get_compliance_overview | 合规评分 + 各法规状态矩阵 + 最近扫描元数据 |
治理与交付
| 工具 | 描述 |
|---|---|
list_principles | 已发布的 EA 原则(陈述、依据、影响) |
list_adrs | 架构决策记录(ADR),可按举措 / 卡片 / 状态 / 搜索词筛选 |
get_adr | 单条 ADR,含各章节、关联卡片、相关 ADR 与签署记录 |
list_soaws | 某项举措的架构工作说明书(SoAW) |
报告
| 工具 | 描述 |
|---|---|
get_portfolio_report | 某卡片类型的气泡图数据(默认:功能契合度 × 技术契合度) |
get_cost_treemap | 卡片成本树形图,可选按相关类型分组 |
get_capability_heatmap | 层级化的业务能力热图 |
get_data_quality_report | 按卡片类型划分的数据完整度明细 |
卡片上下文
| 工具 | 描述 |
|---|---|
get_card_stakeholders | 卡片上分配的用户与角色 |
get_card_comments | 卡片的评论线程 |
get_card_documents | 附加到卡片的文档链接 |
图表
| 工具 | 描述 |
|---|---|
list_diagrams | 列出自由绘制图,可选筛选到某张卡片 |
get_diagram | 通过 ID 获取单个图,包含其 DrawIO XML |
审计与变更历史
| 工具 | 描述 |
|---|---|
get_change_history | 通过 ID 查询某个变更批次(返回该批次及其下按顺序发出的每个事件),或按操作者、工具名称或来源(mcp / web / api)浏览近期批次 |
所有读取工具都受已认证用户 RBAC 的约束——查看者在其无权访问的领域只会得到空列表(或 403);MCP 层无需针对每个工具单独配置。
写入工具
服务器提供 17 个写入工具:13 个附加型(不会破坏数据的创建/更新操作)和 4 个破坏性(可能覆盖或删除数据,尽管其中几个本身是可恢复的——详见下文说明)。
卡片与生命周期
| 工具 | 标注 | 描述 |
|---|---|---|
create_cards_bulk | 附加型 | 在一次调用中根据从工件中提取的行(例如电子表格的多行)批量创建多张卡片。支持在同一批次内按名称引用父卡片,并由服务端执行拓扑排序。 |
update_cards_bulk | 附加型 | 在一次调用中批量更新多张卡片——字段级补丁,演练模式下会给出每行的修改前/后对比。attributes 按行整体替换;strict_attributes=true 会拒绝未知字段键并给出修复提示。 |
transition_card_lifecycle | 附加型 | 推进卡片的审批操作(approve / reject / reset)、生命周期阶段(phaseIn / active / phaseOut / endOfLife)或状态值(ACTIVE / PHASING_IN / PHASING_OUT / END_OF_LIFE / ARCHIVED)。若调用者缺少相应权限,会返回带有 UI 深链接的 pending 响应,而非直接失败。 |
archive_cards | 破坏性 | 对一张或多张卡片执行软删除(归档),演练模式下会给出级联预览(子卡片、孤立关系)。已归档的卡片在自动清除前有 30 天的可恢复期。MCP 有意不暴露硬删除/永久删除功能。 |
关系与图表
| 工具 | 标注 | 描述 |
|---|---|---|
upsert_relations_bulk | 破坏性 | 在卡片之间创建或删除关系。默认拒绝 action: "delete"(详见下文防护栏)——这也是尽管创建关系是常见用例,该工具仍被标注为破坏性的原因。 |
create_diagram | 附加型 | 创建一个自由形式的 DrawIO 图,可选通过 UUID 链接到已有卡片。 |
update_diagram | 破坏性 | 更新已有图的 XML、名称、描述或关联卡片——drawio_xml 会原样替换整个画布。 |
import_bpmn | 附加型 | 将 BPMN 2.0 图保存到已存在的业务流程卡片上,并走完草稿 → 提交 → 审批的工作流。如果没有匹配的卡片,会返回 card_not_found 错误并指向 create_cards_bulk,而不是悄悄创建一张内容稀薄的卡片。 |
GRC — 风险登记册
| 工具 | 标注 | 描述 |
|---|---|---|
create_risks | 附加型 | 创建一条或多条风险,可在同一次调用中关联受影响的卡片。 |
update_risks | 附加型 | 按 ID 修改已有风险;若提供 linked_card_ids,将替换受影响卡片的关联集合。 |
治理与交付
| 工具 | 标注 | 描述 |
|---|---|---|
create_soaw | 附加型 | 为某项举措创建架构工作说明书(SoAW)。 |
create_adr | 附加型 | 创建一条架构决策记录(默认落入 draft 状态)。 |
update_adr | 附加型 | 更新已有 ADR 的标题、章节、状态或关联卡片。 |
sign_adr | 附加型 | 签署一条 ADR。若调用者缺少 adr.sign 权限,会返回带深链接的 pending 响应。 |
协作
| 工具 | 标注 | 描述 |
|---|---|---|
add_card_comment | 附加型 | 在卡片上发表评论(可选作为线程回复)。 |
assign_stakeholders | 附 加型 | 为卡片分配或移除利益相关者角色。后端没有针对此操作的批量端点,因此该工具会在单个变更批次内逐条分发执行。 |
审计
| 工具 | 标注 | 描述 |
|---|---|---|
rollback_batch | 破坏性 | 撤销某个变更批次下执行的写入操作,方法是反向遍历其事件并对每个事件执行相应的逆操作。覆盖 card.created / card.updated / card.archived / card.restored / relation.created / relation.upserted;其他事件类型会在演练计划中标记为 unsupported_events。回滚操作本身会被记录为一个新的批次,因此历史记录永远不会被抹除。如果有更晚的批次触碰了相同的实体,则默认拒绝执行,除非设置 force=true(需要 admin.events 权限)。 |
这些工具存储的内容(评论正文、ADR/SoAW 章节文本)在后续读取时被视为不受信任的数据——服务器绝不会将其解释为指令,只会原样展示。
典型的工件导入工作流
当用户与 AI 代理共享电子表格时:
- 代理调用
list_card_types和get_relation_types以理解元模型。 - 代理解析电子表格(在其自身上下文中完成,而非在 MCP 中),并构建行字典。
- 代理可选地调用
resolve_card_refs,以检查任何基于名称的父级/关系引用是否能唯一解析。