示例客户端
来源:modelcontextprotocol.io/clients
支持 MCP 集成的应用程序列表
本页概述了支持 Model Context Protocol (MCP) 的应用程序。每个客户端可能支持不同的 MCP 功能,允许与 MCP 服务器进行不同级别的集成。
功能支持矩阵
客户端 | Resources | Prompts | Tools | Sampling | Roots | 备注 |
---|---|---|---|---|---|---|
Claude Desktop App | ✅ | ✅ | ✅ | ❌ | ❌ | 完全支持所有 MCP 功能 |
5ire | ❌ | ❌ | ✅ | ❌ | ❌ | 支持 tools。 |
BeeAI Framework | ❌ | ❌ | ✅ | ❌ | ❌ | 在智能工作流中支持 tools。 |
Cline | ✅ | ❌ | ✅ | ❌ | ❌ | 支持 tools 和 resources。 |
Continue | ✅ | ✅ | ✅ | ❌ | ❌ | 完全支持所有 MCP 功能 |
Cursor | ❌ | ❌ | ✅ | ❌ | ❌ | 支持 tools。 |
Emacs Mcp | ❌ | ❌ | ✅ | ❌ | ❌ | 在 Emacs 中支持 tools。 |
Firebase Genkit | ⚠️ | ✅ | ✅ | ❌ | ❌ | 通过 tools 支持 resource 列表和查找。 |
GenAIScript | ❌ | ❌ | ✅ | ❌ | ❌ | 支持 tools。 |
Goose | ❌ | ❌ | ✅ | ❌ | ❌ | 支持 tools。 |
LibreChat | ❌ | ❌ | ✅ | ❌ | ❌ | 为智能体支持 tools |
mcp-agent | ❌ | ❌ | ✅ | ⚠️ | ❌ | 支持 tools、服务器连接管理和智能体工作流。 |
Roo Code | ✅ | ❌ | ✅ | ❌ | ❌ | 支持 tools 和 resources。 |
Sourcegraph Cody | ✅ | ❌ | ❌ | ❌ | ❌ | 通过 OpenCTX 支持 resources |
Superinterface | ❌ | ❌ | ✅ | ❌ | ❌ | 支持 tools |
TheiaAI/TheiaIDE | ❌ | ❌ | ✅ | ❌ | ❌ | 在 Theia AI 和 AI 驱动的 Theia IDE 中为智能体支持 tools |
Windsurf Editor | ❌ | ❌ | ✅ | ❌ | ❌ | 支持带有 AI Flow 的 tools 进行协作开发。 |
Zed | ❌ | ✅ | ❌ | ❌ | ❌ | Prompts 显示为斜杠命令 |
[OpenSumi][OpenSumi] | ❌ | ❌ | ✅ | ❌ | ❌ | 在 OpenSumi 中支持 tools |
客户端详情
Claude Desktop App
Claude 桌面应用程序为 MCP 提供全面支持,实现与本地工具和数据源的深度集成。
主要特性:
- 完全支持 resources,允许附加本地文件和数据
- 支持 prompt 模板
- 集成 tools 执行命令和脚本
- 本地服务器连接以增强隐私和安全性
ⓘ 注意:Claude.ai 网页应用程序目前不支持 MCP。MCP 功能仅在桌面应用程序中可用。
5ire
5ire 是一个开源跨平台桌面 AI 助手,通过 MCP 服务器支持工具。
主要特性:
- 内置 MCP 服务器可以快速启用和禁用。
- 用户可以通过修改配置文件添加更多服务器。
- 它是开源和用户友好的,适合初学者。
- 未来对 MCP 的支持将不断改进。
BeeAI Framework
BeeAI Framework 是一个开源框架,用于构建、部署和大规模提供强大的智能工作流。该框架包括 MCP Tool,这是一个原生功能,简化了将 MCP 服务器集成到智能工作流中。
主要特性:
- 无缝地将 MCP 工具整合到智能工作流中。
- 从已连接的 MCP 客户端快速实例化框架原生工具。
- 计划未来支持智能 MCP 功能。
了解更多:
Cline
Cline 是 VS Code 中的一个自主编码智能体,它可以编辑文件、运行命令、使用浏览器等功能------在每一步都需要您的许可。
主要特性:
- 通过自然语言创建和添加工具(例如"添加一个搜索网络的工具")
- 通过
~/Documents/Cline/MCP
目录与他人共享 Cline 创建的自定义 MCP 服务器 - 显示已配置的 MCP 服务器以及它们的工具、资源和任何错误日志
Continue
Continue 是一个开源 AI 代码助手,内置支持所有 MCP 功能。
主要特性
- 输入 "@" 以提及 MCP 资源
- Prompt 模板显示为斜杠命令
- 直接在聊天中使用内置和 MCP 工具
- 支持 VS Code 和 JetBrains IDE,使用任何 LLM
Cursor
Cursor 是一个 AI 代码编辑器。
主要特性:
- 在 Cursor Composer 中支持 MCP 工具
- 同时支持 STDIO 和 SSE
Emacs Mcp
Emacs Mcp 是一个专为与 MCP 服务器接口而设计的 Emacs 客户端,实现了无缝连接和交互。它为像 gptel 和 llm 这样的 AI 插件提供了 MCP 工具调用支持,遵循 Emacs 的标准工具调用格式。这种集成增强了 Emacs 生态系统中 AI 工具的功能。
主要特性:
- 为 Emacs 提供 MCP 工具支持。
Firebase Genkit
Genkit 是 Firebase 的 SDK,用于构建和将 GenAI 功能集成到应用程序中。genkitx-mcp 插件使得可以将 MCP 服务器作为客户端使用,或者从 Genkit 工具和提示创建 MCP 服务器。
主要特性:
- 客户端支持工具和提示(部分支持资源)
- 在 Genkit 的 Dev UI 游乐场中支持丰富的发现功能
- 与 Genkit 现有工具和提示的无缝互操作性
- 适用于来自顶级提供商的各种 GenAI 模型
GenAIScript
使用 GenAIScript(在 JavaScript 中)以编程方式组装 LLM 的提示。在 JavaScript 中编排 LLM、工具和数据。
主要特性:
- JavaScript 工具箱,用于处理提示
- 使其简单且高效的抽象
- 无缝的 Visual Studio Code 集成
Goose
Goose 是一个开源 AI 智能体,通过自动化编码任务增强你的软件开发。
主要特性:
- 通过工具向 Goose 公开 MCP 功能。
- MCP 可以直接通过扩展目录、CLI 或 UI 安装。
- Goose 允许您通过构建自己的 MCP 服务器扩展其功能。
- 包括用于开发、网页抓取、自动化、记忆的内置工具,以及与 JetBrains 和 Google Drive 的集成。
LibreChat
LibreChat 是一个开源、可定制的 AI 聊天 UI,支持多个 AI 提供商,现在包括 MCP 集成。
主要特性:
- 扩展当前工具生态系统,包括通过 MCP 服务器的代码解释器和图像生成工具
- 向可定制的智能体添加工具,使用来自顶级提供商的各种 LLM
- 开源且可自托管,具有安全的多用户支持
- 未来路线图包括扩展 MCP 功能支持
mcp-agent
mcp-agent 是一个简单、可组合的框架,用于使用 Model Context Protocol 构建智能体。
主要特性:
- 自动管理 MCP 服务器连接。
- 将多个服务器的工具暴露给 LLM。
- 实现构建有效智能体中定义的每种模式。
- 支持工作流暂停/恢复信号,例如等待人类反馈。
Roo Code
Roo Code 通过 MCP 启用 AI 编码辅助。
主要特性:
- 支持 MCP 工具和资源
- 与开发工作流集成
- 可扩展的 AI 功能
Sourcegraph Cody
Cody 是 Sourcegraph 的 AI 编码助手,通过 OpenCTX 实现 MCP。
主要特性:
- 支持 MCP 资源
- 与 Sourcegraph 的代码智能集成
- 使用 OpenCTX 作为抽象层
- 计划未来支持额外的 MCP 功能
Superinterface
Superinterface 是 AI 基础设施和开发者平台,用于构建具有 MCP 支持、交互式组件、客户端函数调用等功能的应用内 AI 助手。
主要特性:
- 在通过 React 组件或脚本标签嵌入的助手中使用来自 MCP 服务器的工具
- SSE 传输支持
- 使用来自任何 AI 提供商的任何 AI 模型(OpenAI、Anthropic、Ollama 等)
TheiaAI/TheiaIDE
Theia AI 是一个用于构建 AI 增强工具和 IDE 的框架。AI 驱动的 Theia IDE 是一个基于 Theia AI 构建的开放灵活的开发环境。
主要特性:
- 工具集成:Theia AI 使 AI 智能体(包括 Theia IDE 中的智能体)能够使用 MCP 服务器进行无缝工具交互。
- 可自定义提示:Theia IDE 允许用户定义和调整提示,动态集成 MCP 服务器以进行定制工作流。
- 自定义智能体:Theia IDE 支持创建利用 MCP 功能的自定义智能体,使用户能够即时设计专用工作流。
Theia AI 和 Theia IDE 的 MCP 集成为用户提供了灵活性,使它们成为探索和适应 MCP 的强大平台。
了解更多:
Windsurf Editor
Windsurf Editor 是一个智能 IDE,结合了 AI 辅助和开发者工作流。它具有创新的 AI Flow 系统,能够实现协作和独立的 AI 交互,同时保持开发者控制。
主要特性:
- 革命性的 AI Flow 范式,用于人类-AI 协作
- 智能代码生成和理解
- 具有多模型支持的丰富开发工具
Zed
Zed 是一个高性能代码编辑器,内置 MCP 支持,专注于提示模板和工具集成。
主要特性:
- 提示模板在编辑器中显示为斜杠命令
- 工具集成以增强编码工作流
- 与编辑器功能和工作区上下文的紧密集成
- 不支持 MCP 资源
OpenSumi
OpenSumi 是一个帮助您快速构建 AI 原生 IDE 产品的框架。
主要特性:
- 在 OpenSumi 中支持 MCP 工具
- 支持内置 IDE MCP 服务器和自定义 MCP 服务器
向您的应用程序添加 MCP 支持
如果您已经向应用程序添加了 MCP 支持,我们鼓励您提交拉取请求将其添加到此列表中。MCP 集成可以为您的用户提供强大的上下文 AI 功能,并使您的应用程序成为不断增长的 MCP 生态系统的一部分。
添加 MCP 支持的好处:
- 允许用户带来自己的上下文和工具
- 加入不断增长的可互操作 AI 应用程序生态系统
- 为用户提供灵活的集成选项
- 支持本地优先的 AI 工作流
要开始在您的应用程序中实现 MCP,请查看我们的 Python 或 TypeScript SDK 文档
更新和更正
此列表由社区维护。如果您注意到任何不准确之处或想要更新有关应用程序中 MCP 支持的信息,请提交拉取请求或在我们的文档仓库中开启一个问题。
贡献
来源:modelcontextprotocol.io/development...
如何参与 Model Context Protocol 开发
我们欢迎社区的贡献!请查看我们的贡献指南了解如何提交更改的详细信息。
所有贡献者必须遵守我们的行为准则。
如有问题和讨论,请使用 GitHub Discussions。
路线图
来源:modelcontextprotocol.io/development...
Model Context Protocol 的发展计划(2025年上半年)
Model Context Protocol 正在快速发展。本页概述了我们对 2025年上半年 关键优先事项和未来方向的当前思考,尽管这些可能会随着项目的发展而发生重大变化。
此处提出的想法不是承诺------我们可能会以不同于描述的方式解决这些挑战,或者有些可能根本不会实现。这也不是详尽列表;我们可能会纳入这里未提及的工作。
我们鼓励社区参与!每个部分都链接到相关讨论,您可以在那里了解更多并贡献您的想法。
远程 MCP 支持
我们的首要任务是启用远程 MCP 连接,允许客户端通过互联网安全地连接到 MCP 服务器。主要举措包括:
-
认证与授权:添加标准化的身份验证功能,特别是关注 OAuth 2.0 支持。
-
服务发现:定义客户端如何发现并连接到远程 MCP 服务器。
-
无状态操作:考虑 MCP 是否也可以涵盖无服务器环境,在那里它们需要主要是无状态的。
参考实现
为了帮助开发者使用 MCP 构建,我们想提供以下文档:
- 客户端示例:全面的参考客户端实现,展示所有协议功能
- 协议起草:提出和合并新协议功能的简化流程
分发与发现
展望未来,我们正在探索使 MCP 服务器更易于访问的方法。我们可能会研究的一些领域包括:
- 包管理:MCP 服务器的标准化打包格式
- 安装工具:跨 MCP 客户端简化服务器安装
- 沙箱:通过服务器隔离提高安全性
- 服务器注册表:发现可用 MCP 服务器的通用目录
智能体支持
我们正在扩展 MCP 的复杂智能工作流功能,特别关注:
-
分层智能体系统:通过命名空间和拓扑感知改进对智能体树的支持。
-
交互式工作流:更好地处理跨智能体层级的用户权限和信息请求,以及将输出发送给用户而非模型的方法。
-
流式结果:长时间运行的智能体操作的实时更新。
更广泛的生态系统
我们也投资于:
- 社区主导的标准开发:培育一个协作生态系统,所有 AI 提供商都可以通过平等参与和共享治理来帮助塑造 MCP 作为一个开放标准,确保它满足多样化 AI 应用程序和用例的需求。
- 额外模态:扩展到文本之外,支持音频、视频和其他格式。
- [标准化] 考虑通过标准化机构进行标准化。
参与其中
我们欢迎社区参与塑造 MCP 的未来。访问我们的 GitHub Discussions 加入对话并贡献您的想法。
最新动态
来源:modelcontextprotocol.io/development...
MCP 的最新更新和改进
* 我们很高兴地宣布,由 VMware Tanzu 的 Spring AI 开发的 Java SDK 现在是 MCP 的官方 [Java SDK](https://github.com/modelcontextprotocol/java-sdk)。 这加入了我们现有的 Kotlin SDK,成为我们不断增长的支持语言列表的一部分。 Spring AI 团队将维护 SDK,作为 Model Context Protocol 组织的核心部分。我们很高兴欢迎他们加入 MCP 社区! * MCP Python SDK 的 [1.2.1](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.2.1) 版本已发布, 提供了重要的稳定性改进和错误修复。 * [TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) 中简化的、类似 express 的 API * 在[客户端页面](https://modelcontextprotocol.io/clients)添加了 8 个新客户端 * [Python SDK](https://github.com/modelcontextprotocol/python-sdk) 中的 FastMCP API * [服务器仓库](https://github.com/modelcontextprotocol/servers)中的 Docker 化 MCP 服务器 * Jetbrains 发布了 MCP 的 Kotlin SDK! * 对于 MCP Kotlin 服务器示例,请查看[这个仓库](https://github.com/modelcontextprotocol/kotlin-sdk/tree/main/samples/kotlin-mcp-server)
核心架构
来源:modelcontextprotocol.io/docs/concep...
了解 MCP 如何连接客户端、服务器和 LLM
Model Context Protocol (MCP) 建立在灵活、可扩展的架构上,使 LLM 应用程序和集成之间的无缝通信成为可能。本文档涵盖了核心架构组件和概念。
概述
MCP 遵循客户端-服务器架构,其中:
- 主机是启动连接的 LLM 应用程序(如 Claude Desktop 或 IDE)
- 客户端在主机应用程序内部维护与服务器的 1:1 连接
- 服务器向客户端提供上下文、工具和提示
核心组件
协议层
协议层处理消息框架、请求/响应链接和高级通信模式。
```typescript class Protocol<Request, Notification, Result> { // 处理传入请求 setRequestHandler(schema: T, handler: (request: T, extra: RequestHandlerExtra) => Promise): void
javascript
Copy
// 处理传入通知
setNotificationHandler<T>(schema: T, handler: (notification: T) => Promise<void>): void
// 发送请求并等待响应
request<T>(request: Request, schema: T, options?: RequestOptions): Promise<T>
// 发送单向通知
notification(notification: Notification): Promise<void>
}
```
```python class Session(BaseSession[RequestT, NotificationT, ResultT]): async def send_request( self, request: RequestT, result_type: type[Result] ) -> Result: """ 发送请求并等待响应。如果响应包含错 ```` class Session(BaseSession[RequestT, NotificationT, ResultT]): async def send_request( self, request: RequestT, result_type: type[Result] ) -> Result: """ 发送请求并等待响应。如果响应包含错误,则引发 McpError。 """ # 请求处理实现
python
async def send_notification(
self,
notification: NotificationT
) -> None:
"""发送不期望响应的单向通知。"""
# 通知处理实现
async def _received_request(
self,
responder: RequestResponder[ReceiveRequestT, ResultT]
) -> None:
"""处理来自另一方的传入请求。"""
# 请求处理实现
async def _received_notification(
self,
notification: ReceiveNotificationT
) -> None:
"""处理来自另一方的传入通知。"""
# 通知处理实现
```
关键类包括:
Protocol
Client
Server
传输层
传输层处理客户端和服务器之间的实际通信。MCP 支持多种传输机制:
-
Stdio 传输
- 使用标准输入/输出进行通信
- 适用于本地进程
-
HTTP 与 SSE 传输
- 使用服务器发送事件(SSE)进行服务器到客户端的消息传输
- 使用 HTTP POST 进行客户端到服务器的消息传输
所有传输都使用 JSON-RPC 2.0 来交换消息。有关 Model Context Protocol 消息格式的详细信息,请参阅规范。
消息类型
MCP 有这些主要类型的消息:
-
请求 期望另一方的响应:
typescriptinterface Request { method: string; params?: { ... }; }
markdown
2. **结果** 是对请求的成功响应:
```
interface Result {
[key: string]: unknown;
}
```
2. **错误** 表示请求失败:
```
interface Error {
code: number;
message: string;
data?: unknown;
}
```
2. **通知** 是不期望响应的单向消息:
```
interface Notification {
method: string;
params?: { ... };
}
```
## 连接生命周期
### 1. 初始化
```
sequenceDiagram
participant Client
participant Server
Client->>Server: initialize request
Server->>Client: initialize response
Client->>Server: initialized notification
Note over Client,Server: Connection ready for use
```
1. 客户端发送带有协议版本和功能的 `initialize` 请求
1. 服务器以其协议版本和功能响应
1. 客户端发送 `initialized` 通知作为确认
1. 开始正常消息交换
### 2. 消息交换
初始化后,支持以下模式:
- **请求-响应**:客户端或服务器发送请求,另一方响应
- **通知**:任一方发送单向消息
### 3. 终止
任一方都可以终止连接:
- 通过 `close()` 干净地关闭
- 传输断开连接
- 错误条件
## 错误处理
MCP 定义了这些标准错误代码:
```
enum ErrorCode {
// 标准 JSON-RPC 错误代码
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InvalidParams = -32602,
InternalError = -32603
}
```
SDK 和应用程序可以定义自己的高于 -32000 的错误代码。
错误通过以下方式传播:
- 对请求的错误响应
- 传输上的错误事件
- 协议级错误处理程序
## 实现示例
以下是实现 MCP 服务器的基本示例:
<Tabs> <Tab title="TypeScript"> ```typescript import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({ name: "example-server", version: "1.0.0" }, { capabilities: { resources: {} } });
// 处理请求 server.setRequestHandler(ListResourcesRequestSchema, async () => { return { resources: [ { uri: "example://resource", name: "Example Resource" } ] }; });
// 连接传输 const transport = new StdioServerTransport(); await server.connect(transport);
```python import asyncio import mcp.types as types from mcp.server import Server from mcp.server.stdio import stdio_server
csharp
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)
```
最佳实践
传输选择
-
本地通信
- 对于本地进程使用 stdio 传输
- 对于同一机器通信高效
- 简单的进程管理
-
远程通信
- 对于需要 HTTP 兼容性的情况使用 SSE
- 考虑安全隐患,包括认证和授权
消息处理
-
请求处理
- 彻底验证输入
- 使用类型安全的架构
- 优雅地处理错误
- 实现超时
-
进度报告
- 对长操作使用进度标记
- 增量报告进度
- 在已知时包括总进度
-
错误管理
- 使用适当的错误代码
- 包含有用的错误消息
- 在出错时清理资源
安全考虑
-
传输安全
- 对远程连接使用 TLS
- 验证连接来源
- 在需要时实现认证
-
消息验证
- 验证所有传入消息
- 净化输入
- 检查消息大小限制
- 验证 JSON-RPC 格式
-
资源保护
- 实现访问控制
- 验证资源路径
- 监控资源使用
- 限制请求速率
-
错误处理
- 不要泄露敏感信息
- 记录与安全相关的错误
- 实现适当的清理
- 处理 DoS 场景
调试和监控
-
日志记录
- 记录协议事件
- 跟踪消息流
- 监控性能
- 记录错误
-
诊断
- 实现健康检查
- 监控连接状态
- 跟踪资源使用
- 性能分析
-
测试
- 测试不同的传输
- 验证错误处理
- 检查边缘情况
- 负载测试服务器
Prompts
来源:modelcontextprotocol.io/docs/concep...
创建可重用的提示模板和工作流
Prompts 使服务器能够定义可重用的提示模板和工作流,客户端可以轻松地向用户和 LLM 展示这些模板和工作流。它们提供了一种强大的方式来标准化和共享常见的 LLM 交互。
Prompts 被设计为用户控制的,意味着它们从服务器暴露给客户端的目的是让用户能够明确地选择它们使用。
概述
MCP 中的 Prompts 是预定义的模板,可以:
- 接受动态参数
- 包含来自资源的上下文
- 链接多个交互
- 指导特定工作流
- 作为 UI 元素显示(如斜杠命令)
Prompt 结构
每个 prompt 的定义如下:
typescript
{
name: string; // 提示的唯一标识符
description?: string; // 人类可读的描述
arguments?: [ // 可选的参数列表
{
name: string; // 参数标识符
description?: string; // 参数描述
required?: boolean; // 参数是否必需
}
]
}
发现 prompts
客户端可以通过 prompts/list
端点发现可用的 prompts:
css
// 请求
{
method: "prompts/list"
}
// 响应
{
prompts: [
{
name: "analyze-code",
description: "分析代码以寻找潜在改进",
arguments: [
{
name: "language",
description: "编程语言",
required: true
}
]
}
]
}
使用 prompts
要使用 prompt,客户端发出 prompts/get
请求:
swift
// 请求
{
method: "prompts/get",
params: {
name: "analyze-code",
arguments: {
language: "python"
}
}
}
// 响应
{
description: "分析 Python 代码以寻找潜在改进",
messages: [
{
role: "user",
content: {
type: "text",
text: "请分析以下 Python 代码以寻找潜在改进:\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```"
}
}
]
}
动态 prompts
Prompts 可以是动态的,包括:
嵌入的资源上下文
json
{
"name": "analyze-project",
"description": "分析项目日志和代码",
"arguments": [
{
"name": "timeframe",
"description": "分析日志的时间段",
"required": true
},
{
"name": "fileUri",
"description": "要审查的代码文件的 URI",
"required": true
}
]
}
处理 prompts/get
请求时:
swift
{
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "分析这些系统日志和代码文件以查找任何问题:"
}
},
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": "logs://recent?timeframe=1h",
"text": "[2024-03-14 15:32:11] ERROR: Connection timeout in network.py:127\n[2024-03-14 15:32:15] WARN: Retrying connection (attempt 2/3)\n[2024-03-14 15:32:20] ERROR: Max retries exceeded",
"mimeType": "text/plain"
}
}
},
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": "file:///path/to/code.py",
"text": "def connect_to_service(timeout=30):\n retries = 3\n for attempt in range(retries):\n try:\n return establish_connection(timeout)\n except TimeoutError:\n if attempt == retries - 1:\n raise\n time.sleep(5)\n\ndef establish_connection(timeout):\n # Connection implementation\n pass",
"mimeType": "text/x-python"
}
}
}
]
}
多步骤工作流
vbnet
const debugWorkflow = {
name: "debug-error",
async getMessages(error: string) {
return [
{
role: "user",
content: {
type: "text",
text: `这是我看到的错误:${error}`
}
},
{
role: "assistant",
content: {
type: "text",
text: "我将帮助分析这个错误。到目前为止您尝试了什么?"
}
},
{
role: "user",
content: {
type: "text",
text: "我尝试重启服务,但错误仍然存在。"
}
}
];
}
};
实现示例
以下是在 MCP 服务器中实现 prompts 的完整示例:
```typescript import { Server } from "@modelcontextprotocol/sdk/server"; import { ListPromptsRequestSchema, GetPromptRequestSchema } from "@modelcontextprotocol/sdk/types";
javascript
const PROMPTS = {
"git-commit": {
name: "git-commit",
description: "生成 Git 提交消息",
arguments: [
{
name: "changes",
description: "Git diff 或更改描述",
required: true
}
]
},
"explain-code": {
name: "explain-code",
description: "解释代码如何工作",
arguments: [
{
name: "code",
description: "要解释的代码",
required: true
},
{
name: "language",
description: "编程语言",
required: false
}
]
}
};
const server = new Server({
name: "example-prompts-server",
version: "1.0.0"
}, {
capabilities: {
prompts: {}
}
});
// 列出可用的 prompts
server.setRequestHandler(ListPromptsRequestSchema, async () => {
return {
prompts: Object.values(PROMPTS)
};
});
// 获取特定 prompt
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
const prompt = PROMPTS[request.params.name];
if (!prompt) {
throw new Error(`Prompt not found: ${request.params.name}`);
}
if (request.params.name === "git-commit") {
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `为这些更改生成一个简洁但描述性的提交消息:\n\n${request.params.arguments?.changes}`
}
}
]
};
}
if (request.params.name === "explain-code") {
const language = request.params.arguments?.language || "Unknown";
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `解释这段 ${language} 代码如何工作:\n\n${request.params.arguments?.code}`
}
}
]
};
}
throw new Error("未找到 Prompt 实现");
});
```
```python from mcp.server import Server import mcp.types as types
ini
# 定义可用的 prompts
PROMPTS = {
"git-commit": types.Prompt(
name="git-commit",
description="生成 Git 提交消息",
arguments=[
types.PromptArgument(
name="changes",
description="Git diff 或更改描述",
required=True
)
],
),
"explain-code": types.Prompt(
name="explain-code",
description="解释代码如何工作",
arguments=[
types.PromptArgument(
name="code",
description="要解释的代码",
required=True
),
types.PromptArgument(
name="language",
description="编程语言",
required=False
)
],
)
}
# 初始化服务器
app = Server("example-prompts-server")
@app.list_prompts()
async def list_prompts() -> list[types.Prompt]:
return list(PROMPTS.values())
@app.get_prompt()
async def get_prompt(
name: str, arguments: dict[str, str] | None = None
) -> types.GetPromptResult:
if name not in PROMPTS:
raise ValueError(f"未找到 Prompt:{name}")
if name == "git-commit":
changes = arguments.get("changes") if arguments else ""
return types.GetPromptResult(
messages=[
types.PromptMessage(
role="user",
content=types.TextContent(
type="text",
text=f"为这些更改生成一个简洁但描述性的提交消息:"
f"for these changes:\n\n{changes}"
)
)
]
)
if name == "explain-code":
code = arguments.get("code") if arguments else ""
language = arguments.get("language", "Unknown") if arguments else "Unknown"
return types.GetPromptResult(
messages=[
types.PromptMessage(
role="user",
content=types.TextContent(
type="text",
text=f"解释这段 {language} 代码如何工作:\n\n{code}"
)
)
]
)
raise ValueError("未找到 Prompt 实现")
```
最佳实践
在实现 prompts 时:
- 使用清晰、描述性的 prompt 名称
- 为 prompts 和参数提供详细描述
- 验证所有必需参数
- 优雅地处理缺失参数
- 考虑对 prompt 模板进行版本控制
- 在适当时缓存动态内容
- 实现错误处理
- 记录预期的参数格式
- 考虑 prompt 可组合性
- 使用各种输入测试 prompts
UI 集成
Prompts 可以在客户端 UI 中显示为:
- 斜杠命令
- 快速操作
- 上下文菜单项
- 命令面板条目
- 引导式工作流
- 交互式表单
更新和变更
服务器可以通知客户端有关 prompt 变更:
- 服务器功能:
prompts.listChanged
- 通知:
notifications/prompts/list_changed
- 客户端重新获取 prompt 列表
安全考虑
在实现 prompts 时:
- 验证所有参数
- 净化用户输入
- 考虑速率限制
- 实现访问控制
- 审计 prompt 使用
- 适当处理敏感数据
- 验证生成的内容
- 实现超时
- 考虑 prompt 注入风险
- 记录安全要求
Resources
来源:modelcontextprotocol.io/docs/concep...
向 LLM 公开服务器中的数据和内容
Resources(资源)是 Model Context Protocol (MCP) 中的一个核心原语,允许服务器公开可被客户端读取并用作 LLM 交互上下文的数据和内容。
Resources 被设计为应用程序控制的,这意味着客户端应用程序可以决定如何以及何时使用它们。 不同的 MCP 客户端可能会以不同方式处理 resources。例如:
- Claude Desktop 目前要求用户在使用 resources 之前明确选择它们
- 其他客户端可能会基于启发式自动选择 resources
- 有些实现甚至可能允许 AI 模型自己决定使用哪些 resources
服务器作者在实现 resource 支持时应该准备好处理任何这些交互模式。为了自动向模型公开数据,服务器作者应该使用模型控制 的原语,如 Tools。
概述
Resources 代表 MCP 服务器希望向客户端提供的任何类型的数据。这可以包括:
- 文件内容
- 数据库记录
- API 响应
- 实时系统数据
- 截图和图像
- 日志文件
- 等等
每个资源由唯一的 URI 标识,可以包含文本或二进制数据。
Resource URI
Resources 使用遵循以下格式的 URI 进行标识:
ini
[protocol]://[host]/[path]
例如:
file:///home/user/documents/report.pdf
postgres://database/customers/schema
screen://localhost/display1
协议和路径结构由 MCP 服务器实现定义。服务器可以定义自己的自定义 URI 方案。
Resource 类型
Resources 可以包含两种类型的内容:
文本资源
文本资源包含 UTF-8 编码的文本数据。这些适用于:
- 源代码
- 配置文件
- 日志文件
- JSON/XML 数据
- 纯文本
二进制资源
二进制资源包含以 base64 编码的原始二进制数据。这些适用于:
- 图像
- 音频文件
- 视频文件
- 其他非文本格式
Resource 发现
客户端可以通过两种主要方法发现可用资源:
直接资源
服务器通过 resources/list
端点公开具体资源列表。每个资源包括:
c
{
uri: string; // 资源的唯一标识符
name: string; // 人类可读的名称
description?: string; // 可选描述
mimeType?: string; // 可选 MIME 类型
}
资源模板
对于动态资源,服务器可以公开URI 模板,客户端可以使用这些模板构建有效的资源 URI:
c
{
uriTemplate: string; // 遵循 RFC 6570 的 URI 模板
name: string; // 这种类型的人类可读名称
description?: string; // 可选描述
mimeType?: string; // 所有匹配资源的可选 MIME 类型
}
读取资源
要读取资源,客户端使用资源 URI 发出 resources/read
请求。
服务器以资源内容列表响应:
c
{
contents: [
{
uri: string; // 资源的 URI
mimeType?: string; // 可选的 MIME 类型
// 以下之一:
text?: string; // 文本资源
blob?: string; // 二进制资源(base64 编码)
}
]
}
服务器可能会响应一个 resources/read
请求返回多个资源。例如,当读取目录时,可以用来返回目录内的文件列表。
资源更新
MCP 通过两种机制支持资源的实时更新:
列表变更
当可用资源列表发生变化时,服务器可以通过 notifications/resources/list_changed
通知客户端。
内容变更
客户端可以订阅特定资源的更新:
- 客户端发送带有资源 URI 的
resources/subscribe
- 当资源发生变化时,服务器发送
notifications/resources/updated
- 客户端可以使用
resources/read
获取最新内容 - 客户端可以使用
resources/unsubscribe
取消订阅
实现示例
以下是在 MCP 服务器中实现资源支持的简单示例:
```typescript const server = new Server({ name: "example-server", version: "1.0.0" }, { capabilities: { resources: {} } });
javascript
// 列出可用资源
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "file:///logs/app.log",
name: "应用程序日志",
mimeType: "text/plain"
}
]
};
});
// 读取资源内容
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri === "file:///logs/app.log") {
const logContents = await readLogFile();
return {
contents: [
{
uri,
mimeType: "text/plain",
text: logContents
}
]
};
}
throw new Error("资源未找到");
});
```
```python app = Server("example-server")
less
@app.list_resources()
async def list_resources() -> list[types.Resource]:
return [
types.Resource(
uri="file:///logs/app.log",
name="应用程序日志",
mimeType="text/plain"
)
]
@app.read_resource()
async def read_resource(uri: AnyUrl) -> str:
if str(uri) == "file:///logs/app.log":
log_contents = await read_log_file()
return log_contents
raise ValueError("资源未找到")
# 启动服务器
async with stdio_server() as streams:
await app.run(
streams[0],
streams[1],
app.create_initialization_options()
)
```
最佳实践
在实现资源支持时:
- 使用清晰、描述性的资源名称和 URI
- 包含有用的描述以指导 LLM 理解
- 在已知的情况下设置适当的 MIME 类型
- 为动态内容实现资源模板
- 对频繁变化的资源使用订阅
- 通过清晰的错误消息优雅地处理错误
- 对大型资源列表考虑分页
- 在适当时缓存资源内容
- 在处理前验证 URI
- 记录您的自定义 URI 方案
安全考虑
在公开资源时:
- 验证所有资源 URI
- 实现适当的访问控制
- 净化文件路径以防止目录遍历
- 谨慎处理二进制数据
- 考虑对资源读取进行速率限制
- 审计资源访问
- 加密传输中的敏感数据
- 验证 MIME 类型
- 为长时间运行的读取实现超时
- 适当处理资源清理
Roots
来源:modelcontextprotocol.io/docs/concep...
理解 MCP 中的 roots
Roots 是 MCP 中定义服务器可以操作的边界的概念。它们为客户端提供了一种方法,可以告知服务器相关资源及其位置。
什么是 Roots?
Root 是客户端建议服务器应该关注的 URI。当客户端连接到服务器时,它声明服务器应该使用哪些 roots。虽然主要用于文件系统