12.5 Apps 与 OpenTelemetry:从服务端提供 UI 与可观测性 本节摘要:第 12 章与全书的收尾节,讲两个进阶能力。一是 Apps——让你从一个 MCP 服务端同时提供 UI(HTML 页面),适用于需要给用户一个管理界面的场景。二是 OpenTelemetry——为你的服务端加上分布式追踪,与标准可观测性生态集成。两者都让你的 MCP 服务从「能用」走向「产品化」。读完本节,第 12 章与全书正文结束,接下来是附录。 一、Apps:从服务端提供 UI 有时候,光提供工具/资源/提示词不够——你想给用户一个可视化界面。
本节摘要:第 12 章与全书的收尾节,讲两个进阶能力。一是 Apps——让你从一个 MCP 服务端同时提供 UI(HTML 页面),适用于需要给用户一个管理界面的场景。二是 OpenTelemetry——为你的服务端加上分布式追踪,与标准可观测性生态集成。两者都让你的 MCP 服务从「能用」走向「产品化」。读完本节,第 12 章与全书正文结束,接下来是附录。
有时候,光提供工具/资源/提示词不够——你想给用户一个可视化界面。比如:
Apps 让你从一个 MCP 服务端同时提供 HTML 页面,客户端(宿主)能加载这些页面:
from mcp.server import MCPServer from mcp.server.apps import Apps, App mcp = MCPServer("Dashboard") # 注册一个 App(HTML 页面) @mcp.custom_route("/dashboard", method="GET") async def dashboard(request): return HTMLResponse(""" <html><body> <h1>服务仪表盘</h1> <div id="status">加载中...</div> <script> // 通过 MCP 调用工具更新状态 fetch('/mcp', {...}).then(...) </script> </body></html> """)
宿主可以加载这个页面,用户在宿主里看到你的 UI,UI 再通过 MCP 调你的工具/资源。这让 MCP 服务端自带可视化层。
Apps 解决「MCP 服务端只暴露能力,没界面」的局限:
| 没有 Apps | 有 Apps |
|---|---|
| 服务端只暴露工具/资源 | 还能提供 UI 页面 |
| 客户端要自己造界面 | 服务端自带界面 |
| 用户体验依赖客户端 | 服务端定义体验 |
没有 Apps: 客户端(宿主) ← 调工具/资源 → 服务端 用户看到的是客户端造的界面(可能简陋) 有 Apps: 客户端(宿主) ← 调工具/资源 → 服务端 ← 加载 UI 页面 服务端(Apps) 用户看到服务端提供的富界面
适用于「服务端想控制用户体验」的场景——如领域专用工具自带可视化操作面板。
💡 技巧:Apps 不是必需的。多数 MCP 服务端只暴露能力,UI 由宿主提供(Claude Desktop 自带对话界面)。只有当你想给用户一个超越对话的可视化操作界面,才用 Apps。它是「锦上添花」,不是「必需」。
第二个能力是 OpenTelemetry——为服务端加分布式追踪。生产环境出问题时,你需要知道「请求在哪里慢、哪里错」。OpenTelemetry 是业界标准,SDK 集成了它:
from mcp.server import MCPServer from opentelemetry.sdk.trace import TracerProvider # 配置 OpenTelemetry(概念性) tracer_provider = TracerProvider() # 配置 exporter(发到 Jaeger、Zipkin 等) tracer_provider.add_span_processor(...) # SDK 自动为每个请求创建 span mcp = MCPServer("Demo") # 服务端运行时,自动产生追踪数据
SDK 在每个 MCP 请求上自动创建 span(追踪单元),记录:
OpenTelemetry 产生的追踪数据,发送到追踪系统(Jaeger、Zipkin、Datadog 等),你在那里查看:
一次工具调用的追踪(概念): span: tools/call add (总 50ms) ├─ span: auth_check (5ms) ├─ span: schema_validate (2ms) ├─ span: tool_execute (40ms) │ └─ span: db_query (35ms) ← 这里慢 └─ span: response_serialize (3ms)
这个追踪让你一眼看出「哪里慢」——上例的 db_query 占了 35ms,是瓶颈。没有追踪,「慢」只是个模糊感觉;有追踪,你能精确定位。
OpenTelemetry 是可观测性(Observability)生态的一部分,它覆盖「三件套」:
| 维度 | 回答什么 | 工具 |
|---|---|---|
| 追踪(Tracing) | 「请求在哪里慢、经过哪些服务」 | OpenTelemetry, Jaeger |
| 指标(Metrics) | 「QPS、错误率、资源使用」 | Prometheus, Grafana |
| 日志(Logging) | 「发生了什么(详细)」 | ELK, Loki |
SDK 主要集成追踪(自动 span)。指标与日志你可以通过中间件(第 12.4 节)补充——指标中间件记 QPS,日志中间件记详细日志。三者合起来构成完整可观测性。
第 12.4 节的中间件,常与可观测性协作:
class TracingMiddleware(ServerMiddleware): """与 OpenTelemetry 协作的追踪中间件。""" async def on_request(self, ctx, next): with tracer.start_as_current_span(ctx.method): return await next(ctx) # span 自动记录耗时、错误 class MetricsMiddleware(ServerMiddleware): """记指标的中间件。""" async def on_request(self, ctx, next): request_counter.inc() # 请求数 +1 try: result = await next(ctx) success_counter.inc() return result except: error_counter.inc() raise
这两个中间件叠加,就让服务端有了完整的追踪与指标——无需侵入业务代码。
本节讲完 Apps 与 OpenTelemetry,第 12 章结束。回顾全书,你已经掌握了:
全书能力图谱 ├── 基础(1-2 章):环境、架构地图 ├── 服务端主线(3-8 章): │ ├─ 三大原语(3-5 章) │ ├─ 上下文与依赖(6 章) │ ├─ 交互式能力(7 章) │ └─ 传输层(8 章) ├── 客户端主线(9-10 章): │ ├─ Client 与会话(9 章) │ └─ 传输/会话组/缓存/订阅(10 章) ├── 横切拔高(11-12 章): │ ├─ OAuth 全链路(11 章) │ └─ 低层/扩展/中间件/可观测性(12 章) └── 附录:术语/速查/排错
从「跑起来」到「理解架构」,从「写服务端」到「写客户端」,从「能用」到「能改、能扩展、能观测」——这是从初学者到熟练开发者的完整路径。
💡 技巧:本书的真正价值不在「教你 API」,而在「讲透为什么」。类型为什么即契约、服务端为什么分两层、传输为什么解耦、引导填写为什么要多轮往返——理解了这些「为什么」,你不仅能用 SDK,还能判断它的边界、改造它的实现、迁移到新版本。这种理解,是抄不来的。
第 12 章与全书正文结束。接下来是附录 A——术语表、API 速查、常见报错排查,以及 v1→v2 迁移要点。