Tools vs Resources vs Prompts in MCP

Understand the three core primitives of the Model Context Protocol — tools, resources, and prompts. Learn when to use each, how they differ, and see practical examples.


title: "Tools vs Resources vs Prompts in MCP" description: "Understand the three core primitives of the Model Context Protocol — tools, resources, and prompts. Learn when to use each, how they differ, and see practical examples." order: 3 keywords:

  • MCP tools
  • MCP resources
  • MCP prompts
  • MCP primitives
  • tools vs resources
  • MCP tool definition
  • MCP resource URI
  • MCP prompt template
  • model context protocol primitives date: "2026-04-01"

Quick Summary

MCP servers expose functionality through three core primitives: Tools (model-controlled functions the AI can invoke), Resources (application-controlled data the AI can read), and Prompts (user-controlled templates for structured interactions). Understanding when to use each primitive is essential for building effective MCP servers.

The Three Primitives

The Model Context Protocol defines three distinct ways for servers to expose functionality to clients. Each primitive serves a different purpose and is controlled by a different actor in the system.

MCP Primitives

MCP primitives are the three fundamental building blocks that MCP servers use to expose capabilities: tools (executable functions), resources (readable data), and prompts (reusable templates). Each primitive has a different control model — tools are model-controlled, resources are application-controlled, and prompts are user-controlled.

At a Glance

AspectToolsResourcesPrompts
PurposeExecute actions and computationsProvide data and contextDefine structured interactions
Controlled byAI model decides when to invokeApplication decides when to fetchUser selects explicitly
AnalogyFunctions / API endpointsGET endpoints / file readsSlash commands / templates
Side effectsCan have side effectsShould be read-onlyNo direct side effects
Discoverytools/listresources/listprompts/list
Invocationtools/callresources/readprompts/get
Input schemaJSON Schema for parametersURI-based addressingJSON Schema for arguments
OutputContent array (text, images)Content with MIME typeArray of prompt messages

Tools: Model-Controlled Functions

Tools are the most commonly used MCP primitive. They represent executable functions that the AI model can decide to invoke based on the user's request.

What Tools Are For

Tools are designed for operations that do something — they perform actions, run computations, interact with external systems, or transform data. Unlike resources, tools can have side effects.

Examples of MCP tools:

  • query_database — Execute SQL queries against a database
  • send_email — Send an email through an email provider
  • create_file — Create a new file on the filesystem
  • search_web — Perform a web search
  • run_tests — Execute a test suite
  • deploy_application — Trigger a deployment pipeline

How Tools Work

Each tool is defined with a name, description, and an input schema written in JSON Schema format. The AI model uses the description and schema to understand what the tool does and how to invoke it.

{
  "name": "query_database",
  "description": "Execute a read-only SQL query against the application database and return results",
  "inputSchema": {
    "type": "object",
    "properties": {
      "sql": {
        "type": "string",
        "description": "The SQL query to execute"
      }
    },
    "required": ["sql"]
  }
}

When the AI model decides to use a tool, the client sends a tools/call request to the server. The server executes the tool logic and returns a result containing one or more content items.

Building Tools with mcp-framework

With mcp-framework, tools are defined as classes with typed input schemas:

import { MCPTool } from "mcp-framework";
import { z } from "zod";

class QueryDatabaseTool extends MCPTool<typeof inputSchema> {
  name = "query_database";
  description = "Execute a read-only SQL query against the application database";

  schema = {
    sql: {
      type: z.string(),
      description: "The SQL query to execute",
    },
  };

  async execute({ sql }: { sql: string }) {
    const results = await db.query(sql);
    return JSON.stringify(results, null, 2);
  }
}

Building Tools with the Official SDK

With the @modelcontextprotocol/sdk, tools are registered using a functional pattern:

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "query_database") {
    const { sql } = request.params.arguments;
    const results = await db.query(sql);
    return {
      content: [{ type: "text", text: JSON.stringify(results) }],
    };
  }
});
Tool Design

Write clear, specific tool descriptions. The AI model relies on the description to decide when and how to use the tool. Include what the tool does, what it returns, and any important constraints. Avoid vague descriptions like "does database stuff" — instead write "Execute a read-only SQL query and return results as JSON."

Resources: Application-Controlled Data

Resources represent data that the server can provide to the client for context. Unlike tools, resources are read-only and should not have side effects.

What Resources Are For

Resources are designed for providing data and context — file contents, database records, API responses, configuration values, or any other information the AI model might need to understand the user's environment.

