← 返回信息流
AI 资讯Hacker News·3 天前

Show HN:别再让 MCP 服务器返回原始 JSON,构建丰富内联 UI

原标题:Show HN: Stop returning raw JSON from MCP servers, build rich inline UIs

速览

该帖子建议 MCP 服务器停止返回原始 JSON 数据,转而构建丰富的内联用户界面。这种做法能够显著提升人机交互的直观性和用户体验。通过内联 UI,用户可以更直接地查看和操作数据,而无需解析复杂的 JSON 结构。

AI 深度解读

Show HN:停止从 MCP 服务器返回原始 JSON,构建丰富的内联 UI

背景

回顾人工智能工具集成的早期阶段,许多开发者都经历过类似的震撼与失落。当首次将简单的天气工具接入 Claude 时,看着模型主动发起调用、获取实时数据并将其编织进回复中,这种体验确实令人着迷。然而,当终端中显示出一大段原始 JSON 数据时,这种兴奋感往往迅速消退。

尽管模型能够准确报告当前温度和天气状况,但它无法展示预报卡片、地图或实时图表。一切仍局限于纯文本。这种局限性在直觉上可能并不显著,但在实际应用中却至关重要:在一个界面至关重要的世界里,一个孤立的数字与一个能让人一眼看出趋势的图表有着天壤之别。

MCP(Model Context Protocol,模型上下文协议)为 AI 代理提供了一套标准化的方式来连接外部世界,但这个世界长期被困在纯文本接口中。直到 MCP Apps 的出现,才打破了这一僵局。如今,通过 Spotify 的 MCP App 向 Claude 请求音乐时,用户获得的是可直接交互的小部件,而非 Markdown 格式的数字列表。

核心内容

MCP Apps 是 MCP 协议在 2026 年初标准化的一项正式扩展。其核心理念是:MCP 服务器不仅可以声明工具,还可以声明 UI 资源。当支持该扩展的主机(如 Claude)调用工具时,它可以在对话中内联渲染完整的交互式 HTML 小部件,而不仅仅是以文本形式打印结果。

架构角色

在 MCP Apps 的实现中,主要涉及三个角色:

  1. Server(服务器):开发者编写的代码。它声明工具、提供数据,并在 ui:// URI 处注册 UI 布局。
  2. Host(主机):用户与之聊天的客户端(如 Claude Desktop、Cursor、Copilot 等)。
  3. View(视图):在 iframe 中运行的 HTML 和 JavaScript。它负责渲染工具结果,并允许用户在交互时请求主机再次调用工具。

对于不支持该扩展的主机,它们会忽略 UI 元数据,继续返回纯文本工具输出,从而保证了向后兼容性。完整规范位于 apps.extensions.modelcontextprotocol.io

工作流程解析

以天气查询为例,整个交互循环如下:

  1. 用户询问天气预报。
  2. 主机调用服务器上的 show_weather 工具。
  3. 服务器返回数据以及工具元数据中的 ui:// 链接。
  4. 主机获取 HTML 资源并挂载视图(View)。
  5. 主机将工具结果推送到 iframe 中。
  6. 用户切换摄氏度/华氏度或点击刷新。
  7. 视图请求主机调用 fetch_weather(注意:这是应用级工具,而非模型工具)。
  8. 服务器返回新数据,卡片就地更新。

关键技术细节

实现这一机制有两个关键细节:

  • 元数据链接:将工具与其 UI 链接只需一个元数据字段:
    "_meta": {
      "ui": {
        "resourceUri": "ui://weather-mcp-app/forecast-card.html",
        "visibility": ["model", "app"]
      }
    }
    
  • 可见性隔离:并非所有工具都属于模型的“工具列表”。刷新按钮或单位切换等功能应使用 visibility: ["app"]。这意味着模型永远看不到这些工具。这一洞察揭示了 MCP Apps 的本质:它们不是聊天中更漂亮的 JSON,而是一个拥有自己工具集的“第二个客户端”,生活在对话内部。

案例演示:天气卡片

作者通过一个 Python 示例展示了这一过程。服务器端代码使用 FastMCP 库,主要执行三项操作:将工具链接到视图、获取天气数据、并将交互式工具对模型隐藏。

