Use MCP Resources, Prompts, and Sampling
Expose capability-filtered context, keep prompt templates user-controlled, and let the client own model selection and approval.
Three distinct surfaces
MCP Resources expose application-controlled context. Prompts expose user-controlled message templates. Sampling lets a server request a model call owned and reviewed by the client. None automatically grants Tool authority, mutates an Agent transcript, or trusts returned content.
Keep these surfaces separate in product UI, authorization, audit, and limits.
Discover and consume Resources and Prompts
Use the initialized McpClient from the main MCP guide. The
convenience list methods follow pagination up to the configured page bound.
use std::collections::BTreeMap;
let initialized = client.initialize().await?;
println!("capabilities: {:?}", initialized.capabilities);
for resource in client.list_resources().await? {
println!("{} — {}", resource.uri, resource.name);
}
let resource = client.read_resource("memory://users/42").await?;
for content in resource.contents {
println!("{content:?}");
}
for prompt in client.list_prompts().await? {
println!("{} — {:?}", prompt.name, prompt.description);
}
let rendered = client
.get_prompt(
"review",
BTreeMap::from([("language".into(), "rust".into())]),
)
.await?;
for message in rendered.messages {
println!("{message:?}");
}Do not call Resource, Prompt, or Completion methods unless the initialize result
advertises that capability. read_resource returns protocol content; validate
the URI and media type before displaying or forwarding it. get_prompt returns
messages but never inserts them into an Agent automatically.
Resources
Resources use absolute URIs and ReadOnly capability descriptors. Listing filters by the session Run's authority; reading checks again immediately before execution. Unknown and unauthorized URIs produce the same not-found behavior.
Validate URI identity, content type, decoded binary size, and returned URI. Treat text and binary content as untrusted application data.
Prompts
Prompt descriptors declare stable name, semantic version, arguments, input schema, effect class, and risk. Rendering rejects missing, unknown, blank, or duplicate arguments and bounds message count and serialized size.
prompts/get returns messages to the host. The host decides whether to display,
edit, approve, or insert them. A remote Prompt is not a system instruction.
Sampling
The server may request sampling/createMessage, but cannot select Provider
credentials or force a model. Client policy validates the request, acquires a
concurrency permit, reviews or edits input, reserves conservative token budget,
selects a host-owned model, validates output, and reviews the response before
disclosure.
Server model hints are advisory. Basic Sampling rejects Tools and ambient MCP context. Denied output is never returned to the server.
Sampling is reverse-direction authority: the MCP server asks the client to spend
its model budget. Enable it only by attaching a host-owned SamplingService to
McpClientConfig::with_sampling(...). The service requires three explicit
pieces: a SamplingApprover, a SamplingProvider (or ModelSamplingProvider),
and SamplingPolicy limits. Review happens before the model call and again
before output disclosure.
At minimum set request timeout, maximum concurrent requests, maximum lifetime requests, and token limits. A server-provided model hint must be mapped through your allowlist; it must never select credentials or bypass the host's normal model routing policy.
Trust boundaries
Negotiate every capability, recheck per operation, limit payload and lifetime usage, preserve cancellation and deadline over reverse requests, and record redacted Sampling stages. In-process, stdio, and Streamable HTTP transports must implement the same authority and correlation rules.
Failure guide
| Failure | Meaning | Action |
|---|---|---|
| capability not negotiated | peer did not advertise the surface | disable the UI/action for this session |
| resource not found | unknown or unauthorized URI | do not reveal which condition occurred |
| invalid prompt arguments | missing, unknown, blank, or oversized value | validate against the descriptor before calling |
| repeated pagination cursor | broken or hostile peer | stop pagination and fail the operation |
| Sampling request rejected | approval policy denied input | return denial without invoking a model |
| Sampling response rejected | output policy denied disclosure | do not return model output to the server |
| deadline exceeded | request or reverse request outlived its bound | cancel local work and report typed timeout |