侧边栏壁纸
博主头像
AI中文站

开拓MCP洪荒时代

  • 累计撰写 17 篇文章
  • 累计创建 3 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

MCP核心概念-核心架构

了解MCP如何连接客户端、服务器和llm

MCP 建立在灵活、可扩展的体系结构之上,可实现LLM应用程序和集成之间的无缝通信。本文档涵盖了核心体系结构组件和概念。

概述

MCP遵循客户端-服务器架构,其中:

  • Hosts 是启动连接的LLM应用程序

  • Clients 在主机应用程序内保持与服务器的1:1连接

  • Servers 向客户端提供上下文、工具和提示

核心组件

协议层

协议层处理消息成帧、请求/响应链接和高级通信模式。

  • TypeScript比较好理解协议层意思,因此贴代码如下

class Protocol<Request, Notification, Result> {
    // Handle incoming requests
    setRequestHandler<T>(schema: T, handler: (request: T, extra: RequestHandlerExtra) => Promise<Result>): void

    // Handle incoming notifications
    setNotificationHandler<T>(schema: T, handler: (notification: T) => Promise<void>): void

    // Send requests and await responses
    request<T>(request: Request, schema: T, options?: RequestOptions): Promise<T>

    // Send one-way notifications
    notification(notification: Notification): Promise<void>
}

关键类别包括:

  • Protocol

  • Client

  • Server

传输层

传输层处理客户端和服务器之间的实际通信。MCP支持多种传输机制:

  1. Stdio运输

    • 使用标准输入/输出进行通信

    • 本地流程的理想选择

  2. 使用SSE传输的HTTP

    • 将服务器发送的事件用于服务器到客户端的消息

    • 用于客户端到服务器消息的HTTP POST

所有运输使用JSON-RPC2.0交换消息。具体消息格式可查看

消息类型

MCP有这些主要类型的消息:

  1. 请求期待对方的回应:

interface Request {
  method: string;
  params?: { ... };
}

2. 结果是对请求的成功响应:

interface Result {
  [key: string]: unknown;
}

3. 错误指示请求失败:

interface Error {
  code: number;
  message: string;
  data?: unknown;
}

4. 通知是不期望响应的单向消息:

interface Notification {
  method: string;
  params?: { ... };
}

连接生命周期

1.初始化

  1. 客户端发送initialize具有协议版本和功能的请求

  2. 服务器以其协议版本和功能进行响应

  3. 客户端发送initialized作为确认的通知

  4. 正常的消息交换开始

2.消息交换

初始化后,支持以下模式:

  • 请求-响应: 客户端或服务器发送请求,另一个响应

  • 通知: 任何一方发送单向消息

3.终止

任何一方都可以终止连接:

  • 清洁关机通过close()

  • 传输断开

  • 错误条件

错误处理

MCP定义这些标准错误代码:

enum ErrorCode {
  // Standard JSON-RPC error codes
  ParseError = -32700,
  InvalidRequest = -32600,
  MethodNotFound = -32601,
  InvalidParams = -32602,
  InternalError = -32603,
}

Sdk和应用程序可以定义自己的-32000以上的错误代码。

错误通过以下方式传播:

  • 对请求的错误响应

  • 传输上的错误事件

  • 协议级错误处理程序

实现示例

下面是实现MCP服务器的基本示例:

Python

import asyncio
import mcp.types as types
from mcp.server import Server
from mcp.server.stdio import stdio_server

app = Server("example-server")

@app.list_resources()
async def list_resources() -> list[types.Resource]:
    return [
        types.Resource(
            uri="example://resource",
            name="Example Resource"
        )
    ]

async def main():
    async with stdio_server() as streams:
        await app.run(
            streams[0],
            streams[1],
            app.create_initialization_options()
        )

if __name__ == "__main__":
    asyncio.run(main())

最佳实践

Type的选择

  1. 本地通信

    • 对本地进程使用stdio传输

    • 高效的同机通信

    • 简单的流程管理

  2. 远程通信

    • 将SSE用于需要HTTP兼容性的方案

    • 考虑安全隐患,包括身份验证和授权

消息处理

  1. 请求处理

    • 彻底验证输入

    • 使用类型安全架构

    • 优雅地处理错误

    • 实现超时

  2. 进度报告

    • 对长操作使用进度标记

    • 逐步报告进度

    • 包括已知的总进度

  3. 错误管理

    • 使用适当的错误代码

    • 包括有用的错误消息

    • 清理错误上的资源

安全注意事项

  1. 运输安全

    • 使用TLS进行远程连接

    • 验证连接来源

    • 在需要时实施身份验证

  2. 消息验证

    • 验证所有传入消息

    • 防止恶意代码输入

    • 检查邮件大小限制

    • 验证json-rpc格式

  3. 资源保护

    • 实施访问控制

    • 验证资源路径

    • 监控资源使用情况

    • 速率限制请求

  4. 错误处理

    • 不要泄露敏感信息

    • 日志安全相关错误

    • 实施适当的清理

    • 处理DoS方案

调试和监控

  1. 日志记录

    • 记录协议事件

    • 跟踪消息流

    • 监控性能

    • 记录错误

  2. 诊断

    • 实施健康检查

    • 监控连接状态

    • 跟踪资源使用情况

    • 配置文件性能

  3. 测试

    • 测试不同的传输

    • 验证错误处理

    • 测试边界case

    • 负载测试服务器

0

评论区