logo

该视频仅会员有权观看

立即开通课程「MCP 协议」权限。

¥
199
/ 年

详细理解MCP服务器概念

在开发 MCP 服务器的过程中,我们需要好好理解几个相关的概念:资源、工具、提示词等。

Resources 资源

这里我们需要对 Resources 资源进行一些说明,资源是 MCP 协议中的一种概念,它表示一个可以被读取和操作的对象,我们可以将服务器中的数据和内容作为资源暴露给 LLM,然后 LLM 就可以通过工具来操作这些资源。比如我们可以将一个笔记、一个文件、一个数据库表等作为资源。

资源代表 MCP 服务器希望向客户端提供的任何类型的数据,可以包括如下类型:

  • 文件内容
  • 数据库记录
  • API 响应
  • 实时系统数据
  • 屏幕截图和图像
  • 日志文件
  • 还有更多

每个资源都由唯一的 URI 标识,并且可以包含文本或二进制数据。

资源 URI

资源使用遵循以下格式的 URI 进行标识:

[protocol]://[host]/[path]

例如:

  • file:///home/user/documents/report.pdf
  • postgres://database/customers/schema
  • screen://localhost/display1

其中 protocol 协议和 path 路径结构由 MCP 服务器实现定义,当然服务器可以定义自己的自定义 URI 方案。

资源发现

客户端可以通过两种主要方法发现可用资源:

直接资源

服务器通过 resources/list 端点公开暴露具体资源的列表。每个资源包括:

{ uri: string; // 资源的唯一标识符 name: string; // 人类可读的名称 description?: string; // 可选描述 mimeType?: string; // 可选的 MIME 类型 }

资源模板

对于动态资源,服务器可以暴露 URI 模板,客户端可以使用该模板来构造有效的资源 URI:

{ uriTemplate: string; // 遵循 RFC 6570 的 URI 模板 name: string; // 该类型的人类可读名称 description?: string; // 可选描述 mimeType?: string; // 所有匹配资源的可选 MIME 类型 }

读取资源

要读取资源,客户端用资源 URI 发出 resources/read 请求。服务器响应如下所示的资源内容列表:

{ contents: [ { uri: string; // 资源的 URI mimeType?: string; // 可选的 MIME 类型 // 其中之一: text?: string; // 对于文本资源 blob?: string; // 对于二进制资源 (base64 编码) } ] }

服务器可能会返回多个资源来响应一个 resources/read 请求,比如在读取目录时返回目录内的文件列表。

资源更新

MCP 通过两种机制支持资源的实时更新:

列表变更

当可用资源列表发生变化时,服务器可以通过 notification/resources/list_changed 通知客户端。

内容变更

客户端可以订阅指定资源的更新:

  • 客户端使用资源 URI 发送 resources/subscribe 请求
  • 当资源发生变化时服务器发送 notification/resources/update 通知
  • 客户端可以通过 resources/read 来获取最新内容
  • 客户端可以取消订阅资源/取消订阅

工具 Tools

工具使 LLM 能够通过你的服务器执行操作,Tools 使服务器能够向客户端暴露可执行功能,通过工具,LLM 可以与外部系统交互、执行计算并在现实世界中执行操作。工具从服务器暴露给客户端,目的是 AI 模型能够自动调用它们(授予批准)。

MCP 中的工具允许服务器暴露可执行函数,这些函数可以被客户端调用,并被 LLM 用来执行操作,实现工具主要包含以下几个方面:

  • 发现:客户端可以通过 tools/list 端点列出可用的工具调用
  • 调用:使用 tools/call 端点调用工具,服务器在其中执行请求操作并返回结果
  • 灵活性:工具的范围可以从简单的计算到复杂的 API 交互

与资源一样,工具由唯一名称标识,并且可以包含描述来标识其用途,但是与资源不同,工具代表可以修改状态或与外部系统交互的动态操作。

每个工具都定义有以下结构:

{ name: string; // 工具的唯一标识符 description?: string; // 人类可读的描述 inputSchema: { // 工具参数的 JSON Schema type: "object"; properties: { ... } // 工具特定参数 } }

提示词 Prompts

Prompts 提示词是 MCP 协议中用于定义可重复使用的提示词模板和工作流程的机制,客户可以轻松地向用户和 LLM 展示这些模板和工作流程。提示词被设计为由用户控制,这意味着它们从服务器暴露给客户端,以便用户能够显式选择使用它们。

MCP 中的提示词是预定义的模板,可以:

  • 接受动态参数
  • 从资源中包含上下文
  • 链多个交互
  • 指导特定工作流程
  • 作为 UI 元素(如斜杠命令)

每个 Prompt 定义包含以下结构:

{ name: string; // 提示词的唯一标识符 description?: string; // 人类可读的描述 arguments?: [ // 可选的参数列表 { name: string; // 参数的标识符 description?: string; // 参数的描述 required?: boolean; // 是否必须 } ] }

客户端可以通过 prompts/list 端点来发现所有可用的提示词,比如发起如下所示的请求:

// Request { method: "prompts/list" } // Response { prompts: [ { name: "analyze-code", description: "Analyze code for potential improvements", arguments: [ { name: "language", description: "Programming language", required: true } ] } ] }

然后可以通过 prompts/get 端点来获取指定提示词的详细信息:

// Request { "method": "prompts/get", "params": { "name": "analyze-code", "arguments": { "language": "python" } } } // Response { "description": "Analyze Python code for potential improvements", "messages": [ { "role": "user", "content": { "type": "text", "text": "Please analyze the following Python code for potential improvements:\\n\\n\`\`\`python\\ndef calculate\_sum(numbers):\\n total = 0\\n for num in numbers:\\n total = total + num\\n return total\\n\\nresult = calculate\_sum(\[1, 2, 3, 4, 5\])\\nprint(result)\\n\`\`\`" } } ] }