Core architecture
Understand how MCP connects clients, servers, and LLMs
The Model Context Protocol (MCP) is built on a flexible, extensible architecture that enables seamless communication between LLM applications and integrations. This document covers the core architectural components and concepts.
Overview
MCP follows a client-server architecture where:
- Hosts are LLM applications (like Claude Desktop or IDEs) that initiate connections
- Clients maintain 1:1 connections with servers, inside the host application
- Servers provide context, tools, and prompts to clients
Core components
Protocol layer
The protocol layer handles message framing, request/response linking, and high-level communication patterns.
Key classes include:
Protocol
Client
Server
Transport layer
The transport layer handles the actual communication between clients and servers. MCP supports multiple transport mechanisms:
-
Stdio transport
- Uses standard input/output for communication
- Ideal for local processes
-
HTTP with SSE transport
- Uses Server-Sent Events for server-to-client messages
- HTTP POST for client-to-server messages
All transports use JSON-RPC 2.0 to exchange messages. See the specification for detailed information about the Model Context Protocol message format.
Message types
MCP has these main types of messages:
-
Requests expect a response from the other side:
-
Notifications are one-way messages that don’t expect a response:
-
Results are successful responses to requests:
-
Errors indicate that a request failed:
Connection lifecycle
1. Initialization
- Client sends
initialize
request with protocol version and capabilities - Server responds with its protocol version and capabilities
- Client sends
initialized
notification as acknowledgment - Normal message exchange begins
2. Message exchange
After initialization, the following patterns are supported:
- Request-Response: Client or server sends requests, the other responds
- Notifications: Either party sends one-way messages
3. Termination
Either party can terminate the connection:
- Clean shutdown via
close()
- Transport disconnection
- Error conditions
Error handling
MCP defines these standard error codes:
SDKs and applications can define their own error codes above -32000.
Errors are propagated through:
- Error responses to requests
- Error events on transports
- Protocol-level error handlers
Implementation example
Here’s a basic example of implementing an MCP server:
Best practices
Transport selection
-
Local communication
- Use stdio transport for local processes
- Efficient for same-machine communication
- Simple process management
-
Remote communication
- Use SSE for scenarios requiring HTTP compatibility
- Consider security implications including authentication and authorization
Message handling
-
Request processing
- Validate inputs thoroughly
- Use type-safe schemas
- Handle errors gracefully
- Implement timeouts
-
Progress reporting
- Use progress tokens for long operations
- Report progress incrementally
- Include total progress when known
-
Error management
- Use appropriate error codes
- Include helpful error messages
- Clean up resources on errors
Security considerations
-
Transport security
- Use TLS for remote connections
- Validate connection origins
- Implement authentication when needed
-
Message validation
- Validate all incoming messages
- Sanitize inputs
- Check message size limits
- Verify JSON-RPC format
-
Resource protection
- Implement access controls
- Validate resource paths
- Monitor resource usage
- Rate limit requests
-
Error handling
- Don’t leak sensitive information
- Log security-relevant errors
- Implement proper cleanup
- Handle DoS scenarios
Debugging and monitoring
-
Logging
- Log protocol events
- Track message flow
- Monitor performance
- Record errors
-
Diagnostics
- Implement health checks
- Monitor connection state
- Track resource usage
- Profile performance
-
Testing
- Test different transports
- Verify error handling
- Check edge cases
- Load test servers