MCP tools, resources & prompts
Tools, resources and prompts are the three primitives a Model Context Protocol (MCP) server can expose to an AI agent. Tools are callable functions the model can invoke (each with a name, a description and a JSON Schema for inputs, plus an optional output schema); resources are readable data the agent pulls into context, addressed by URI; and prompts are reusable, parameterized prompt templates. MCP rides on JSON-RPC 2.0: after the host's MCP client performs a capability handshake with the server, it discovers all three over JSON-RPC, then the model decides which tool to call, and the host or user decides what to read or apply.
The three MCP primitives
An MCP server can expose three kinds of capability, and a client discovers each through its own JSON-RPC method. Tools are listed via tools/list and invoked via tools/call. Resources are listed via resources/list and read via resources/read. Prompts are listed via prompts/list and fetched via prompts/get. A server may offer any combination — many servers are tool-only — and the client only sees a primitive if the server advertised that capability during the initial handshake.
The dividing line between them is who is in control. Tools are model-controlled: the agent decides, on its own, when to call one and with what arguments. Resources are application- or user-controlled: they are data the host or user chooses to pull into context, not actions the model triggers. Prompts are user-controlled: they are templates a user typically selects (a slash command, a menu entry) to start or shape an interaction.
Getting this distinction right matters for both design and security. A capability that performs a side effect (sending an email, writing a file) belongs as a tool with a clear schema and, if destructive, a confirmation step — not hidden behind a resource read.
Tools: callable functions with schemas
A tool is a function the model can invoke. Each tool has a unique name, a natural-language description telling the model what it does and when to use it, an inputSchema (JSON Schema) defining its parameters, and optionally an outputSchema describing the shape of what it returns. MCP also defines behavioral annotations — readOnlyHint, destructiveHint, idempotentHint, openWorldHint — that signal whether a tool is safe to call speculatively or changes state.
Tools are the highest-leverage and the highest-risk surface, because everything about a tool is text the agent reads as part of its reasoning. The name, the description, every parameter's description, default and example, and the output schema are all loaded into the model's context. Whatever instructions live there, the model may treat as authoritative — which is exactly what tool poisoning abuses.
Good tool design means tight, accurate descriptions, complete and correctly-typed schemas, consolidation of overlapping actions into fewer tools, and honest annotations. Verbose descriptions and oversized schemas also inflate context cost, because the full tool list is re-sent to the model on essentially every turn the server is enabled.
Resources: readable data addressed by URI
A resource is a piece of readable data the server can hand to the agent — a file, a database record, a log, an API response, a documentation page. Each resource is identified by a URI (for example file:///path or a custom scheme like db://orders/42), and the server can also expose resource templates with URI patterns so the client can construct addresses for a family of resources.
Resources are read, not executed. The agent — or, more often, the host application or user — pulls a resource into context to give the model material to reason over; reading a resource should not cause a side effect. Servers can also notify clients when a resource changes, so a host can keep context fresh.
From a safety standpoint, remember that resource contents are untrusted text the model will read. A document or record fetched as a resource can carry injected instructions just like any other external content, so resources contribute to the untrusted-content leg of the lethal trifecta even though they are not, themselves, actions.
Prompts: reusable, parameterized templates
A prompt is a reusable template the server offers to the user, usually surfaced in the host UI as a slash command or menu item. A prompt has a name, an optional description, and an optional set of arguments; when the user selects it and supplies the arguments, prompts/get returns one or more ready-to-send messages that seed or structure the conversation.
Prompts standardize common, high-value interactions — a code-review template, a structured bug report, a summarization recipe — so users do not have to hand-write the same scaffolding each time, and so a server author can encode best-practice phrasing once. Because they are user-invoked rather than model-invoked, they are lower-risk than tools, but their text still enters the model's context and should be reviewed like any other instruction the agent will follow.
How an agent discovers and uses them
The flow is uniform across all three primitives. The host starts one MCP client per server and performs a capability handshake (the initialize exchange) in which the server declares which of tools, resources and prompts it supports. The client then enumerates each supported primitive (tools/list, resources/list, prompts/list) and the host makes them available to the model and the user.
At runtime the model calls tools/call when it decides a function is needed, the host or user triggers resources/read to bring data into context, and the user invokes prompts/get to apply a template. All of this rides on JSON-RPC 2.0 over a transport — stdio for local servers, Streamable HTTP (or the legacy HTTP+SSE pairing) for remote ones, which may sit behind OAuth 2.1.
Because tool and prompt definitions and resource contents all flow into the model's context as text, the practical security boundary is the same for every primitive: an untrusted server can ship hostile text in any of them. That is why a server should be audited — its tools, resources and prompts inspected — before an agent is allowed to trust it.
How CheckMCP handles it
CheckMCP audits all three primitives on a live MCP server and folds them into its explainable 0-100 MCP Score (grade A-F) across seven weighted pillars. Tools dominate the analysis: tool design (weight 18) grades sprawl vs. consolidation, schemas & descriptions (16) grades how completely each tool's inputs and outputs are described, context-cost (12) measures the tokens the whole tool list spends in context, and security (20) runs an OWASP MCP Top 10 pass over every tool's name, description, parameter schema and output schema — flagging tool poisoning (MCP03), hardcoded secrets in a schema (MCP01), destructive tools missing a confirmation or destructiveHint (MCP02) and the lethal trifecta (MCP06). A secret found in a tool schema caps the grade at D, and a failed MCP handshake caps it at F. The coverage/use-case pillar (8) credits a server for usefully exposing tools, resources and prompts for its use case, and the opt-in behavioral evals exercise only read-only-safe tools with benign canary inputs to catch prompt-injection or data-exfiltration in tool responses — never invoking mutating tools. You get the score by pasting a URL at checkmcp.dev or running uvx checkmcp <url>.