Welcome back! In the last two lessons, you learned how to connect your agent to one or more MCP servers, giving it access to a wide range of tools and services. You saw how tool caching can make your agent more efficient and how connecting to multiple MCP servers allows your agent to coordinate complex tasks — like managing a shopping list and placing orders — across different services.
In this lesson, we will take your skills a step further by showing you how to combine your MCP server with a modern web framework using ASGI. Specifically, you will learn how to mount your MCP server inside a FastAPI application. This approach lets you serve your MCP tools alongside other web endpoints, making your application more flexible and scalable. By the end of this lesson, you will be able to run your MCP server as part of a FastAPI app, ready to handle both standard API requests and agent tool calls — all in one place.
Before we dive into the code, let’s quickly review what ASGI and FastAPI are and why they matter for your projects.
ASGI stands for Asynchronous Server Gateway Interface. It is a modern standard for Python web servers and applications, designed to support asynchronous programming. This means your application can handle many requests at the same time without waiting for each one to finish before starting the next. This is especially useful for real-time features, streaming, and high-concurrency workloads.
FastAPI is a popular ASGI framework that makes it easy to build fast, modern web APIs in Python. It is built on top of Starlette and uses Python’s async features to deliver high performance. FastAPI is known for its simple syntax, automatic documentation, and support for both synchronous and asynchronous code.
By combining your MCP server with FastAPI, you get the best of both worlds: the ability to serve your agent tools and regular web endpoints together, and the performance benefits of asynchronous programming.
If you are working on your own machine, you would typically install Uvicorn and FastAPI using pip:
However, on CodeSignal, these libraries are already installed for you, so you can focus on writing and running your code without worrying about setup.
Let’s look at how you can mount your MCP server inside a FastAPI application. Below is a simplified version of the code you will work with:
Here’s what’s happening in this code:
-
First, we import the necessary modules, including FastAPI and our MCP server instance.
-
Next, we create a FastAPI app.
-
Then, we add a regular HTTP endpoint at
/items/
that returns the current shopping list. This is just a typical web route in FastAPI — when someone visits/items/
in their browser or makes a request to that URL, they’ll get back the list of shopping items. -
The key part is the line
app.mount('/', mcp.sse_app())
. Here, we mount our MCP server’s SSE (Server-Sent Events) app at the root path of the FastAPI application. This means any requests to the root (such as/sse
) will be handled by our MCP server, while other routes (like/items/
) are handled by FastAPI.
The mcp.sse_app()
method returns an ASGI-compatible application specifically designed to handle Server-Sent Events (SSE) for the MCP server. This application is not a FastAPI app but a standalone ASGI app built for streaming communication. By mounting it within the FastAPI application using app.mount('/', mcp.sse_app())
, FastAPI transparently forwards requests to the MCP server’s SSE app, leveraging FastAPI’s ASGI-compliant structure. This integration allows you to combine the strengths of both frameworks: you can serve your MCP tools for real-time agent communication and also provide regular API endpoints, all within a single, unified application.
To run your combined FastAPI and MCP server application, you use Uvicorn, which is an ASGI server designed for high performance. In your code, you see the following block:
This tells Python to start the Uvicorn server, serving your FastAPI app on port 3000. The reload=True
option is helpful during development, as it automatically restarts the server when you make changes to your code.
To start the server, you can simply run the following command from the directory containing your script:
Once the server is running, you can access your regular API endpoints and your MCP server tools from the same application.
Now, let’s see how an agent can connect to your MCP server running inside the FastAPI app. Here is an example agent script:
In this script, the client connects to your MCP server by establishing a real-time SSE (Server-Sent Events) connection to the endpoint you set up in your FastAPI app (for example, http://localhost:3000/sse
). The MCPServerSse
class manages this connection, allowing the agent and server to exchange messages directly.
Once the connection is established, the agent is given instructions to use the shopping list tools and processes the sample input. When the agent needs to use a tool (like getting the shopping list), it sends a request to the /messages
endpoint on your server. FastAPI routes this request to the MCP server, which processes it and sends the response back to the agent over the SSE connection. This setup allows the agent to interact with your custom tools in real time and return the final result.
You have the flexibility to mount your MCP server at any route within your FastAPI application—not just at the root ('/'
). This is an important architectural decision that can help you keep your application organized, avoid route conflicts, and apply different access controls as your project grows.
For example, mounting your MCP server at /mcp
is a common choice to clearly separate MCP-related endpoints from your main API:
With this configuration, all requests to /mcp
and its subpaths (like /mcp/sse
) are handled by your MCP server, while your other FastAPI endpoints (such as /items/
) remain unaffected and accessible as usual.
Why is choosing a custom route important?
- Clear separation of concerns: By mounting at a dedicated path like
/mcp
, you keep your MCP endpoints distinct from your main API, making your application easier to maintain and reason about. - Scalability and flexibility: As your application grows, this separation helps prevent route conflicts and allows you to expand your API surface without worrying about overlapping paths.
- Security and access control: You can apply specific authentication or authorization rules to the
/mcp
path, giving you fine-grained control over who can access your agent tools.
If you decide to mount your MCP server at a custom route, remember to update your client's connection URL accordingly:
This ensures the client connects to the correct endpoint for the MCP server. The handshake at /mcp/sse
establishes a real-time connection, allowing the server to send events and instructions back to the agent. After the handshake, when the agent needs to use a tool, the client sends requests to the /mcp/messages
endpoint as directed by the server. The MCP server processes these requests—such as adding an item to a shopping list or retrieving data—and sends the results back through the established SSE connection. This separation of endpoints keeps communication organized and efficient, and by mounting your MCP server at /mcp
, your application structure remains clean and scalable for more complex scenarios.
In this lesson, you learned how to mount your MCP server inside a FastAPI application, allowing you to serve both MCP tools and regular API endpoints from a single, scalable ASGI app. You saw how to use FastAPI’s app.mount()
method to integrate your MCP server and how to run the combined application using Uvicorn. You also reviewed how an agent can connect to your MCP server through the mounted endpoint and complete real-world tasks.
This approach makes your applications more flexible and production-ready, as you can now combine agent tools and standard web APIs in one place. You are now ready to practice these skills in hands-on exercises. Great work progressing through this advanced integration technique!
