Gradio's Journey to 1 Million Monthly Users!

Read More
  1. Other Tutorials
  2. Building Mcp Server With Gradio

Building an MCP Server with Gradio

In this guide, we will describe how to launch your Gradio app so that it functions as an MCP Server.

Punchline: it's as simple as setting mcp_server=True in .launch().

Prerequisites

If not already installed, please install Gradio with the MCP extra:

pip install gradio[mcp]

This will install the necessary dependencies, including the mcp package. Also, you will need a LLM application that supports tool calling using the MCP protocol, such as Claude Desktop, Cursor, or Cline (these are known as "MCP Clients").

What is an MCP Server?

An MCP (Model Control Protocol) server is a standardized way to expose tools so that they can be used by LLMs. A tool can provide an LLM functionality that it does not have natively, such as the ability to generate images or calculate the prime factors of a number.

Example: Counting Letters in a Word

LLMs are famously not great at counting the number of letters in a word (e.g. the number of "r"-s in "strawberry"). But what if we equip them with a tool to help? Let's start by writing a simple Gradio app that counts the number of letters in a word or phrase:

import gradio as gr

def letter_counter(word, letter):
    """
    Count the number of occurrences of a letter in a word or text.

    Args:
        word (str): The input text to search through
        letter (str): The letter to search for

    Returns:
        str: A message indicating how many times the letter appears
    """
    word = word.lower()
    letter = letter.lower()
    count = word.count(letter)
    return count

demo = gr.Interface(
    fn=letter_counter,
    inputs=["textbox", "textbox"],
    outputs="number",
    title="Letter Counter",
    description="Enter text and a letter to count how many times the letter appears in the text."
)

if __name__ == "__main__":
    demo.launch(mcp_server=True)

Notice that we have set mcp_server=True in .launch(). This is all that's needed for your Gradio app to serve as an MCP server! Now, when you run this app, it will:

  1. Start the regular Gradio web interface
  2. Start the MCP server
  3. Print the MCP server URL in the console

The MCP server will be accessible at:

http://your-server:port/gradio_api/mcp/sse

Gradio automatically converts the letter_counter function into an MCP tool that can be used by LLMs. The docstring of the function of the function will be used to generate the description of the tool and its parameters.

All you need to do is add this URL endpoint to your MCP Client (e.g. Claude Desktop, Cursor, or Cline), which typically means pasting this config in the settings:

{
  "mcpServers": {
    "gradio": {
      "url": "http://your-server:port/gradio_api/mcp/sse"
    }
  }
}

(By the way, you can find the exact config to copy-paste by going to the "View API" link in the footer of your Gradio app, and then clicking on "MCP").

Key features of the Gradio <> MCP Integration

  1. Tool Conversion: Each API endpoint in your Gradio app is automatically converted into an MCP tool with a corresponding name, description, and input schema. To view the tools and schemas, visit http://your-server:port/gradio_api/mcp/schema or go to the "View API" link in the footer of your Gradio app, and then click on "MCP".
  1. Environment variable support. There are two ways to enable the MCP server functionality:
  • Using the mcp_server parameter, as shown above:

    demo.launch(mcp_server=True)
  • Using environment variables:

    export GRADIO_MCP_SERVER=True
  1. File Handling: The server automatically handles file data conversions, including:

    • Converting base64-encoded strings to file data

    • Processing image files and returning them in the correct format

    • Managing temporary file storage

      It is strongly recommended that input images and files be passed as full URLs ("http://..." or "https:/...") as MCP Clients do not always handle local files correctly.

  1. Hosted MCP Servers on 󠀠🤗 Spaces: You can publish your Gradio application for free on Hugging Face Spaces, which will allow you to have a free hosted MCP server. Here's an example of such a Space: https://huggingface.co/spaces/abidlabs/mcp-tools. Notice that you can add this config to your MCP Client to start using the tools from this Space immediately:
{
  "mcpServers": {
    "gradio": {
      "url": "https://abidlabs-mcp-tools.hf.space/gradio_api/mcp/sse"
    }
  }
}

Custom MCP Servers

For a more fine-grained control, you might want to manually create an MCP Server that interfaces with hosted Gradio apps. This approach is useful when you want to:

  • Choose specific endpoints within a larger Gradio app to serve as tools
  • Customize how your tools are presented to LLMs (e.g. change the schema or description)
  • Start the Gradio app MCP server when a tool is called (if you are running multiple Gradio apps locally and want to save memory / GPU)
  • Use a different MCP protocol than SSE

This is very doable thanks to the Gradio Python Client and the MCP Python SDK. Here's an example of creating a custom MCP server that connects to various Gradio apps hosted on HuggingFace Spaces using the stdio protocol:

from mcp.server.fastmcp import FastMCP
from gradio_client import Client
import sys
import io
import json 

# Initialize FastMCP server
mcp = FastMCP("gradio-spaces")

# Dictionary to store Gradio clients
clients = {}

def get_client(space_id: str) -> Client:
    """Get or create a Gradio client for the specified space."""
    if space_id not in clients:
        clients[space_id] = Client(space_id)
    return clients[space_id]


@mcp.tool()
async def generate_image(prompt: str, space_id: str = "ysharma/SanaSprint") -> str:
    """Generate an image using Flux.
    
    Args:
        prompt: Text prompt describing the image to generate
        space_id: HuggingFace Space ID to use 
    """
    client = get_client(space_id)
    result = client.predict(
            prompt=prompt,
            model_size="1.6B",
            seed=0,
            randomize_seed=True,
            width=1024,
            height=1024,
            guidance_scale=4.5,
            num_inference_steps=2,
            api_name="/infer"
    )
    return result


@mcp.tool()
async def run_dia_tts(prompt: str, space_id: str = "ysharma/Dia-1.6B") -> str:
    """Text-to-Speech Synthesis.
    
    Args:
        prompt: Text prompt describing the conversation between speakers S1, S2
        space_id: HuggingFace Space ID to use 
    """
    client = get_client(space_id)
    result = client.predict(
            text_input=f"""{prompt}""",
            audio_prompt_input=None, 
            max_new_tokens=3072,
            cfg_scale=3,
            temperature=1.3,
            top_p=0.95,
            cfg_filter_top_k=30,
            speed_factor=0.94,
            api_name="/generate_audio"
    )
    return result


if __name__ == "__main__":
    # Ensure stdout uses UTF-8 encoding
    import sys
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    
    # Initialize and run the server
    mcp.run(transport='stdio')

This server exposes two tools:

  1. run_dia_tts - Generates a conversation for the given transcript in the form of [S1]first-sentence. [S2]second-sentence. [S1]...
  2. generate_image - Generates images using a fast text-to-image model

To use this MCP Server with Claude Desktop (as MCP Client):

  1. Save the code to a file (e.g., gradio_mcp_server.py)
  2. Install the required dependencies: pip install mcp gradio-client
  3. Configure Claude Desktop to use your server by editing the configuration file at ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
    "mcpServers": {
        "gradio-spaces": {
            "command": "python",
            "args": [
                "/absolute/path/to/gradio_mcp_server.py"
            ]
        }
    }
}
  1. Restart Claude Desktop

Now, when you ask Claude about generating an image or transcribing audio, it can use your Gradio-powered tools to accomplish these tasks.