当前位置: 首页 > news >正文

当 AI 不再只是“说话“:OpenClaw.NET 率先原生支持 MCP Apps

从"对话"到"界面":MCP Apps 的诞生

1.1 当前 AI 交互的痛点

相信你已经深有体会:今天的 AI 助手,无论是 Claude、ChatGPT 还是基于大模型的各种 Agent,核心交互方式都是文本对话。你问一句,AI 答一段。需要数据分析?AI 给你生成一段 Markdown 表格。需要可视化?它最多画一张静态的 ASCII 图表。

这种模式在简单场景下够用,但一旦涉及复杂操作——筛选数据、调整参数、实时预览——"对话"就成了效率的瓶颈。

开发者们很早就意识到这个问题。既然 MCP 协议已经让 AI 能够调用外部工具,为什么不进一步让工具返回的不仅是文本,而是一套完整的交互界面呢?

1.2 MCP Apps 是什么

MCP Apps(仓库名ext-apps)是 MCP 协议的官方扩展,由 Anthropic 于 2026 年 1 月 26 日正式发布。它的核心能力可以用一句话概括:

MCP 工具可以返回交互式 UI,直接嵌在 Claude、ChatGPT 的对话窗口里。

具体来说,对话窗口中会嵌入一个真实的 iframe,里面跑的是由 MCP Server 提供的前端代码。按钮能点、图表能拖、表单能填,数据在前后端之间双向流动。

最关键的是它的渐进增强设计哲学:支持渲染的客户端显示交互界面;不支持的客户端(比如终端工具)照样收到纯文本,不会破坏任何现有功能。

1.3 三方架构模型

MCP Apps 的架构由三个核心角色组成:

┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ MCP Server │ │ Host │ │ View │ │ │ │ │ │ │ │ • 注册工具 │◄────┤ • Claude Desktop │◄────┤ • iframe 沙箱 │ │ • 暴露资源 │ │ • ChatGPT │ │ • 前端渲染 │ │ • UI 资源声明 │ │ • VS Code │ │ • 用户交互 │ │ │ │ • 数据中转 │ │ │ └─────────────────┘ └──────────────────┘ └─────────────────┘ ▲ │ │ └───────────────────────┴────────────────────────┘ 所有通信经 Host 中转
角色职责实例
MCP Server注册工具时在_meta.ui.resourceUri里指向ui://资源Grocery Inventory API
Host创建 iframe、负责数据搬运、通信中转Claude Desktop、ChatGPT、VS Code Insiders
View跑在 iframe 沙箱里的前端代码,渲染界面,反向调用 Server 工具仪表盘、地图、图表组件

一个关键的架构约束:View 不能直接跟 MCP Server 通信,所有通信必须经过 Host 中转。这确保了安全性和可审计性。

1.4 View 的七种能力

View 并不是简单的静态页面,它拥有一整套与 MCP Server 和 Host 交互的能力:

能力作用
tools/call调用 Server 的工具
resources/read读取 Server 的资源
ui/message往对话里插入消息
ui/update-model-context静默更新模型上下文(核心能力,用户在 UI 上的操作实时反馈给 LLM)
ui/open-link打开外部链接
ui/request-display-mode切换显示模式:inline/fullscreen/pip
visibility工具可见性控制,["app"]标记仅 View 可调

其中,ui/update-model-context是实现Human-in-the-Loop的核心机制。用户在 UI 上的每一次操作——点了哪个按钮、改了哪个筛选条件、选了哪个时间范围——都可以通过这条通道实时反馈给大模型,形成一个用户操作 → 更新上下文 → LLM 重新决策 → 刷新界面的完整闭环。

1.5 MCP Apps 的价值

MCP Apps 的出现,本质上是在回答一个 AI 产品设计的核心命题:如何让 AI 干活,同时在关键节点上让人确认?

传统的 Agent 模式是"AI 决定 → 执行 → 告诉你结果",用户全程被动。而 MCP Apps 开启了一种新的范式:"AI 决定调什么工具 → 给你一个交互界面 → 你在界面上确认/调整 → 结果实时反馈给 AI 继续处理"。

这不仅仅是"更好看的输出",而是人机协作范式的升级


二、OpenClaw.NET 率先响应:PR #168 的意义

2.1 .NET 生态的"第一个"

MCP Apps 协议发布后,各路 SDK 和框架开始跟进。但在 .NET 生态中,率先给出完整答案的是OpenClaw.NET

