diff --git a/litellm/proxy/_experimental/mcp_server/server.py b/litellm/proxy/_experimental/mcp_server/server.py index 4c86769c69a..ba98aa23579 100644 --- a/litellm/proxy/_experimental/mcp_server/server.py +++ b/litellm/proxy/_experimental/mcp_server/server.py @@ -176,7 +176,9 @@ if MCP_AVAILABLE: meta = getattr(content, "meta", None) if meta is None and hasattr(content, "model_dump"): d = content.model_dump() - meta = d.get("meta") or d.get("_meta") + meta = d.get("meta") + if meta is None: + meta = d.get("_meta") if isinstance(content, TextResourceContents): normalized.append( ReadResourceContents( @@ -189,7 +191,7 @@ if MCP_AVAILABLE: normalized.append( ReadResourceContents( content=content.blob, - mime_type=None, + mime_type=content.mimeType, meta=meta, ) ) diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py index c73b41c7c05..b8761ea669b 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py @@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from fastapi import HTTPException from mcp import ReadResourceResult, Resource -from mcp.types import Prompt, ResourceTemplate, TextResourceContents +from mcp.types import BlobResourceContents, Prompt, ResourceTemplate, TextResourceContents from litellm.proxy._types import ( LiteLLM_MCPServerTable, @@ -439,6 +439,60 @@ def test_normalize_resource_contents_passes_metadata(): assert result[0].meta == meta +def test_normalize_resource_contents_blob_with_metadata(): + """Test that _normalize_resource_contents preserves meta for BlobResourceContents.""" + try: + from litellm.proxy._experimental.mcp_server.server import ( + _normalize_resource_contents, + ) + except ImportError: + pytest.skip("MCP server not available") + + meta = {"encoding": "base64"} + contents = [ + BlobResourceContents( + uri="https://example.com/image.png", + blob="aGVsbG8=", + mimeType="image/png", + meta=meta, + ) + ] + + result = _normalize_resource_contents(contents) + + assert len(result) == 1 + assert result[0].content == "aGVsbG8=" + assert result[0].mime_type == "image/png" + assert result[0].meta == meta + + +def test_normalize_resource_contents_preserves_empty_metadata(): + """Test that empty dict meta is preserved (truthiness bug fix).""" + try: + from litellm.proxy._experimental.mcp_server.server import ( + _normalize_resource_contents, + ) + except ImportError: + pytest.skip("MCP server not available") + + empty_meta: dict = {} + contents = [ + TextResourceContents( + uri="https://example.com/resource", + text="hi", + mimeType="text/plain", + meta=empty_meta, + ) + ] + + result = _normalize_resource_contents(contents) + + assert len(result) == 1 + assert result[0].meta == empty_meta + assert result[0].meta is not None + assert result[0].meta == {} + + def test_normalize_resource_contents_without_metadata(): """Test that _normalize_resource_contents works when meta is absent (backward compat).""" try: