Resources
In the Basics chapter, we learned how to read a resource. In this section, we’ll explore in more detail how deal with resources provided by the MCP server.
Reading a Resource
To read a resource, use the read_resource() method.
It requires the tool name and optional arguments.
use neva::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Error> {
let mut client = Client::new()
.with_options(|opt| opt
.with_stdio(
"cargo",
["run", "--manifest-path", "./neva-mcp-server/Cargo.toml"]));
client.connect().await?;
let resource = client.read_resource("res://resource-1").await?
println!("{:?}", result.contents);
client.disconnect().await
}
Contents
In the example above, the read_resource method returns a ReadResourceResult,
which contains a Vec of ResourceContents.
You can access individual resource fields using the following methods:
uri()title()mime()annotations()text()— returns the text contentblob()— returns the binary (blob) contentjson()— returns the JSON content
Subscribing to resource updates
Two notifications carry resource changes: notifications/resources/list_changed
when the list itself changes (the server must have declared listChanged),
and notifications/resources/updated when a specific resource changes (the
server must have declared subscribe).
Register the handlers after connect() — they assert on what the server
advertises, which is not known until discovery has run:
client.on_resources_changed(|_: Notification| async {
println!("Resource list has been updated");
});
client.on_resource_changed(|n: Notification| async move {
let params = n.params::<SubscribeRequestParams>()
.expect("Expected SubscribeRequestParams");
println!("Resource '{}' has been updated", params.uri);
});
Handlers alone do not make notifications arrive: under MCP 2026-07-28 the
client asks for them with a subscriptions/listen stream, which is where the
per-resource subscription lives:
let mut subscription = client
.listen(SubscriptionFilter::new()
.with_resources_changed()
.with_resource("res://some-resource"))
.await?;
// ...
subscription.cancel().await?;
See Subscriptions for the filter, the acknowledgment, and the subscription's lifecycle.
subscribe_to_resourceclient.subscribe_to_resource(uri) / unsubscribe_from_resource(uri) are the
legacy pair. They stay compiled — the dual-mode fallback still reaches legacy
peers — but reject a 2026-07-28 peer with MethodNotFound. Use
SubscriptionFilter::with_resource(uri) instead, as above.
Learn By Example
Here you may find the full example