PR #168(作者:geffzhang,已合并至 main 分支)为 OpenClaw.NET 增加了原生的 MCP App 支持。这个 PR 的规模充分体现了其工程完整度:

  • +4,012 行代码,22 个文件变更
  • 43 个全新单元测试
  • 2,308 个现有测试全部通过,零破坏性变更
  • 中英双语文档

这个数字很有意思:4,000+ 行新代码,却没有任何破坏性变更。这说明 OpenClaw.NET 的架构设计从一开始就为扩展预留了足够的空间。

2.2 为什么是"第三层"架构

要理解 OpenClaw.NET 的 MCP App 支持,我们需要先看看它已有的 MCP 相关架构。

在 PR #168 之前,OpenClaw.NET 已经在两个维度上支持了 MCP:

层级模块方向用途
MCP ServerOpenClaw.Gateway/Mcp对外暴露把 OpenClaw 自身作为 MCP Server,对外提供工具
MCP ClientOpenClaw.Agent/Plugins对内消费连接外部 MCP Server,消费第三方工具
MCP App (新增)OpenClaw.McpApp托管管理发现、管理、托管第三方 MCP 应用

前两层解决的是"如何连接"的问题:作为 Server 被连,或作为 Client 去连别人。而新增的第三层OpenClaw.McpApp解决的是一个更上层的问题:如何在一个统一的框架内,大规模地管理、运行、协调多个 MCP 应用?

这不是简单的"再加一个客户端",而是一个完整的应用生命周期管理层


三、三层架构的完整图景

让我们把三个层级放在一起,看看 OpenClaw.NET 的 MCP 架构全景:

┌─────────────────────────────────────────────────────────────────────┐ │ OpenClaw.NET 生态 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────┐ │ │ │ OpenClaw.Gateway │ ◄── 外部 MCP Client(如 Claude Desktop) │ │ │ (MCP Server 层) │ 通过 MCP 协议连接 │ │ │ │ │ │ │ 暴露 OpenClaw 工具 │ │ │ │ 作为标准 MCP Server │ │ │ └──────────┬──────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────┐ ┌──────────────────────────────────┐ │ │ │ OpenClaw.McpApp │ │ OpenClaw.Agent/Plugins │ │ │ │ (MCP App 托管层) │ │ (MCP Client 层) │ │ │ │ │ │ │ │ │ │ • 发现 MCP App │ │ • 连接到外部 MCP Server │ │ │ │ • 管理生命周期 │ │ • 消费外部工具 │ │ │ │ • 维护连接状态 │ │ • 集成到 Agent 工作流 │ │ │ │ • 桥接为 ITool │◄────┤ │ │ │ │ │ │ 方向:Client → 外部 Server │ │ │ │ 方向:Host → 托管 App│ │ │ │ │ └──────────┬──────────┘ └──────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 第三方 MCP App 生态 │ │ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ │ │ │ │ │库存管理 │ │系统监控 │ │地图服务 │ │PDF 查看器 │ │ │ │ │ │(grocery) │ │(system) │ │(map) │ │(pdf) │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘

这个架构的精妙之处在于方向性的清晰划分

  • MCP Server 层(向外):OpenClaw 说"我的工具在这里,谁来连我"
  • MCP Client 层(向内):OpenClaw 说"我去看外面有什么工具可以用"
  • MCP App 层(托管):OpenClaw 说"我来管理和运行这些完整的 MCP 应用"

四、核心组件深度解析

OpenClaw.McpApp项目包含 7 个核心组件,它们共同构成了一个完整的 MCP 应用托管平台。让我们逐一拆解。

4.1 McpAppManifest — 应用的"身份证"

每个 MCP App 都需要一个openclaw.mcpapp.json清单文件,它定义了应用的基本信息、传输方式和能力声明。

{ "id": "grocery-inventory", "name": "Grocery Inventory Manager", "description": "Multi-store inventory management system", "version": "1.0.0", "transport": "http", "url": "https://localhost:5001/mcp", "hasUi": true, "uiResourceUri": "ui://grocery/store-dashboard.html", "toolNamePrefix": "grocery.", "capabilities": ["tools", "resources", "prompts", "completions"] }

这个设计体现了几个关键考量:

  • transport支持stdio(子进程)、http(远程端点)、inprocess(进程内),覆盖了从本地工具到远程服务的全部场景
  • toolNamePrefix避免了命名冲突——grocery.inventory.searchsales.inventory.search可以共存
  • hasUi+uiResourceUri声明了交互式 UI 的能力和资源地址
  • capabilities显式声明支持的功能,便于 Host 做能力协商

4.2 McpAppInstallState — 六阶段生命周期

