Custom HTTP Client & Transport

By default, FastApiMCP uses an efficient in-memory ASGI transport to communicate with your FastAPI application's logic. This means it doesn't make actual network requests to your endpoints, avoiding network overhead and the need for a running HTTP server for the core logic to function.

However, there are scenarios where you might want to customize this behavior. FastApiMCP allows you to provide your own httpx.AsyncClient instance to take full control over how the MCP server communicates with your API.

When to Use a Custom Client

  • Setting Custom Timeouts: If you have long-running API endpoints, you may need to increase the request timeout.
  • Using an External API: If your MCP server needs to call an API that is running in a separate process or on a different machine.
  • Adding Custom Headers or Authentication: To inject specific headers into every request made to your API.
  • Configuring HTTP/2, proxies, or custom transport logic.

Example: Configuring a Custom Timeout

Here is how you can provide a custom httpx.AsyncClient with a longer timeout.

# examples/07_configure_http_timeout_example.py
import httpx
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP

app = FastAPI()

@app.get("/long_running_task", operation_id="long_task")
async def long_task():
    import time
    time.sleep(15) # This task takes 15 seconds
    return {"status": "complete"}

# By default, httpx has a 5-second timeout, which would fail for the above endpoint.
# We create a custom client with a 20-second timeout.
custom_client = httpx.AsyncClient(timeout=20.0)

# Provide the custom client during initialization.
# Note: When providing an external client, it will make real HTTP requests.
# Ensure your FastAPI app is running and accessible if you provide a base_url.
mcp = FastApiMCP(app, http_client=custom_client)
mcp.mount_http()

if __name__ == "__main__":
    import uvicorn
    # In this specific case, since we did not provide a base_url to httpx.AsyncClient,
    # it will still use the in-memory ASGI transport, but with the new timeout.
    uvicorn.run(app, host="0.0.0.0", port=8000)

Example: Connecting to an External API

If your API runs separately, you can configure the client with a base_url.

import httpx
from fastapi_mcp import FastApiMCP
from your_app_definition import app # Just for endpoint discovery

# The API is running on another host or port
external_api_url = "http://api.service.internal:8001"

custom_client = httpx.AsyncClient(
    base_url=external_api_url,
    timeout=30.0
)

# The MCP server will now make real network requests to the external API.
mcp = FastApiMCP(app, http_client=custom_client)
mcp.mount_http()