MCP resource design
Resources are for reading and tools are for doing. Modelling readable data as a tool call wastes the distinction and usually returns too much, while good resource design lets a client fetch precisely what it needs and cache it.
Method
- Use resources for state, tools for actions. If the operation has no side effect and returns data, it is a resource. This distinction is what lets clients handle each appropriately.
- Design URIs to be stable and meaningful. A resource URI is referenced and cached, so it should identify the thing rather than encode a query that changes.
- Make listings cheap and complete. Clients discover through listing, so it must be fast and paginated rather than returning everything.
- Size responses for a context window. A resource that returns a large document unpaged is unusable in practice, so offer ranges or sections (see mcp-context-budgeting).
- Declare the MIME type honestly. Clients render and chunk based on it, and mislabelled content is handled wrongly downstream.
- Support subscription only where change matters. Live updates are valuable for changing state and unnecessary overhead for static content.
- Apply access control per resource. Listing must not reveal resources the caller may not read, since the listing itself leaks structure (see mcp-security-boundaries).
Boundaries
Resources are read-only by contract; anything with an effect belongs in a tool. Not every client supports resources fully, so critical capability may need a tool equivalent. Large binary content is usually better referenced by URL than embedded.