Skip to content

Commit f07ee4a

Browse files
authored
docs: align README examples with v2 model API (#928)
1 parent f1daa92 commit f07ee4a

2 files changed

Lines changed: 188 additions & 256 deletions

File tree

README.md

Lines changed: 94 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,11 @@ struct MyServer;
239239

240240
impl ServerHandler for MyServer {
241241
fn get_info(&self) -> ServerInfo {
242-
ServerInfo {
243-
capabilities: ServerCapabilities::builder()
242+
ServerInfo::new(
243+
ServerCapabilities::builder()
244244
.enable_resources()
245245
.build(),
246-
..Default::default()
247-
}
246+
)
248247
}
249248

250249
async fn list_resources(
@@ -254,8 +253,8 @@ impl ServerHandler for MyServer {
254253
) -> Result<ListResourcesResult, McpError> {
255254
Ok(ListResourcesResult {
256255
resources: vec![
257-
RawResource::new("file:///config.json", "config").no_annotation(),
258-
RawResource::new("memo://insights", "insights").no_annotation(),
256+
Resource::new("file:///config.json", "config"),
257+
Resource::new("memo://insights", "insights"),
259258
],
260259
next_cursor: None,
261260
meta: None,
@@ -268,12 +267,12 @@ impl ServerHandler for MyServer {
268267
_context: RequestContext<RoleServer>,
269268
) -> Result<ReadResourceResult, McpError> {
270269
match request.uri.as_str() {
271-
"file:///config.json" => Ok(ReadResourceResult {
272-
contents: vec![ResourceContents::text(r#"{"key": "value"}"#, &request.uri)],
273-
}),
274-
"memo://insights" => Ok(ReadResourceResult {
275-
contents: vec![ResourceContents::text("Analysis results...", &request.uri)],
276-
}),
270+
"file:///config.json" => Ok(ReadResourceResult::new(vec![
271+
ResourceContents::text(r#"{"key": "value"}"#, &request.uri),
272+
])),
273+
"memo://insights" => Ok(ReadResourceResult::new(vec![
274+
ResourceContents::text("Analysis results...", &request.uri),
275+
])),
277276
_ => Err(McpError::resource_not_found(
278277
"resource_not_found",
279278
Some(json!({ "uri": request.uri })),
@@ -304,10 +303,9 @@ use rmcp::model::{ReadResourceRequestParams};
304303
let resources = client.list_all_resources().await?;
305304

306305
// Read a specific resource by URI
307-
let result = client.read_resource(ReadResourceRequestParams {
308-
meta: None,
309-
uri: "file:///config.json".into(),
310-
}).await?;
306+
let result = client.read_resource(
307+
ReadResourceRequestParams::new("file:///config.json"),
308+
).await?;
311309

312310
// List resource templates
313311
let templates = client.list_all_resource_templates().await?;
@@ -322,9 +320,9 @@ Servers can notify clients when the resource list changes or when a specific res
322320
context.peer.notify_resource_list_changed().await?;
323321

324322
// Notify that a specific resource was updated
325-
context.peer.notify_resource_updated(ResourceUpdatedNotificationParam {
326-
uri: "file:///config.json".into(),
327-
}).await?;
323+
context.peer.notify_resource_updated(
324+
ResourceUpdatedNotificationParam::new("file:///config.json"),
325+
).await?;
328326
```
329327

330328
Clients handle these via `ClientHandler`:
@@ -397,7 +395,7 @@ impl MyServer {
397395
#[prompt(name = "greeting", description = "A simple greeting")]
398396
async fn greeting(&self) -> Vec<PromptMessage> {
399397
vec![PromptMessage::new_text(
400-
PromptMessageRole::User,
398+
Role::User,
401399
"Hello! How can you help me today?",
402400
)]
403401
}
@@ -411,25 +409,20 @@ impl MyServer {
411409
let focus = args.focus_areas
412410
.unwrap_or_else(|| vec!["correctness".into()]);
413411

414-
Ok(GetPromptResult {
415-
description: Some(format!("Code review for {}", args.language)),
416-
messages: vec![
417-
PromptMessage::new_text(
418-
PromptMessageRole::User,
419-
format!("Review my {} code. Focus on: {}", args.language, focus.join(", ")),
420-
),
421-
],
422-
})
412+
Ok(GetPromptResult::new(vec![
413+
PromptMessage::new_text(
414+
Role::User,
415+
format!("Review my {} code. Focus on: {}", args.language, focus.join(", ")),
416+
),
417+
])
418+
.with_description(format!("Code review for {}", args.language)))
423419
}
424420
}
425421

426422
#[prompt_handler]
427423
impl ServerHandler for MyServer {
428424
fn get_info(&self) -> ServerInfo {
429-
ServerInfo {
430-
capabilities: ServerCapabilities::builder().enable_prompts().build(),
431-
..Default::default()
432-
}
425+
ServerInfo::new(ServerCapabilities::builder().enable_prompts().build())
433426
}
434427
}
435428
```
@@ -485,25 +478,22 @@ Access the client's sampling capability through `context.peer.create_message()`:
485478
use rmcp::model::*;
486479

487480
// Inside a ServerHandler method (e.g., call_tool):
488-
let response = context.peer.create_message(CreateMessageRequestParams {
489-
meta: None,
490-
task: None,
491-
messages: vec![SamplingMessage::user_text("Explain this error: connection refused")],
492-
model_preferences: Some(ModelPreferences {
493-
hints: Some(vec![ModelHint { name: Some("claude".into()) }]),
494-
cost_priority: Some(0.3),
495-
speed_priority: Some(0.8),
496-
intelligence_priority: Some(0.7),
497-
}),
498-
system_prompt: Some("You are a helpful assistant.".into()),
499-
include_context: Some(ContextInclusion::None),
500-
temperature: Some(0.7),
501-
max_tokens: 150,
502-
stop_sequences: None,
503-
metadata: None,
504-
tools: None,
505-
tool_choice: None,
506-
}).await?;
481+
let response = context.peer.create_message(
482+
CreateMessageRequestParams::new(
483+
vec![SamplingMessage::user_text("Explain this error: connection refused")],
484+
150,
485+
)
486+
.with_model_preferences(
487+
ModelPreferences::new()
488+
.with_hints(vec![ModelHint::new("claude")])
489+
.with_cost_priority(0.3)
490+
.with_speed_priority(0.8)
491+
.with_intelligence_priority(0.7),
492+
)
493+
.with_system_prompt("You are a helpful assistant.")
494+
.with_include_context(ContextInclusion::None)
495+
.with_temperature(0.7),
496+
).await?;
507497

508498
// Extract the response text
509499
let text = response.message.content
@@ -531,11 +521,11 @@ impl ClientHandler for MyClient {
531521
// Forward to your LLM, or return a mock response:
532522
let response_text = call_your_llm(&params.messages).await;
533523

534-
Ok(CreateMessageResult {
535-
message: SamplingMessage::assistant_text(response_text),
536-
model: "my-model".into(),
537-
stop_reason: Some(CreateMessageResult::STOP_REASON_END_TURN.into()),
538-
})
524+
Ok(CreateMessageResult::new(
525+
SamplingMessage::assistant_text(response_text),
526+
"my-model".into(),
527+
)
528+
.with_stop_reason(CreateMessageResult::STOP_REASON_END_TURN))
539529
}
540530
}
541531
```
@@ -593,14 +583,9 @@ impl ClientHandler for MyClient {
593583
&self,
594584
_context: RequestContext<RoleClient>,
595585
) -> Result<ListRootsResult, ErrorData> {
596-
Ok(ListRootsResult {
597-
roots: vec![
598-
Root {
599-
uri: "file:///home/user/project".into(),
600-
name: Some("My Project".into()),
601-
},
602-
],
603-
})
586+
Ok(ListRootsResult::new(vec![
587+
Root::new("file:///home/user/project").with_name("My Project"),
588+
]))
604589
}
605590
}
606591
```
@@ -631,12 +616,11 @@ use rmcp::{ServerHandler, model::*, service::RequestContext};
631616

632617
impl ServerHandler for MyServer {
633618
fn get_info(&self) -> ServerInfo {
634-
ServerInfo {
635-
capabilities: ServerCapabilities::builder()
619+
ServerInfo::new(
620+
ServerCapabilities::builder()
636621
.enable_logging()
637622
.build(),
638-
..Default::default()
639-
}
623+
)
640624
}
641625

642626
// Client sets the minimum log level
@@ -651,14 +635,16 @@ impl ServerHandler for MyServer {
651635
}
652636

653637
// Send a log message from any handler with access to the peer:
654-
context.peer.notify_logging_message(LoggingMessageNotificationParam {
655-
level: LoggingLevel::Info,
656-
logger: Some("my-server".into()),
657-
data: serde_json::json!({
658-
"message": "Processing completed",
659-
"items_processed": 42
660-
}),
661-
}).await?;
638+
context.peer.notify_logging_message(
639+
LoggingMessageNotificationParam::new(
640+
LoggingLevel::Info,
641+
serde_json::json!({
642+
"message": "Processing completed",
643+
"items_processed": 42
644+
}),
645+
)
646+
.with_logger("my-server"),
647+
).await?;
662648
```
663649

664650
Available log levels (from least to most severe): `Debug`, `Info`, `Notice`, `Warning`, `Error`, `Critical`, `Alert`, `Emergency`.
@@ -683,10 +669,7 @@ impl ClientHandler for MyClient {
683669
Clients can also set the server's log level:
684670

685671
```rust
686-
client.set_level(SetLevelRequestParams {
687-
level: LoggingLevel::Warning,
688-
meta: None,
689-
}).await?;
672+
client.set_level(SetLevelRequestParams::new(LoggingLevel::Warning)).await?;
690673
```
691674

692675
---
@@ -706,13 +689,12 @@ use rmcp::{ErrorData as McpError, ServerHandler, model::*, service::RequestConte
706689

707690
impl ServerHandler for MyServer {
708691
fn get_info(&self) -> ServerInfo {
709-
ServerInfo {
710-
capabilities: ServerCapabilities::builder()
692+
ServerInfo::new(
693+
ServerCapabilities::builder()
711694
.enable_completions()
712695
.enable_prompts()
713696
.build(),
714-
..Default::default()
715-
}
697+
)
716698
}
717699

718700
async fn complete(
@@ -750,13 +732,9 @@ impl ServerHandler for MyServer {
750732
.filter(|v| v.to_lowercase().contains(&request.argument.value.to_lowercase()))
751733
.collect();
752734

753-
Ok(CompleteResult {
754-
completion: CompletionInfo {
755-
values: filtered,
756-
total: None,
757-
has_more: Some(false),
758-
},
759-
})
735+
let completion = CompletionInfo::with_pagination(filtered, None, false)
736+
.map_err(|e| McpError::internal_error(e, None))?;
737+
Ok(CompleteResult::new(completion))
760738
}
761739
}
762740
```
@@ -766,17 +744,10 @@ impl ServerHandler for MyServer {
766744
```rust
767745
use rmcp::model::*;
768746

769-
let result = client.complete(CompleteRequestParams {
770-
meta: None,
771-
r#ref: Reference::Prompt(PromptReference {
772-
name: "sql_query".into(),
773-
}),
774-
argument: ArgumentInfo {
775-
name: "operation".into(),
776-
value: "SEL".into(),
777-
},
778-
context: None,
779-
}).await?;
747+
let result = client.complete(CompleteRequestParams::new(
748+
Reference::for_prompt("sql_query"),
749+
ArgumentInfo::new("operation", "SEL"),
750+
)).await?;
780751

781752
// result.completion.values contains suggestions like ["SELECT"]
782753
```
@@ -802,12 +773,14 @@ use rmcp::model::*;
802773
for i in 0..total_items {
803774
process_item(i).await;
804775

805-
context.peer.notify_progress(ProgressNotificationParam {
806-
progress_token: ProgressToken(NumberOrString::Number(i as i64)),
807-
progress: i as f64,
808-
total: Some(total_items as f64),
809-
message: Some(format!("Processing item {}/{}", i + 1, total_items)),
810-
}).await?;
776+
context.peer.notify_progress(
777+
ProgressNotificationParam::new(
778+
ProgressToken(NumberOrString::Number(i as i64)),
779+
i as f64,
780+
)
781+
.with_total(total_items as f64)
782+
.with_message(format!("Processing item {}/{}", i + 1, total_items)),
783+
).await?;
811784
}
812785
```
813786

@@ -817,10 +790,10 @@ Either side can cancel an in-progress request:
817790

818791
```rust
819792
// Send a cancellation
820-
context.peer.notify_cancelled(CancelledNotificationParam {
821-
request_id: the_request_id,
822-
reason: Some("User requested cancellation".into()),
823-
}).await?;
793+
context.peer.notify_cancelled(CancelledNotificationParam::new(
794+
Some(the_request_id),
795+
Some("User requested cancellation".into()),
796+
)).await?;
824797
```
825798

826799
Handle cancellation in `ServerHandler` or `ClientHandler`:
@@ -891,13 +864,12 @@ struct MyServer {
891864

892865
impl ServerHandler for MyServer {
893866
fn get_info(&self) -> ServerInfo {
894-
ServerInfo {
895-
capabilities: ServerCapabilities::builder()
867+
ServerInfo::new(
868+
ServerCapabilities::builder()
896869
.enable_resources()
897870
.enable_resources_subscribe()
898871
.build(),
899-
..Default::default()
900-
}
872+
)
901873
}
902874

903875
async fn subscribe(
@@ -924,9 +896,9 @@ When a subscribed resource changes, notify the client:
924896

925897
```rust
926898
// Check if the resource has subscribers, then notify
927-
context.peer.notify_resource_updated(ResourceUpdatedNotificationParam {
928-
uri: "file:///config.json".into(),
929-
}).await?;
899+
context.peer.notify_resource_updated(
900+
ResourceUpdatedNotificationParam::new("file:///config.json"),
901+
).await?;
930902
```
931903

932904
### Client-side
@@ -935,16 +907,10 @@ context.peer.notify_resource_updated(ResourceUpdatedNotificationParam {
935907
use rmcp::model::*;
936908

937909
// Subscribe to updates for a resource
938-
client.subscribe(SubscribeRequestParams {
939-
meta: None,
940-
uri: "file:///config.json".into(),
941-
}).await?;
910+
client.subscribe(SubscribeRequestParams::new("file:///config.json")).await?;
942911

943912
// Unsubscribe when no longer needed
944-
client.unsubscribe(UnsubscribeRequestParams {
945-
meta: None,
946-
uri: "file:///config.json".into(),
947-
}).await?;
913+
client.unsubscribe(UnsubscribeRequestParams::new("file:///config.json")).await?;
948914
```
949915

950916
Handle update notifications in `ClientHandler`:

0 commit comments

Comments
 (0)