fix: Return images as MCP image resources instead of text
Browse filesChanged MCP tools/call response format to properly return images:
- Detects when result contains image data (image or dataUrl field)
- Extracts base64 data from data URI
- Returns as MCP image resource with type='image' and mimeType='image/png'
- Also includes text description of the operation
- Non-image results still returned as formatted JSON text
This fixes HuggingChat not displaying thumbnail images.
Now HuggingChat will show the actual PNG image instead of just JSON.
- mcp_server_comprehensive.py +55 -6
mcp_server_comprehensive.py
CHANGED
|
@@ -665,16 +665,65 @@ async def mcp_post(request: Request):
|
|
| 665 |
# Execute the tool
|
| 666 |
result = await TOOLS[tool_name](arguments)
|
| 667 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 668 |
return {
|
| 669 |
"jsonrpc": "2.0",
|
| 670 |
"id": request_id,
|
| 671 |
"result": {
|
| 672 |
-
"content":
|
| 673 |
-
{
|
| 674 |
-
"type": "text",
|
| 675 |
-
"text": json.dumps(result)
|
| 676 |
-
}
|
| 677 |
-
]
|
| 678 |
}
|
| 679 |
}
|
| 680 |
|
|
|
|
| 665 |
# Execute the tool
|
| 666 |
result = await TOOLS[tool_name](arguments)
|
| 667 |
|
| 668 |
+
# Check if result contains an image
|
| 669 |
+
content_items = []
|
| 670 |
+
|
| 671 |
+
if result.get("success") and result.get("image"):
|
| 672 |
+
# Add image as image content
|
| 673 |
+
image_data = result["image"]
|
| 674 |
+
|
| 675 |
+
# Extract base64 data (remove data:image/png;base64, prefix if present)
|
| 676 |
+
if image_data.startswith("data:"):
|
| 677 |
+
image_data = image_data.split(",", 1)[1]
|
| 678 |
+
|
| 679 |
+
content_items.append({
|
| 680 |
+
"type": "image",
|
| 681 |
+
"data": image_data,
|
| 682 |
+
"mimeType": "image/png"
|
| 683 |
+
})
|
| 684 |
+
|
| 685 |
+
# Add text description
|
| 686 |
+
description = f"Successfully created thumbnail ({result.get('width')}x{result.get('height')}px)"
|
| 687 |
+
if result.get("steps"):
|
| 688 |
+
description += f"\n\nSteps completed:\n"
|
| 689 |
+
for step in result["steps"]:
|
| 690 |
+
step_name = step.get("step", "").replace("_", " ").title()
|
| 691 |
+
description += f"- {step_name}\n"
|
| 692 |
+
|
| 693 |
+
content_items.append({
|
| 694 |
+
"type": "text",
|
| 695 |
+
"text": description
|
| 696 |
+
})
|
| 697 |
+
elif result.get("success") and result.get("dataUrl"):
|
| 698 |
+
# Handle canvas_export result format
|
| 699 |
+
image_data = result["dataUrl"]
|
| 700 |
+
|
| 701 |
+
# Extract base64 data
|
| 702 |
+
if image_data.startswith("data:"):
|
| 703 |
+
image_data = image_data.split(",", 1)[1]
|
| 704 |
+
|
| 705 |
+
content_items.append({
|
| 706 |
+
"type": "image",
|
| 707 |
+
"data": image_data,
|
| 708 |
+
"mimeType": "image/png"
|
| 709 |
+
})
|
| 710 |
+
|
| 711 |
+
content_items.append({
|
| 712 |
+
"type": "text",
|
| 713 |
+
"text": f"Canvas exported successfully ({result.get('width')}x{result.get('height')}px)"
|
| 714 |
+
})
|
| 715 |
+
else:
|
| 716 |
+
# Regular text response for non-image results
|
| 717 |
+
content_items.append({
|
| 718 |
+
"type": "text",
|
| 719 |
+
"text": json.dumps(result, indent=2)
|
| 720 |
+
})
|
| 721 |
+
|
| 722 |
return {
|
| 723 |
"jsonrpc": "2.0",
|
| 724 |
"id": request_id,
|
| 725 |
"result": {
|
| 726 |
+
"content": content_items
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 727 |
}
|
| 728 |
}
|
| 729 |
|