Skip to content

Commit 0be6067

Browse files
4t145jefrydco
andauthored
Move whole rmcp crate to offcial rust sdk (#44)
* get rid of async-trait * move rmcp to official-rust-sdk * replace master with main * update readme, change license * fix typo * Update README.md Co-authored-by: Jefry Dewangga <[email protected]> * fix typos --------- Co-authored-by: = <=> Co-authored-by: Jefry Dewangga <[email protected]>
1 parent 31493cf commit 0be6067

File tree

113 files changed

+8676
-4466
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+8676
-4466
lines changed

.github/workflows/release.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches: [ release ]
6+
tags:
7+
- 'release-*'
8+
pull_request:
9+
branches: [ release ]
10+
env:
11+
CARGO_TERM_COLOR: always
12+
ARTIFACT_DIR: release-artifacts
13+
14+
jobs:
15+
release:
16+
name: Release crates
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v3
20+
21+
- name: Install Rust
22+
uses: dtolnay/rust-toolchain@stable
23+
24+
- name: Cache dependencies
25+
uses: actions/cache@v3
26+
with:
27+
path: |
28+
~/.cargo/registry
29+
~/.cargo/git
30+
target
31+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
32+
restore-keys: ${{ runner.os }}-cargo-
33+
34+
- name: Check formatting
35+
run: cargo fmt --all -- --check
36+
- name: Run clippy
37+
run: cargo clippy --all-targets --all-features -- -D warnings
38+
- name: Cargo login
39+
run: cargo login ${{ secrets.CRATES_TOKEN }}
40+
- name: Publish macros dry run
41+
run: cargo publish -p rmcp-macros --dry-run
42+
continue-on-error: true
43+
- name: Publish rmcp dry run
44+
run: cargo publish -p rmcp --dry-run
45+
continue-on-error: true
46+
- name: Publish macro
47+
if: ${{ startsWith(github.ref, 'refs/tags/release') }}
48+
continue-on-error: true
49+
run: cargo publish -p rmcp-macros
50+
- name: Publish rmcp
51+
if: ${{ startsWith(github.ref, 'refs/tags/release') }}
52+
continue-on-error: true
53+
run: cargo publish -p rmcp
54+

.github/workflows/test.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,19 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- uses: actions/checkout@v3
18-
18+
# install nodejs
19+
- name: Setup Node.js
20+
uses: actions/setup-node@v2
21+
with:
22+
node-version: '20'
23+
- name: Install uv
24+
uses: astral-sh/setup-uv@v5
1925
- name: Install Rust
2026
uses: dtolnay/rust-toolchain@stable
21-
27+
- name: Set up Python
28+
run: uv python install
29+
- name: Create venv for python
30+
run: uv venv
2231
- name: Cache dependencies
2332
uses: actions/cache@v3
2433
with:

Cargo.toml

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
[workspace]
2-
members = [
3-
"crates/*",
4-
"examples/clients",
5-
"examples/servers",
6-
"examples/macros"
7-
]
2+
members = ["crates/rmcp", "crates/rmcp-macros", "examples/*"]
83
resolver = "2"
94

105
[workspace.dependencies]
11-
mcp-core = { path = "./crates/mcp-core" }
12-
mcp-macros = { path = "./crates/mcp-macros" }
6+
rmcp = { version = "0.1.5", path = "./crates/rmcp" }
7+
rmcp-macros = { version = "0.1.5", path = "./crates/rmcp-macros" }
138

149
[workspace.package]
15-
edition = "2021"
16-
version = "1.0.7"
17-
authors = ["Block <[email protected]>"]
18-
license = "MIT"
19-
repository = "https://github.com/modelcontextprotocol/rust-sdk/"
10+
edition = "2024"
11+
version = "0.1.5"
12+
authors = ["4t145 <[email protected]>"]
13+
license = "MIT/Apache-2.0"
14+
repository = "https://github.commodelcontextprotocol/rust-sdk/"
2015
description = "Rust SDK for the Model Context Protocol"
16+
keywords = ["mcp", "sdk", "tokio", "modelcontextprotocol"]
17+
homepage = "https://github.com/modelcontextprotocol/rust-sdk"
18+
categories = [
19+
"network-programming",
20+
"asynchronous",
21+
]
22+
readme = "README.md"

README.md

Lines changed: 169 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,169 @@
1-
# rust-sdk
2-
The official Rust SDK for the Model Context Protocol
1+
<div align = "right">
2+
<a href="docs/readme/README.zh-cn.md">简体中文</a>
3+
</div>
4+
5+
# RMCP
6+
[![Crates.io Version](https://img.shields.io/crates/v/rmcp)](https://crates.io/crates/rmcp)
7+
![Release status](https://github.commodelcontextprotocol/rust-sdk/actions/workflows/release.yml/badge.svg)
8+
[![docs.rs](https://img.shields.io/docsrs/rmcp)](https://docs.rs/rmcp/latest/rmcp)
9+
10+
An official rust Model Context Protocol SDK implementation with tokio async runtime.
11+
12+
## Usage
13+
14+
### Import
15+
```toml
16+
rmcp = { version = "0.1", features = ["server"] }
17+
## or dev channel
18+
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "dev" }
19+
```
20+
21+
### Quick start
22+
Start a client in one line:
23+
```rust
24+
use rmcp::{ServiceExt, transport::TokioChildProcess};
25+
use tokio::process::Command;
26+
27+
let client = ().serve(
28+
TokioChildProcess::new(Command::new("npx").arg("-y").arg("@modelcontextprotocol/server-everything"))?
29+
).await?;
30+
```
31+
32+
#### 1. Build a transport
33+
34+
```rust, ignore
35+
use tokio::io::{stdin, stdout};
36+
let transport = (stdin(), stdout());
37+
```
38+
39+
The transport type must implemented [`IntoTransport`](crate::transport::IntoTransport) trait, which allow split into a sink and a stream.
40+
41+
For client, the sink item is [`ClientJsonRpcMessage`](crate::model::ClientJsonRpcMessage) and stream item is [`ServerJsonRpcMessage`](crate::model::ServerJsonRpcMessage)
42+
43+
For server, the sink item is [`ServerJsonRpcMessage`](crate::model::ServerJsonRpcMessage) and stream item is [`ClientJsonRpcMessage`](crate::model::ClientJsonRpcMessage)
44+
45+
##### These types is automatically implemented [`IntoTransport`](crate::transport::IntoTransport) trait
46+
1. The types that already implement both [`Sink`](futures::Sink) and [`Stream`](futures::Stream) trait.
47+
2. A tuple of sink `Tx` and stream `Rx`: `(Tx, Rx)`.
48+
3. The type that implement both [`tokio::io::AsyncRead`] and [`tokio::io::AsyncWrite`] trait.
49+
4. A tuple of [`tokio::io::AsyncRead`] `R `and [`tokio::io::AsyncWrite`] `W`: `(R, W)`.
50+
51+
For example, you can see how we build a transport through TCP stream or http upgrade so easily. [examples](examples/README.md)
52+
53+
#### 2. Build a service
54+
You can easily build a service by using [`ServerHandler`](crates/rmcp/src/handler/server.rs) or [`ClientHandler`](crates/rmcp/src/handler/client.rs).
55+
56+
```rust, ignore
57+
let service = common::counter::Counter::new();
58+
```
59+
60+
#### 3. Serve them together
61+
```rust, ignore
62+
// this call will finish the initialization process
63+
let server = service.serve(transport).await?;
64+
```
65+
66+
#### 4. Interact with the server
67+
Once the server is initialized, you can send requests or notifications:
68+
69+
```rust, ignore
70+
// request
71+
let roots = server.list_roots().await?;
72+
73+
// or send notification
74+
server.notify_cancelled(...).await?;
75+
```
76+
77+
#### 5. Waiting for service shutdown
78+
```rust, ignore
79+
let quit_reason = server.waiting().await?;
80+
// or cancel it
81+
let quit_reason = server.cancel().await?;
82+
```
83+
84+
### Use marcos to declaring tool
85+
Use `toolbox` and `tool` macros to create tool quickly.
86+
87+
Check this [file](examples/servers/src/common/calculator.rs).
88+
```rust, ignore
89+
use rmcp::{ServerHandler, model::ServerInfo, schemars, tool};
90+
91+
use super::counter::Counter;
92+
93+
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
94+
pub struct SumRequest {
95+
#[schemars(description = "the left hand side number")]
96+
pub a: i32,
97+
#[schemars(description = "the right hand side number")]
98+
pub b: i32,
99+
}
100+
#[derive(Debug, Clone)]
101+
pub struct Calculator;
102+
103+
// create a static toolbox to store the tool attributes
104+
#[tool(tool_box)]
105+
impl Calculator {
106+
// async function
107+
#[tool(description = "Calculate the sum of two numbers")]
108+
async fn sum(&self, #[tool(aggr)] SumRequest { a, b }: SumRequest) -> String {
109+
(a + b).to_string()
110+
}
111+
112+
// sync function
113+
#[tool(description = "Calculate the sum of two numbers")]
114+
fn sub(
115+
&self,
116+
#[tool(param)]
117+
// this macro will transfer the schemars and serde's attributes
118+
#[schemars(description = "the left hand side number")]
119+
a: i32,
120+
#[tool(param)]
121+
#[schemars(description = "the right hand side number")]
122+
b: i32,
123+
) -> String {
124+
(a - b).to_string()
125+
}
126+
}
127+
128+
// impl call_tool and list_tool by querying static toolbox
129+
#[tool(tool_box)]
130+
impl ServerHandler for Calculator {
131+
fn get_info(&self) -> ServerInfo {
132+
ServerInfo {
133+
instructions: Some("A simple calculator".into()),
134+
..Default::default()
135+
}
136+
}
137+
}
138+
139+
```
140+
The only thing you should do is to make the function's return type implement `IntoCallToolResult`.
141+
142+
And you can just implement `IntoContents`, and the return value will be marked as success automatically.
143+
144+
If you return a type of `Result<T, E>` where `T` and `E` both implemented `IntoContents`, it's also OK.
145+
146+
### Manage Multi Services
147+
For many cases you need to manage several service in a collection, you can call `into_dyn` to convert services into the same type.
148+
```rust, ignore
149+
let service = service.into_dyn();
150+
```
151+
152+
153+
### Examples
154+
See [examples](examples/README.md)
155+
156+
### Features
157+
- `client`: use client side sdk
158+
- `server`: use server side sdk
159+
- `macros`: macros default
160+
#### Transports
161+
- `transport-io`: Server stdio transport
162+
- `transport-sse-server`: Server SSE transport
163+
- `transport-child-process`: Client stdio transport
164+
- `transport-sse`: Client sse transport
165+
166+
## Related Resources
167+
- [MCP Specification](https://spec.modelcontextprotocol.io/specification/2024-11-05/)
168+
169+
- [Schema](https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.ts)

crates/mcp-client/Cargo.toml

Lines changed: 0 additions & 27 deletions
This file was deleted.

crates/mcp-client/README.md

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)