MCP follows a client-server architecture where an MCP host --an AI application, like Claude Code or Claude Desktop -- establishes connections to one or more MCP servers. The MCP host accomplishes this by creating one MCP client for each MCP server. Each MCP client maintains a dedicated one-to-one connection with its corresponding MCP server.
The key participants in the MCP architecture are:
1) MCP Host: The AI application that coordinates and manages one or multiple MCP clients.
2) MCP Client: A component that maintains a connection to an MCP server and obtains context from an MCP server for the MCP host to use.
3) MCP Server: A program that provides context to MCP clients
For example: Visual Studio Code acts as an MCP host. When Visual Studion Code establishes a connection to an MCP server, such as the Sentry MCP server, the Visual Studion Code runtime instantiates an MCP client object that maintains the connection to the Sentry MCP server. When Visual Studio COde subsequently connects to another MCP server, such as the local filesystem server, the Visual Studio Code runtime instantiates an additional MCP client object to maintain this connection, hence maintaining a one-to-one relationship of MCP clients to MCP servers.
Note that MCP server refers to the program that servers context data, regardless of where it runs. MCP servers can execute locally or remotely. For example, when Claude Desktop launches the filesystem server, the server runs locally on the same machine because it uses the STDIO transport. This is commonly referred to as a "local" MCP server. The official Sentry MCP server runs on the Sentry platform, and uses the Streamable HTTP transport. This is commonly referred to as a "remote" MCP server.
Laysers
MCP consists of two layers:
1) Data layer: Defines the JSON-PRC based protocol for client-server communication, including lifecycle management, and core primitives, such as tools, resources, prompts and notifications.
2) Transport layer: Defines the communicaiton mechanisms and channels that enable data exchange between clients and servers, including transport-specific connection establishment, message framing, and authorization.
Conceptually the data layer is the inner layer, while the transport layer is the outer layer.
Data layer
The data layer implements JSON-PRC 2.0 based exchange protocol that defines the message structure and semantics. This layer includes:
1) Lifecycle management: Handles connection initialization, capability negotiation, and connection termination between clients and servers.
2)Server features: Enables servers to provide core functionality including tools for AI actions, resources for context data, and prompts for interaction templates from and to the client
3)Client features: Enables servers to ask the client to sample from the host LLM, elicit input from the user, and log messages to the client
4)Utility features: Supports additional capabilities like notifications for real-time updates and progress tracking for long-running operations
Transport layer
The transport layer manages communication channels and authentication between clients and servers. It handles connection establishment, message framing, and secure communicaiton between MCP participants.
MCP supports two transport mechanisms:
1) Stdio transport: Users standard input/output streams for direct process communicaiton between local processes on the same machine, providing optimal performance with no network overhead.
2) Streamable HTTP transport: Use HTTP POST for client-to-server messages with optional Server-Sent Events for streaming capabilities. This transport enables remote serve communication and supports standard HTTP anuthentication methods including bearer tokens, API keys, and custom headers. MCP recommends using OAuth to obtain authentication tokens.
The transport layer abstracts communication details from the protocol layer, enabling the same JSON-RPC message format across all transport mechanisms.

Data Layer Protocol
A core part of MCP is defining the schema and semantics between MCP clients and MCP servers. Developers will likely find the data layer --in particular, the set of primitives --to be the most intersting part of MCP. It is the part of MCP that defines the ways developers can share context from MCP servers to MCP clients.
MCP uses JSON-PRC 2.0 as its underlying RPC protocol. Client and servers send requests to each other and respond accordingly. Notificaitons can be used when no response is required.

Lifecycle management
MCP is a stateful protocol that requires life cycle management. The purpose of lifecycle management is to negotiate the capabilities that both client and server support.

Primitives
MCP primitives are the most important concept within MCP. They define what clients and servers can offer each other. These primitives specify the types of contextual information that can be shared with AI applications and the range of actions that can be performed.
MCP defines three core primitives that servers can expose:
1) Tools: Executable functions that AI applicaitons can invoke to perform actions (e.g., file operations, API calls, database queries)
2) Resources: Data sources that provide contextual informaiton to AI applications (e.g., file contents, database records, API responses)
3) Prompts: Reusable templates that help structure interactions with language models ( e.g., system prompts, few-shot examples)
Each primitive type has associated methods for discovery (*/list), retrieval (*/get), and in some cases, execution (tools/call). MCP clients will use the */list methods to discover available primitives. For examp;le, a client can firsst list all availabel tools (tools/list) and then execute them. This design allows listings to be dynamc.

As a concrete example, consider an MCP server that provides contxt about a database. It can expose tools for querying the databse, a resource that contains the schema of the database, and a prompt that includes few -shot examples for interacting with tools.
MCP also defines primitives that clients can expose. These primitives allow MCP server authors to build richer interactions.
1) Sampling: Allows servers to request language model completions from the client's AI application. This is useful when server's authors want access to a languages model, but want to stay model independent and not include a language model SDK in their MCP server. They can use sampling/complet method to request a language model completion from the client's AP application.
2) Elicitation: Allows servers to request additional information from users. This is useful when server's authors want to get more information from the user, or ask for confirmation of an action. They can use the elicitation/request method to request additional information from the user.
3) Logging: Enables servers to send log messages to clients for edbugging and monitoring purposes.

Notifications
The protocol supports real-time notificaitons to enable dynamic updates between servers and clients. For example, when a server's available tools change-such as when new functionality becomes available or existing tools are modified -- the server can sent tool update notificaitons to inform connected clients about these change. Notifications are sent as JSON-RPC 2.0 notification messages (without expecting a response) and enable MCP servers to provide real-time updates to connected clients.