Compare commits

...

2 commits

Author SHA1 Message Date
marvin-context-protocol[bot]
a99abe020f chore: Update SDK documentation 2026-02-21 02:53:08 +00:00
Marvin Context Protocol
37e9875cbe Exclude authorization header from get_http_headers()
Closes #3260

Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>

🤖 Generated with Claude Code
2026-02-21 02:51:30 +00:00
3 changed files with 66 additions and 26 deletions

View file

@ -169,7 +169,7 @@ By default, strips problematic headers like `content-length` that cause issues
if forwarded to downstream clients. If `include_all` is True, all headers are returned.
### `get_access_token` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L483" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `get_access_token` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L487" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
get_access_token() -> AccessToken | None
@ -188,7 +188,7 @@ token snapshot stored in Redis at task submission time.
- The access token if an authenticated user is available, None otherwise.
### `without_injected_parameters` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L555" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `without_injected_parameters` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L559" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
without_injected_parameters(fn: Callable[..., Any]) -> Callable[..., Any]
@ -213,7 +213,7 @@ Handles:
- Async wrapper function without injected parameters
### `resolve_dependencies` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L704" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `resolve_dependencies` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L708" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
resolve_dependencies(fn: Callable[..., Any], arguments: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]
@ -239,7 +239,7 @@ time, so all injection goes through the unified DI system.
which will be filtered out)
### `CurrentContext` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L845" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `CurrentContext` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L849" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
CurrentContext() -> Context
@ -258,7 +258,7 @@ current MCP operation (tool/resource/prompt call).
- `RuntimeError`: If no active context found (during resolution)
### `CurrentDocket` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L888" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `CurrentDocket` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L892" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
CurrentDocket() -> Docket
@ -278,7 +278,7 @@ automatically creates for background task scheduling.
- `ImportError`: If fastmcp[tasks] not installed
### `CurrentWorker` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L933" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `CurrentWorker` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L937" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
CurrentWorker() -> Worker
@ -298,7 +298,7 @@ automatically creates for background task processing.
- `ImportError`: If fastmcp[tasks] not installed
### `CurrentFastMCP` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L975" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `CurrentFastMCP` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L979" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
CurrentFastMCP() -> FastMCP
@ -316,7 +316,7 @@ This dependency provides access to the active FastMCP server.
- `RuntimeError`: If no server in context (during resolution)
### `CurrentRequest` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1010" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `CurrentRequest` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1014" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
CurrentRequest() -> Request
@ -336,7 +336,7 @@ current HTTP request. Only available when running over HTTP transports
- `RuntimeError`: If no HTTP request in context (e.g., STDIO transport)
### `CurrentHeaders` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1046" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `CurrentHeaders` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1050" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
CurrentHeaders() -> dict[str, str]
@ -353,7 +353,7 @@ safe to use in code that might run over any transport.
- A dependency that resolves to a dictionary of header name -> value
### `CurrentAccessToken` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1236" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `CurrentAccessToken` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1240" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
CurrentAccessToken() -> AccessToken
@ -372,7 +372,7 @@ authenticated request. Raises an error if no authentication is present.
- `RuntimeError`: If no authenticated user (use get_access_token() for optional)
### `TokenClaim` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1288" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `TokenClaim` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1292" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
TokenClaim(name: str) -> str
@ -406,7 +406,7 @@ Returned by ``get_task_context()`` when running inside a Docket worker.
Contains identifiers needed to communicate with the MCP session.
### `ProgressLike` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1073" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `ProgressLike` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1077" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Protocol for progress tracking interface.
@ -417,7 +417,7 @@ and Docket's Progress (worker context).
**Methods:**
#### `current` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1081" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `current` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1085" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
current(self) -> int | None
@ -426,7 +426,7 @@ current(self) -> int | None
Current progress value.
#### `total` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1086" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `total` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1090" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
total(self) -> int
@ -435,7 +435,7 @@ total(self) -> int
Total/target progress value.
#### `message` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1091" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `message` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1095" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
message(self) -> str | None
@ -444,7 +444,7 @@ message(self) -> str | None
Current progress message.
#### `set_total` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1095" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `set_total` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1099" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
set_total(self, total: int) -> None
@ -453,7 +453,7 @@ set_total(self, total: int) -> None
Set the total/target value for progress tracking.
#### `increment` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1099" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `increment` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1103" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
increment(self, amount: int = 1) -> None
@ -462,7 +462,7 @@ increment(self, amount: int = 1) -> None
Atomically increment the current progress value.
#### `set_message` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1103" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `set_message` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1107" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
set_message(self, message: str | None) -> None
@ -471,7 +471,7 @@ set_message(self, message: str | None) -> None
Update the progress status message.
### `InMemoryProgress` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1108" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `InMemoryProgress` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1112" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
In-memory progress tracker for immediate tool execution.
@ -483,25 +483,25 @@ progress doesn't need to be observable across processes.
**Methods:**
#### `current` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1128" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `current` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1132" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
current(self) -> int | None
```
#### `total` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1132" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `total` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1136" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
total(self) -> int
```
#### `message` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1136" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `message` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1140" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
message(self) -> str | None
```
#### `set_total` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1139" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `set_total` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1143" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
set_total(self, total: int) -> None
@ -510,7 +510,7 @@ set_total(self, total: int) -> None
Set the total/target value for progress tracking.
#### `increment` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1145" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `increment` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1149" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
increment(self, amount: int = 1) -> None
@ -519,7 +519,7 @@ increment(self, amount: int = 1) -> None
Atomically increment the current progress value.
#### `set_message` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1154" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `set_message` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1158" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
set_message(self, message: str | None) -> None
@ -528,7 +528,7 @@ set_message(self, message: str | None) -> None
Update the progress status message.
### `Progress` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1159" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `Progress` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/dependencies.py#L1163" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
FastMCP Progress dependency that works in both server and worker contexts.

View file

@ -457,6 +457,10 @@ def get_http_headers(include_all: bool = False) -> dict[str, str]:
"keep-alive",
"expect",
"accept",
# Auth headers — the MCP transport's credentials must not leak
# to downstream APIs (e.g. OpenAPI backends) which have their
# own authentication configured on the httpx client.
"authorization",
# Proxy-related headers
"proxy-authenticate",
"proxy-authorization",

View file

@ -166,3 +166,39 @@ async def test_get_http_headers_excludes_content_type(sse_server: str):
# Custom headers should be included
assert "x-custom-header" in headers
assert headers["x-custom-header"] == "should-be-included"
async def test_get_http_headers_excludes_authorization():
"""Test that get_http_headers() excludes the authorization header (#3260).
The MCP transport's auth credentials must not be forwarded to downstream
APIs (e.g. OpenAPI backends) which use their own authentication.
"""
from fastmcp.server.dependencies import get_http_headers
server = FastMCP()
@server.tool
def check_auth_header() -> dict[str, str]:
"""Return filtered headers to verify authorization is excluded."""
return get_http_headers()
async with run_server_async(server, transport="sse") as url:
async with Client(
transport=SSETransport(
url,
headers={
"Authorization": "Bearer mcp-client-token",
"X-Custom-Header": "should-be-included",
},
)
) as client:
result = await client.call_tool("check_auth_header")
headers = result.data
# Authorization header must be excluded
assert "authorization" not in headers
# Custom headers should still be included
assert "x-custom-header" in headers
assert headers["x-custom-header"] == "should-be-included"