Skip to content

Commit 5413bca

Browse files
committed
use request obeject
1 parent 81123c6 commit 5413bca

File tree

5 files changed

+24
-34
lines changed

5 files changed

+24
-34
lines changed

src/mcp/server/lowlevel/server.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,7 @@ def get_capabilities(
215215
)
216216

217217
@property
218-
def request_context(
219-
self,
220-
) -> RequestContext[ServerSession, LifespanResultT]:
218+
def request_context(self) -> RequestContext[ServerSession, LifespanResultT]:
221219
"""If called outside of a request context, this will raise a LookupError."""
222220
return request_ctx.get()
223221

src/mcp/server/sse.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ async def handle_sse(request):
5353

5454
import mcp.types as types
5555
from mcp.shared.message import ServerMessageMetadata, SessionMessage
56-
from mcp.types import RequestData
5756

5857
logger = logging.getLogger(__name__)
5958

@@ -204,18 +203,9 @@ async def handle_post_message(
204203
await writer.send(err)
205204
return
206205

207-
# Extract request headers and other context
208-
request_context: RequestData = {
209-
"headers": dict(request.headers),
210-
"method": request.method,
211-
"url": str(request.url),
212-
"client": request.client,
213-
"path_params": request.path_params,
214-
"query_params": dict(request.query_params),
215-
}
216-
217-
# Create session message with request context
218-
metadata = ServerMessageMetadata(request_context=request_context)
206+
# Pass the raw request object for maximum flexibility
207+
# Consumers can use isinstance to check the request type
208+
metadata = ServerMessageMetadata(request_context=request)
219209
session_message = SessionMessage(message, metadata=metadata)
220210
logger.debug(f"Sending session message to writer: {session_message}")
221211
response = Response("Accepted", status_code=202)

src/mcp/types.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
Role = Literal["user", "assistant"]
3737
RequestId = str | int
3838
AnyFunction: TypeAlias = Callable[..., Any]
39-
# Http request-specific data (e.g., headers, auth info)
40-
RequestData = dict[str, Any]
39+
# HTTP request object from web framework (e.g., starlette.requests.Request)
40+
RequestData: TypeAlias = object
4141

4242

4343
class RequestParams(BaseModel):

tests/server/fastmcp/test_integration.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import uvicorn
1616
from pydantic import AnyUrl
1717
from starlette.applications import Starlette
18+
from starlette.requests import Request
1819

1920
import mcp.types as types
2021
from mcp.client.session import ClientSession
@@ -89,7 +90,7 @@ def echo(message: str) -> str:
8990
return f"Echo: {message}"
9091

9192
# Create the SSE app
92-
app: Starlette = mcp.sse_app()
93+
app = mcp.sse_app()
9394

9495
return mcp, app
9596

@@ -201,7 +202,7 @@ def make_everything_fastmcp_app():
201202
"""Create a comprehensive FastMCP server with SSE transport."""
202203
mcp = make_everything_fastmcp()
203204
# Create the SSE app
204-
app: Starlette = mcp.sse_app()
205+
app = mcp.sse_app()
205206
return mcp, app
206207

207208

@@ -440,11 +441,10 @@ def make_fastmcp_with_context_app():
440441
def echo_headers(ctx: Context) -> str:
441442
"""Returns the request headers as JSON."""
442443
headers_info = {}
443-
try:
444-
if ctx.request_context.request:
445-
headers_info = ctx.request_context.request.get("headers", {})
446-
except Exception:
447-
pass
444+
if ctx.request_context.request and isinstance(
445+
ctx.request_context.request, Request
446+
):
447+
headers_info = dict(ctx.request_context.request.headers)
448448
return json.dumps(headers_info)
449449

450450
# Tool that returns full request context
@@ -457,17 +457,15 @@ def echo_context(custom_request_id: str, ctx: Context) -> str:
457457
"method": None,
458458
"url": None,
459459
}
460-
try:
461-
if ctx.request_context.request:
462-
context_data["headers"] = ctx.request_context.request.get("headers", {})
463-
context_data["method"] = ctx.request_context.request.get("method")
464-
context_data["url"] = ctx.request_context.request.get("url")
465-
except Exception:
466-
pass
460+
if ctx.request_context.request:
461+
if isinstance(ctx.request_context.request, Request):
462+
context_data["headers"] = dict(ctx.request_context.request.headers)
463+
context_data["method"] = ctx.request_context.request.method
464+
context_data["url"] = str(ctx.request_context.request.url)
467465
return json.dumps(context_data)
468466

469467
# Create the SSE app
470-
app: Starlette = mcp.sse_app()
468+
app = mcp.sse_app()
471469
return mcp, app
472470

473471

tests/shared/test_sse.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,11 @@ async def handle_call_tool(name: str, args: dict) -> list[TextContent]:
333333
try:
334334
context = self.request_context
335335
if context.request:
336-
headers_info = context.request.get("headers", {})
336+
# Check if it's a Starlette Request object
337+
from starlette.requests import Request
338+
339+
if isinstance(context.request, Request):
340+
headers_info = dict(context.request.headers)
337341
except LookupError:
338342
pass # No request context available
339343

0 commit comments

Comments
 (0)