When should something be modeled as a resource instead of a tool result?
Quick Answer
Model something as a resource when it represents addressable, relatively stable data the host or user might want to browse, reference, re-read, or attach independent of any specific tool invocation — a file, a document, a database table's schema. Model it as a tool result when producing the data is itself an action with parameters, side effects, or a computation the model needs to explicitly decide to trigger — running a search, executing a query, sending a request. A useful test: if you'd want a UI element that lets a user browse and pick from a list of these things ahead of time (a file picker, a "recent items" panel), it's a resource; if it only makes sense as something the model does in response to a specific need in the conversation, it's a tool.
Detailed Answer
The line between "expose this as a resource" and "expose this as a tool" isn't always obvious, especially for read-only data. Both can return the same underlying content, so the choice comes down to who should control access to it.
A decision framework
| Signal | Favor resource | Favor tool |
|---|---|---|
| Does producing it require meaningful parameters/search? | No — mostly just a URI | Yes — query, filters, pagination params |
| Should a user be able to browse/pick it ahead of time? | Yes | Not really |
| Is fetching it an "action" the model deliberately decides to take mid-task? | No | Yes |
| Does the host want to auto-attach it as background context? | Yes | No |
| Is the underlying operation read-only and idempotent? | Almost always | Often, but not required |
Worked examples
- A specific, known file's contents → resource. It has a stable address (
file:///path), a user might open it directly from a file browser, and reading it isn't really a "decision" so much as a lookup. - "Search all files for a term" → tool. It takes a parameter (the search term). The result set depends entirely on that input, and it's naturally something the model decides to invoke based on the conversation, not something pre-listed for a user to browse.
- A database table's current schema → resource. Stable, addressable, useful as background context.
- "Run this SQL query" → tool. Parameterized, potentially has side effects if it's not a plain
SELECT, and represents a deliberate action.
The nuance
Nothing stops a server from exposing the same underlying data both ways. A file server might offer files as browsable resources and a read_file(path) tool, for the model to fetch one on demand by a path it derived during reasoning — a path mentioned in another tool's output, say, that wasn't in the original resource list. Offering both isn't redundant. It serves the two different control models — host-driven browsing vs. model-driven, ad hoc lookup — that resources and tools exist to separate.