每个 MCP App 从被发现到最终运行,会经历一个严格定义的状态机:

┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Discovered │───►│ Validated │───►│ Loaded │ │ (被发现) │ │ (已验证) │ │ (已加载) │ └─────────────┘ └──────┬──────┘ └──────┬──────┘ │ │ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ Disabled │ │ Running │ │ (禁用) │ │ (运行中) │ └─────────────┘ └──────┬──────┘ │ ┌────────────────────┘ ▼ ┌─────────────┐ ┌─────────────┐ │ Stopped │◄─────│ Failed │ │ (已停止) │ │ (失败) │ └─────────────┘ └─────────────┘
状态含义转换条件
Discovered清单文件被扫描发现自动扫描触发
Validated清单格式验证通过JSON Schema 校验
Disabled被配置显式禁用Enabled: false
Loaded应用配置已加载验证通过后自动进入
Running连接已建立,工具可用McpAppServer成功连接
Stopped已停止运行框架关闭或手动停止
Failed连接或运行出错超时、网络错误、协议错误

这个状态机的价值在于可观测性和可控性。在生产环境中,你可以精确知道每个 MCP App 处于什么状态,出了什么问题,而不是面对一个"连不上"的黑盒。

4.3 McpAppDiscovery — 智能发现机制

McpAppDiscovery是一个递归清单扫描器,负责在指定路径下自动发现 MCP App:

// Discovery 配置示例 { "DiscoveryPaths": ["./mcpapps"], // 扫描哪些目录 "Allow": ["grocery-*", "monitor*"], // 白名单,支持 glob 模式 "Deny": ["*-test", "deprecated-*"] // 黑名单,优先于 Allow }

扫描器会递归搜索**/openclaw.mcpapp.json文件,反序列化后进行验证,再通过allow/deny/glob过滤规则筛选。这套机制让 MCP App 的部署变得极其简单——把应用目录扔进去,框架自己找到并加载

4.4 McpAppServer — 连接的生命周期管理

McpAppServer负责管理单个 MCP App 的连接生命周期。它的核心职责包括:

  • 根据transport类型选择连接方式(stdio 子进程 / HTTP 端点 / 进程内)
  • 建立 MCP 协议连接
  • 枚举可用的toolsresourcesprompts
  • 生成IMcpAppInfoProvider供上层使用
  • 支持幂等重连——连接断开时自动恢复
// 伪代码示意 class McpAppServer { // 幂等启动:如果已经在运行,直接返回 async Task StartAsync() { if (State == ConnectionState.Connected) return; // 根据 transport 创建连接 var transport = transportType switch { "stdio" => new StdioTransport(executablePath), "http" => new HttpTransport(endpointUrl), "inprocess" => new InProcessTransport(instance), _ => throw new NotSupportedException() }; // 连接、握手、枚举能力 await transport.ConnectAsync(); var capabilities = await EnumerateCapabilitiesAsync(); State = ConnectionState.Connected; } }

4.5 McpAppNativeTool — 无缝桥接到 ITool

这是整个架构中最关键的"胶水层"。McpAppNativeTool将远程 MCP App 提供的工具,桥接到 OpenClaw 内部的ITool接口:

┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ MCP App │ │ McpAppNativeTool │ │ OpenClaw Agent │ │ (远程) │◄───────►│ (桥接层) │◄───────►│ (ITool 接口) │ │ │ MCP │ │ ITool │ │ │ • search │ 协议 │ 封装远程调用 │ 协议 │ Agent 无感调用 │ │ • update │ │ 统一错误处理 │ │ │ │ • delete │ │ 参数/结果映射 │ │ │ └─────────────────┘ └──────────────────┘ └─────────────────┘

对于 Agent 来说,调用一个 MCP App 的工具和调用一个原生插件的工具没有任何区别。Agent 不需要知道grocery.inventory.search是来自一个本地函数还是一个远程 HTTP 服务——这一切都被桥接层透明地处理了。

4.6 McpAppRegistry — 集中注册表

McpAppRegistry是整个 MCP App 子系统的"指挥中心":

  • 管理全部 App 的发现、连接和追踪
  • 协调McpAppDiscoveryMcpAppServer
  • 提供查询接口:按 ID 查找、按能力过滤、按状态筛选
  • 处理启动时的批量连接和关闭时的优雅清理

4.7 McpAppServiceExtensions — 极简的 DI 注册

最后,McpAppServiceExtensions提供了一行代码完成所有注册的体验:

// Program.cs builder.Services.AddOpenClawMcpApps(builder.Configuration.GetSection("McpApps"));

