Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .cursorignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Repomix output
!repomix-output.txt
!repomix-output.xml
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ repos:
rev: v5.0.0
hooks:
- id: trailing-whitespace
exclude: \.md$
exclude: \.(md|mdx)$
- id: check-yaml
- id: check-added-large-files

Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

🚀 **FastAPI-MCP now supports Streamable HTTP transport.**

HTTP transport is now the recommended approach, following the specification that positions HTTP as the standard while maintaining SSE for backwards compatibility.

### ⚠️ Breaking Changes
- **`mount()` method is deprecated** and will be removed in a future version. Use `mount_http()` for HTTP transport (recommended) or `mount_sse()` for SSE transport.

### Added
- 🎉 **Streamable HTTP Transport Support** - New `mount_http()` method implementing the MCP Streamable HTTP specification
- 🎉 **Stateful Session Management** - For both HTTP and SSE transports

## [0.3.7]

### Fixed
Expand Down
31 changes: 31 additions & 0 deletions docs/advanced/asgi.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: Transport
description: How to communicate with the FastAPI app
icon: microchip
---

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()
```
10 changes: 5 additions & 5 deletions docs/advanced/auth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ mcp = FastApiMCP(
dependencies=[Depends(verify_auth)],
),
)
mcp.mount()
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.
Expand Down Expand Up @@ -79,7 +79,7 @@ mcp = FastApiMCP(
),
)

mcp.mount()
mcp.mount_http()
```

And you can call it like:
Expand Down Expand Up @@ -131,7 +131,7 @@ mcp = FastApiMCP(
),
)

mcp.mount()
mcp.mount_http()
```

This approach gives you complete control over the OAuth metadata and is useful when:
Expand Down Expand Up @@ -195,8 +195,8 @@ You also need to make sure to configure callback URLs properly in your OAuth pro
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 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**:
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/deploy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mcp_app = FastAPI()
mcp = FastApiMCP(api_app)

# Mount the MCP server to the separate app
mcp.mount(mcp_app)
mcp.mount_http(mcp_app)
```

Then, you can run both apps separately:
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/refresh.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ from fastapi_mcp import FastApiMCP
app = FastAPI()

mcp = FastApiMCP(app)
mcp.mount()
mcp.mount_http()

# Add new endpoints after MCP server creation
@app.get("/new/endpoint/", operation_id="new_endpoint")
Expand Down
92 changes: 76 additions & 16 deletions docs/advanced/transport.mdx
Original file line number Diff line number Diff line change
@@ -1,31 +1,91 @@
---
title: Transport
description: How to communicate with the FastAPI app
title: MCP Transport
description: Understanding MCP transport methods and how to choose between them
icon: car
---

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.
FastAPI-MCP supports two MCP transport methods for client-server communication: **HTTP transport** (recommended) and **SSE transport** (backwards compatibility).

It's not even necessary that the FastAPI server will run.
## HTTP Transport (Recommended)

If you need to specify a custom base URL or use a different transport method, you can provide your own `httpx.AsyncClient`:
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.

```python {7-10, 14}
import httpx
### 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"
}
}
}
```

custom_client = httpx.AsyncClient(
base_url="https://api.example.com",
timeout=30.0
)
### SSE Transport Client Connection

mcp = FastApiMCP(
app,
http_client=custom_client
)
For SSE transport, MCP clients use the same URL but communicate via Server-Sent Events:

mcp.mount()
```json
{
"mcpServers": {
"fastapi-mcp": {
"url": "http://localhost:8000/sse"
}
}
}
```
14 changes: 7 additions & 7 deletions docs/configurations/customization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mcp = FastApiMCP(
name="My API MCP",
description="Very cool MCP server",
)
mcp.mount()
mcp.mount_http()
```

## Tool and schema descriptions
Expand All @@ -39,7 +39,7 @@ mcp = FastApiMCP(
describe_full_response_schema=True
)

mcp.mount()
mcp.mount_http()
```

## Customizing Exposed Endpoints
Expand All @@ -66,7 +66,7 @@ The relevant arguments for these configurations are `include_operations`, `exclu
app,
include_operations=["get_user", "create_user"]
)
mcp.mount()
mcp.mount_http()
```

```python Exclude Operations {8}
Expand All @@ -79,7 +79,7 @@ The relevant arguments for these configurations are `include_operations`, `exclu
app,
exclude_operations=["delete_user"]
)
mcp.mount()
mcp.mount_http()
```

```python Include Tags {8}
Expand All @@ -92,7 +92,7 @@ The relevant arguments for these configurations are `include_operations`, `exclu
app,
include_tags=["users", "public"]
)
mcp.mount()
mcp.mount_http()
```

```python Exclude Tags {8}
Expand All @@ -105,7 +105,7 @@ The relevant arguments for these configurations are `include_operations`, `exclu
app,
exclude_tags=["admin", "internal"]
)
mcp.mount()
mcp.mount_http()
```

```python Combined (include mode) {8-9}
Expand All @@ -119,7 +119,7 @@ The relevant arguments for these configurations are `include_operations`, `exclu
include_operations=["user_login"],
include_tags=["public"]
)
mcp.mount()
mcp.mount_http()
```
</CodeGroup>

Expand Down
Loading