Podcast Title

Author Name

0:00
0:00
Album Art

Building a Remote MCP Server with FastAPI in 5 Minutes

By 10xdev team August 03, 2025

In a recent article, we explored how the Machine-readable Capability Protocol (MCP) works by setting up a simple MCP server and client that communicated locally on the same machine. Today, this article unlocks MCP's true potential: remote servers via Server-Sent Events (SSE). While a local MCP server limits tool access to the host machine, a remote server allows any client, anywhere in the world, to access its resources.

This guide will demonstrate how to extend an existing FastAPI server with an MCP server application that operates over SSE, making your tools globally accessible.

A Quick Refresher on MCP

The MCP setup involves a server (which can be local or remote) and a client. The server exposes several tools and resources. For instance, it might have an SQLite tool to execute SQL commands on a database.

The client is typically a chat application equipped with an MCP client and an AI model (LLM). The process unfolds as follows:

  1. User Query: A user sends a query to the agent.
  2. Tool Discovery: The agent consults the MCP client to find suitable tools for the task. For example, if the task is to create a database table.
  3. Action Request: The agent understands the tool's functionality and instructs the client to execute the action. The client then calls the server to perform the requested action.
  4. Execution: The server executes the command (e.g., an SQLite command), which may modify data.
  5. Result: The server responds with the result, such as a success message confirming the table's creation.
  6. Final Answer: This result is sent back to the AI agent, which then formulates the final response for the user.

This is the fundamental workflow of MCP. Now, let's explore how to configure this connection using SSE, enabling the server to be hosted anywhere globally while remaining accessible to clients.

Why Use Server-Sent Events (SSE)?

You might wonder why Server-Sent Events are necessary. Why not just use standard HTTP requests to implement the MCP protocol? The MCP protocol is more sophisticated than simple client-to-server requests. Crucially, the server sometimes needs to push data to the client without an initial client request.

With standard HTTP, the client must always initiate the request for the server to send a response. However, SSE establishes a long-lived, unidirectional connection, allowing the server to push data to the client whenever necessary, without waiting for a client request.

Diving into the Implementation

Let's dive into the code and build our remote server and client.

Step 1: Building the MCP Server with FastAPI

First, we'll create a server.py script. The initial step is to import FastAPI and FastMCP. We use the FastMCP library, which is quite similar to FastAPI, for declaring and exposing tools.

We'll create an MCP application and define our first tool. This simple tool, get_weather, will return the weather for a given city. For this example, it will simply return a "sunny" forecast.

Next, we create a FastAPI application to demonstrate how seamlessly the two can be integrated. This allows you to have both REST endpoints and MCP tools within the same server. We'll create a test route at /test that returns a simple JSON "Hello World" message.

Finally, we mount the MCP application's SSE handler to the main FastAPI app. The mcp_app.sse_app method handles all the necessary configuration for you.

Here is the complete server code:

# server.py
from fastapi import FastAPI
from fastmcp import McpApplication

# Create an MCP application
mcp_app = McpApplication()

# Define a simple tool
@mcp_app.tool()
def get_weather(city: str) -> str:
    """Gets the weather for a city."""
    return f"The weather in {city} is sunny"

# Create a standard FastAPI application
app = FastAPI()

# Add a regular REST endpoint
@app.get("/test")
def read_root():
    return {"message": "Hello World"}

# Mount the MCP SSE application onto the FastAPI app
app.mount("/sse", mcp_app.sse_app)

At this point, the server is fully equipped with standard FastAPI routes and has all its MCP tools exposed for client consumption.

Step 2: Creating the Client

With the server ready, we need a client to interact with it. We'll create an asynchronous main function in a client.py file. This function begins by creating an SSEClient imported from the mcp library. We specify the server's URL (http://localhost:8000) and the path for the MCP server, which is /sse.

Next, we create a client session, which is essential for discovering and invoking tools. We start by awaiting the initialize method to set up the protocol, followed by a ping to test the connection. The next step is to fetch and display the list of available tools to confirm the connection is working. Then, we can call our get_weather function.

Finally, a call to the FastAPI server's /test endpoint demonstrates that both services run in parallel on the same server.

Here is the client code:

# client.py
import asyncio
import httpx
from mcp.client.sse import SSEClient

async def main():
    # Create an SSE client pointing to the server
    mcp_client = SSEClient(base_url="http://localhost:8000/sse")

    # Start a session to interact with the server
    async with mcp_client.session() as session:
        await session.initialize()
        await session.ping()

        # Discover and print available tools
        tools = await session.get_tools()
        print("Available tools:", tools)

        # Invoke the remote tool
        result = await session.invoke("get_weather", city="Tokyo")
        print("Tool result:", result)

    # Make a standard HTTP request to the FastAPI endpoint
    async with httpx.AsyncClient() as client:
        response = await client.get("http://localhost:8000/test")
        print("FastAPI endpoint response:", response.json())

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

Step 3: Running the Application

Let's run the server and client to see them in action. You can start the server with the following command:

uvicorn server:app --host 0.0.0.0 --port 8000

Then, run the client in a separate terminal:

python client.py

The output shows a successful connection to the remote server. We receive the tool's name and description, the tool call is made, and we get the expected answer: 'The weather in Tokyo is sunny.' Furthermore, the FastAPI application works as expected, responding to the RESTful call with the correct message.

Conclusion: Unlocking a World of Tools

You now know how to create a remote MCP server with FastAPI. This opens your server to a global audience, allowing anyone to use your tools with clients like ChatGPT Desktop, Claude Desktop, or any other program that integrates an LLM.

You also understand a crucial feature of MCP: sharing tools via remote servers. This enables you to connect to a vast ecosystem of APIs and control them with your preferred LLM.

Join the 10xdev Community

Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.

Recommended For You

Up Next