1111from fastmcp import Client
1212
1313
14+ def extract_mcp_json_content (mcp_result ):
15+ """
16+ Helper to extract JSON content from MCP CallToolResult.
17+
18+ FastMCP auto-serializes our List[Dict[str, Any]] return values, so we need to:
19+ 1. Get the content list from the CallToolResult
20+ 2. Parse the JSON string in the text field (which is our serialized list)
21+ 3. Extract the actual JSON from the MCP content array structure
22+ """
23+ content_list = mcp_result .content
24+ mcp_content_list = json .loads (content_list [0 ].text )
25+ return json .loads (mcp_content_list [0 ]["text" ])
26+
27+
1428@pytest .mark .asyncio
1529async def test_chatgpt_search_basic (mcp_server , app , test_project ):
1630 """Test basic ChatGPT search functionality with MCP content array format."""
@@ -68,13 +82,8 @@ async def test_chatgpt_search_basic(mcp_server, app, test_project):
6882 },
6983 )
7084
71- # Verify MCP content array format
72- assert isinstance (search_result , list )
73- assert len (search_result ) == 1
74- assert search_result [0 ]["type" ] == "text"
75-
76- # Parse JSON response
77- results_json = json .loads (search_result [0 ]["text" ])
85+ # Extract JSON content from MCP result
86+ results_json = extract_mcp_json_content (search_result )
7887 assert "results" in results_json
7988 assert len (results_json ["results" ]) > 0
8089
@@ -104,13 +113,8 @@ async def test_chatgpt_search_empty_results(mcp_server, app, test_project):
104113 },
105114 )
106115
107- # Verify MCP content array format
108- assert isinstance (search_result , list )
109- assert len (search_result ) == 1
110- assert search_result [0 ]["type" ] == "text"
111-
112- # Parse JSON response
113- results_json = json .loads (search_result [0 ]["text" ])
116+ # Extract JSON content from MCP result
117+ results_json = extract_mcp_json_content (search_result )
114118 assert "results" in results_json
115119 assert len (results_json ["results" ]) == 0
116120 assert results_json ["query" ] == "NonExistentTopic12345"
@@ -156,7 +160,7 @@ async def test_chatgpt_search_with_boolean_operators(mcp_server, app, test_proje
156160 },
157161 )
158162
159- results_json = json . loads (search_result [ 0 ][ "text" ] )
163+ results_json = extract_mcp_json_content (search_result )
160164 titles = [r ["title" ] for r in results_json ["results" ]]
161165 assert "Python Web Frameworks" in titles
162166 assert "JavaScript Frameworks" not in titles
@@ -208,13 +212,8 @@ def wrapper(*args, **kwargs):
208212 },
209213 )
210214
211- # Verify MCP content array format
212- assert isinstance (fetch_result , list )
213- assert len (fetch_result ) == 1
214- assert fetch_result [0 ]["type" ] == "text"
215-
216- # Parse JSON response
217- document_json = json .loads (fetch_result [0 ]["text" ])
215+ # Extract JSON content from MCP result
216+ document_json = extract_mcp_json_content (fetch_result )
218217 assert "id" in document_json
219218 assert "title" in document_json
220219 assert "text" in document_json
@@ -254,7 +253,7 @@ async def test_chatgpt_fetch_by_permalink(mcp_server, app, test_project):
254253 },
255254 )
256255
257- results_json = json . loads (search_result [ 0 ][ "text" ] )
256+ results_json = extract_mcp_json_content (search_result )
258257 assert len (results_json ["results" ]) > 0
259258 permalink = results_json ["results" ][0 ]["id" ]
260259
@@ -268,7 +267,7 @@ async def test_chatgpt_fetch_by_permalink(mcp_server, app, test_project):
268267 )
269268
270269 # Verify the fetched document
271- document_json = json . loads (fetch_result [ 0 ][ "text" ] )
270+ document_json = extract_mcp_json_content (fetch_result )
272271 assert document_json ["id" ] == permalink
273272 assert "Test Document" in document_json ["title" ]
274273 assert "test content for permalink fetching" in document_json ["text" ]
@@ -288,13 +287,8 @@ async def test_chatgpt_fetch_nonexistent_document(mcp_server, app, test_project)
288287 },
289288 )
290289
291- # Verify MCP content array format
292- assert isinstance (fetch_result , list )
293- assert len (fetch_result ) == 1
294- assert fetch_result [0 ]["type" ] == "text"
295-
296- # Parse JSON response
297- document_json = json .loads (fetch_result [0 ]["text" ])
290+ # Extract JSON content from MCP result
291+ document_json = extract_mcp_json_content (fetch_result )
298292
299293 # Should have document structure even for errors
300294 assert "id" in document_json
@@ -333,7 +327,7 @@ async def test_chatgpt_fetch_with_empty_title(mcp_server, app, test_project):
333327 )
334328
335329 # Parse JSON response
336- document_json = json . loads (fetch_result [ 0 ][ "text" ] )
330+ document_json = extract_mcp_json_content (fetch_result )
337331
338332 # Should have a title even if content doesn't have one
339333 assert "title" in document_json
@@ -369,7 +363,7 @@ async def test_chatgpt_search_pagination_default(mcp_server, app, test_project):
369363 },
370364 )
371365
372- results_json = json . loads (search_result [ 0 ][ "text" ] )
366+ results_json = extract_mcp_json_content (search_result )
373367
374368 # Should have at most 10 results (the default page_size)
375369 assert len (results_json ["results" ]) <= 10
@@ -392,12 +386,14 @@ async def test_chatgpt_tools_error_handling(mcp_server, app, test_project):
392386 )
393387
394388 # Should still return MCP content array format
395- assert isinstance (search_result , list )
396- assert len (search_result ) == 1
397- assert search_result [0 ]["type" ] == "text"
389+ assert hasattr (search_result , 'content' )
390+ content_list = search_result .content
391+ assert isinstance (content_list , list )
392+ assert len (content_list ) == 1
393+ assert content_list [0 ].type == "text"
398394
399395 # Should be valid JSON even on error
400- results_json = json . loads (search_result [ 0 ][ "text" ] )
396+ results_json = extract_mcp_json_content (search_result )
401397 assert "results" in results_json # Should have results key even if empty
402398
403399
@@ -452,7 +448,7 @@ async def test_chatgpt_integration_workflow(mcp_server, app, test_project):
452448 },
453449 )
454450
455- results_json = json . loads (search_result [ 0 ][ "text" ] )
451+ results_json = extract_mcp_json_content (search_result )
456452 assert len (results_json ["results" ]) >= 2
457453
458454 # Step 3: Fetch one of the search results (as ChatGPT would)
@@ -465,7 +461,7 @@ async def test_chatgpt_integration_workflow(mcp_server, app, test_project):
465461 },
466462 )
467463
468- document_json = json . loads (fetch_result [ 0 ][ "text" ] )
464+ document_json = extract_mcp_json_content (fetch_result )
469465
470466 # Verify the fetched document matches search result
471467 assert document_json ["id" ] == first_result_id
0 commit comments