跪拜 Guibai
← All articles
Artificial Intelligence

MCP Resources Don't Auto-Feed the Model — Here's the Explicit 4-Step Chain

By 东风破_ ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Assuming MCP Resources auto-populate the model's context is a common mistake that leads to silent failures: the model answers as if the documentation doesn't exist because, from its perspective, it doesn't. Understanding the explicit Host-driven injection chain prevents wasted debugging time and clarifies where filtering, permission checks, and token budgeting must live in an AI application.

Summary

MCP Resources and Tools follow fundamentally different paths into a model's context. Tools wait for the model to initiate a call, and the Runtime returns results via ToolMessage. Resources, by contrast, must be actively discovered and read by the Host application before the first model invocation even begins. A Resource registered on a Server is invisible to the LLM until the Host completes four explicit steps: listResources, readResource, organize the text, and place it into a SystemMessage.

A minimal Demo using a local MCP Server with stdio transport walks through the full chain. The Server registers a usage guide at docs://guide, but the model never sees it automatically. The Host must call listResources to discover what is available, then readResource with both the server name and URI to fetch the body, and finally construct a SystemMessage containing that text alongside the user's HumanMessage. Only then does the guide enter the context window.

This design keeps token consumption and permission control in the application layer. Real projects should filter resources by URI, user permissions, and task relevance rather than blindly dumping everything into the prompt. The article also distinguishes Resources from RAG: short, stable instructions suit direct Resource injection, while large document collections call for vector retrieval. Both chains can coexist in the same MCP Server alongside Tools, each serving a different control pattern.

Takeaways
registerResource only declares a resource on the Server; it does not modify the model's context.
Tools wait for the model to call them; Resources wait for the Host application to read them.
The Host must call listResources to discover available resources, then readResource with both serverName and URI to fetch the content.
Resource content enters the model only when the Host explicitly places it into a SystemMessage before the first LLM call.
Resource injection does not use ToolMessage because the model never initiates a resource call.
Real applications should filter resources by URI, user permissions, and task relevance rather than dumping everything into the prompt.
Short, stable instructions suit direct Resource injection; large document collections are better served by RAG retrieval.
Always close the MCP Client connection in a finally block to prevent orphaned child processes.
Conclusions

The mental model that 'registration equals visibility' is the root cause of most MCP Resource debugging pain. The Server advertises; the Host decides.

Separating Resource discovery from injection gives the application layer explicit control over token budgets and access permissions, but it also means the developer must wire that control deliberately — there is no default convenience.

Resource and RAG are not competitors. Resource handles curated, always-needed context; RAG handles ad-hoc retrieval from large corpora. Confusing the two leads to either bloated prompts or unnecessary infrastructure.

Concepts & terms
MCP Resource
A capability exposed by an MCP Server that provides static or semi-static materials (guides, schemas, documentation) to be read by the Host application and injected into the model's context, as opposed to Tools which the model invokes dynamically.
SystemMessage
A message role in LLM conversation APIs used to provide instructions or context that the model should follow. MCP Resource content is typically placed here by the Host before the user's query.
ToolMessage
A message role used to return the result of a tool call that the model initiated. It carries a tool_call_id to match the response to the original request. Resources do not use this because the model never calls them.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