Build Custom MCP Servers | Clarifai Docs

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 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 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 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:

You can run the following command to install them:

pip install --upgrade fastmcp pydantic clarifai

Or, you can define the packages in a requirements.txt file and run the following command to install them:

pip install -r requirements.txt

Set a PAT Key

You need to have a Personal Access Token (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.

export CLARIFAI_PAT=YOUR_PERSONAL_ACCESS_TOKEN_HERE
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.

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. You can then edit them as needed.

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:

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:

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:

In our example, we define a tool and a resource:

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:

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.

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:

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.

clarifai model serve

b. MCP Inspector

You can also use the MCP 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.

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:

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:

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:

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.