MCP's Three Primitives: Tools, Resources, and Prompts
MCP servers can expose three first-class capability types: tools, resources, and prompts.
Search across all documentation pages
MCP servers can expose three first-class capability types: tools, resources, and prompts.
Clients negotiate which of these a server supports during session initialization. Not every server implements all three.
| Primitive | Direction of initiative | Typical content | Model usually... | Host usually... |
|---|---|---|---|---|
| Tools | Model/host invokes action | Args in, result out | Chooses when to call | Authorizes, executes via MCP, returns observation |
| Resources | Host/user selects data | URIs + text/binary content | Reads injected context | Lists, fetches, attaches to context |
| Prompts | User/host starts workflow | Templated messages | Follows the filled template | Lists, fills arguments, inserts messages |
Tools → "do something" (side effects possible)
Resources → "read this context" (mostly passive data)
Prompts → "start this workflow" (guided multi-message shapes)What they are: Named operations with JSON Schema-like input definitions and structured results.
When to expose as a tool:
Client flow (conceptual):
tools/list → expose schemas to model
tools/call → { name, arguments } → result contentDesign rules:
| Rule | Why |
|---|---|
Verb-noun names (get_order, create_ticket) | Clear selection |
| Tight required fields + enums | Fewer bad args |
| Short structured results | Protects context budget |
| Separate read vs write tools | Easier least privilege |
| Host allowlists after list | Servers may be over-broad |
# Conceptual tool descriptor (server SDK shapes vary)
tool = {
"name": "get_order_status",
"description": "Fetch order status by id. Use for live status, not historical analytics.",
"inputSchema": {
"type": "object",
"properties": {
"order_id": {"type": "integer", "description": "Numeric order id"}
},
"required": ["order_id"],
"additionalProperties": False,
},
}Security note: Tools are the highest risk primitive because they can mutate systems.
What they are: Addressable pieces of context (files, docs, records, configs) identified by URIs.
When to expose as a resource:
Client flow (conceptual):
resources/list → pick URI
resources/read → content (text or binary metadata)
optional: subscribe / notifications when content changesURI examples (illustrative):
| URI pattern | Meaning |
|---|---|
file:///project/README.md | Local file resource |
docs://handbook/onboarding | Knowledge base page |
db://customers/42 | Record snapshot |
config://agent/policy | Host policy blob |
Design rules:
| Rule | Why |
|---|---|
| Stable URIs | Caching and bookmarks |
| MIME / mime-like typing | Host can render correctly |
| Size limits or pagination | Avoid multi-MB dumps into prompts |
| Read-only default | Resources should not mutate silently |
| Redact secrets on read | Resources enter model context |
Resources are not a substitute for tools when the model must act. They shine when the host wants to attach known context without inventing a pseudo-tool.
What they are: Named, parameterized message templates (workflows) a user or host can invoke.
When to expose as a prompt:
Client flow (conceptual):
prompts/list → show catalog in UI
prompts/get → fill arguments → message list for the host# Conceptual prompt descriptor
prompt = {
"name": "summarize_diff",
"description": "Summarize a git diff for a PR description",
"arguments": [
{"name": "diff", "description": "Unified diff text", "required": True},
{"name": "audience", "description": "engineer|pm", "required": False},
],
}Design rules:
| Rule | Why |
|---|---|
| Clear argument list | Hosts can render forms |
| Opinionated structure | Consistent outputs |
| No hidden side effects | Prompts should not silently write systems |
| Version names when behavior changes | Avoid surprise template drift |
Prompts are usually user- or host-initiated, not free-fired by the model on every turn. Some hosts may also load prompt text as system instructions; treat that as a product choice.
| Need | Prefer | Avoid |
|---|---|---|
| Model should decide when to act | Tool | Encoding actions only as free text |
| Attach a known document | Resource | Forcing the model to cat via a shell tool every time |
| Start a standardized workflow | Prompt | Pasting a long template manually each session |
| Both read and write the same system | Tools (+ optional resources for snapshots) | One mega-tool that does everything |
| Huge corpus | Resources with selective attach or search tools | Always-on full dump |
Servers advertise support; clients only call what was negotiated.
initialize
server capabilities: { tools?, resources?, prompts?, logging?, ... }
client only requests listed methodsIf list_tools works but list_resources fails, the server may simply not implement resources.
Design hosts to degrade gracefully.
| Primitive | Typical insertion point |
|---|---|
| Tools | Model tool list + tool-result observations |
| Resources | System/user context before reason steps |
| Prompts | Initial messages or slash-command workflows |
User picks prompt "incident_triage"
→ host fills args
→ messages seeded
→ model may call tools
→ host may attach resources as evidenceNo. Tools-only servers are common and valid.
Yes, depending on client support. Prefer references or strict size caps for model context.
Not exactly. MCP prompts are named templates from a server. A host may place their content into system or user roles.
The host. MCP delivers the call path; policy stays with your agent runtime.
Usually no. Hosts list and select what to attach unless a product auto-includes them.
Some servers notify clients when resource lists or contents change so hosts can refresh context (verify support for your protocol version).
No. Curate a small, agent-friendly surface with clear names and tight schemas.
They are additional protocol capabilities beyond the three core primitives. Start with tools/resources/prompts, then add advanced features as needed.
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026