Examples of MCP resources:

  • file:///project/src/index.ts — Contents of a source file
  • db://users/schema — Database table schema
  • config://app/settings — Application configuration
  • git://repo/status — Current git repository status
  • metrics://dashboard/today — Today's application metrics

How Resources Work

Resources are identified by URIs and can be either static (listed by the server) or dynamic (resolved via URI templates). The client reads a resource by sending a resources/read request with the resource URI.

{
  "uri": "file:///project/src/index.ts",
  "name": "index.ts",
  "description": "Main application entry point",
  "mimeType": "text/typescript"
}

Static vs Dynamic Resources

AspectStatic ResourcesDynamic Resources
DiscoveryListed via resources/listResolved via URI templates
URIFixed, known ahead of timeConstructed from template parameters
Exampleconfig://app/settingsdb://users/{userId}
Use caseKnown files, fixed endpointsUser-specific data, parameterized queries

Resource Subscriptions

Clients can subscribe to resource changes using resources/subscribe. When a subscribed resource changes, the server sends a notification, allowing the client to re-read the resource and update its context.

Resources vs Tools

If you are unsure whether to expose something as a resource or a tool, ask: "Does this operation have side effects?" If yes, make it a tool. If it is purely reading data, make it a resource. That said, many simple read operations work fine as tools too — the distinction is about signaling intent to the client and the AI model.

Prompts: User-Controlled Templates

Prompts are reusable templates that define structured interactions. They are the least commonly used primitive but are powerful for creating consistent, repeatable workflows.

What Prompts Are For

Prompts define multi-step interaction patterns — predefined workflows with specific roles, context injection, and structured outputs. Users explicitly select prompts, typically through a UI element like a slash command or dropdown menu.

Examples of MCP prompts:

  • code_review — A structured code review workflow that examines code for bugs, style, and performance
  • summarize_document — A template for summarizing documents with specific focus areas
  • debug_error — A guided debugging workflow that collects error details and suggests fixes
  • generate_tests — A template for generating test cases from source code

How Prompts Work

Each prompt is defined with a name, description, and optional arguments. When a user selects a prompt, the client sends a prompts/get request and receives back an array of messages that define the interaction:

{
  "name": "code_review",
  "description": "Perform a structured code review",
  "arguments": [
    {
      "name": "code",
      "description": "The code to review",
      "required": true
    },
    {
      "name": "language",
      "description": "Programming language",
      "required": false
    }
  ]
}

The server responds with structured messages:

{
  "messages": [
    {
      "role": "user",
      "content": {
        "type": "text",
        "text": "Please review the following TypeScript code for bugs, performance issues, and style:\n\n```typescript\n// code here\n```"
      }
    }
  ]
}

Prompts with Embedded Resources

Prompts can embed resources directly, combining templates with dynamic data:

{
  "messages": [
    {
      "role": "user",
      "content": {
        "type": "resource",
        "resource": {
          "uri": "file:///project/src/index.ts",
          "text": "// file contents...",
          "mimeType": "text/typescript"
        }
      }
    }
  ]
}

Choosing the Right Primitive

Decision Matrix

Use this guide to choose the right primitive:

  • Use a Tool when: The AI model needs to perform an action, the operation may have side effects, or the operation requires computed input from the AI model.
  • Use a Resource when: You are exposing read-only data, the data can be identified by a URI, or the application (not the AI) should control when the data is fetched.
  • Use a Prompt when: You want to define a reusable interaction pattern, the workflow has a specific structure, or users should explicitly choose when to invoke it.

Common Patterns

ScenarioRecommended PrimitiveReason
Search a databaseToolRequires computed input (search query) from the AI model
Read a config fileResourceStatic, read-only data identified by a path
Send an emailToolHas side effects (sends a real email)
Code review workflowPromptStructured interaction pattern selected by the user
List git branchesTool or ResourceNo side effects, but may benefit from AI-driven filtering
Application logsResourceRead-only data stream that the application controls
Deploy to productionToolCritical side effect requiring explicit invocation
Generate test casesPromptStructured workflow with specific template format

Combining Primitives

The most powerful MCP servers combine all three primitives. For example, a database MCP server might expose:

  • Tools: query_database, insert_record, update_record
  • Resources: db://schema, db://tables/{table}/sample
  • Prompts: analyze_query_performance, generate_migration

This gives the AI model tools for taking action, resources for understanding context, and prompts for structured workflows — all through a single MCP server.

Start with Tools

If you are building your first MCP server, start with tools. They are the most commonly used primitive and provide the most immediate value. You can always add resources and prompts later as your server matures. Both mcp-framework and the @modelcontextprotocol/sdk make it easy to add primitives incrementally.

Frequently Asked Questions