# Build performant MCP servers with FastMCP for Clarifai

The Model Context Protocol (MCP) is an open standard developed by Anthropic that acts as a universal language for AI models, particularly large language models (LLMs), to interact with external data sources (like GitHub, Slack, or databases) and extend their capabilities.

With MCP, you can build intelligent agents and complex workflows on top of LLMs, enabling secure and efficient access to contextual information.

## How it Works

At its core, MCP follows a [client-server architecture](/content/blog/mcp-vs-a2a-clearly-explained/index.html) where a host application (like an AI chatbot or an IDE with AI features) can connect to an MCP server. The server acts as a gateway to specific external data, tools, or functionalities.

An MCP server can expose several key capabilities — most notably, tools that function as callable actions for LLMs, such as updating records or interacting with external systems.

While MCP provides the specification, implementing clients and servers that adhere to it can involve substantial boilerplate code and intricate protocol handling. This is exactly where [FastMCP](https://github.com/jlowin/fastmcp) excels. FastMCP is a high-level framework that significantly simplifies the development of MCP servers and clients.

Clarifai allows you to build performant MCP servers with FastMCP by providing the necessary infrastructure needed to define, deploy, and manage custom MCP servers at scale.

## Build an MCP Server

Building an MCP server with FastMCP using Clarifai follows the same intuitive pattern as [building and uploading models](https://docs.clarifai.com/compute/models/upload/) on the platform.

Let's demonstrate how you can build a simple MCP server using the FastMCP framework. This server will expose callable tools for LLMs or other AI agents, and we'll upload it to the Clarifai platform as a custom model, making its functionalities accessible within the Clarifai ecosystem.

### Step 1: Perform Prerequisites

#### Install Packages

You need to install the following Python packages:

- `clarifai` – The latest version of the Clarifai Python SDK required for integrating your MCP server with the Clarifai platform. This also installs the Clarifai [Command Line Interface (CLI)](https://docs.clarifai.com/resources/api-overview/cli), which we'll use for uploading the server.

- `fastmcp` – This is the core framework used to define and manage the MCP server.

- `pydantic` – [Pydantic](https://github.com/pydantic/pydantic) is essential for data validation and defining the structure (schema) of your tool arguments, particularly using `Field`. We'll pair it with `Any` and `Annotated` from Python's `typing` module to add vital metadata, like descriptions, to function arguments, which is key for `fastmcp`'s type hinting and automatic schema generation.

You can run the following command to install them:

```bash
pip install --upgrade fastmcp pydantic clarifai
```

Or, you can define the packages in a [`requirements.txt`](https://docs.clarifai.com/compute/agents/mcp/#step-4-define-dependencies-in-requirementstxt) file and run the following command to install them:

```bash
pip install -r requirements.txt
```

#### Set a PAT Key

You need to have a [Personal Access Token](https://docs.clarifai.com/control/authentication/pat) (PAT) to authenticate your connection with the Clarifai platform. You can get one by navigating to **Settings** in the collapsible left sidebar, selecting **Secrets**, and creating or copying an existing token from there.

Then, set the `CLARIFAI_PAT` as an environment variable.

- Unix-Like Systems  
```bash
export CLARIFAI_PAT=YOUR_PERSONAL_ACCESS_TOKEN_HERE
```

- Windows  
```bash
set CLARIFAI_PAT=YOUR_PERSONAL_ACCESS_TOKEN_HERE
```

#### Create Files

Create a project directory and organize your files as indicated below to fit the requirements of building custom models for the Clarifai platform.

```text
your_model_directory/
├── 1/
│   └── model.py
├── requirements.txt
└── config.yaml
└── client.py
```

You can automatically generate these files by running this CLI command: [`clarifai model init --toolkit mcp`](https://docs.clarifai.com/resources/api-overview/cli#clarifai-model-init). You can then edit them as needed.

- **your_model_directory/**– The root directory containing all files related to your server.
  - **1/** – A subdirectory that holds the model file ( _Note that the folder is named as **1**_).
    - **model.py** – Contains the main logic for the MCP server implementation.
  - **requirements.txt** – Lists the Python dependencies required to run your server.
  - **config.yaml** – Contains metadata and configuration settings needed for uploading the model to Clarifai.
  - **client.py** – Only contains an example client for demonstrating MCP usage after uploading the model to Clarifai.

### Step 2: Prepare `model.py` File

`model.py` is the main file where you'll implement your MCP server's logic.

Here's the `model.py` file for the custom model (or, in this case, a server) we want to build:

```python
from typing import Any

from fastmcp import FastMCP
from pydantic import Field

from clarifai.runners.models.mcp_class import MCPModelClass

server = FastMCP("my-mcp-server", instructions="A sample MCP server.", stateless_http=True)

@server.tool("hello", description="Say hello to someone")
def hello(name: str = Field(description="Name to greet")) -> str:
    """Greet a user by name."""
    return f"Hello, {name}!"

@server.resource("config://version")
def get_version():
    """Return the server version."""
    return "1.0.0"

class MyModel(MCPModelClass):
    """MCP model that exposes tools, resources, and prompts."""

def get_server(self) -> FastMCP:
        """Return the FastMCP server instance."""
        return server
```

Let’s break down what each part of the file does.

#### a. Initialize the FastMCP Server

You'll start by creating an instance of the `FastMCP` class to set up your server.

Here are the key arguments you can pass to the `FastMCP` constructor:
- `name` – An optional identifier for your MCP server. This is useful for distinguishing it in logs or when managing multiple servers in client applications.
- `instructions` – An optional, short description that helps clients understand the server's purpose or how to best interact with its functionalities.
- `stateless_http` – A boolean flag (`True`/`False`) that configures the server to operate over stateless HTTP. Turning this on is ideal for lightweight deployments, as it simplifies communication by not requiring persistent sessions.

#### b. Define Tools

An empty MCP server isn't very useful; its power comes from the **tools** it exposes. We define these tools by applying the `@server.tool(...)` decorator directly to Python functions. This decorator registers the function as an MCP "tool," making it discoverable and invokable by any MCP client (like an LLM).

Each tool is enriched with essential metadata:
- Tool-level metadata – The `@server.tool()` decorator itself takes a `name` and `description` to explain the tool's overall purpose.
- Input descriptions – The tool's input arguments are precisely described using `Annotated` in conjunction with `Field`.

In our example, we define a tool and a resource:
- `hello` – A tool that takes a `name` parameter and returns a greeting message.
- `config://version` – A resource that returns the server version.

#### c. Define Clarifai's Model Class

The custom-named model class serves as the integration point between your MCP server and the Clarifai platform.

You must define it by subclassing Clarifai's `MCPModelClass` and implementing the `get_server()` method. This method returns the `FastMCP` server instance (such as `server`) that Clarifai should use when running your model.

When Clarifai runs the model, it calls `get_server()` to load your MCP server and expose its defined tools and capabilities to LLMs or other agents.

### Step 3: Prepare `config.yaml` File

The `config.yaml` file is used to configure the build and deployment settings for a custom model on the Clarifai platform. It tells Clarifai how to build your model's environment and where to place it within your account.

This is the `config.yaml` file for the custom model (or, in this case, a server) we want to build:

```yaml
model:
  id: "my-mcp-server"
  model_type_id: "mcp"

compute:
  instance: g5.xlarge  # Run 'clarifai list-instances' to see all options.
  # cloud: aws          # Cloud provider (aws, gcp, vultr). Auto-detected from instance.
  # region: us-east-1   # Cloud region. Auto-detected from instance.

# Uncomment to auto-download model checkpoints:
# checkpoints:
#   repo_id: owner/model-name
```

Let’s break down what each part of the file does.

- **`model.id`** – A unique identifier for your model. You can choose any name you want.
- **`model.model_type_id`** – Set to "mcp" to indicate this is an MCP server model.
- **`compute.instance`** – The compute instance type for deployment. Run `clarifai list-instances` to see all available options.
- **`checkpoints`** – (Optional) Uncomment to auto-download model checkpoints from Hugging Face at runtime.

### Step 4: Define Dependencies in `requirements.txt`

The `requirements.txt` file lists all the Python packages your MCP server depends on. Clarifai uses this file during deployment to automatically install the necessary libraries, ensuring your server runs correctly.

Here's the `requirements.txt` file for the custom model (or, in this case, a server) we want to build:

```text
clarifai
fastmcp
```

### Step 5: Test the Model Locally

Before uploading your server to the Clarifai platform, you can test it locally to catch any typos or misconfigurations in the code.

#### a. Local Runners

You can use the Clarifai CLI to test and run your model as a local development runner. You can learn how to use the tool [here](https://docs.clarifai.com/compute/local-runners/).

```bash
clarifai model serve
```

#### b. MCP Inspector

You can also use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) to easily test and debug your MCP server through a user-friendly, web-based interface that allows you to connect to your server and explore its capabilities.

To launch the Inspector, run the following command.

```bash
npx @modelcontextprotocol/inspector
```

### Step 6: Deploy to Clarifai

You can deploy the MCP server to the Clarifai platform using a single command. Navigate to its root directory and run:

```bash
clarifai model deploy
```

This command handles everything — building, uploading, and deploying your model.

### Step 7: Interact With Server

After uploading your server to Clarifai, you can create a separate client script to communicate with it and invoke its tools.

Here’s an example `client.py` that demonstrates how to interact with your deployed MCP server:

```python
from clarifai.urls.helper import ClarifaiUrlHelper
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport
import asyncio
import os
import logging

# Suppress verbose MCP client HTTP logs
logging.getLogger('mcp.client.streamable_http').setLevel(logging.CRITICAL)

# Set as environment variable export CLARIFAI_PAT="YOUR_PAT_HERE"
PAT = os.environ['CLARIFAI_PAT']

# Retrieve MCP API base URL 
url = ClarifaiUrlHelper().mcp_api_url()
print(url)

# Create MCP HTTP transport targeting your deployed MCP model on Clarifai
transport = StreamableHttpTransport(url=url, headers={"Authorization": "Bearer " + PAT})

async def main():
    print("=== Sample MCP Server Client Examples ===\n")

async with Client(transport) as client:
        # List all available tools exposed by the MCP server
        print("Available tools:")
        tools = await client.list_tools()
        for tool in tools:
            print(f"- {tool.name}: {tool.description}")

if __name__ == "__main__":
    asyncio.run(main())
```

To execute the client example, run the following command:

```bash
python client.py
```

**Note:** If you make changes to your server code and re-deploy it, Clarifai automatically creates a new version of your model.
