The M × N problem
Lesson 1 of 5 in MCP Fundamentals: One Protocol Instead of M × N Integrations.
You already know function calling: you hand a model a JSON Schema for each tool, it emits a tool call, your runtime executes it. That works beautifully for one application with a handful of tools you wrote yourself.
Now scale it. You have M AI applications — a desktop assistant, an IDE, a CI bot, an internal agent — and N systems worth connecting: GitHub, Postgres, Slack, Sentry, the filesystem, your internal ticketing API. Every application needs its own connector for every system, with its own auth handling, its own schema translation, its own retry logic. That is M × N integrations, each one maintained by whoever happened to write it.
The Model Context Protocol collapses that into M + N. Every system is wrapped once as an MCP server; every application speaks MCP client once. Anything that speaks the protocol works with anything else that speaks it.
| Concern | Bespoke connectors (M × N) | One protocol (M + N) |
|---|---|---|
Integration count | 4 apps × 6 systems = 24 connectors, each written and maintained separately. | 4 clients + 6 servers = 10 components. Each system is wrapped once. |
Who writes the integration | Every app team re-learns every API. The GitHub connector exists four times, subtly differently. | Whoever knows the system best writes the server once — often the vendor themselves. |
Tool schemas | Hand-authored per app; drift between apps is invisible until it bites. | The server declares |
Adding a new app | Re-implement all N integrations before it is useful. | Implement the client side of the protocol; inherit every existing server. |
Where trust decisions live | Scattered through each connector, in code the app team owns. | Concentrated in the host, which mediates every server and every consent prompt — the subject of lesson 4. |
The architecture that makes this work has three roles, and the spec is precise about them. A host is the LLM application — it initiates connections, coordinates clients, enforces security policy, handles user authorization, and aggregates context. Inside the host, one client is created per server, and each client holds a 1:1 connection to exactly one server. A server provides context and capabilities, and it may be a local process or a remote service.
That 1:1 rule is not bureaucratic. It is how the spec keeps servers apart from each other.
One tool call, end to end
- User goal in the host app
The host is the LLM application: an IDE, a desktop assistant, an agent runtime. It owns the conversation and the security policy.
- Clients list server capabilities
Each client asks its one server what it offers — tools/list, resources/list, prompts/list. Under 2026-07-28 a client MAY first call server/discover for supported protocol versions, capabilities, and identity.
- Host aggregates tool definitions into the model context
The host decides which servers’ tools the model even sees. Names are unique per server, so an aggregating host needs a disambiguation strategy — commonly server-prefixing.
- Model emits a tool call
Ordinary function calling: the model names a tool and supplies arguments matching the declared inputSchema.
- Host policy: allow this invocation?
The spec says hosts must obtain explicit user consent before invoking any tool, and that there SHOULD always be a human in the loop able to deny it. The protocol does not mandate the UI.
- Client sends tools/call as JSON-RPC 2.0
One client, one server, one connection. The message format is JSON-RPC 2.0 regardless of transport.
- Server executes and returns a result
Results carry unstructured content (text, images, resource links) and/or structuredContent. Execution failures come back as isError: true rather than as protocol errors.
- Result appended to context; loop continues
- Denied — nothing executes
Key terms: MCP, MCP host, MCP client, MCP server, function calling, tool, JSON-RPC 2.0
Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.