The MCP Protocol

Jérémy Martin
April 16, 2025
IA

The MCP Protocol

Artificial intelligence models are only as performant as the context in which they operate.A model can be extremely powerful, but without the right information, it will be ineffective.

  • APIs connect applications to backend services.
  • LSP connects IDEs to language tools.
  • MCP connects AIs to their entire contextual ecosystem.

Without MCP, each application had to maintain a specific implementation with specific calls to tools.

MCP provides standardized AI development:

  • For AI application developers: Connect your application to any MCP server without extra work.
  • For tool or API developers: Build an MCP server once, adopt it everywhere.
  • For end users: More powerful and context-enriched AI applications.
  • For businesses: A clear separation of responsibilities between AI product teams.

MCP is simply a client-server protocol where the application plays the role of the client (also called host) and thus the server exposes tools, resources (documents), and prompts.

FAST MCP

FastMCP is a framework designed to facilitate the creation of servers compliant with the Model Context Protocol (MCP). Since MCP is a standard allowing artificial intelligence applications to interact with external data and tools in a secure and standardized way, FastMCP aims to accelerate and simplify this integration process for developers. By using FastMCP, developers can quickly expose tools (executable functions), resources (accessible data), and prompts (prompt templates) to language models or MCP-compatible applications.

One of the main advantages of FastMCP lies in its ability to abstract the complexity of the MCP protocol itself. Rather than having to manually implement the client-server communication logic, message serialization/deserialization, management of different request types (tools, resources, prompts), and potentially the intricacies of stdio or SSE transports, the developer can rely on the framework.

FastMCP generally offers clear and intuitive syntax, often inspired by modern web frameworks like FastAPI (to which its name likely refers). This typically translates to:

  • Declarative approach: Use of decorators (e.g., @tool, @resource) to simply register Python functions or classes as MCP components.
  • Automatic data validation: Frequent integration with libraries like Pydantic to use Python 'type hints' to define the structure of expected and returned data, and to automatically validate exchanges, thus reducing errors.
  • Integrated protocol management: The framework handles the details of MCP communication in the background, allowing the developer to focus solely on the business logic of the tool or resource they wish to expose.
  • Potential transport support: A good FastMCP framework could offer built-in support for starting the server in stdio or SSE mode with minimal configuration.

To concretely illustrate the simplicity offered by FastMCP, here is a minimalist Python example that creates an MCP server exposing a single tool capable of adding two numbers:

Analysis of the example:

  • Line 2: We import the FastMCP class, which is the framework's entry point.
  • Line 5: An instance of the server is created. The name "Add" could be used by the client to identify this specific server.
  • Line 8 (@mcp.tool()): This is where the magic happens. This decorator transforms the simple Python function add defined just below it into an MCP Tool. FastMCP will handle making this function discoverable by MCP clients and managing calls to it. This is a perfect example of the declarative approach.
  • Line 9 (def add...): This is a standard Python function definition. It contains the business logic: adding a and b.
  • Type Hints (a: int, b: int -> int): Type annotations are crucial. FastMCP uses them to:
    • Define the tool's "schema": what arguments it accepts and what type of result it returns.
    • Automatically validate data received from the client. If the client sends something other than an integer for a or b, FastMCP can reject the request before the add function is even executed.
    • Manage serialization/deserialization between Python types and the format expected by the MCP protocol.
  • Line 10 (Docstring): The documentation string ("""Adds two integers.""") is often used by the framework to generate the tool's description that will be presented to the client or the AI model.

This example demonstrates how, with very little code (mostly standard Python, a decorator, and type hints), FastMCP allows for the creation of a functional MCP server. All the complexity of protocol management, communication, and validation is handled by the framework, allowing the developer to focus on implementing the functionality (here, a simple addition).

