Prerequisites
Make sure you have FastMCP installed. If not, follow the installation guide.Step 1: Choose a Target API
For this tutorial, we’ll use the JSONPlaceholder API, a free, fake online REST API for testing and prototyping. It’s perfect because it’s simple and has a public OpenAPI specification.- API Base URL:
https://jsonplaceholder.typicode.com - OpenAPI Spec URL: We’ll use a community-provided spec for it.
Step 2: Create the MCP Server
Now for the magic. We’ll useFastMCP.from_openapi. This method takes an httpx.AsyncClient configured for your API and its OpenAPI specification, and automatically converts every endpoint into a callable MCP Tool.
For this tutorial, we’ll use a simplified OpenAPI spec directly in the code. In a real project, you would typically load the spec from a URL or local file.
api_server.py:
api_server.py
Step 3: Test the Generated Server
Let’s verify that our new MCP server works. We can use thefastmcp.Client to connect to it and inspect its tools.
Create a separate file, api_client.py:
api_client.py
get_users, get_user_by_id) and the result of calling the get_user_by_id tool, which fetches data from the live JSONPlaceholder API.

Step 4: Customizing Route Maps
By default, FastMCP converts every API endpoint into an MCPTool. This ensures maximum compatibility with contemporary LLM clients, many of which only support the tools part of the MCP specification.
However, for clients that support the full MCP spec, representing GET requests as Resources can be more semantically correct and efficient.
FastMCP allows users to customize this behavior using the concept of “route maps”. A RouteMap is a mapping of an API route to an MCP type. FastMCP checks each API route against your custom maps in order. If a route matches a map, it’s converted to the specified mcp_type. Any route that doesn’t match your custom maps will fall back to the default behavior (becoming a Tool).
Here’s how you can add custom route maps to turn GET requests into Resources and ResourceTemplates (if they have path parameters):
api_server_with_resources.py
GET /users/{id}becomes aResourceTemplate.GET /usersbecomes aResource.- Any
POST,PUT, etc. endpoints would still becomeToolsby default.

