MCP Server Design · ~6 min
Before you name a single tool, you make one decision: what kind of capability is this? Pick the wrong primitive and every later choice fights you.
MCP standardises the interface between an agent and the outside world. The agent speaks MCP on one side; your server speaks MCP on the other. Like TCP/IP, the protocol decouples the agent's reasoning from your tool's implementation — so the first thing to understand is exactly what your server is allowed to put on the wire.
An MCP server exposes exactly three kinds of capability. They differ not by what they do but by who decides to invoke them — and that ownership is the whole design signal.
| Primitive | Controlled by | Use when |
|---|---|---|
| Tool | The model (agent invokes) | The agent takes an action or fetches dynamic data — create_issue, search_logs |
| Resource | The application (client attaches) | Read-only context the agent sees but cannot call — project config, a schema, env info |
| Prompt | The user (slash command) | A reusable multi-step workflow the user triggers — /summarize-pr, /deploy-staging |
At startup the host reads your server's manifest and hands the agent your tool descriptions — names and prose, not the code behind them. That manifest is the agent's entire mental model of your server. The agent discovers capabilities from it and decides, turn by turn, which tool fits the task.
This is the clean split MCP enforces: the agent handles reasoning, planning, and language; your server handles execution. The agent never needs to know how a query runs — it calls the tool and reads the result. Reasoning becomes auditable (which tools, in what order?) separately from implementation.
The same server can run in two places, and the choice ripples through everything later (auth, hosting, latency):
The server runs as a subprocess on the same machine, talking over stdin/stdout. Fast, and sufficient for most developer tooling. Each session spawns it fresh.
The server runs elsewhere and accepts HTTP connections with optional streaming, so a whole team shares one hosted server. (The older HTTP+SSE transport is deprecated — don't build on it.)
Because both implement MCP, they're interchangeable from the agent's point of view. Switch hosts — Claude Code to Copilot — and neither server changes.
Retrieval practice — recall, don't peek
Question 1The three MCP primitives are distinguished mainly by…
Question 2Read-only context the agent shouldn't have to call for is best exposed as a…
Question 3At startup, the agent's model of your server comes from…
Question 4A team that wants one shared, hosted server should use…
Question 5 · looking aheadMCP's separation of concerns lets the agent handle…