Available methods (public) on FastMCP:

  • add_tool(name, function, description, schema): Method to programmatically add a tool (an executable function) to the server. The server can then expose this tool to MCP clients.
  • add_resource(name, data_or_provider, description, schema): Method to programmatically add a resource (accessible data) or a resource provider to the server.
  • add_prompt(name, template, description): Method to programmatically add a prompt template (predefined text) to the server.
  • tool(...): Decorator (@mcp.tool()) to be placed above a Python function to automatically register it as an MCP tool (as in the article's example). More common in FastMCP than add_tool.
  • resource(...): Decorator (@mcp.resource()) to register a function or class as an MCP resource or resource provider.
  • prompt(...): Decorator (@mcp.prompt()) to register a string or a function generating text as an MCP prompt.

Server operations (Responding to client requests):

  • call_tool(tool_name, args): Internal server method triggered when a client requests to execute a specific tool. It finds the tool by its name, passes the arguments provided by the client, executes the associated function, and returns the result to the client.
  • get_context(): Internal method responding to the client's request to get the complete list of all tools, resources, and prompts currently available on this server.
  • get_prompt(prompt_name): Internal method to retrieve and return the content of a specific prompt requested by the client.
  • list_prompts(): Internal method responding to the client's request to list the names and descriptions of available prompts.
  • list_resource_templates(): Internal method to list the types or templates of available resources (e.g., "file", "CRM contact").
  • list_resources(): Internal method to list specific instances of currently accessible resources (e.g., "/home/user/doc.txt", "Contact ID 123"). The difference from the previous one is subtle and depends on the implementation.
  • list_tools(): Internal method responding to the client's request to list the names, descriptions, and schemas (expected parameters, return type) of available tools.
  • read_resource(resource_name): Internal method that handles reading and returning the content of a specific resource (e.g., file content) requested by the client.

Server management (Startup and configuration):

  • run(...): Main method to start the MCP server. It might detect or take as a parameter the transport type (stdio or SSE) and start the appropriate listening loop.
  • run_sse_async(...): Specifically starts the server in SSE (Server-Sent Events) mode over HTTP, asynchronously. Suitable for network servers.
  • run_stdio_async(...): Specifically starts the server in stdio (standard input/output) mode, asynchronously. Suitable for local servers managed by the client application.
  • sse_app(...): Could expose the underlying web application object (e.g., a FastAPI or Starlette instance) used when the server runs in SSE mode. This would allow for deeper integration or adding non-MCP routes if needed.

MCP TRANSPORT TYPES

The MCP protocol defines two main transport mechanisms for communication between the client (the AI application) and the MCP server. The choice of transport depends on where the server runs and how it is managed.

stdio Transport (Standard Input/Output)

This transport mode is designed for servers running locally on the same machine as the client application.

  • Local execution: The server is a process launched on the user's machine.
  • Automatic management: Typically, the client application (like Cursor) is responsible for starting and stopping the server process.
  • Direct communication: Data exchange occurs via the standard input (stdin) and standard output (stdout) streams of the server process.
  • Local access only: By nature, this server is only accessible by the client application on the local machine.
  • Configuration: The client is configured with the necessary shell command to launch the server (e.g., using npx for a Node.js server or python for a Python server).

SSE Transport (Server-Sent Events)

This transport mode uses the Server-Sent Events protocol over HTTP(S), enabling network communication.

  • Local or remote execution: The server can run on the local machine or on a remote server.
  • Manual management: The user is responsible for starting, stopping, and managing the server. They must ensure the server is accessible over the network if necessary.
  • Network communication: Data exchange occurs via HTTP requests to a specific endpoint (usually /sse).
  • Sharing possible: An SSE server can be shared between multiple machines or users if exposed on the network.
  • Configuration: The client is configured with the full URL of the MCP server's /sse endpoint.

In summary, the stdio transport is ideal for simple, local integration managed by the application, while the SSE transport offers the flexibility needed for remote, shared, or independently managed servers.

Written by
Jérémy Martin
Research Director