# Transport Source: https://tadata-a67d782f.mintlify.app/advanced/asgi How to communicate with the FastAPI app FastAPI-MCP uses ASGI transport by default, which means it communicates directly with your FastAPI app without making HTTP requests. This is more efficient and doesn't require a base URL. It's not even necessary that the FastAPI server will run. If you need to specify a custom base URL or use a different transport method, you can provide your own `httpx.AsyncClient`: ```python {7-10, 14} import httpx from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() custom_client = httpx.AsyncClient( base_url="https://api.example.com", timeout=30.0 ) mcp = FastApiMCP( app, http_client=custom_client ) mcp.mount() ``` # Authentication & Authorization Source: https://tadata-a67d782f.mintlify.app/advanced/auth FastAPI-MCP supports authentication and authorization using your existing FastAPI dependencies. It also supports the full OAuth 2 flow, compliant with [MCP Spec 2025-03-26](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). It's worth noting that most MCP clients currently do not support the latest MCP spec, so for our examples we might use a bridge client such as `npx mcp-remote`. We recommend you use it as well, and we'll show our examples using it. ## Basic Token Passthrough If you just want to be able to pass a valid authorization header, without supporting a full authentication flow, you don't need to do anything special. You just need to make sure your MCP client is sending it: ```json {8-9, 13} { "mcpServers": { "remote-example": { "command": "npx", "args": [ "mcp-remote", "http://localhost:8000/mcp", "--header", "Authorization:${AUTH_HEADER}" ] }, "env": { "AUTH_HEADER": "Bearer " } } } ``` This is enough to pass the authorization header to your FastAPI endpoints. Optionally, if you want your MCP server to reject requests without an authorization header, you can add a dependency: ```python {1-2, 7-9} from fastapi import Depends from fastapi_mcp import FastApiMCP, AuthConfig mcp = FastApiMCP( app, name="Protected MCP", auth_config=AuthConfig( dependencies=[Depends(verify_auth)], ), ) mcp.mount_http() ``` For a complete working example of authorization header, check out the [Token Passthrough Example](https://github.com/tadata-org/fastapi_mcp/blob/main/examples/08_auth_example_token_passthrough.py) in the examples folder. ## OAuth Flow FastAPI-MCP supports the full OAuth 2 flow, compliant with [MCP Spec 2025-03-26](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). It would look something like this: ```python {7-16} from fastapi import Depends from fastapi_mcp import FastApiMCP, AuthConfig mcp = FastApiMCP( app, name="MCP With OAuth", auth_config=AuthConfig( issuer=f"https://auth.example.com/", authorize_url=f"https://auth.example.com/authorize", oauth_metadata_url=f"https://auth.example.com/.well-known/oauth-authorization-server", audience="my-audience", client_id="my-client-id", client_secret="my-client-secret", dependencies=[Depends(verify_auth)], setup_proxies=True, ), ) mcp.mount_http() ``` And you can call it like: ```json { "mcpServers": { "fastapi-mcp": { "command": "npx", "args": [ "mcp-remote", "http://localhost:8000/mcp", "8080" // Optional port number. Necessary if you want your OAuth to work and you don't have dynamic client registration. ] } } } ``` You can use it with any OAuth provider that supports the OAuth 2 spec. See explanation on [AuthConfig](#authconfig-explained) for more details. ## Custom OAuth Metadata If you already have a properly configured OAuth server that works with MCP clients, or if you want full control over the metadata, you can provide your own OAuth metadata directly: ```python {9, 22} from fastapi import Depends from fastapi_mcp import FastApiMCP, AuthConfig mcp = FastApiMCP( app, name="MCP With Custom OAuth", auth_config=AuthConfig( # Provide your own complete OAuth metadata custom_oauth_metadata={ "issuer": "https://auth.example.com", "authorization_endpoint": "https://auth.example.com/authorize", "token_endpoint": "https://auth.example.com/token", "registration_endpoint": "https://auth.example.com/register", "scopes_supported": ["openid", "profile", "email"], "response_types_supported": ["code"], "grant_types_supported": ["authorization_code"], "token_endpoint_auth_methods_supported": ["none"], "code_challenge_methods_supported": ["S256"] }, # Your auth checking dependency dependencies=[Depends(verify_auth)], ), ) mcp.mount_http() ``` This approach gives you complete control over the OAuth metadata and is useful when: * You have a fully MCP-compliant OAuth server already configured * You need to customize the OAuth flow beyond what the proxy approach offers * You're using a custom or specialized OAuth implementation For this to work, you have to make sure mcp-remote is running [on a fixed port](#add-a-fixed-port-to-mcp-remote), for example `8080`, and then configure the callback URL to `http://127.0.0.1:8080/oauth/callback` in your OAuth provider. ## Working Example with Auth0 For a complete working example of OAuth integration with Auth0, check out the [Auth0 Example](https://github.com/tadata-org/fastapi_mcp/blob/main/examples/09_auth_example_auth0.py) in the examples folder. This example demonstrates the simple case of using Auth0 as an OAuth provider, with a working example of the OAuth flow. For it to work, you need an .env file in the root of the project with the following variables: ``` AUTH0_DOMAIN=your-tenant.auth0.com AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/ AUTH0_CLIENT_ID=your-client-id AUTH0_CLIENT_SECRET=your-client-secret ``` You also need to make sure to configure callback URLs properly in your Auth0 dashboard. ## AuthConfig Explained ### `setup_proxies=True` Most OAuth providers need some adaptation to work with MCP clients. This is where `setup_proxies=True` comes in - it creates proxy endpoints that make your OAuth provider compatible with MCP clients: ```python mcp = FastApiMCP( app, auth_config=AuthConfig( # Your OAuth provider information issuer="https://auth.example.com", authorize_url="https://auth.example.com/authorize", oauth_metadata_url="https://auth.example.com/.well-known/oauth-authorization-server", # Credentials registered with your OAuth provider client_id="your-client-id", client_secret="your-client-secret", # Recommended, since some clients don't specify them audience="your-api-audience", default_scope="openid profile email", # Your auth checking dependency dependencies=[Depends(verify_auth)], # Create compatibility proxies - usually needed! setup_proxies=True, ), ) ``` You also need to make sure to configure callback URLs properly in your OAuth provider. With mcp-remote for example, you have to [use a fixed port](#add-a-fixed-port-to-mcp-remote). ### Why Use Proxies? Proxies solve several problems: 1. **Missing registration endpoints**:\ The MCP spec expects OAuth providers to support [dynamic client registration (RFC 7591)](https://datatracker.ietf.org/doc/html/rfc7591), but many don't. Furthermore, dynamic client registration is probably overkill for most use cases. The `setup_fake_dynamic_registration` option (True by default) creates a compatible endpoint that just returns a static client ID and secret. 2. **Scope handling**:\ Some MCP clients don't properly request scopes, so our proxy adds the necessary scopes for you. 3. **Audience requirements**:\ Some OAuth providers require an audience parameter that MCP clients don't always provide. The proxy adds this automatically. ### Add a fixed port to mcp-remote ```json { "mcpServers": { "example": { "command": "npx", "args": [ "mcp-remote", "http://localhost:8000/mcp", "8080" ] } } } ``` Normally, mcp-remote will start on a random port, making it impossible to configure the OAuth provider's callback URL properly. You have to make sure mcp-remote is running on a fixed port, for example `8080`, and then configure the callback URL to `http://127.0.0.1:8080/oauth/callback` in your OAuth provider. # Deploying the Server Source: https://tadata-a67d782f.mintlify.app/advanced/deploy ## Deploying separately from original FastAPI app You are not limited to serving the MCP on the same FastAPI app from which it was created. You can create an MCP server from one FastAPI app, and mount it to a different app: ```python {9, 15, } from fastapi import FastAPI from fastapi_mcp import FastApiMCP # Your API app api_app = FastAPI() # ... define your API endpoints on api_app ... # A separate app for the MCP server mcp_app = FastAPI() # Create MCP server from the API app mcp = FastApiMCP(api_app) # Mount the MCP server to the separate app mcp.mount_http(mcp_app) ``` Then, you can run both apps separately: ```bash uvicorn main:api_app --host api-host --port 8001 uvicorn main:mcp_app --host mcp-host --port 8000 ``` # Refreshing the Server Source: https://tadata-a67d782f.mintlify.app/advanced/refresh Adding endpoints after MCP server creation If you add endpoints to your FastAPI app after creating the MCP server, you'll need to refresh the server to include them: ```python {9-12, 15} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP(app) mcp.mount_http() # Add new endpoints after MCP server creation @app.get("/new/endpoint/", operation_id="new_endpoint") async def new_endpoint(): return {"message": "Hello, world!"} # Refresh the MCP server to include the new endpoint mcp.setup_server() ``` # MCP Transport Source: https://tadata-a67d782f.mintlify.app/advanced/transport Understanding MCP transport methods and how to choose between them FastAPI-MCP supports two MCP transport methods for client-server communication: **HTTP transport** (recommended) and **SSE transport** (backwards compatibility). ## HTTP Transport (Recommended) HTTP transport is the **recommended** transport method as it implements the latest MCP Streamable HTTP specification. It provides better session management, more robust connection handling, and aligns with standard HTTP practices. ### Using HTTP Transport ```python {7} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP(app) # Mount using HTTP transport (recommended) mcp.mount_http() ``` ## SSE Transport (Backwards Compatibility) SSE (Server-Sent Events) transport is maintained for backwards compatibility with older MCP implementations. ### Using SSE Transport ```python {7} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP(app) # Mount using SSE transport (backwards compatibility) mcp.mount_sse() ``` ## Advanced Configuration Both transport methods support the same FastAPI integration features like custom routing and authentication: ```python from fastapi import FastAPI, APIRouter from fastapi_mcp import FastApiMCP app = FastAPI() router = APIRouter(prefix="/api/v1") mcp = FastApiMCP(app) # Mount to custom path with HTTP transport mcp.mount_http(router, mount_path="/my-http") # Or with SSE transport mcp.mount_sse(router, mount_path="/my-sse") ``` ## Client Connection Examples ### HTTP Transport Client Connection For HTTP transport, MCP clients connect directly to the HTTP endpoint: ```json { "mcpServers": { "fastapi-mcp": { "url": "http://localhost:8000/mcp" } } } ``` ### SSE Transport Client Connection For SSE transport, MCP clients use the same URL but communicate via Server-Sent Events: ```json { "mcpServers": { "fastapi-mcp": { "url": "http://localhost:8000/sse" } } } ``` # Customization Source: https://tadata-a67d782f.mintlify.app/configurations/customization ## Server metadata You can define the MCP server name and description by modifying: ```python {8-9} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP( app, name="My API MCP", description="Very cool MCP server", ) mcp.mount_http() ``` ## Tool and schema descriptions When creating the MCP server you can include all possible response schemas in tool descriptions by changing the flag `describe_all_responses`, or include full JSON schema in tool descriptions by changing `describe_full_response_schema`: ```python {10-11} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP( app, name="My API MCP", description="Very cool MCP server", describe_all_responses=True, describe_full_response_schema=True ) mcp.mount_http() ``` ## Customizing Exposed Endpoints You can control which FastAPI endpoints are exposed as MCP tools using Open API operation IDs or tags to: * Only include specific operations * Exclude specific operations * Only include operations with specific tags * Exclude operations with specific tags * Combine operation IDs and tags ### Code samples The relevant arguments for these configurations are `include_operations`, `exclude_operations`, `include_tags`, `exclude_tags` and can be used as follows: ```python Include Operations {8} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP( app, include_operations=["get_user", "create_user"] ) mcp.mount_http() ``` ```python Exclude Operations {8} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP( app, exclude_operations=["delete_user"] ) mcp.mount_http() ``` ```python Include Tags {8} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP( app, include_tags=["users", "public"] ) mcp.mount_http() ``` ```python Exclude Tags {8} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP( app, exclude_tags=["admin", "internal"] ) mcp.mount_http() ``` ```python Combined (include mode) {8-9} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP( app, include_operations=["user_login"], include_tags=["public"] ) mcp.mount_http() ``` ### Notes on filtering * You cannot use both `include_operations` and `exclude_operations` at the same time * You cannot use both `include_tags` and `exclude_tags` at the same time * You can combine operation filtering with tag filtering (e.g., use `include_operations` with `include_tags`) * When combining filters, a greedy approach will be taken. Endpoints matching either criteria will be included # Tool Naming Source: https://tadata-a67d782f.mintlify.app/configurations/tool-naming FastAPI-MCP uses the `operation_id` from your FastAPI routes as the MCP tool names. When you don't specify an `operation_id`, FastAPI auto-generates one, but these can be cryptic. Compare these two endpoint definitions: ```python {2, 7} # Auto-generated operation_id (something like "read_user_users__user_id__get") @app.get("/users/{user_id}") async def read_user(user_id: int): return {"user_id": user_id} # Explicit operation_id (tool will be named "get_user_info") @app.get("/users/{user_id}", operation_id="get_user_info") async def read_user(user_id: int): return {"user_id": user_id} ``` For clearer, more intuitive tool names, we recommend adding explicit `operation_id` parameters to your FastAPI route definitions. To find out more, read FastAPI's official docs about [advanced config of path operations.](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/) # FAQ Source: https://tadata-a67d782f.mintlify.app/getting-started/FAQ Frequently Asked Questions ## Usage ### How do I configure HTTP request timeouts? By default, HTTP requests timeout after 5 seconds. If you have API endpoints that take longer to respond, you can configure a custom timeout by injecting your own httpx client. For a working example, see [Configure HTTP Timeout Example](https://github.com/tadata-org/fastapi_mcp/blob/main/examples/07_configure_http_timeout_example.py). ### Why are my tools not showing up in the MCP inspector? If you add endpoints after creating and mounting the MCP server, they won't be automatically registered as tools. You need to either: 1. Move the MCP creation after all your endpoint definitions 2. Call `mcp.setup_server()` after adding new endpoints to re-register all tools For a working example, see [Reregister Tools Example](https://github.com/tadata-org/fastapi_mcp/blob/main/examples/05_reregister_tools_example.py). ### Can I add custom tools other than FastAPI endpoints? Currently, FastApiMCP only supports tools that are derived from FastAPI endpoints. If you need to add custom tools that don't correspond to API endpoints, you can: 1. Create a FastAPI endpoint that wraps your custom functionality 2. Contribute to the project by implementing custom tool support Follow the discussion in [issue #75](https://github.com/tadata-org/fastapi_mcp/issues/75) for updates on this feature request. If you have specific use cases for custom tools, please share them in the issue to help guide the implementation. ### How do I test my FastApiMCP server is working? To verify your FastApiMCP server is working properly, you can use the MCP Inspector tool. Here's how: 1. Start your FastAPI application 2. Open a new terminal and run the MCP Inspector: ```bash npx @modelcontextprotocol/inspector ``` 3. Connect to your MCP server by entering the mount path URL (default: `http://127.0.0.1:8000/mcp`) 4. Navigate to the `Tools` section and click `List Tools` to see all available endpoints 5. Test an endpoint by: * Selecting a tool from the list * Filling in any required parameters * Clicking `Run Tool` to execute 6. Check your server logs for additional debugging information if needed This will help confirm that your MCP server is properly configured and your endpoints are accessible. ## Development ### Can I contribute to the project? Yes! Please read our [CONTRIBUTING.md](https://github.com/tadata-org/fastapi_mcp/blob/main/CONTRIBUTING.md) file for detailed guidelines on how to contribute to the project and where to start. ## Support ### Where can I get help? * Check the documentation * Open an issue on GitHub * Join our community chat [MCParty Slack community](https://join.slack.com/t/themcparty/shared_invite/zt-30yxr1zdi-2FG~XjBA0xIgYSYuKe7~Xg) # Best Practices Source: https://tadata-a67d782f.mintlify.app/getting-started/best-practices This guide outlines best practices for converting standard APIs into Model Context Protocol (MCP) tools for use with AI agents. Proper tool design helps ensure LLMs can understand and safely use your APIs. By following these best practices, you can build safer, more intuitive MCP tools that enhance the capabilities of LLM agents. ## Tool Selection * **Be selective:**\ Avoid exposing every endpoint as a tool. LLM clients perform better with a limited number of well-defined tools, and providers often impose tool limits. * **Prioritize safety:**\ Do **not** expose `PUT` or `DELETE` endpoints unless absolutely necessary. LLMs are non-deterministic and could unintentionally alter or damage systems or databases. * **Focus on data retrieval:**\ Prefer `GET` endpoints that return data safely and predictably. * **Emphasize meaningful workflows:**\ Expose endpoints that reflect clear, goal-oriented tasks. Tools with focused actions are easier for agents to understand and use effectively. ## Tool Naming * **Use short, descriptive names:**\ Helps LLMs select and use the right tool. Know that some MCP clients restrict tool name length. * **Follow naming constraints:** * Must start with a letter * Can include only letters, numbers, and underscores * Avoid hyphens (e.g., AWS Nova does **not** support them) * Use either `camelCase` or `snake_case` consistently across all tools * **Ensure uniqueness:**\ Each tool name should be unique and clearly indicate its function. ## Documentation * **Describe every tool meaningfully:**\ Provide a clear and concise summary of what each tool does. * **Include usage examples and parameter descriptions:**\ These help LLMs understand how to use the tool correctly. * **Standardize documentation across tools:**\ Keep formatting and structure consistent to maintain quality and readability. # Installation Source: https://tadata-a67d782f.mintlify.app/getting-started/installation ## Install FastAPI-MCP We recommend using [uv](https://docs.astral.sh/uv/), a fast Python package installer: ```bash uv add fastapi-mcp ``` Alternatively, you can install with `pip` or `uv pip`: ```bash uv uv pip install fastapi-mcp ``` ```bash pip pip install fastapi-mcp ``` # Quickstart Source: https://tadata-a67d782f.mintlify.app/getting-started/quickstart This guide will help you quickly run your first MCP server using FastAPI-MCP. If you haven't already installed FastAPI-MCP, follow the [installation instructions](/getting-started/installation). ## Creating a basic MCP server To create a basic MCP server, import or create a FastAPI app, wrap it with the `FastApiMCP` class and mount the MCP to your existing application: ```python {2, 8, 11} from fastapi import FastAPI from fastapi_mcp import FastApiMCP # Create (or import) a FastAPI app app = FastAPI() # Create an MCP server based on this app mcp = FastApiMCP(app) # Mount the MCP server directly to your app mcp.mount_http() ``` For more usage examples, see [Examples](https://github.com/tadata-org/fastapi_mcp/tree/main/examples) section in the project. ## Running the server By running your FastAPI, your MCP will run at `https://app.base.url/mcp`. For example, by using uvicorn, add to your code: ```python {9-11} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP(app) mcp.mount_http() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000) ``` and run the server using `python fastapi_mcp_server.py`, which will serve you the MCP at `http://localhost:8000/mcp`. ## Connecting a client to the MCP server Once your FastAPI app with MCP integration is running, you would want to connect it to an MCP client. ### Connecting to the MCP Server using SSE For any MCP client supporting SSE, you will simply need to provide the MCP url. All the most popular MCP clients (Claude Desktop, Cursor & Windsurf) use the following config format: ```json { "mcpServers": { "fastapi-mcp": { "url": "http://localhost:8000/mcp" } } } ``` ### Connecting to the MCP Server using [mcp-remote](https://www.npmjs.com/package/mcp-remote) If you want to support authentication, or your MCP client does not support SSE, we recommend using `mcp-remote` as a bridge. ```json { "mcpServers": { "fastapi-mcp": { "command": "npx", "args": [ "mcp-remote", "http://localhost:8000/mcp", "8080" // Optional port number. Necessary if you want your OAuth to work and you don't have dynamic client registration. ] } } } ``` # Welcome to FastAPI-MCP! Source: https://tadata-a67d782f.mintlify.app/getting-started/welcome Expose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth! MCP (Model Context Protocol) is the emerging standard to define how AI agents communicate with applications. Using FastAPI-MCP, creating a secured MCP server to your application takes only 3 lines of code: ```python {2, 6, 7} from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() mcp = FastApiMCP(app) mcp.mount_http() ``` That's it! Your auto-generated MCP server is now available at `https://app.base.url/mcp` ## Features * [**Authentication**](/advanced/auth) built in, using your existing FastAPI dependencies! * **FastAPI-native:** Not just another OpenAPI -> MCP converter * **Zero configuration** required - just point it at your FastAPI app and it works * **Preserving schemas** of your request models and response models * **Preserve documentation** of all your endpoints, just as it is in Swagger * [**Flexible deployment**](/advanced/deploy) - Mount your MCP server to the same app, or deploy separately * [**ASGI interface**](/advanced/asgi) - Uses FastAPI's ASGI interface directly for efficient internal communication ## Hosted Solution If you prefer a managed hosted solution check out [tadata.com](https://tadata.com).