|
3 | 3 | 
|
4 | 4 | [](https://docs.rs/rmcp/latest/rmcp)
|
5 | 5 |
|
6 |
| -一个基于tokio异步运行时的官方Model Context Protocol SDK实现。 |
| 6 | +一个基于 tokio 异步运行时的官方 Model Context Protocol SDK 实现。 |
| 7 | + |
| 8 | +本项目使用了以下开源库: |
| 9 | + |
| 10 | +- [rmcp](crates/rmcp): 实现 RMCP 协议的核心库 (详见:[rmcp](crates/rmcp/README.md)) |
| 11 | +- [rmcp-macros](crates/rmcp-macros): 一个用于生成 RMCP 工具实现的过程宏库。 (详见:[rmcp-macros](crates/rmcp-macros/README.md)) |
7 | 12 |
|
8 | 13 | ## 使用
|
9 | 14 |
|
10 | 15 | ### 导入
|
11 | 16 | ```toml
|
12 |
| -rmcp = { version = "0.1", features = ["server"] } |
13 |
| -## 或者开发者频道 |
| 17 | +rmcp = { version = "0.2.0", features = ["server"] } |
| 18 | +## 或使用最新开发版本 |
14 | 19 | rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main" }
|
15 | 20 | ```
|
16 | 21 |
|
17 |
| -### 快速上手 |
18 |
| -一行代码启动客户端: |
19 |
| -```rust |
| 22 | +### 第三方依赖库 |
| 23 | +基本依赖: |
| 24 | +- [tokio required](https://github.com/tokio-rs/tokio) |
| 25 | +- [serde required](https://github.com/serde-rs/serde) |
| 26 | + |
| 27 | +### 构建客户端 |
| 28 | +<details> |
| 29 | +<summary>构建客户端</summary> |
| 30 | + |
| 31 | +```rust, ignore |
20 | 32 | use rmcp::{ServiceExt, transport::{TokioChildProcess, ConfigureCommandExt}};
|
21 | 33 | use tokio::process::Command;
|
22 | 34 |
|
23 |
| -let client = ().serve(TokioChildProcess::new(Command::new("npx").configure(|cmd| { |
24 |
| - cmd.arg("-y").arg("@modelcontextprotocol/server-everything"); |
25 |
| -}))?).await?; |
| 35 | +#[tokio::main] |
| 36 | +async fn main() -> Result<(), Box<dyn std::error::Error>> { |
| 37 | + let client = ().serve(TokioChildProcess::new(Command::new("npx").configure(|cmd| { |
| 38 | + cmd.arg("-y").arg("@modelcontextprotocol/server-everything"); |
| 39 | + }))?).await?; |
| 40 | + Ok(()) |
| 41 | +} |
26 | 42 | ```
|
| 43 | +</details> |
27 | 44 |
|
28 |
| -#### 1. 构建传输层 |
| 45 | +### 构建服务端 |
| 46 | + |
| 47 | +<details> |
| 48 | +<summary>构建传输层</summary> |
29 | 49 |
|
30 | 50 | ```rust, ignore
|
31 | 51 | use tokio::io::{stdin, stdout};
|
32 | 52 | let transport = (stdin(), stdout());
|
33 | 53 | ```
|
34 | 54 |
|
35 |
| -传输层类型必须实现 [`IntoTransport`](crate::transport::IntoTransport) trait, 这个特性允许分割成一个sink和一个stream。 |
36 |
| - |
37 |
| -对于客户端, Sink 的 Item 是 [`ClientJsonRpcMessage`](crate::model::ClientJsonRpcMessage), Stream 的 Item 是 [`ServerJsonRpcMessage`](crate::model::ServerJsonRpcMessage) |
| 55 | +</details> |
38 | 56 |
|
39 |
| -对于服务端, Sink 的 Item 是 [`ServerJsonRpcMessage`](crate::model::ServerJsonRpcMessage), Stream 的 Item 是 [`ClientJsonRpcMessage`](crate::model::ClientJsonRpcMessage) |
| 57 | +<details> |
| 58 | +<summary>构建服务</summary> |
40 | 59 |
|
41 |
| -##### 这些类型自动实现了 [`IntoTransport`](crate::transport::IntoTransport) trait |
42 |
| -1. 已经同时实现了 [`Sink`](futures::Sink) 和 [`Stream`](futures::Stream) trait的类型。 |
43 |
| -2. 由sink `Tx` 和 stream `Rx`组成的元组: `(Tx, Rx)`。 |
44 |
| -3. 同时实现了 [`tokio::io::AsyncRead`] 和 [`tokio::io::AsyncWrite`] trait的类型。 |
45 |
| -4. 由 [`tokio::io::AsyncRead`] `R `和 [`tokio::io::AsyncWrite`] `W` 组成的元组: `(R, W)`。 |
46 |
| - |
47 |
| -例如,你可以看到我们如何轻松地通过TCP流或http升级构建传输层。 [examples](examples/README.md) |
48 |
| - |
49 |
| -#### 2. 构建服务 |
50 |
| -你可以通过 [`ServerHandler`](crates/rmcp/src/handler/server.rs) 或 [`ClientHandler`](crates/rmcp/src/handler/client.rs) 轻松构建服务 |
| 60 | +You can easily build a service by using [`ServerHandler`](crates/rmcp/src/handler/server.rs) or [`ClientHandler`](crates/rmcp/src/handler/client.rs). |
51 | 61 |
|
52 | 62 | ```rust, ignore
|
53 | 63 | let service = common::counter::Counter::new();
|
54 | 64 | ```
|
| 65 | +</details> |
| 66 | + |
| 67 | +<details> |
| 68 | +<summary>启动服务端</summary> |
55 | 69 |
|
56 |
| -#### 3. 把他们组装到一起 |
57 | 70 | ```rust, ignore
|
58 |
| -// 这里会自动完成初始化流程 |
| 71 | +// this call will finish the initialization process |
59 | 72 | let server = service.serve(transport).await?;
|
60 | 73 | ```
|
| 74 | +</details> |
| 75 | + |
| 76 | +<details> |
| 77 | +<summary>与服务端交互</summary> |
61 | 78 |
|
62 |
| -#### 4. 与服务交互 |
63 |
| -一旦服务初始化完成,你可以发送请求或通知: |
| 79 | +Once the server is initialized, you can send requests or notifications: |
64 | 80 |
|
65 | 81 | ```rust, ignore
|
66 |
| -// 请求 |
| 82 | +// request |
67 | 83 | let roots = server.list_roots().await?;
|
68 | 84 |
|
69 |
| -// 或发送通知 |
| 85 | +// or send notification |
70 | 86 | server.notify_cancelled(...).await?;
|
71 | 87 | ```
|
| 88 | +</details> |
| 89 | + |
| 90 | +<details> |
| 91 | +<summary>等待服务停止</summary> |
72 | 92 |
|
73 |
| -#### 5. 等待服务关闭 |
74 | 93 | ```rust, ignore
|
75 | 94 | let quit_reason = server.waiting().await?;
|
76 |
| -// 或取消它 |
| 95 | +// 或将其取消 |
77 | 96 | let quit_reason = server.cancel().await?;
|
78 | 97 | ```
|
| 98 | +</details> |
79 | 99 |
|
80 |
| -### 使用宏来声明工具 |
81 |
| -使用 `toolbox` 和 `tool` 宏来快速创建工具。 |
82 |
| - |
83 |
| -请看这个[文件](examples/servers/src/common/calculator.rs)。 |
84 |
| -```rust, ignore |
85 |
| -use rmcp::{ServerHandler, model::ServerInfo, schemars, tool}; |
86 |
| -
|
87 |
| -use super::counter::Counter; |
88 |
| -
|
89 |
| -#[derive(Debug, serde::Deserialize, schemars::JsonSchema)] |
90 |
| -pub struct SumRequest { |
91 |
| - #[schemars(description = "the left hand side number")] |
92 |
| - pub a: i32, |
93 |
| - #[schemars(description = "the right hand side number")] |
94 |
| - pub b: i32, |
95 |
| -} |
96 |
| -#[derive(Debug, Clone)] |
97 |
| -pub struct Calculator; |
98 |
| -
|
99 |
| -// create a static toolbox to store the tool attributes |
100 |
| -#[tool_router] |
101 |
| -impl Calculator { |
102 |
| - // async function |
103 |
| - #[tool(description = "Calculate the sum of two numbers")] |
104 |
| - async fn sum(&self, #[tool(aggr)] SumRequest { a, b }: SumRequest) -> String { |
105 |
| - (a + b).to_string() |
106 |
| - } |
107 |
| -
|
108 |
| - // sync function |
109 |
| - #[tool(description = "Calculate the sum of two numbers")] |
110 |
| - fn sub( |
111 |
| - &self, |
112 |
| - #[tool(param)] |
113 |
| - // this macro will transfer the schemars and serde's attributes |
114 |
| - #[schemars(description = "the left hand side number")] |
115 |
| - a: i32, |
116 |
| - #[tool(param)] |
117 |
| - #[schemars(description = "the right hand side number")] |
118 |
| - b: i32, |
119 |
| - ) -> String { |
120 |
| - (a - b).to_string() |
121 |
| - } |
122 |
| -} |
| 100 | +### 示例 |
| 101 | +查看 [examples](examples/README.md) |
123 | 102 |
|
124 |
| -// impl call_tool and list_tool by querying static toolbox |
125 |
| -#[tool_handler] |
126 |
| -impl ServerHandler for Calculator { |
127 |
| - fn get_info(&self) -> ServerInfo { |
128 |
| - ServerInfo { |
129 |
| - instructions: Some("A simple calculator".into()), |
130 |
| - ..Default::default() |
131 |
| - } |
132 |
| - } |
133 |
| -} |
| 103 | +## OAuth 支持 |
134 | 104 |
|
135 |
| -``` |
136 |
| -你要做的唯一事情就是确保函数的返回类型实现了 `IntoCallToolResult`。 |
| 105 | +查看 [oauth_support](docs/OAUTH_SUPPORT.md) |
137 | 106 |
|
138 |
| -你可以为返回类型实现 `IntoContents`,那么返回值将自动标记为成功。 |
| 107 | +## 相关资源 |
139 | 108 |
|
140 |
| -如果返回类型是 `Result<T, E>`,其中 `T` 与 `E` 都实现了 `IntoContents`,那也是可以的。 |
| 109 | +- [MCP Specification](https://spec.modelcontextprotocol.io/specification/2024-11-05/) |
| 110 | +- [Schema](https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.ts) |
141 | 111 |
|
142 |
| -### 管理多个服务 |
143 |
| -在很多情况下你需要在一个集合中管理多个服务,你可以调用 `into_dyn` 来将服务转换为相同类型。 |
144 |
| -```rust, ignore |
145 |
| -let service = service.into_dyn(); |
146 |
| -``` |
| 112 | +## 相关项目 |
| 113 | +- [containerd-mcp-server](https://github.com/jokemanfire/mcp-containerd) - 基于 containerd 实现的 MCP 服务 |
147 | 114 |
|
| 115 | +## 开发 |
148 | 116 |
|
149 |
| -### 示例 |
150 |
| -查看 [examples](examples/README.md) |
| 117 | +### 贡献指南 |
151 | 118 |
|
152 |
| -### 功能特性 |
153 |
| -- `client`: 使用客户端sdk |
154 |
| -- `server`: 使用服务端sdk |
155 |
| -- `macros`: 宏默认 |
156 |
| -#### 传输层 |
157 |
| -- `transport-io`: 服务端标准输入输出传输 |
158 |
| -- `transport-sse-server`: 服务端SSE传输 |
159 |
| -- `transport-child-process`: 客户端标准输入输出传输 |
160 |
| -- `transport-sse`: 客户端SSE传输 |
| 119 | +查看 [docs/CONTRIBUTE.MD](docs/CONTRIBUTE.MD) |
161 | 120 |
|
162 |
| -## 相关资源 |
163 |
| -- [MCP Specification](https://spec.modelcontextprotocol.io/specification/2024-11-05/) |
| 121 | +### 使用 Dev Container |
164 | 122 |
|
165 |
| -- [Schema](https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.ts) |
| 123 | +如果你想使用 Dev Container,查看 [docs/DEVCONTAINER.md](docs/DEVCONTAINER.md) 获取开发指南。 |
0 commit comments