MCP resources and prompts
The two capabilities beside tools — what #[prompt] generates, and when a host writes rmcp directly instead.
MCP defines two primitives beyond tools: prompts (parameterized templates the user picks) and resources (documents the model can list and fetch).
A prompt is a #[prompt] method in the same decorated block as your tools —
one impl, both routers:
#[tools]impl WeatherTool { #[tool(description = "Return the current temperature for a city.")] #[public] async fn current_temperature(&self, /* … */) -> Result<String, McpError> { /* … */ }
#[prompt(description = "Draft a travel note for a city, primed with today's conditions.")] #[public] async fn travel_note(&self, /* … */) -> Result<GetPromptResult, McpError> { /* … */ }}Resources have no decorator
Section titled “Resources have no decorator”They are the one surface without one, because they are a mapping from
URIs to rows rather than a set of methods. A host that serves them writes its own
impl ServerHandler — list_resources / read_resource /
list_resource_templates — and that is the documented way out of the sugar: it
uses rmcp’s #[tool_router] / #[tool_handler] directly, since #[tools]
cannot generate a second ServerHandler beside a hand-written one. demo’s
posts/mcp/tool.rs is that host.
Either way the guarantee is the same one the tool gets. CrudService::list
above writes no organization filter — the ambient ability applies it, so a
caller from another org gets an empty prompt, and read_resource answers
resource_not_found for a row that exists but is not theirs. The demo asserts
exactly that in apps/assistant/tests/e2e/posts_tool.rs.
Everything else the protocol defines — completion, logging levels,
subscriptions, the tasks/* extension, elicitation, custom methods — is a
ServerHandler method on the same struct, and gets the same treatment. The
protocol types live under nest_rs::mcp::model, the per-operation handles
under nest_rs::mcp::service, and anything newer than this page under
nest_rs::mcp::rmcp.
Going further
Section titled “Going further”- MCP — the
#[tools]block a#[prompt]method lives in. - Authorization — every capability is gated, not just
tools/call.