diff --git a/README.md b/README.md
index 892d55655..b2d17c084 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
# RMCP
[](https://crates.io/crates/rmcp)
-
-
-
+[](https://docs.rs/rmcp/latest/rmcp)
+[](https://github.com/modelcontextprotocol/rust-sdk/actions/workflows/ci.yml)
+[](LICENSE)
An official Rust Model Context Protocol SDK implementation with tokio async runtime.
@@ -20,7 +20,7 @@ This repository contains the following crates:
### Import the crate
```toml
-rmcp = { version = "0.8.0", features = ["server"] }
+rmcp = { version = "0.16.0", features = ["server"] }
## or dev channel
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main" }
```
@@ -111,6 +111,10 @@ let quit_reason = server.cancel().await?;
See [examples](examples/README.md).
+## Feature Documentation
+
+See [docs/FEATURES.md](docs/FEATURES.md) for detailed documentation on core MCP features: resources, prompts, sampling, roots, logging, completions, notifications, and subscriptions.
+
## OAuth Support
See [Oauth_support](docs/OAUTH_SUPPORT.md) for details.
@@ -129,6 +133,8 @@ See [Oauth_support](docs/OAUTH_SUPPORT.md) for details.
### Built with `rmcp`
+- [goose](https://github.com/block/goose) - An open-source, extensible AI agent that goes beyond code suggestions
+- [apollo-mcp-server](https://github.com/apollographql/apollo-mcp-server) - MCP server that connects AI agents to GraphQL APIs via Apollo GraphOS
- [rustfs-mcp](https://github.com/rustfs/rustfs/tree/main/crates/mcp) - High-performance MCP server providing S3-compatible object storage operations for AI/LLM integration
- [containerd-mcp-server](https://github.com/jokemanfire/mcp-containerd) - A containerd-based MCP server implementation
- [rmcp-openapi-server](https://gitlab.com/lx-industries/rmcp-openapi/-/tree/main/crates/rmcp-openapi-server) - High-performance MCP server that exposes OpenAPI definition endpoints as MCP tools
diff --git a/crates/rmcp/README.md b/crates/rmcp/README.md
index 60f5e02d4..217b22cd6 100644
--- a/crates/rmcp/README.md
+++ b/crates/rmcp/README.md
@@ -191,7 +191,9 @@ async fn main() -> Result<(), Box> {
}
```
-For more examples, see the [examples directory](https://github.com/anthropics/mcp-rust-sdk/tree/main/examples) in the repository.
+For more examples, see the [examples directory](https://github.com/modelcontextprotocol/rust-sdk/tree/main/examples) in the repository.
+
+For detailed documentation on core MCP features (resources, prompts, sampling, roots, logging, completions, notifications, subscriptions), see [FEATURES.md](https://github.com/modelcontextprotocol/rust-sdk/blob/main/docs/FEATURES.md).
## Transport Options
diff --git a/docs/FEATURES.md b/docs/FEATURES.md
new file mode 100644
index 000000000..f27a152d6
--- /dev/null
+++ b/docs/FEATURES.md
@@ -0,0 +1,758 @@
+# RMCP Feature Documentation
+
+This document covers the core MCP features supported by `rmcp`, with server and client code examples for each.
+
+For the full MCP specification, see [modelcontextprotocol.io](https://modelcontextprotocol.io/specification/2025-11-25).
+
+## Table of Contents
+
+- [Resources](#resources)
+- [Prompts](#prompts)
+- [Sampling](#sampling)
+- [Roots](#roots)
+- [Logging](#logging)
+- [Completions](#completions)
+- [Notifications](#notifications)
+- [Subscriptions](#subscriptions)
+
+---
+
+## Resources
+
+Resources let servers expose data (files, database records, API responses) that clients can read. Each resource is identified by a URI and returns content as text or binary (base64-encoded) data. Resource templates allow servers to declare URI patterns with dynamic parameters.
+
+**MCP Spec:** [Resources](https://modelcontextprotocol.io/specification/2025-11-25/server/resources)
+
+### Server-side
+
+Implement `list_resources()`, `read_resource()`, and optionally `list_resource_templates()` on the `ServerHandler` trait. Enable the resources capability in `get_info()`.
+
+```rust
+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-side
+
+```rust
+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?;
+```
+
+### Notifications
+
+Servers can notify clients when the resource list changes or when a specific resource is updated:
+
+```rust
+// 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?;
+```
+
+Clients handle these via `ClientHandler`:
+
+```rust
+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
+ }
+}
+```
+
+**Example:** [`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)
+
+---
+
+## Prompts
+
+Prompts are reusable message templates that servers expose to clients. They accept typed arguments and return conversation messages. The `#[prompt]` macro handles argument validation and routing automatically.
+
+**MCP Spec:** [Prompts](https://modelcontextprotocol.io/specification/2025-11-25/server/prompts)
+
+### Server-side
+
+Use the `#[prompt_router]`, `#[prompt]`, and `#[prompt_handler]` macros to define prompts declaratively. Arguments are defined as structs deriving `JsonSchema`.
+
+```rust
+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()
+ }
+ }
+}
+```
+
+Prompt functions support several return types:
+- `Vec` -- simple message list
+- `GetPromptResult` -- messages with an optional description
+- `Result` -- either of the above, with error handling
+
+### Client-side
+
+```rust
+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?;
+```
+
+### Notifications
+
+```rust
+// Server: notify that available prompts have changed
+context.peer.notify_prompt_list_changed().await?;
+```
+
+**Example:** [`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)
+
+---
+
+## Sampling
+
+Sampling flips the usual direction: the server asks the client to run an LLM completion. The server sends a `create_message` request, the client processes it through its LLM, and returns the result.
+
+**MCP Spec:** [Sampling](https://modelcontextprotocol.io/specification/2025-11-25/client/sampling)
+
+### Server-side (requesting sampling)
+
+Access the client's sampling capability through `context.peer.create_message()`:
+
+```rust
+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-side (handling sampling)
+
+On the client side, implement `ClientHandler::create_message()`. This is where you'd call your actual LLM:
+
+```rust
+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()),
+ })
+ }
+}
+```
+
+**Example:** [`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)
+
+---
+
+## Roots
+
+Roots tell servers which directories or projects the client is working in. A root is a URI (typically `file://`) pointing to a workspace or repository. Servers can query roots to know where to look for files and how to scope their work.
+
+**MCP Spec:** [Roots](https://modelcontextprotocol.io/specification/2025-11-25/client/roots)
+
+### Server-side
+
+Ask the client for its root list, and handle change notifications:
+
+```rust
+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-side
+
+Clients declare roots capability and implement `list_roots()`:
+
+```rust
+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()),
+ },
+ ],
+ })
+ }
+}
+```
+
+Clients notify the server when roots change:
+
+```rust
+// After adding or removing a workspace root:
+client.notify_roots_list_changed().await?;
+```
+
+---
+
+## Logging
+
+Servers can send structured log messages to clients. The client sets a minimum severity level, and the server sends messages through the peer notification interface.
+
+**MCP Spec:** [Logging](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging)
+
+### Server-side
+
+Enable the logging capability, handle level changes from the client, and send log messages via the peer:
+
+```rust
+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?;
+```
+
+Available log levels (from least to most severe): `Debug`, `Info`, `Notice`, `Warning`, `Error`, `Critical`, `Alert`, `Emergency`.
+
+### Client-side
+
+Clients handle incoming log messages via `ClientHandler`:
+
+```rust
+impl ClientHandler for MyClient {
+ async fn on_logging_message(
+ &self,
+ params: LoggingMessageNotificationParam,
+ _context: NotificationContext,
+ ) {
+ println!("[{}] {}: {}", params.level,
+ params.logger.unwrap_or_default(), params.data);
+ }
+}
+```
+
+Clients can also set the server's log level:
+
+```rust
+client.set_level(SetLevelRequestParams {
+ level: LoggingLevel::Warning,
+ meta: None,
+}).await?;
+```
+
+---
+
+## Completions
+
+Completions give auto-completion suggestions for prompt or resource template arguments. As a user fills in arguments, the client can ask the server for suggestions based on what's already been entered.
+
+**MCP Spec:** [Completions](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/completion)
+
+### Server-side
+
+Enable the completions capability and implement the `complete()` handler. Use `request.context` to inspect previously filled arguments:
+
+```rust
+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-side
+
+```rust
+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"]
+```
+
+**Example:** [`examples/servers/src/completion_stdio.rs`](../examples/servers/src/completion_stdio.rs)
+
+---
+
+## Notifications
+
+Notifications are fire-and-forget messages -- no response is expected. They cover progress updates, cancellation, and lifecycle events. Both sides can send and receive them.
+
+**MCP Spec:** [Notifications](https://modelcontextprotocol.io/specification/2025-11-25/basic/notifications)
+
+### Progress notifications
+
+Servers can report progress during long-running operations:
+
+```rust
+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?;
+}
+```
+
+### Cancellation
+
+Either side can cancel an in-progress request:
+
+```rust
+// Send a cancellation
+context.peer.notify_cancelled(CancelledNotificationParam {
+ request_id: the_request_id,
+ reason: Some("User requested cancellation".into()),
+}).await?;
+```
+
+Handle cancellation in `ServerHandler` or `ClientHandler`:
+
+```rust
+impl ServerHandler for MyServer {
+ async fn on_cancelled(
+ &self,
+ params: CancelledNotificationParam,
+ _context: NotificationContext,
+ ) {
+ // Abort work for params.request_id
+ }
+}
+```
+
+### Initialized notification
+
+Clients send `initialized` after the handshake completes:
+
+```rust
+// 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
+ }
+}
+```
+
+### List-changed notifications
+
+When available tools, prompts, or resources change, tell the client:
+
+```rust
+context.peer.notify_tool_list_changed().await?;
+context.peer.notify_prompt_list_changed().await?;
+context.peer.notify_resource_list_changed().await?;
+```
+
+**Example:** [`examples/servers/src/common/progress_demo.rs`](../examples/servers/src/common/progress_demo.rs)
+
+---
+
+## Subscriptions
+
+Clients can subscribe to specific resources. When a subscribed resource changes, the server sends a notification and the client can re-read it.
+
+**MCP Spec:** [Resources - Subscriptions](https://modelcontextprotocol.io/specification/2025-11-25/server/resources#subscriptions)
+
+### Server-side
+
+Enable subscriptions in the resources capability and implement the `subscribe()` / `unsubscribe()` handlers:
+
+```rust
+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(())
+ }
+}
+```
+
+When a subscribed resource changes, notify the client:
+
+```rust
+// Check if the resource has subscribers, then notify
+context.peer.notify_resource_updated(ResourceUpdatedNotificationParam {
+ uri: "file:///config.json".into(),
+}).await?;
+```
+
+### Client-side
+
+```rust
+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?;
+```
+
+Handle update notifications in `ClientHandler`:
+
+```rust
+impl ClientHandler for MyClient {
+ async fn on_resource_updated(
+ &self,
+ params: ResourceUpdatedNotificationParam,
+ _context: NotificationContext,
+ ) {
+ // Re-read the resource at params.uri
+ }
+}
+```
diff --git a/docs/coverage.svg b/docs/coverage.svg
deleted file mode 100644
index 229bca9a6..000000000
--- a/docs/coverage.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/docs/readme/README.zh-cn.md b/docs/readme/README.zh-cn.md
index edd01ad60..f666928f2 100644
--- a/docs/readme/README.zh-cn.md
+++ b/docs/readme/README.zh-cn.md
@@ -1,32 +1,41 @@
+
+
# RMCP
[](https://crates.io/crates/rmcp)
-
[](https://docs.rs/rmcp/latest/rmcp)
+[](https://github.com/modelcontextprotocol/rust-sdk/actions/workflows/ci.yml)
+[](../../LICENSE)
-一个基于 tokio 异步运行时的官方 Model Context Protocol SDK 实现。
+一个基于 tokio 异步运行时的官方 Rust Model Context Protocol SDK 实现。
-本项目使用了以下开源库:
+本仓库包含以下 crate:
-- [rmcp](crates/rmcp): 实现 RMCP 协议的核心库 (详见:[rmcp](crates/rmcp/README.md))
-- [rmcp-macros](crates/rmcp-macros): 一个用于生成 RMCP 工具实现的过程宏库。 (详见:[rmcp-macros](crates/rmcp-macros/README.md))
+- [rmcp](../../crates/rmcp):实现 RMCP 协议的核心库 - 详见 [rmcp](../../crates/rmcp/README.md)
+- [rmcp-macros](../../crates/rmcp-macros):用于生成 RMCP 工具实现的过程宏库 - 详见 [rmcp-macros](../../crates/rmcp-macros/README.md)
## 使用
### 导入
+
```toml
-rmcp = { version = "0.2.0", features = ["server"] }
+rmcp = { version = "0.16.0", features = ["server"] }
## 或使用最新开发版本
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main" }
```
+### 第三方依赖
-### 第三方依赖库
-基本依赖:
-- [tokio required](https://github.com/tokio-rs/tokio)
-- [serde required](https://github.com/serde-rs/serde)
+基本依赖:
+- [tokio](https://github.com/tokio-rs/tokio)
+- [serde](https://github.com/serde-rs/serde)
+JSON Schema 生成 (version 2020-12):
+- [schemars](https://github.com/GREsau/schemars)
### 构建客户端
+
-构建客户端
+启动客户端
```rust, ignore
use rmcp::{ServiceExt, transport::{TokioChildProcess, ConfigureCommandExt}};
@@ -57,7 +66,7 @@ let transport = (stdin(), stdout());
构建服务
-You can easily build a service by using [`ServerHandler`](crates/rmcp/src/handler/server.rs) or [`ClientHandler`](crates/rmcp/src/handler/client.rs).
+你可以通过 [`ServerHandler`](../../crates/rmcp/src/handler/server.rs) 或 [`ClientHandler`](../../crates/rmcp/src/handler/client.rs) 轻松构建服务。
```rust, ignore
let service = common::counter::Counter::new();
@@ -68,7 +77,7 @@ let service = common::counter::Counter::new();
启动服务端
```rust, ignore
-// this call will finish the initialization process
+// 此调用将完成初始化过程
let server = service.serve(transport).await?;
```
@@ -76,13 +85,13 @@ let server = service.serve(transport).await?;
与服务端交互
-Once the server is initialized, you can send requests or notifications:
+服务端初始化完成后,你可以发送请求或通知:
```rust, ignore
-// request
+// 请求
let roots = server.list_roots().await?;
-// or send notification
+// 或发送通知
server.notify_cancelled(...).await?;
```
@@ -97,27 +106,54 @@ let quit_reason = server.cancel().await?;
```
-### 示例
-查看 [examples](examples/README.md)
+
+## 示例
+
+查看 [examples](../../examples/README.md)。
+
+## 功能文档
+
+查看 [docs/FEATURES.md](../FEATURES.md) 了解核心 MCP 功能的详细文档:资源、提示词、采样、根目录、日志、补全、通知和订阅。
## OAuth 支持
-查看 [oauth_support](docs/OAUTH_SUPPORT.md)
+查看 [OAuth 支持](../OAUTH_SUPPORT.md) 了解详情。
## 相关资源
-- [MCP Specification](https://modelcontextprotocol.io/specification/2025-11-25)
+- [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) - 基于 `actix_web` 的 `rmcp` 后端
+- [rmcp-openapi](https://gitlab.com/lx-industries/rmcp-openapi) - 将 OpenAPI 定义的端点转换为 MCP 工具
+
+### 基于 `rmcp` 构建
+
+- [goose](https://github.com/block/goose) - 一个超越代码建议的开源、可扩展 AI 智能体
+- [apollo-mcp-server](https://github.com/apollographql/apollo-mcp-server) - 通过 Apollo GraphOS 将 AI 智能体连接到 GraphQL API 的 MCP 服务
+- [rustfs-mcp](https://github.com/rustfs/rustfs/tree/main/crates/mcp) - 为 AI/LLM 集成提供 S3 兼容对象存储操作的高性能 MCP 服务
- [containerd-mcp-server](https://github.com/jokemanfire/mcp-containerd) - 基于 containerd 实现的 MCP 服务
+- [rmcp-openapi-server](https://gitlab.com/lx-industries/rmcp-openapi/-/tree/main/crates/rmcp-openapi-server) - 将 OpenAPI 定义的端点暴露为 MCP 工具的高性能 MCP 服务
+- [nvim-mcp](https://github.com/linw1995/nvim-mcp) - 与 Neovim 交互的 MCP 服务
+- [terminator](https://github.com/mediar-ai/terminator) - AI 驱动的桌面自动化 MCP 服务,支持跨平台,成功率超过 95%
+- [stakpak-agent](https://github.com/stakpak/agent) - 安全加固的 DevOps 终端智能体,支持 MCP over mTLS、流式传输、密钥令牌化和异步任务管理
+- [video-transcriber-mcp-rs](https://github.com/nhatvu148/video-transcriber-mcp-rs) - 使用 whisper.cpp 从 1000+ 平台转录视频的高性能 MCP 服务
+- [NexusCore MCP](https://github.com/sjkim1127/Nexuscore_MCP) - 具有 Frida 集成和隐蔽脱壳功能的高级恶意软件分析与动态检测 MCP 服务
+- [spreadsheet-mcp](https://github.com/PSU3D0/spreadsheet-mcp) - 面向 LLM 智能体的高效 Token 使用的电子表格分析 MCP 服务,支持自动区域检测、重新计算、截图和编辑
+- [hyper-mcp](https://github.com/hyper-mcp-rs/hyper-mcp) - 通过 WebAssembly (WASM) 插件扩展功能的快速、安全的 MCP 服务
+- [rudof-mcp](https://github.com/rudof-project/rudof/tree/master/rudof_mcp) - RDF 验证和数据处理 MCP 服务,支持 ShEx/SHACL 验证、SPARQL 查询和格式转换。支持 stdio 和 Streamable HTTP 传输,具备完整的 MCP 功能(工具、提示词、资源、日志、补全、任务)
+
## 开发
### 贡献指南
-查看 [docs/CONTRIBUTE.MD](docs/CONTRIBUTE.MD)
+查看 [docs/CONTRIBUTE.MD](../CONTRIBUTE.MD) 获取贡献提示。
### 使用 Dev Container
-如果你想使用 Dev Container,查看 [docs/DEVCONTAINER.md](docs/DEVCONTAINER.md) 获取开发指南。
+如果你想使用 Dev Container,查看 [docs/DEVCONTAINER.md](../DEVCONTAINER.md) 获取开发指南。