框架内部会依次注册 Discovery → Registry → Server Factory → NativeTool Factory,完全不需要手动干预。


五、实战:从配置到运行

5.1 Gateway 配置

appsettings.json中新增McpApps配置节:

{ "McpApps": { "Enabled": true, "DiscoveryPaths": ["./mcpapps"], "Allow": ["*"], "Deny": [], "Entries": { "grocery-inventory": { "Enabled": true, "Url": "https://localhost:5001/mcp", "ToolNamePrefix": "grocery.", "StartupTimeoutSeconds": 15 } } } }

配置分为两部分:

  • 全局配置Enabled总开关、DiscoveryPaths扫描路径、Allow/Deny过滤规则
  • 应用配置Entries下每个 MCP App 的具体连接参数

零开销设计McpApps.Enabled默认为false。如果你不启用这个功能,整个OpenClaw.McpApp模块不会被激活,对性能和启动时间没有任何影响。

5.2 启动流程

OpenClaw Gateway 启动时,MCP App 子系统会按以下顺序执行:

appsettings.json / GatewayConfig.McpApps │ ▼ McpAppDiscovery 扫描 DiscoveryPaths(默认 ./mcpapps/) 查找 **/openclaw.mcpapp.json 反序列化 + 验证 + allow/deny 过滤 │ ▼ McpAppInstallState(每个 App 一个实例) 生命周期: Discovered → Validated → [Disabled|Failed] → Loaded → Running → Stopped │ ▼ McpAppRegistry 管理全部 App 的集中注册表 调用 McpAppServer 建立连接
http://www.jsqmd.com/news/1139566/

相关文章:

  • freeCodeCamp前端开发库认证:从零到专业的完整学习指南
  • 本地部署AI生图与视频生成:从环境配置到生产实践指南
  • windows远程桌面连接软件 电脑怎么远程控制
  • 别再把 Claude Code 用乱了:CLAUDE.md、Rules、Skills、Hooks 到底怎么分工?
  • Java毕设选题推荐:基于 SpringBoot 的农产品行情研究报告智能管理系统的设计与实现 基于 SpringBoot+Vue 的全国农业研【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 【Java课程设计/毕业设计】基于 SpringBoot 的农产品研究报告分类检索系统的设计与实现 基于 SpringBoot+Vue 的智慧农业研究报告管理平台【附源码、数据库、万字文档】
  • 理解Shell:从命令到原理
  • Python密码学实战:深入解析cryptography库中的密钥派生函数
  • 武汉智能体选型对比:评价与推荐
  • “人机共生,产需共融”,2026世界机器人大会定档8月19日至23日
  • 探索Urho3D:一款轻量级跨平台游戏引擎的5大核心优势
  • 2026美缝剂用量怎么算?缝隙宽度和砖缝面积对照表
  • 沙利文全栈AI云服务报告:阿里云占比40.1%,超第二至第四名总和
  • Vue 懒挂载组件设计
  • DApp合约审计多少钱?项目有必要做智能合约审计吗?
  • Claude Code 中转站怎么选?从稳定性、缓存到成本的完整判断
  • CTF实战:从ZIP伪加密识别到时间戳掩码爆破的完整解题思路
  • 英雄联盟智能工具箱:3分钟掌握League Akari的终极使用技巧
  • 【计算机Java毕业设计案例】基于 SpringBoot 的农产品年度研究报告台账系统的设计与实现 基于 SpringBoot+Vue 的农产品数据研究成果管理系统(程序+文档+讲解+定制)
  • 2026国产CAD软件排行
  • 解放双手的智能游戏助手:基于图像识别的鸣潮自动化系统深度解析
  • 通用轴承密封选型参考梳理J型四氟油封密封圈是否合适?
  • 天幕传媒全品类活动物料定制,自主供应链与标准化品控体系
  • 猫抓浏览器扩展:新手快速上手指南 - 简单三步学会网页资源嗅探
  • Balena Etcher:如何重新定义系统镜像烧录的体验?
  • 2026年AI PPT制作工具横评:PaperRed、ChatGPT、豆包,谁才是答辩神器?
  • 直驱电机之DD马达选型
  • 128.工业级故障安全!PLC 电机正反转|软硬件双互锁 + 过载保护全套源码
  • Java毕设项目:基于 SpringBoot 的全国农产品调研数据管理系统的设计与实现 基于前后端分离的农业行业报告发布管理系统 (源码+文档,讲解、调试运行,定制等)
  • 敏捷测试转型:自动化与AI融合的工程实践与策略指南