1515import sentry_sdk
1616from sentry_sdk .consts import OP , SPANDATA
1717from sentry_sdk .integrations import DidNotEnable , Integration , _check_minimum_version
18- from sentry_sdk .scope import should_send_default_pii
1918from sentry_sdk .utils import (
2019 capture_internal_exceptions ,
2120 event_from_exception ,
22- has_data_collection_enabled ,
2321 package_version ,
2422 safe_serialize ,
2523)
@@ -245,15 +243,9 @@ async def _instrument_tool_call(
245243 client = sentry_sdk .get_client ()
246244 handler_name = ctx .params ["name" ]
247245 arguments = ctx .params .get ("arguments" )
248- if arguments is None :
246+ if arguments is None or not client . options [ "data_collection" ][ "gen_ai" ][ "inputs" ] :
249247 arguments = {}
250248
251- if has_data_collection_enabled (client .options ):
252- if not client .options ["data_collection" ]["gen_ai" ]["inputs" ]:
253- # Arguments can contain sensitive data and shouldn't be added to the span
254- # if the user has opted out via this config.
255- arguments = {}
256-
257249 # Get request ID, session ID, and transport from context
258250 request_id , session_id , mcp_transport = _get_request_context_data (ctx = ctx )
259251
@@ -287,36 +279,32 @@ async def _instrument_tool_call(
287279 if not isinstance (result , dict ):
288280 return result
289281
290- # Get integration to check PII settings
291282 integration = client .get_integration (MCPIntegration )
292283 if integration is None :
293284 return result
294285
295- # Check if we should include sensitive data
296- should_include_result_data = False
297- if has_data_collection_enabled (client .options ):
298- if client .options ["data_collection" ]["gen_ai" ]["outputs" ]:
299- should_include_result_data = True
300- elif should_send_default_pii ():
301- should_include_result_data = True
302-
303286 result_content = result
304287 if "structuredContent" in result :
305288 result_content = result ["structuredContent" ]
306289 elif isinstance (result .get ("content" ), list ):
307290 result_content = _extract_text_from_content_blocks (result ["content" ])
308291
309- if result_content is not None and should_include_result_data :
292+ if (
293+ result_content is None
294+ or not client .options ["data_collection" ]["gen_ai" ]["outputs" ]
295+ ):
296+ return result
297+
298+ span .set_attribute (
299+ SPANDATA .MCP_TOOL_RESULT_CONTENT ,
300+ safe_serialize (result_content ),
301+ )
302+ # Set content count if result is a dict
303+ if isinstance (result_content , dict ):
310304 span .set_attribute (
311- SPANDATA .MCP_TOOL_RESULT_CONTENT ,
312- safe_serialize (result_content ),
305+ SPANDATA .MCP_TOOL_RESULT_CONTENT_COUNT ,
306+ len (result_content ),
313307 )
314- # Set content count if result is a dict
315- if isinstance (result_content , dict ):
316- span .set_attribute (
317- SPANDATA .MCP_TOOL_RESULT_CONTENT_COUNT ,
318- len (result_content ),
319- )
320308
321309 return result
322310
@@ -337,15 +325,9 @@ async def _instrument_prompt_get(
337325
338326 arguments = ctx .params .get ("arguments" )
339327
340- if arguments is None :
328+ if arguments is None or not client . options [ "data_collection" ][ "gen_ai" ][ "inputs" ] :
341329 arguments = {}
342330
343- if has_data_collection_enabled (client .options ):
344- if not client .options ["data_collection" ]["gen_ai" ]["inputs" ]:
345- # Arguments can contain sensitive data and shouldn't be added to the span
346- # if the user has opted out via this config.
347- arguments = {}
348-
349331 # Get request ID, session ID, and transport from context
350332 request_id , session_id , mcp_transport = _get_request_context_data (ctx = ctx )
351333
@@ -379,19 +361,10 @@ async def _instrument_prompt_get(
379361 if not isinstance (result , dict ):
380362 return result
381363
382- # Get integration to check PII settings
383364 integration = client .get_integration (MCPIntegration )
384365 if integration is None :
385366 return result
386367
387- # Check if we should include sensitive data
388- should_include_result_data = False
389- if has_data_collection_enabled (client .options ):
390- if client .options ["data_collection" ]["gen_ai" ]["inputs" ]:
391- should_include_result_data = True
392- elif should_send_default_pii ():
393- should_include_result_data = True
394-
395368 # For prompts, count messages and set role/content only for single-message prompts
396369 try :
397370 messages : "Optional[list[dict[str, Any]]]" = None
@@ -407,28 +380,33 @@ async def _instrument_prompt_get(
407380 SPANDATA .MCP_PROMPT_RESULT_MESSAGE_COUNT , message_count
408381 )
409382
410- # Only set role and content for single-message prompts if PII is allowed
411- if message_count == 1 and should_include_result_data and messages :
412- first_message = messages [0 ]
413- # Extract role
414- role = None
415- if "role" in first_message :
416- role = first_message ["role" ]
417-
418- if role :
419- span .set_attribute (SPANDATA .MCP_PROMPT_RESULT_MESSAGE_ROLE , role )
420-
421- content_text = None
422- if "content" in first_message :
423- msg_content = first_message ["content" ]
424- if "text" in msg_content :
425- content_text = msg_content ["text" ]
426-
427- if content_text :
428- span .set_attribute (
429- SPANDATA .MCP_PROMPT_RESULT_MESSAGE_CONTENT ,
430- content_text ,
431- )
383+ if (
384+ message_count != 1
385+ or not client .options ["data_collection" ]["gen_ai" ]["inputs" ]
386+ or not messages
387+ ):
388+ return result
389+
390+ first_message = messages [0 ]
391+ # Extract role
392+ role = None
393+ if "role" in first_message :
394+ role = first_message ["role" ]
395+
396+ if role :
397+ span .set_attribute (SPANDATA .MCP_PROMPT_RESULT_MESSAGE_ROLE , role )
398+
399+ content_text = None
400+ if "content" in first_message :
401+ msg_content = first_message ["content" ]
402+ if "text" in msg_content :
403+ content_text = msg_content ["text" ]
404+
405+ if content_text :
406+ span .set_attribute (
407+ SPANDATA .MCP_PROMPT_RESULT_MESSAGE_CONTENT ,
408+ content_text ,
409+ )
432410 except Exception :
433411 # Silently ignore if we can't extract message info
434412 pass
0 commit comments