Building an MCP server means deciding, for every piece of functionality, whether it should be a resource or a tool. Get this wrong and the server either floods the model with data it didn't ask for, or forces it to guess at actions it should have been offered directly. The distinction is simple once it clicks, and easy to muddle before it does.
Resources: data the model can read
A resource is something the model can look at: a file, a database record, a status snapshot. Resources are passive. They describe state. A resource exposing "current invoice list" or "this week's roster" gives Claude something to reference, similar to handing over a printed report. The model reads it, reasons about it, and doesn't expect anything to change as a result of looking.
A useful test: if the answer to "does calling this change anything" is no, it's a resource. If the answer is yes, or if it triggers a side effect anywhere else in the system, like sending a notification or updating a downstream record, it's a tool, and it should require an explicit, deliberate call rather than being folded quietly into something that looks passive.
Resource: exposes data for the model to read and reason over
Tool: performs an action, often with side effects, that the model explicitly calls
Resources are typically cheaper to serve and easier to cache
Tools need clear names and descriptions so the model calls them correctly
Tools: actions the model can take
A tool is something the model can do: send an email, create a record, update a status, run a calculation. Tools have side effects, or at minimum represent a deliberate action rather than passive reading. The design bar for tools is higher than for resources, because a poorly described tool gets called wrong, called too often, or not called when it should be, and each of those failure modes shows up as a broken workflow rather than a clean error.
A worked example: a rostering MCP server
Building a server for a rostering system, the current week's roster is a resource, exposed once and read as needed. Approving a shift swap is a tool, because it changes state and has consequences someone needs to be able to trace. Getting this split wrong in either direction causes real problems: exposing the roster as a tool that has to be explicitly called every time adds friction for no reason, while exposing shift approval as a resource means there's no clean way for the model to actually take the action a manager asked for.
Why the distinction matters for cost and reliability
Resources tend to be cheap: static data, cached easily, read many times without much overhead. Tools carry more weight, since each call is a deliberate, traceable action, and getting the schema and description right is what determines whether the model calls it correctly the first time or needs three attempts. For an Australian business building an internal MCP server, a rough rule of thumb: if in doubt whether something changes state, treat it as a tool and require an explicit call, because the cost of an accidental unwanted action is higher than the cost of one extra explicit step. A misfired tool call that emails a client twice or double-books a shift costs more in cleanup than the few seconds saved by looser design.
Naming and descriptions matter for both
Whichever you build, the name and description you give it is doing real work. A resource named "data1" tells the model nothing about when to read it. A tool named "process" with a one-line description invites the model to call it for the wrong reason. Specific names and descriptions that state exactly what's returned or what changes, along with any constraints, cut down on the wrong call getting made. This is the same discipline documented in Anthropic's own guidance on writing tools for agents, and it applies whether you're serving three resources or thirty.
If you're scoping an MCP server for your own systems and aren't sure where the resource-versus-tool line falls for your data, that's worth mapping out on paper before writing any code.
A Melbourne logistics business building an internal MCP server for its dispatch system spent a full day upfront mapping every function to resource or tool before writing a line of connecting code. That planning session, worth maybe $600 in billed time, avoided a rebuild three weeks in when the first version had shift assignment wired up as a resource and the model kept describing changes instead of making them.
Get this split right early and the server scales cleanly as you add more functionality later.



