2121 from typing import Any , Callable
2222
2323
24- def _get_span_config (handler_type , handler_name ):
25- # type: (str, str) -> tuple[str, str, str, str]
24+ def _get_span_config (handler_type , item_name ):
25+ # type: (str, str) -> tuple[str, str, str, str | None ]
2626 """
2727 Get span configuration based on handler type.
2828
2929 Returns:
3030 Tuple of (span_data_key, span_name, mcp_method_name, result_data_key)
31+ Note: result_data_key is None for resources
3132 """
3233 if handler_type == "tool" :
3334 span_data_key = SPANDATA .MCP_TOOL_NAME
@@ -40,9 +41,9 @@ def _get_span_config(handler_type, handler_name):
4041 else : # resource
4142 span_data_key = SPANDATA .MCP_RESOURCE_URI
4243 mcp_method_name = "resources/read"
43- result_data_key = SPANDATA . MCP_RESOURCE_RESULT_CONTENT
44+ result_data_key = None # Resources don't capture result content
4445
45- span_name = f"{ handler_type } { handler_name } "
46+ span_name = f"{ mcp_method_name } { item_name } "
4647 return span_data_key , span_name , mcp_method_name , result_data_key
4748
4849
@@ -116,7 +117,7 @@ def _extract_tool_result_content(result):
116117
117118
118119def _set_span_output_data (span , result , result_data_key , handler_type ):
119- # type: (Any, Any, str, str) -> None
120+ # type: (Any, Any, str | None , str) -> None
120121 """Set output span data for MCP handlers."""
121122 if result is None :
122123 return
@@ -184,9 +185,7 @@ def _set_span_output_data(span, result, result_data_key, handler_type):
184185 except Exception :
185186 # Silently ignore if we can't extract message info, but still serialize result
186187 span .set_data (result_data_key , safe_serialize (result ))
187- else :
188- # For resources, serialize directly
189- span .set_data (result_data_key , safe_serialize (result ))
188+ # Resources don't capture result content (result_data_key is None)
190189
191190
192191def patch_lowlevel_server ():
@@ -390,6 +389,13 @@ def decorator(func):
390389 async def async_wrapper (uri ):
391390 # type: (Any) -> Any
392391 uri_str = str (uri ) if uri else "unknown"
392+ # Extract protocol/scheme from URI
393+ protocol = None
394+ if hasattr (uri , "scheme" ):
395+ protocol = uri .scheme
396+ elif uri_str and "://" in uri_str :
397+ protocol = uri_str .split ("://" )[0 ]
398+
393399 span_data_key , span_name , mcp_method_name , result_data_key = (
394400 _get_span_config ("resource" , uri_str )
395401 )
@@ -412,6 +418,9 @@ async def async_wrapper(uri):
412418 {},
413419 request_id ,
414420 )
421+ # Set protocol if found
422+ if protocol :
423+ span .set_data (SPANDATA .MCP_RESOURCE_PROTOCOL , protocol )
415424 try :
416425 result = await func (uri )
417426 _set_span_output_data (
@@ -429,6 +438,13 @@ async def async_wrapper(uri):
429438 def sync_wrapper (uri ):
430439 # type: (Any) -> Any
431440 uri_str = str (uri ) if uri else "unknown"
441+ # Extract protocol/scheme from URI
442+ protocol = None
443+ if hasattr (uri , "scheme" ):
444+ protocol = uri .scheme
445+ elif uri_str and "://" in uri_str :
446+ protocol = uri_str .split ("://" )[0 ]
447+
432448 span_data_key , span_name , mcp_method_name , result_data_key = (
433449 _get_span_config ("resource" , uri_str )
434450 )
@@ -451,6 +467,9 @@ def sync_wrapper(uri):
451467 {},
452468 request_id ,
453469 )
470+ # Set protocol if found
471+ if protocol :
472+ span .set_data (SPANDATA .MCP_RESOURCE_PROTOCOL , protocol )
454473 try :
455474 result = func (uri )
456475 _set_span_output_data (
0 commit comments