Model Context Protocol
The Model Context Protocol (MCP) is an open standard which was released by Anthropic in November 2024.
What is MCP?
An abstraction for exposing tools for LLMs. A standardisation for providing an LLM with tools, resources and prompts.
What are the main primitives?
- Tools - for adding functionality
- Resources - static or dynamic URI based resources
- Prompts - for creating workflows based on custom commands or user actions
Sampling
This is a form of callback which gets executed on the client side - it allows an MCP server to interact with an LLM provider via the client. This means you can control LLM implementation client side, as well as things like LLM API keys. The network traffic then also originates from the client side.
Log and Progress Notifications
Allows you to send logs and progress info from the server to the client to improve UX.
context.info() - Send log messages to the client
context.report_progress() - Update progress with current and total values
@mcp.tool(
name="research",
description="Research a given topic"
)
async def research(
topic: str = Field(description="Topic to research"),
*,
context: Context
):
await context.info("About to do research...")
await context.report_progress(20, 100)
Roots
Used to give MCP servers access to folders or files - you still have to implement the actual checks and enforce it.
The MCP SDK doesn't automatically enforce root restrictions
- you need to implement this yourself. A typical pattern
is to create a helper function like is_path_allowed() that:
* Takes a requested file path
* Gets the list of approved roots
* Checks if the requested path falls within one of those roots
* Returns true/false for access permission
* You then call this function in any tool that accesses files or
directories before performing the actual file operation.
Transports
MCP uses a request-result style messaging pattern.
STDIO
Communication between MCP client and MCP server occurs over stdio - only on the same machine.
Streaming HTTP
Can also use streaming HTTP and SSE. There is configuration for whether a result is returned as JSON (give me the result, don't stream it too me), as well as whether to use stateful HTTP (consider horizontal scalability, if you had multiple MCP servers and they may want to do sampling to access LLMs).
SSE for server to client messages using a session ID established on an initial handshake over GET.