Skip to content

Commit afa6a7b

Browse files
authored
feat!: improve shema_utils, generqted new schema sets (#95)
* feat!: improve shema_utils, generqted new schema sets * chore: update test * chore: flix rustfmt * chore: typo
1 parent 9eecf0f commit afa6a7b

File tree

14 files changed

+3220
-7204
lines changed

14 files changed

+3220
-7204
lines changed

README.md

Lines changed: 75 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -159,29 +159,20 @@ The following code snippet demonstrates how an MCP message, represented as a JSO
159159
160160
```rs
161161

162-
pub fn handle_message(message_payload: &str)->Result<Error> {
163-
164-
// Deserialize message into ClientMessage.
165-
// ClientMessage is an enum defined in schema_utils.
166-
let message = ClientMessage::from_str(&message_payload)?;
167-
168-
// Check if the message is a Request
169-
if let ClientMessage::Request(message_object) = message {
170-
171-
// Check if it's a standard ClientRequest (not a CustomRequest)
172-
if let RequestFromClient::ClientRequest(client_request) = message_object.request {
173-
174-
// Check if it's an InitializeRequest
175-
if let rust_mcp_schema::ClientRequest::InitializeRequest(initialize_request) = client_request {
176-
177-
// Process the InitializeRequest (and eventually send back a InitializedNotification back to the server)
178-
handle_initialize_request(initialize_request);
179-
180-
}
181-
}
162+
pub fn handle_messagew(message_payload: &str) -> std::result::Result<(), RpcError> {
163+
// Deserialize message into ClientMessage.
164+
let message = ClientMessage::from_str(&message_payload)?;
165+
166+
// Check if the message is a Request
167+
if let ClientMessage::Request(message_object) = message {
168+
// Check if it's an InitializeRequest
169+
if let ClientRequest::InitializeRequest(initialize_request) = client_request {
170+
// Process the InitializeRequest (and eventually send back a InitializedNotification back to the server)
171+
handle_initialize_request(initialize_request);
182172
}
183-
184173
}
174+
Ok(())
175+
}
185176

186177
```
187178

@@ -194,91 +185,90 @@ In response to an InitializeRequest, the MCP Server is expected to return an Ini
194185
This code snippet demonstrates how to create an InitializeRequest, serialize it into a string, and send it back to the client via the transport layer.
195186

196187
```rs
197-
// create InitializeResult object
198-
let initial_result = InitializeResult {
199-
capabilities: ServerCapabilities {
200-
experimental: None,
201-
logging: None,
202-
prompts: Some(ServerCapabilitiesPrompts {
203-
list_changed: Some(true),
204-
}),
205-
resources: Some(ServerCapabilitiesResources {
206-
list_changed: Some(true),
207-
subscribe: Some(true),
208-
}),
209-
tools: Some(ServerCapabilitiesTools {
210-
list_changed: Some(true),
211-
}),
212-
},
213-
instructions: Some(String::from("mcp server instructions....")),
214-
meta: Some(
215-
vec![
216-
("meta 1".to_string(), Value::String("meta-value".to_string())),
217-
("meta 2".to_string(), Value::Number(serde_json::Number::from(225))),
218-
("feature-xyz".to_string(), Value::Bool(true)),
219-
]
220-
.into_iter()
221-
.collect(),
222-
),
223-
protocol_version: LATEST_PROTOCOL_VERSION.to_string(),
224-
server_info: Implementation {
225-
name: String::from("example-servers/everything"),
226-
version: String::from("1.0.0"),
227-
},
228-
};
229-
230-
188+
// create InitializeResult object
189+
let initial_result = InitializeResult {
190+
capabilities: ServerCapabilities {
191+
logging: None,
192+
prompts: Some(ServerCapabilitiesPrompts {list_changed: Some(true)}),
193+
resources: Some(ServerCapabilitiesResources {list_changed: Some(true),subscribe: Some(true)}),
194+
tools: Some(ServerCapabilitiesTools { list_changed: Some(true)}),
195+
completions: None,
196+
tasks: Some(ServerTasks { cancel: Some(Map::new()), list: Some(Map::new()), requests: None }),
197+
experimental: None,
198+
},
199+
instructions: Some(String::from("mcp server instructions....")),
200+
meta: Some(
201+
json!({
202+
"meta 1": serde_json::Value::String("meta-value".into()),
203+
"meta 2": serde_json::Value::Number(serde_json::Number::from(225)),
204+
"feature-xyz": serde_json::Value::Bool(true)
205+
}).as_object().unwrap().to_owned(),
206+
),
207+
protocol_version: ProtocolVersion::V2025_11_25.into(),
208+
server_info: Implementation {
209+
name: String::from("rust mcp server"),
210+
title: Some("Cool mcp server!".into()),
211+
version: String::from("1.0.0"),
212+
description: Some("your rust mcp server description....".into()),
213+
icons: vec![],
214+
website_url: Some("https://github.com/rust-mcp-stack/rust-mcp-schema".into()),
215+
},
216+
};
217+
218+
// JsonrpcResultResponse vs JsonrpcResponse
231219
// Create a ServerMessage (a message intended to be sent from the server)
232-
let message: ServerMessage = initial_result.to_message(request_id).unwrap();
220+
let message = ServerJsonrpcResponse::new(RequestId::Integer(0), initial_result.into());
233221

234-
// Serialize the MCP message into a valid JSON string for sending to the client
235-
let json_payload = message.to_string();
222+
// Serialize the MCP message into a valid JSON string for sending to the client
223+
let json_payload = serde_json::to_string(&message).unwrap();
236224

237-
println!("{}", json_payload);
225+
println!("{}", json_payload);
238226
```
239227

240228
output:
241229

242230
```json
243231
{
244-
"id": 15,
232+
"id": 0,
245233
"jsonrpc": "2.0",
246234
"result": {
247235
"capabilities": {
248236
"prompts": { "listChanged": true },
249237
"resources": { "listChanged": true, "subscribe": true },
238+
"tasks": { "cancel": {}, "list": {} },
250239
"tools": { "listChanged": true }
251240
},
252241
"instructions": "mcp server instructions....",
253-
"_meta": { "feature-xyz": true, "meta 1": "meta-value", "meta 2": 225 },
254-
"protocolVersion": "2024-11-05",
255-
"serverInfo": { "name": "example-servers/everything", "version": "1.0.0" }
242+
"protocolVersion": "2025-11-25",
243+
"serverInfo": {
244+
"description": "your rust mcp server description....",
245+
"name": "rust mcp server",
246+
"title": "Cool mcp server!",
247+
"version": "1.0.0",
248+
"websiteUrl": "https://github.com/rust-mcp-stack/rust-mcp-schema"
249+
},
250+
"_meta": { "feature-xyz": true, "meta 1": "meta-value", "meta 2": 225 }
256251
}
257252
}
258253
```
259254

260-
### Detecting an `InitializeResult` Response Message in an MCP Client.
255+
### Detecting an `InitializeResult` Response Message in an MCP Client:
261256

262257
```rs
263258
fn handle_message(message_payload: &str) -> std::result::Result<(), AppError> {
264259
// Deserialize message into ServerMessage.
265260
// ServerMessage represents a message sent by an MCP Server and received by an MCP Client.
266261
let mcp_message = ServerMessage::from_str(message_payload)?;
267262

268-
// Check if the message is a Response type of message
269-
if let ServerMessage::Response(message_object) = mcp_message {
270-
271-
// Check if it's a standard ServerResult (not a CustomResult)
272-
if let ResultFromServer::ServerResult(server_response) = message_object.result {
273-
274-
// Check if it's a InitializeResult type of response
275-
if let ServerResult::InitializeResult(server_response){
276-
//Process the InitializeResult and send an InitializedNotification back to the server for acknowledgment.
277-
handle_initialize_result(initialize_request);
278-
279-
}
263+
// Check if the message is a Response type of message
264+
if let ServerMessage::Response(server_response) = mcp_message {
265+
// Check if it's a InitializeResult response
266+
if let ServerResult::InitializeResult(initialize_result) = server_response.result {
267+
//Process the InitializeResult and send an InitializedNotification back to the server for acknowledgment.
268+
handle_initialize_result(initialize_request);
280269
}
281-
}
270+
}
271+
Ok(())
282272
}
283273
```
284274

@@ -295,31 +285,21 @@ The following code example illustrates how to detect an InitializeRequest messag
295285
```rs
296286

297287
fn handle_message(message_payload: &str) -> std::result::Result<(), AppError> {
298-
299-
// Deserialize json string into JsonrpcMessage
300-
let message: JsonrpcMessage = serde_json::from_str(message_payload)?;
288+
// Deserialize json string into JsonrpcMessage
289+
let message: JsonrpcMessage = serde_json::from_str(message_payload).unwrap();
301290

302291
// Check it's a Request type of message
303292
if let JsonrpcMessage::Request(client_message) = message {
293+
let client_request: ClientRequest = serde_json::from_value(client_message.params.into()).unwrap();
304294

305295
// Check method to detect is a "initialize" request
306-
if client_message.method == "initialize" {
307-
296+
if let ClientRequest::InitializeRequest(initialize_request) = client_request {
308297
// Now that we can handle the message, we simply print out the details.
309-
println!("{} request received!", "initialize");
310-
311-
if let Some(params) = client_message.params {
312-
// print out params meta
313-
println!("params.meta : {:?} ", params.meta);
314-
315-
let params: InitializeRequestParams = serde_json::from_value(Value::Object(params.extra.unwrap())).unwrap();
298+
println!("Initialize request received!");
316299

317-
// print out InitializeRequestParams param values
318-
println!(
319-
"client_info : {:?} \ncapabilities: {:?} \nprotocol_version: {:?}",
320-
params.client_info, params.capabilities, params.protocol_version
321-
);
322-
}
300+
println!("Client name : {:?} ", initialize_request.params.client_info.name);
301+
println!("Client version : {:?} ", initialize_request.params.client_info.version);
302+
323303
}
324304
}
325305

0 commit comments

Comments
 (0)