modelcontextprotocol/rust-sdk
GitHub: modelcontextprotocol/rust-sdk
官方 Rust 版 Model Context Protocol SDK,用于构建高性能 MCP 客户端和服务端,连接 AI 助手与各类数据源和工具。
Stars: 3126 | Forks: 471
# RMCP
[](https://crates.io/crates/rmcp)
[](https://docs.rs/rmcp/latest/rmcp)
[](https://github.com/modelcontextprotocol/rust-sdk/actions/workflows/ci.yml)
[](LICENSE)
一个基于 tokio async runtime 的官方 Rust Model Context Protocol SDK 实现。
本仓库包含以下 crate:
- [rmcp](crates/rmcp):提供 RMCP 协议实现的核心 crate - 请参阅 [rmcp](crates/rmcp/README.md)
- [rmcp-macros](crates/rmcp-macros):用于生成 RMCP 工具实现的过程宏 crate - 请参阅 [rmcp-macros](crates/rmcp-macros/README.md)
有关完整的 MCP 规范,请参阅 [modelcontextprotocol.io](https://modelcontextprotocol.io/specification/2025-11-25)。
## 目录
- [使用方法](#usage)
- [资源](#resources)
- [提示词](#prompts)
- [采样](#sampling)
- [根目录](#roots)
- [日志](#logging)
- [补全](#completions)
- [通知](#notifications)
- [订阅](#subscriptions)
- [示例](#examples)
- [OAuth 支持](#oauth-support)
- [相关资源](#related-resources)
- [相关项目](#related-projects)
- [开发](#development)
## 使用方法
### 导入 crate
```
rmcp = { version = "0.16.0", features = ["server"] }
## 或 dev channel
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main" }
```
### 第三方依赖
基础依赖:
- [tokio](https://github.com/tokio-rs/tokio)
- [serde](https://github.com/serde-rs/serde)
JSON Schema 生成(版本 2020-12):
- [schemars](https://github.com/GREsau/schemars)
### 构建 Client
> {
let client = ().serve(TokioChildProcess::new(Command::new("npx").configure(|cmd| {
cmd.arg("-y").arg("@modelcontextprotocol/server-everything");
}))?).await?;
Ok(())
}
```
### 构建 Server
## 资源
资源允许 server 暴露 client 可以读取的数据(文件、数据库记录、API 响应)。每个资源由一个 URI 标识,并以文本或二进制(base64 编码)数据的形式返回内容。资源模板允许 server 声明带有动态参数的 URI 模式。
**MCP 规范:** [资源](https://modelcontextprotocol.io/specification/2025-11-25/server/resources)
### Server 端
在 `ServerHandler` trait 上实现 `list_resources()`、`read_resource()` 以及可选的 `list_resource_templates()`。在 `get_info()` 中启用资源能力。
```
use rmcp::{
ErrorData as McpError, RoleServer, ServerHandler, ServiceExt,
model::*,
service::RequestContext,
transport::stdio,
};
use serde_json::json;
#[derive(Clone)]
struct MyServer;
impl ServerHandler for MyServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
capabilities: ServerCapabilities::builder()
.enable_resources()
.build(),
..Default::default()
}
}
async fn list_resources(
&self,
_request: Option,
_context: RequestContext,
) -> Result {
Ok(ListResourcesResult {
resources: vec![
RawResource::new("file:///config.json", "config").no_annotation(),
RawResource::new("memo://insights", "insights").no_annotation(),
],
next_cursor: None,
meta: None,
})
}
async fn read_resource(
&self,
request: ReadResourceRequestParams,
_context: RequestContext,
) -> Result {
match request.uri.as_str() {
"file:///config.json" => Ok(ReadResourceResult {
contents: vec![ResourceContents::text(r#"{"key": "value"}"#, &request.uri)],
}),
"memo://insights" => Ok(ReadResourceResult {
contents: vec![ResourceContents::text("Analysis results...", &request.uri)],
}),
_ => Err(McpError::resource_not_found(
"resource_not_found",
Some(json!({ "uri": request.uri })),
)),
}
}
async fn list_resource_templates(
&self,
_request: Option,
_context: RequestContext,
) -> Result {
Ok(ListResourceTemplatesResult {
resource_templates: vec![],
next_cursor: None,
meta: None,
})
}
}
```
### Client 端
```
use rmcp::model::{ReadResourceRequestParams};
// List all resources (handles pagination automatically)
let resources = client.list_all_resources().await?;
// Read a specific resource by URI
let result = client.read_resource(ReadResourceRequestParams {
meta: None,
uri: "file:///config.json".into(),
}).await?;
// List resource templates
let templates = client.list_all_resource_templates().await?;
```
### 通知
当资源列表发生变化或特定资源更新时,server 可以通知 client:
```
// Notify that the resource list has changed (clients should re-fetch)
context.peer.notify_resource_list_changed().await?;
// Notify that a specific resource was updated
context.peer.notify_resource_updated(ResourceUpdatedNotificationParam {
uri: "file:///config.json".into(),
}).await?;
```
client 通过 `ClientHandler` 处理这些通知:
```
impl ClientHandler for MyClient {
async fn on_resource_list_changed(
&self,
_context: NotificationContext,
) {
// Re-fetch the resource list
}
async fn on_resource_updated(
&self,
params: ResourceUpdatedNotificationParam,
_context: NotificationContext,
) {
// Re-read the updated resource at params.uri
}
}
```
**示例:** [`examples/servers/src/common/counter.rs`](examples/servers/src/common/counter.rs) (server), [`examples/clients/src/everything_stdio.rs`](examples/clients/src/everything_stdio.rs) (client)
## 提示词
提示词是 server 暴露给 client 的可复用消息模板。它们接受类型化参数并返回对话消息。`#[prompt]` 宏会自动处理参数验证和路由。
**MCP 规范:** [提示词](https://modelcontextprotocol.io/specification/2025-11-25/server/prompts)
### Server 端
使用 `#[prompt_router]`、`#[prompt]` 和 `#[prompt_handler]` 宏来声明式地定义提示词。参数定义为派生 `JsonSchema` 的结构体。
```
use rmcp::{
ErrorData as McpError, RoleServer, ServerHandler, ServiceExt,
handler::server::{router::prompt::PromptRouter, wrapper::Parameters},
model::*,
prompt, prompt_handler, prompt_router,
schemars::JsonSchema,
service::RequestContext,
transport::stdio,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CodeReviewArgs {
#[schemars(description = "Programming language of the code")]
pub language: String,
#[schemars(description = "Focus areas for the review")]
pub focus_areas: Option>,
}
#[derive(Clone)]
pub struct MyServer {
prompt_router: PromptRouter,
}
#[prompt_router]
impl MyServer {
fn new() -> Self {
Self { prompt_router: Self::prompt_router() }
}
/// Simple prompt without parameters
#[prompt(name = "greeting", description = "A simple greeting")]
async fn greeting(&self) -> Vec {
vec![PromptMessage::new_text(
PromptMessageRole::User,
"Hello! How can you help me today?",
)]
}
/// Prompt with typed arguments
#[prompt(name = "code_review", description = "Review code in a given language")]
async fn code_review(
&self,
Parameters(args): Parameters,
) -> Result {
let focus = args.focus_areas
.unwrap_or_else(|| vec!["correctness".into()]);
Ok(GetPromptResult {
description: Some(format!("Code review for {}", args.language)),
messages: vec![
PromptMessage::new_text(
PromptMessageRole::User,
format!("Review my {} code. Focus on: {}", args.language, focus.join(", ")),
),
],
})
}
}
#[prompt_handler]
impl ServerHandler for MyServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
capabilities: ServerCapabilities::builder().enable_prompts().build(),
..Default::default()
}
}
}
```
提示词函数支持多种返回类型:
- `Vec` -- 简单消息列表
- `GetPromptResult` -- 带有可选描述的消息
- `Result` -- 上述任一类型,包含错误处理
### Client 端
```
use rmcp::model::GetPromptRequestParams;
// List all prompts
let prompts = client.list_all_prompts().await?;
// Get a prompt with arguments
let result = client.get_prompt(GetPromptRequestParams {
meta: None,
name: "code_review".into(),
arguments: Some(rmcp::object!({
"language": "Rust",
"focus_areas": ["performance", "safety"]
})),
}).await?;
```
### 通知
```
// Server: notify that available prompts have changed
context.peer.notify_prompt_list_changed().await?;
```
**示例:** [`examples/servers/src/prompt_stdio.rs`](examples/servers/src/prompt_stdio.rs) (server), [`examples/clients/src/everything_stdio.rs`](examples/clients/src/everything_stdio.rs) (client)
## 采样
采样反转了通常的方向:server 请求 client 运行 LLM 补全。server 发送一个 `create_message` 请求,client 通过其 LLM 处理它,并返回结果。
**MCP 规范:** [采样](https://modelcontextprotocol.io/specification/2025-11-25/client/sampling)
### Server 端(请求采样)
通过 `context.peer.create_message()` 访问 client 的采样能力:
```
use rmcp::model::*;
// Inside a ServerHandler method (e.g., call_tool):
let response = context.peer.create_message(CreateMessageRequestParams {
meta: None,
task: None,
messages: vec![SamplingMessage::user_text("Explain this error: connection refused")],
model_preferences: Some(ModelPreferences {
hints: Some(vec![ModelHint { name: Some("claude".into()) }]),
cost_priority: Some(0.3),
speed_priority: Some(0.8),
intelligence_priority: Some(0.7),
}),
system_prompt: Some("You are a helpful assistant.".into()),
include_context: Some(ContextInclusion::None),
temperature: Some(0.7),
max_tokens: 150,
stop_sequences: None,
metadata: None,
tools: None,
tool_choice: None,
}).await?;
// Extract the response text
let text = response.message.content
.first()
.and_then(|c| c.as_text())
.map(|t| &t.text);
```
### Client 端(处理采样)
在 client 端,实现 `ClientHandler::create_message()`。在这里你可以调用实际的 LLM:
```
use rmcp::{ClientHandler, model::*, service::{RequestContext, RoleClient}};
#[derive(Clone, Default)]
struct MyClient;
impl ClientHandler for MyClient {
async fn create_message(
&self,
params: CreateMessageRequestParams,
_context: RequestContext,
) -> Result {
// Forward to your LLM, or return a mock response:
let response_text = call_your_llm(¶ms.messages).await;
Ok(CreateMessageResult {
message: SamplingMessage::assistant_text(response_text),
model: "my-model".into(),
stop_reason: Some(CreateMessageResult::STOP_REASON_END_TURN.into()),
})
}
}
```
**示例:** [`examples/servers/src/sampling_stdio.rs`](examples/servers/src/sampling_stdio.rs) (server), [`examples/clients/src/sampling_stdio.rs`](examples/clients/src/sampling_stdio.rs) (client)
## 根目录
根目录告诉 server client 正在处理哪些目录或项目。根目录是一个 URI(通常是 `file://`),指向工作区或仓库。server 可以查询根目录以了解文件位置及如何界定其工作范围。
**MCP 规范:** [根目录](https://modelcontextprotocol.io/specification/2025-11-25/client/roots)
### Server 端
向 client 请求其根目录列表,并处理变更通知:
```
use rmcp::{ServerHandler, model::*, service::{NotificationContext, RoleServer}};
impl ServerHandler for MyServer {
// Query the client for its roots
async fn call_tool(
&self,
request: CallToolRequestParams,
context: RequestContext,
) -> Result {
let roots = context.peer.list_roots().await?;
// Use roots.roots to understand workspace boundaries
// ...
}
// Called when the client's root list changes
async fn on_roots_list_changed(
&self,
_context: NotificationContext,
) {
// Re-fetch roots to stay current
}
}
```
### Client 端
client 声明根目录能力并实现 `list_roots()`:
```
use rmcp::{ClientHandler, model::*};
impl ClientHandler for MyClient {
async fn list_roots(
&self,
_context: RequestContext,
) -> Result {
Ok(ListRootsResult {
roots: vec![
Root {
uri: "file:///home/user/project".into(),
name: Some("My Project".into()),
},
],
})
}
}
```
client 在根目录变更时通知 server:
```
// After adding or removing a workspace root:
client.notify_roots_list_changed().await?;
```
## 日志
server 可以向 client 发送结构化日志消息。client 设置最低严重性级别,server 通过 peer 通知接口发送消息。
**MCP 规范:** [日志](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging)
### Server 端
启用日志能力,处理来自 client 的级别更改,并通过 peer 发送日志消息:
```
use rmcp::{ServerHandler, model::*, service::RequestContext};
impl ServerHandler for MyServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
capabilities: ServerCapabilities::builder()
.enable_logging()
.build(),
..Default::default()
}
}
// Client sets the minimum log level
async fn set_level(
&self,
request: SetLevelRequestParams,
_context: RequestContext,
) -> Result<(), ErrorData> {
// Store request.level and filter future log messages accordingly
Ok(())
}
}
// Send a log message from any handler with access to the peer:
context.peer.notify_logging_message(LoggingMessageNotificationParam {
level: LoggingLevel::Info,
logger: Some("my-server".into()),
data: serde_json::json!({
"message": "Processing completed",
"items_processed": 42
}),
}).await?;
```
可用的日志级别(从最轻到最严重):`Debug`、`Info`、`Notice`、`Warning`、`Error`、`Critical`、`Alert`、`Emergency`。
### Client 端
client 通过 `ClientHandler` 处理传入的日志消息:
```
impl ClientHandler for MyClient {
async fn on_logging_message(
&self,
params: LoggingMessageNotificationParam,
_context: NotificationContext,
) {
println!("[{}] {}: {}", params.level,
params.logger.unwrap_or_default(), params.data);
}
}
```
client 也可以设置 server 的日志级别:
```
client.set_level(SetLevelRequestParams {
level: LoggingLevel::Warning,
meta: None,
}).await?;
```
## 补全
补全为提示词或资源模板参数提供自动补全建议。当用户填写参数时,client 可以根据已输入的内容向 server 请求建议。
**MCP 规范:** [补全](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/completion)
### Server 端
启用补全能力并实现 `complete()` handler。使用 `request.context` 检查先前填写的参数:
```
use rmcp::{ErrorData as McpError, ServerHandler, model::*, service::RequestContext, RoleServer};
impl ServerHandler for MyServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
capabilities: ServerCapabilities::builder()
.enable_completions()
.enable_prompts()
.build(),
..Default::default()
}
}
async fn complete(
&self,
request: CompleteRequestParams,
_context: RequestContext,
) -> Result {
let values = match &request.r#ref {
Reference::Prompt(prompt_ref) if prompt_ref.name == "sql_query" => {
match request.argument.name.as_str() {
"operation" => vec!["SELECT", "INSERT", "UPDATE", "DELETE"],
"table" => vec!["users", "orders", "products"],
"columns" => {
// Adapt suggestions based on previously filled arguments
if let Some(ctx) = &request.context {
if let Some(op) = ctx.get_argument("operation") {
match op.to_uppercase().as_str() {
"SELECT" | "UPDATE" => {
vec!["id", "name", "email", "created_at"]
}
_ => vec![],
}
} else { vec![] }
} else { vec![] }
}
_ => vec![],
}
}
_ => vec![],
};
// Filter by the user's partial input
let filtered: Vec = values.into_iter()
.map(String::from)
.filter(|v| v.to_lowercase().contains(&request.argument.value.to_lowercase()))
.collect();
Ok(CompleteResult {
completion: CompletionInfo {
values: filtered,
total: None,
has_more: Some(false),
},
})
}
}
```
### Client 端
```
use rmcp::model::*;
let result = client.complete(CompleteRequestParams {
meta: None,
r#ref: Reference::Prompt(PromptReference {
name: "sql_query".into(),
}),
argument: ArgumentInfo {
name: "operation".into(),
value: "SEL".into(),
},
context: None,
}).await?;
// result.completion.values contains suggestions like ["SELECT"]
```
**示例:** [`examples/servers/src/completion_stdio.rs`](examples/servers/src/completion_stdio.rs)
## 通知
通知即发即弃消息——不期待任何响应。它们涵盖进度更新、取消和生命周期事件。双方都可以发送和接收它们。
**MCP 规范:** [通知](https://modelcontextprotocol.io/specification/2025-11-25/basic/notifications)
### 进度通知
server 可以在长时间运行的操作期间报告进度:
```
use rmcp::model::*;
// Inside a tool handler:
for i in 0..total_items {
process_item(i).await;
context.peer.notify_progress(ProgressNotificationParam {
progress_token: ProgressToken(NumberOrString::Number(i as i64)),
progress: i as f64,
total: Some(total_items as f64),
message: Some(format!("Processing item {}/{}", i + 1, total_items)),
}).await?;
}
```
### 取消
任何一方都可以取消正在进行的请求:
```
// Send a cancellation
context.peer.notify_cancelled(CancelledNotificationParam {
request_id: the_request_id,
reason: Some("User requested cancellation".into()),
}).await?;
```
在 `ServerHandler` 或 `ClientHandler` 中处理取消:
```
impl ServerHandler for MyServer {
async fn on_cancelled(
&self,
params: CancelledNotificationParam,
_context: NotificationContext,
) {
// Abort work for params.request_id
}
}
```
### 初始化通知
client 在握手完成后发送 `initialized`:
```
// Sent automatically by rmcp during the serve() handshake.
// Servers handle it via:
impl ServerHandler for MyServer {
async fn on_initialized(
&self,
_context: NotificationContext,
) {
// Server is ready to receive requests
}
}
```
### 列表变更通知
当可用工具、提示词或资源发生变化时,通知 client:
```
context.peer.notify_tool_list_changed().await?;
context.peer.notify_prompt_list_changed().await?;
context.peer.notify_resource_list_changed().await?;
```
**示例:** [`examples/servers/src/common/progress_demo.rs`](examples/servers/src/common/progress_demo.rs)
## 订阅
client 可以订阅特定资源。当订阅的资源发生变化时,server 发送通知,client 可以重新读取它。
**MCP 规范:** [资源 - 订阅](https://modelcontextprotocol.io/specification/2025-11-25/server/resources#subscriptions)
### Server 端
在资源能力中启用订阅,并实现 `subscribe()` / `unsubscribe()` handler:
```
use rmcp::{ErrorData as McpError, ServerHandler, model::*, service::RequestContext, RoleServer};
use std::sync::Arc;
use tokio::sync::Mutex;
use std::collections::HashSet;
#[derive(Clone)]
struct MyServer {
subscriptions: Arc>>,
}
impl ServerHandler for MyServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
capabilities: ServerCapabilities::builder()
.enable_resources()
.enable_resources_subscribe()
.build(),
..Default::default()
}
}
async fn subscribe(
&self,
request: SubscribeRequestParams,
_context: RequestContext,
) -> Result<(), McpError> {
self.subscriptions.lock().await.insert(request.uri);
Ok(())
}
async fn unsubscribe(
&self,
request: UnsubscribeRequestParams,
_context: RequestContext,
) -> Result<(), McpError> {
self.subscriptions.lock().await.remove(&request.uri);
Ok(())
}
}
```
当订阅的资源发生变化时,通知 client:
```
// Check if the resource has subscribers, then notify
context.peer.notify_resource_updated(ResourceUpdatedNotificationParam {
uri: "file:///config.json".into(),
}).await?;
```
### Client 端
```
use rmcp::model::*;
// Subscribe to updates for a resource
client.subscribe(SubscribeRequestParams {
meta: None,
uri: "file:///config.json".into(),
}).await?;
// Unsubscribe when no longer needed
client.unsubscribe(UnsubscribeRequestParams {
meta: None,
uri: "file:///config.json".into(),
}).await?;
```
在 `ClientHandler` 中处理更新通知:
```
impl ClientHandler for MyClient {
async fn on_resource_updated(
&self,
params: ResourceUpdatedNotificationParam,
_context: NotificationContext,
) {
// Re-read the resource at params.uri
}
}
```
## 示例
请参阅 [examples](examples/README.md)。
## OAuth 支持
详情请参阅 [Oauth_support](docs/OAUTH_SUPPORT.md)。
## 相关资源
- [MCP 规范](https://modelcontextprotocol.io/specification/2025-11-25)
- [Schema](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-11-25/schema.ts)
## 相关项目
### 扩展 `rmcp`
- [rmcp-actix-web](https://gitlab.com/lx-industries/rmcp-actix-web) - `rmcp` 的 `actix_web` 后端
- [rmcp-openapi](https://gitlab.com/lx-industries/rmcp-openapi) - 将 OpenAPI 定义端点转换为 MCP 工具
### 基于 `rmcp` 构建
- [goose](https://github.com/block/goose) - 一个开源、可扩展的 AI agent,功能超越代码建议
- [apollo-mcp-server](https://github.com/apollographql/apollo-mcp-server) - 通过 Apollo GraphOS 将 AI agent 连接到 GraphQL API 的 MCP server
- [rustfs-mcp](https://github.com/rustfs/rustfs/tree/main/crates/mcp) - 高性能 MCP server,为 AI/LLM 集成提供 S3 兼容的对象存储操作
- [containerd-mcp-server](https://github.com/jokemanfire/mcp-containerd) - 基于 containerd 的 MCP server 实现
- [rmcp-openapi-server](https://gitlab.com/lx-industries/rmcp-openapi/-/tree/main/crates/rmcp-openapi-server) - 将 OpenAPI 定义端点暴露为 MCP 工具的高性能 MCP server
- [nvim-mcp](https://github.com/linw1995/nvim-mcp) - 用于与 Neovim 交互的 MCP server
- [terminator](https://github.com/mediar-ai/terminator) - AI 驱动的桌面自动化 MCP server,支持跨平台且成功率 >95%
- [stakpak-agent](https://github.com/stakpak/agent) - 面向 DevOps 的安全加固终端 agent,支持基于 mTLS 的 MCP、流式传输、密钥令牌化和异步任务管理
- [video-transcriber-mcp-rs](https://github.com/nhatvu148/video-transcriber-mcp-rs) - 使用 whisper.cpp 转录 1000+ 平台视频的高性能 MCP server
- [NexusCore MCP](https://github.com/sjkim1127/Nexuscore_MCP) - 高级恶意软件分析与动态插桩 MCP server,集成 Frida 并具备隐蔽脱壳能力
- [spreadsheet-mcp](https://github.com/PSU3D0/spreadsheet-mcp) - 节省 token 的电子表格分析 MCP server,支持自动区域检测、重新计算、截图和编辑,适用于 LLM agent
- [hyper-mcp](https://github.com/hyper-mcp-rs/hyper-mcp) - 一个快速、安全的 MCP server,通过 WebAssembly (WASM) 插件扩展其能力
- [rudof-mcp](https://github.com/rudof-project/rudof/tree/master/rudof_mcp) - RDF 验证和数据处理 MCP server,支持 ShEx/SHACL 验证、SPARQL 查询和格式转换。支持 stdio 和可流式 HTTP 传输,具备完整的 MCP 能力(工具、提示词、资源、日志、补全、任务)
- [McpMux](https://github.com/mcpmux/mcp-mux) - 桌面应用,允许在 McpMux 处配置一次 MCP server,通过单一加密本地网关连接所有 AI client(Cursor、Claude Desktop、VS Code、Windsurf),支持用于项目组织的 Spaces、用于切换工具集的 FeatureSets 以及内置 server 注册表
## 开发
### 贡献者提示
请参阅 [docs/CONTRIBUTE.MD](docs/CONTRIBUTE.MD) 获取有关贡献的一些提示。
### 使用 Dev Container
如果你想使用 dev container,请参阅 [docs/DEVCONTAINER.md](docs/DEVCONTAINER.md) 获取有关使用 Dev Container 进行开发的说明。
启动 client
``` use rmcp::{ServiceExt, transport::{TokioChildProcess, ConfigureCommandExt}}; use tokio::process::Command; #[tokio::main] async fn main() -> Result<(), Box构建 transport
``` use tokio::io::{stdin, stdout}; let transport = (stdin(), stdout()); ```构建 service
你可以通过使用 [`ServerHandler`](crates/rmcp/src/handler/server.rs) 或 [`ClientHandler`](crates/rmcp/src/handler/client.rs) 轻松构建 service。 ``` let service = common::counter::Counter::new(); ```启动 server
``` // this call will finish the initialization process let server = service.serve(transport).await?; ```与 server 交互
一旦 server 初始化完成,你可以发送请求或通知: ``` // request let roots = server.list_roots().await?; // or send notification server.notify_cancelled(...).await?; ```等待 service 关闭
``` let quit_reason = server.waiting().await?; // or cancel it let quit_reason = server.cancel().await?; ```标签:Anthropic, CIS基准, Crates.io, DNS解析, LLM, MCP, Model Context Protocol, Rust, Tokio, Unmanaged PE, 人工智能, 可视化界面, 大模型, 客户端, 工具开发, 开源项目, 异步编程, 服务端, 用户模式Hook绕过, 网络流量审计, 过程宏, 通知系统