MCP architecture is easiest to understand as a layered system. A host owns the user and model experience. A client connection inside that host speaks the protocol. A server exposes capabilities and mediates access to underlying systems.
The protocol base is JSON-RPC 2.0, but the architectural value is higher-level: capability negotiation, lifecycle management, transport choice, and a clean separation between interface and execution.
A single host can maintain multiple MCP client connections at once, each connected to a focused server. That pattern is one of the reasons MCP scales well across domains like code, documentation, ticketing, and internal operations.
Think in layers: host policy and UX at the top, protocol session in the middle, backend adapters at the bottom. Most bugs and security problems happen when those layers leak into each other.
The architecture page is the primary home for understanding how the protocol is assembled. The host is the application the user interacts with. The client is the protocol implementation within the host. The server is the process or service that describes capabilities and executes work safely.
This layered split is what keeps MCP from becoming just a bag of tool definitions. The host decides how and when to involve the model. The client manages session mechanics. The server decides what capability surface is actually safe and valid.
Initialization is not a formality. It is the first contractual checkpoint of the session. The client and server agree on protocol version and declare which capabilities they support. If a feature is not negotiated, neither side should assume it exists.
This matters because the modern MCP ecosystem includes optional features such as roots, sampling, logging, prompt support, and resource templates. Production integrations stay robust by checking declared capabilities instead of assuming parity between different hosts and servers.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {
"roots": { "listChanged": true }
},
"clientInfo": {
"name": "enterprise-assistant",
"version": "2.4.0"
}
}
}
During normal operation, the client sends requests such as tools/list, tools/call, resources/list, resources/read, or prompts/get. The server may also emit notifications for list changes or logging. That means MCP is not just a request-response API surface. It is a session with state and negotiated features.
For remote transports, session management matters even more. Modern Streamable HTTP deployments can run statefully or statelessly, and that choice affects resumability, routing, and horizontal scale.
Real hosts rarely talk to only one server. A coding assistant may need a repository server, a file server, an internal documentation server, and a ticketing server. The host can keep them separate and choose which one to involve based on user intent and policy.
That decomposition is healthy. A documentation team should not need to ship the same server process as a deployment automation team. Separate servers keep ownership, review, and blast radius smaller.
| Server | Why It Exists | Typical Capabilities |
|---|---|---|
| Filesystem server | Expose current workspace context | read files, search files, list directories |
| Repository server | Work with version control systems | list PRs, read diffs, comment on issues |
| Docs server | Expose curated knowledge | search docs, read policies, fetch runbooks |
| Workflow server | Execute guarded business actions | create tickets, trigger workflows, post updates |
A local stdio server is simple and low-latency because the host spawns a child process and speaks JSON-RPC over stdin and stdout. A remote server is operationally heavier but easier to centralize, monitor, and govern across many users.
The right architecture depends on ownership and trust. If the capability depends on local files, stdio is often natural. If it depends on shared enterprise systems and central identity, a remote deployment is usually cleaner.
Review MCP architecture as a sequence. First, the host knows which server configuration or endpoint to connect to. Second, the client opens a transport session. Third, initialization negotiates protocol version and capabilities. Fourth, the host discovers tools, resources, and prompts. Fifth, the host filters and presents capabilities. Sixth, calls execute with validation, authorization, and structured results.
Each step has its own failure mode. A server can fail to start, initialize with incompatible capabilities, omit an expected tool, expose a capability with a weak schema, reject authorization, return oversized data, or fail backend execution. Treating all of those as "MCP failed" makes debugging slow.
The architecture also separates ownership. The host owns user experience and overall orchestration. The client owns one protocol connection. The server owns capability definitions and backend adapters. The authorization system owns identity and token issuance for remote deployments. Backend services own final data permissions.
This layered view helps teams make safe design decisions. For example, a host may hide a discovered write tool from the model until a user enables it. A server may expose the same tool but still deny calls for users without object-level permission. A backend may reject an action even after the MCP layer approved it.
Draw one MCP session as a sequence diagram: process or endpoint connection, initialize, capability discovery, host filtering, invocation, validation, backend call, response, and trace. Add failure points at each stage.
This diagram becomes a debugging tool. When a real integration fails, you can point to the exact stage instead of saying the server is broken. It also helps security reviewers see where authorization and consent belong.
A useful architecture diagram should show both success and failure paths, because most production MCP debugging is about finding which layer failed and who owns the fix.
For expert practice, connect the concept on this page to one concrete MCP exchange. Identify the request, response, capability metadata, authorization context, and user-facing result so the protocol behavior becomes observable rather than abstract.
User
-> Host UI / Conversation Runtime
-> MCP Client Session
-> Transport (stdio or Streamable HTTP)
-> MCP Server
-> Validation and Authorization
-> Backend System
-> Result
-> Structured MCP Response
Yes. Many servers do, but each capability type should still have a clear job and boundary.
No. The transport changes how messages move, not the meaning of lifecycle, discovery, or capability invocation.
Explore 500+ free tutorials across 20+ languages and frameworks.