Skip to content

Commit 9e515ac

Browse files
committed
fix auth context reset for streamable HTTP
1 parent b9bf42a commit 9e515ac

2 files changed

Lines changed: 11 additions & 12 deletions

File tree

src/mcp/server/auth/middleware/auth_context.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ def push_auth_context_from_request(request: Request | None) -> Token[Authenticat
3838
user = getattr(request, "user", None)
3939
except AssertionError:
4040
user = None
41-
if isinstance(user, AuthenticatedUser):
42-
return auth_context_var.set(user)
43-
return None
41+
return auth_context_var.set(user if isinstance(user, AuthenticatedUser) else None)
4442

4543

4644
def pop_auth_context(token: Token[AuthenticatedUser | None] | None) -> None:

tests/server/auth/test_get_access_token_streamable_http.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from mcp.server.auth.middleware.bearer_auth import BearerAuthBackend
1515
from mcp.server.auth.provider import AccessToken
1616
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
17-
from mcp.server.transport_security import TransportSecuritySettings
1817
from mcp.types import (
1918
CallToolRequestParams,
2019
CallToolResult,
@@ -43,11 +42,12 @@ async def _handle_list_tools(ctx: ServerRequestContext, params: PaginatedRequest
4342

4443

4544
class _MutableBearerAuth(httpx.Auth):
46-
def __init__(self, token: str) -> None:
45+
def __init__(self, token: str | None) -> None:
4746
self.token = token
4847

4948
def auth_flow(self, request: httpx.Request):
50-
request.headers["Authorization"] = f"Bearer {self.token}"
49+
if self.token is not None:
50+
request.headers["Authorization"] = f"Bearer {self.token}"
5151
yield request
5252

5353

@@ -61,11 +61,7 @@ async def test_get_access_token_reflects_current_request_in_stateful_session() -
6161
on_list_tools=_handle_list_tools,
6262
)
6363

64-
security = TransportSecuritySettings(
65-
allowed_hosts=[host, f"{host}:*"],
66-
allowed_origins=[f"http://{host}:*"],
67-
)
68-
session_manager = StreamableHTTPSessionManager(app=server, security_settings=security, stateless=False)
64+
session_manager = StreamableHTTPSessionManager(app=server, stateless=False)
6965

7066
asgi_app = Starlette(
7167
routes=[Mount("/mcp", app=session_manager.handle_request)],
@@ -89,7 +85,7 @@ async def test_get_access_token_reflects_current_request_in_stateful_session() -
8985
) as http_client,
9086
):
9187
transport_ctx = streamable_http_client(f"http://{host}/mcp", http_client=http_client)
92-
async with Client(transport_ctx) as client:
88+
async with Client(transport_ctx) as client: # pragma: no branch
9389
r1 = await client.call_tool("whoami", {})
9490
assert isinstance(r1.content[0], TextContent)
9591
assert r1.content[0].text == "token-A"
@@ -98,3 +94,8 @@ async def test_get_access_token_reflects_current_request_in_stateful_session() -
9894
r2 = await client.call_tool("whoami", {})
9995
assert isinstance(r2.content[0], TextContent)
10096
assert r2.content[0].text == "token-B"
97+
98+
auth.token = None
99+
r3 = await client.call_tool("whoami", {})
100+
assert isinstance(r3.content[0], TextContent)
101+
assert r3.content[0].text == "<none>"

0 commit comments

Comments
 (0)