Part 1 · The Surface

MCP Server Design · ~6 min

What a Server Exposes

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.

Why this, for you: the Model Context Protocol is how a tool you write once works in any agent host — Claude Code, Copilot, Cursor — without a per-host integration. But the agent only sees what your server declares. Get the surface right and the right call becomes obvious; get it wrong and the agent burns tokens guessing.

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.

1 Three primitives, three owners

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.

PrimitiveControlled byUse when
ToolThe model (agent invokes)The agent takes an action or fetches dynamic data — create_issue, search_logs
ResourceThe application (client attaches)Read-only context the agent sees but cannot call — project config, a schema, env info
PromptThe user (slash command)A reusable multi-step workflow the user triggers — /summarize-pr, /deploy-staging
Picking the wrong primitive creates friction before naming or schema design even matters. Read-only context jammed into a tool forces the agent to call for something it should simply be handed — wasted turns, wasted tokens.

2 The agent only knows what you declare

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.

3 Two transports: local and remote

The same server can run in two places, and the choice ripples through everything later (auth, hosting, latency):

stdio — local

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.

Streamable HTTP — remote

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.

↪ Your win: choose the primitive before you name anything

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…

Ask me anything. Want a minimal stdio server skeleton, or help deciding tool-vs-resource for a capability you have in mind? Next in Part 1: Data, Just in Time — why you expose a corpus as searchable tools instead of dumping it into context.
✎ Feedback