from mcp.server.fastmcp import FastMCP
from mcp import types

VIEW_URI = "ui://weather-mcp-app/forecast-card.html"
mcp = FastMCP("Weather Card", stateless_http=True)

# 主工具:对模型可见,链接到 UI
@mcp.tool(meta={"ui": {"resourceUri": VIEW_URI}, "ui/resourceUri": VIEW_URI})
def show_weather(city: str = "London", units: str = "celsius") -> types.CallToolResult:
    payload = _lookup(city, units) # 调用 Open-Meteo
    return types.CallToolResult(
        content=[types.TextContent(type="text", text=_text_summary(payload))],
        structuredContent=payload,
    )

# 应用级工具:仅对 UI 可见,模型不可见
@mcp.tool(meta={"ui": {"visibility": ["app"]}})
def fetch_weather(city: str, latitude: float, longitude: float, units: str = "celsius") -> types.CallToolResult:
    """刷新或切换单位。仅限 UI 使用,对模型隐藏。"""
    payload = _fetch_weather(city=city, latitude=latitude, longitude=longitude, units=units)
    return types.CallToolResult(
        content=[types.TextContent(type="text", text=_text_summary(payload))],
        structuredContent=payload,
    )

# 注册 UI 资源
@mcp.resource(VIEW_URI, mime_type="text/html;profile=mcp-app",
              meta={"ui": {"csp": {"resourceDomains": ["https://unpkg.com"]}}})
def forecast_card_view() -> str:
    return EMBEDDED_VIEW_HTML

在此架构中,外部 API 调用保留在服务器端的 Python 中,而视图仅与主机通信。

进阶应用:LangMCP 调试

除了演示性的天气卡片,作者正在将 MCP Apps 应用于更复杂的场景:LangMCP。这是一个用于检查 LangGraph 检查点、线程状态和长期记忆的只读 MCP 服务器。

LangMCP 的文本工具已经能够服务于代理,而 MCP App 则是叠加在其上的视图层。其模式与天气卡片相同:show_inspector 供模型使用,__ui_* 辅助函数处理 iframe 内的点击事件,底层共享相同的 Python 路径。这使得在 MCP 主机内部实现图遍历器的调试体验成为可能,相比纯文本,它能更好地处理序列化和分支的检查点历史。

关键要点

  • 从文本到交互:MCP Apps 允许 MCP 服务器在对话中内联渲染交互式 HTML 小部件,突破了纯文本输出的限制。
  • 双向通信机制:通过 ui:// URI 和元数据,服务器可以将工具结果与特定的 UI 视图绑定。
  • 工具可见性分离:引入了 visibility 概念,区分“模型可见”工具和“应用可见”工具。后者(如刷新、切换单位)由 UI 直接触发,不经过 LLM 推理,提高了效率和安全性。
  • 向后兼容:不支持 MCP Apps 的主机会自动忽略 UI 元数据,继续以传统方式处理工具输出。
  • 实际应用场景
    • 天气卡片:展示实时数据,支持用户直接切换单位或刷新,无需重新询问模型。
    • LangGraph 调试:通过可视化界面检查复杂的图状态和检查点历史,比阅读嵌套 JSON 更直观。

意义与影响

MCP Apps 标志着 AI 工具集成的一个重要转折点。最强大的 AI 工具将不再是那些能生成最长回答的工具,而是那些能让答案易于理解并便于操作的工具。

  1. 提升认知效率:一个可以切换单位的天气预报、一个一目了然的日程表、一个允许逐步跟踪图运行而无需阅读原始 JSON 的调试视图,这些都不是表面的美化,而是显著改变了人类理解信息和做出决策的速度。
  2. 确立 UI 层标准:数据层已经存在,协议已经运行。MCP Apps 的加入填补了 UI 层的空白,为 AI 代理与人类交互提供了更丰富、更原生的体验。
  3. 开发者体验优化:对于开发者而言,这意味着可以更精细地控制 AI 代理的输出展示方式,将复杂的结构化数据转化为直观的用户界面,从而提升最终用户的生产力。

总之,MCP Apps 不仅仅是一个

查看原文 →medium.com