From 6d909505871b2d9c660695abafe2cf59cea7d18d Mon Sep 17 00:00:00 2001 From: Dale Seo <5466341+DaleSeo@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:42:15 -0500 Subject: [PATCH 1/3] docs: add prose documentation for core features to meet conformance --- README.md | 8 +- crates/rmcp/README.md | 4 +- docs/FEATURES.md | 758 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 768 insertions(+), 2 deletions(-) create mode 100644 docs/FEATURES.md diff --git a/README.md b/README.md index 892d5565..e42ffccf 100644 --- a/README.md +++ b/README.md @@ -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 60f5e02d..217b22cd 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 00000000..f27a152d --- /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 + } +} +``` From c204e2e144951a1a1bc603701e0f5a1ccdb15ddc Mon Sep 17 00:00:00 2001 From: Dale Seo <5466341+DaleSeo@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:57:41 -0500 Subject: [PATCH 2/3] docs: remove static coverage badge and svg --- README.md | 1 - docs/coverage.svg | 1 - 2 files changed, 2 deletions(-) delete mode 100644 docs/coverage.svg diff --git a/README.md b/README.md index e42ffccf..52f3230a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ [![Crates.io Version](https://img.shields.io/crates/v/rmcp)](https://crates.io/crates/rmcp) -![Coverage](docs/coverage.svg) An official Rust Model Context Protocol SDK implementation with tokio async runtime. diff --git a/docs/coverage.svg b/docs/coverage.svg deleted file mode 100644 index 229bca9a..00000000 --- a/docs/coverage.svg +++ /dev/null @@ -1 +0,0 @@ -Coverage: 53%Coverage53% \ No newline at end of file From 8bf3d916f7ec3a3992c5fc3acadebcb196e018b3 Mon Sep 17 00:00:00 2001 From: Dale Seo <5466341+DaleSeo@users.noreply.github.com> Date: Thu, 26 Feb 2026 22:05:23 -0500 Subject: [PATCH 3/3] docs: rewrite Chinese README to match current English README --- README.md | 7 ++-- docs/readme/README.zh-cn.md | 80 +++++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 52f3230a..b2d17c08 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # RMCP [![Crates.io Version](https://img.shields.io/crates/v/rmcp)](https://crates.io/crates/rmcp) - - +[![docs.rs](https://img.shields.io/docsrs/rmcp)](https://docs.rs/rmcp/latest/rmcp) +[![CI](https://github.com/modelcontextprotocol/rust-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/modelcontextprotocol/rust-sdk/actions/workflows/ci.yml) +[![License](https://img.shields.io/crates/l/rmcp)](LICENSE) An official Rust Model Context Protocol SDK implementation with tokio async runtime. diff --git a/docs/readme/README.zh-cn.md b/docs/readme/README.zh-cn.md index edd01ad6..f666928f 100644 --- a/docs/readme/README.zh-cn.md +++ b/docs/readme/README.zh-cn.md @@ -1,32 +1,41 @@ + + # RMCP [![Crates.io Version](https://img.shields.io/crates/v/rmcp)](https://crates.io/crates/rmcp) -![Release status](https://github.commodelcontextprotocol/rust-sdk/actions/workflows/release.yml/badge.svg) [![docs.rs](https://img.shields.io/docsrs/rmcp)](https://docs.rs/rmcp/latest/rmcp) +[![CI](https://github.com/modelcontextprotocol/rust-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/modelcontextprotocol/rust-sdk/actions/workflows/ci.yml) +[![License](https://img.shields.io/crates/l/rmcp)](../../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) 获取开发指南。