fastapi-mcp2
by rafal-one
README.md
# fastapi-mcp2
[](#tests)
**A maintained, drop-in fork of [fastapi-mcp](https://github.com/tadata-org/fastapi_mcp) that works with `mcp` 2.x.**
Expose your FastAPI endpoints as Model Context Protocol (MCP) tools. The import name is unchanged (`fastapi_mcp`), so
switching is one line.
## Why this fork exists
Upstream `fastapi-mcp` 0.4.0 (July 2025) has no release since, and `pip install fastapi-mcp` now pulls `mcp` 2.x, which
changed the low-level server API. A fresh install then dies on the first line that matters:
```text
>>> FastApiMCP(app)
TypeError: Server.__init__() takes 2 positional arguments but 3 were given
```
The fix pull requests on upstream were closed unmerged, and pinning `mcp<2` collides with other packages that need
`mcp>=2.3`. This fork ports the code to the new API (and keeps `mcp` 1.x working), and adds the fixes that were waiting.
## Switch in 30 seconds
```console
$ pip uninstall fastapi-mcp # both packages install the same module, so remove the old one first
$ pip install fastapi-mcp2
```
No code change: `from fastapi_mcp import FastApiMCP` keeps working.
```python
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP
app = FastAPI()
mcp = FastApiMCP(app)
mcp.mount_http() # streamable HTTP at /mcp (recommended); mcp.mount_sse() serves SSE at /sse
```
Point any MCP client at `http://localhost:8000/mcp`. All the upstream options (`include_operations`,
`exclude_tags`, `auth_config`, `headers`, `http_client`, ...) work as documented in the
[upstream docs](https://fastapi-mcp.tadata.com/); the `examples/` folder is carried over.
## What changed compared with fastapi-mcp 0.4.0
- **Works with `mcp` 1.12+ and 2.x** (tested on 1.30 and 2.3). One compat module, `fastapi_mcp/_compat.py`, hides the API difference.
- **Input validation on mcp 2**: the 2.x server stopped validating tool arguments against the input schema, so the
fork does it (`Input validation error: ...` as a tool error, like 1.x did).
- **Unknown tools and API errors** come back as MCP tool errors (`isError`), not as protocol crashes.
- **Server description** is passed as the MCP server `instructions` (upstream passed it into the *version* slot).
- **No OAuth client-secret leak (behavior change)**: the fake dynamic registration endpoint is unauthenticated and used
to hand your `client_secret` to anyone. It no longer does, unless you set `AuthConfig(expose_client_secret=True)`.
- **Path parameters are URL-encoded** (`name="a b?c"` no longer breaks the request path).
- **Recursive models** (a tree node that contains nodes) no longer overflow the stack while schemas are resolved.
- **Optional/union parameters** get a deterministic JSON type instead of a set-order dependent one.
- **Clean shutdown**: the HTTP session manager's background task stops with the FastAPI app (your own `lifespan` still runs).
- **SSE message endpoint** checks that a session is used with the credential that opened it (mcp 2 rule).
- **Fewer dependencies**: `typer`, `rich`, `requests` and `tomli` were never imported by the library and are gone.
What is *not* changed: the public API, the module name, tool naming and the OpenAPI to tool conversion.
## Install
```console
$ pip install fastapi-mcp2
```
Needs Python 3.10+ (the same as `mcp`).
## Tests
```console
$ pip install -e . pytest pytest-asyncio pytest-cov pyjwt cryptography
$ pytest
```
99 tests (conversion, tool calls, SSE and streamable-HTTP transports against a real uvicorn server, auth config,
OAuth registration, header forwarding, lifespan). The suite passes on Python 3.10, 3.12 and 3.14 with `mcp` 2.3, and on 3.10 and 3.12 with `mcp` 1.12, 1.20 and 1.30.
## Credits and license
Based on [fastapi-mcp](https://github.com/tadata-org/fastapi_mcp) by Tadata Inc. (MIT). This fork is independent and
not affiliated with Tadata. MIT license; both copyright notices are kept in `LICENSE`.
## Support
If this saves you time, you can donate via [PayPal](https://paypal.me/RafalBaranowski).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues