4The decision framework

Tools vs resources vs prompts

5 min read970 words

You have built an MCP server with tools, resources, and prompts. You have built a client that consumes all three. The plumbing is in your head. What is left — and what this lesson is for — is a single crisp mental model for when to reach for each primitive on the next project you build.

The trick is to stop thinking about what each primitive does and start thinking about who controls it. Every MCP primitive is controlled by a different layer of your application stack, and that control pattern is what tells you which one to pick.

Tools: model-controlled

Tools are controlled by Claude. The model decides when to call them, what arguments to pass, and how to use the results. Your job as the server author is to make capabilities available; Claude's job is to decide when they are appropriate.

Tools are the right answer when you want to extend what Claude can do. If a user asks for the square root of three via JavaScript, Claude can decide — autonomously, mid-conversation — to call a JavaScript execution tool and use the result. You did not have to script the decision. That is the point.

In your project, read_doc_contents and edit_document are tools for exactly this reason. You want Claude to decide, on its own, that reformatting a document requires reading it first and editing it second. Tools serve the model.

Resources: app-controlled

Resources are controlled by your application code. Your app decides when to fetch them and what to do with the data — usually either populating a UI element or augmenting a prompt with extra context.

Think about how the Add from Google Drive button works inside Claude's own interface. The application decides which documents to show in the picker. The application decides to fetch the selected document's content. The application decides to inject that content into the chat context. Claude never made a tool call — it just received a prompt that happened to contain the document.

In your project, docs://documents and docs://documents/{doc_id} serve the same pattern. The CLI decides to fetch the document list when the user types @. The CLI decides to fetch the selected document's content. The content is ready in the prompt before Claude ever sees the turn. Resources serve the app.

Prompts: user-controlled

Prompts are controlled by the user. They are triggered by explicit user actions — button clicks, menu selections, slash commands — and they run predefined workflows the server author crafted in advance.

Look at the workflow buttons beneath the chat input in Claude's interface. Each one is a prompt. The user clicks, the predefined workflow fires, and Claude gets a carefully tuned starting message that the user did not have to write themselves. The expertise lives in the prompt; the activation lives with the user.

In your project, /format is exactly this. The user decides when a document needs reformatting. The server provides the instructions for how to do it well. Prompts serve the user.

The decision guide

When you are building your next MCP integration and trying to decide which primitive fits, ask one question: who should be in control of this?

  • Need to give Claude a new capability it can use autonomously? Tools.
  • Need to pull data into your app for UI population or prompt augmentation? Resources.
  • Want to give users a named, reusable workflow they can trigger on demand? Prompts.

You will see all three patterns in production Claude interfaces. Workflow buttons are prompts. Google Drive document selection is a resource. Code execution is a tool. Once you notice the pattern, you see it everywhere.

Where this leaves you

You started this course with a single user query — "what open pull requests do I have?" — and a vague sense that MCP was the answer. You end it with a working CLI chatbot that implements both sides of the protocol, an understanding of all three MCP primitives, and a decision framework for picking between them.

The next project is up to you. Pick an outside service. Pick the primitives that match how you want users, your app, and Claude to interact with it. Then write the server — or find one someone else already wrote. That is the whole promise of MCP: the integration work compounds because it is shared.

Key Takeaways

  • 1The three MCP primitives are distinguished by their control pattern: tools are model-controlled, resources are app-controlled, and prompts are user-controlled.
  • 2Tools give Claude new capabilities it invokes autonomously; reach for them when the model should decide when a capability is needed.
  • 3Resources let your application fetch data upfront and inject it into prompts or UI elements; reach for them when the app should decide what data Claude sees.
  • 4Prompts expose server-authored workflows that users trigger explicitly; reach for them when you want to package domain expertise into a named, reusable action.
  • 5The decision guide is one question — who should be in control of this? — and the answer maps directly to tools, resources, or prompts.