@@ -50,7 +50,7 @@ async def __call__(self, *args, **kwargs):
5050
5151def json_rpc (app , method : str , params , request_id : str | None = None ):
5252 if request_id is None :
53- request_id = "2 " # arbitrary
53+ request_id = "1 " # arbitrary
5454
5555 with TestClient (app ) as client :
5656 init_response = client .post (
@@ -73,6 +73,22 @@ def json_rpc(app, method: str, params, request_id: str | None = None):
7373
7474 session_id = init_response .headers ["mcp-session-id" ]
7575
76+ # Notification response is mandatory.
77+ # https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle
78+ client .post (
79+ "/mcp/" ,
80+ headers = {
81+ "Accept" : "application/json, text/event-stream" ,
82+ "Content-Type" : "application/json" ,
83+ "mcp-session-id" : session_id ,
84+ },
85+ json = {
86+ "jsonrpc" : "2.0" ,
87+ "method" : "notifications/initialized" ,
88+ "params" : {},
89+ },
90+ )
91+
7692 response = client .post (
7793 "/mcp/" ,
7894 headers = {
@@ -91,6 +107,18 @@ def json_rpc(app, method: str, params, request_id: str | None = None):
91107 return session_id , response
92108
93109
110+ def select_transactions_with_mcp_spans (events , method_name ):
111+ return [
112+ transaction
113+ for transaction in events
114+ if transaction ["type" ] == "transaction"
115+ and any (
116+ span ["data" ].get ("mcp.method.name" ) == method_name
117+ for span in transaction .get ("spans" , [])
118+ )
119+ ]
120+
121+
94122@pytest .fixture (autouse = True )
95123def reset_request_ctx ():
96124 """Reset request context before and after each test"""
@@ -305,13 +333,9 @@ async def test_tool_async(tool_name, arguments):
305333 )
306334 assert not result .json ()["result" ]["isError" ]
307335
308- http_requests_in_mcp_session = [
309- transaction
310- for transaction in events
311- if "mcp-session-id" in transaction ["request" ]["headers" ]
312- ]
313- assert len (http_requests_in_mcp_session ) == 1
314- tx = http_requests_in_mcp_session [0 ]
336+ transactions = select_transactions_with_mcp_spans (events , "tools/call" )
337+ assert len (transactions ) == 1
338+ tx = transactions [0 ]
315339
316340 assert tx ["type" ] == "transaction"
317341 assert len (tx ["spans" ]) == 1
@@ -503,13 +527,9 @@ async def test_prompt_async(name, arguments):
503527 )
504528 assert len (result .json ()["result" ]["messages" ]) == 2
505529
506- http_requests_in_mcp_session = [
507- transaction
508- for transaction in events
509- if "mcp-session-id" in transaction ["request" ]["headers" ]
510- ]
511- assert len (http_requests_in_mcp_session ) == 1
512- tx = http_requests_in_mcp_session [0 ]
530+ transactions = select_transactions_with_mcp_spans (events , "prompts/get" )
531+ assert len (transactions ) == 1
532+ tx = transactions [0 ]
513533
514534 assert tx ["type" ] == "transaction"
515535 assert len (tx ["spans" ]) == 1
@@ -637,13 +657,9 @@ async def test_resource_async(uri):
637657 },
638658 )
639659
640- http_requests_in_mcp_session = [
641- transaction
642- for transaction in events
643- if "mcp-session-id" in transaction ["request" ]["headers" ]
644- ]
645- assert len (http_requests_in_mcp_session ) == 1
646- tx = http_requests_in_mcp_session [0 ]
660+ transactions = select_transactions_with_mcp_spans (events , "resources/read" )
661+ assert len (transactions ) == 1
662+ tx = transactions [0 ]
647663
648664 assert result .json ()["result" ]["contents" ][0 ]["text" ] == json .dumps (
649665 {"data" : "resource data" }
@@ -1123,13 +1139,9 @@ async def test_tool(tool_name, arguments):
11231139 )
11241140 assert not result .json ()["result" ]["isError" ]
11251141
1126- http_requests_in_mcp_session = [
1127- transaction
1128- for transaction in events
1129- if "mcp-session-id" in transaction ["request" ]["headers" ]
1130- ]
1131- assert len (http_requests_in_mcp_session ) == 1
1132- tx = http_requests_in_mcp_session [0 ]
1142+ transactions = select_transactions_with_mcp_spans (events , "tools/call" )
1143+ assert len (transactions ) == 1
1144+ tx = transactions [0 ]
11331145
11341146 span = tx ["spans" ][0 ]
11351147
0 commit comments