From 62ab00bb234b9afc0c57a9d3d05516bf8bd929ac Mon Sep 17 00:00:00 2001 From: Matthias Hinrichs Date: Sat, 30 May 2026 17:36:30 +0200 Subject: [PATCH] feat: render activity map directly inline using iframe srcdoc --- scripts/generate_test_map.py | 34 +++++++++--- src/strava_mcp_server/__init__.py | 2 +- src/strava_mcp_server/tools/activities.py | 65 ++++++----------------- tests/unit/test_map.py | 35 ++++++------ 4 files changed, 60 insertions(+), 76 deletions(-) diff --git a/scripts/generate_test_map.py b/scripts/generate_test_map.py index 346347f..8198daf 100644 --- a/scripts/generate_test_map.py +++ b/scripts/generate_test_map.py @@ -114,9 +114,20 @@ async def generate(): html_text = None for item in result: - if isinstance(item, TextContent) and "" in item.text: - html_text = item.text - break + if isinstance(item, TextContent): + if "" in item.text: + html_text = item.text + break + elif '' + return [TextContent(type="text", text=iframe_content)] except Exception as e: error_msg = f"Error rendering activity map: {str(e)}" await ctx.error(error_msg) diff --git a/tests/unit/test_map.py b/tests/unit/test_map.py index ddf9ae4..b544764 100644 --- a/tests/unit/test_map.py +++ b/tests/unit/test_map.py @@ -46,27 +46,22 @@ async def test_get_activity_map_success(): get_activity_map = mcp.tools["get_activity_map"] result = await get_activity_map(ctx, 12345) - assert len(result) == 2 - # First block is the HTML embedded resource - assert result[0].type == "resource" - assert result[0].resource.mimeType == "text/html" - assert "internal://activities/12345/map.html" in str(result[0].resource.uri) + assert len(result) == 1 + assert result[0].type == "text" + iframe_text = result[0].text + assert iframe_text.startswith('') - html_text = result[0].resource.text - assert "" in html_text - assert "a~l~FqzbwOq}@it@..." in html_text - assert "unpkg.com/leaflet" in html_text - assert "latlngData" in html_text - assert "[47.1, 9.1]" in html_text - assert 'sportEmoji = "🚴"' in html_text - assert "L.control.layers" in html_text - assert "satellite" in html_text - assert "🟢" in html_text - assert "🏁" in html_text - - # Second block is the internal resource - assert result[1].type == "resource" - assert "internal://activities/12345/map" in str(result[1].resource.uri) + decoded_html = iframe_text.replace(""", '"') + assert "" in decoded_html + assert "unpkg.com/leaflet" in decoded_html + assert "latlngData" in decoded_html + assert "[47.1, 9.1]" in decoded_html + assert 'sportEmoji = "🚴"' in decoded_html + assert "L.control.layers" in decoded_html + assert "satellite" in decoded_html + assert "🟢" in decoded_html + assert "🏁" in decoded_html @pytest.mark.asyncio