Skip to content

Commit 28d73cd

Browse files
.
1 parent 9408067 commit 28d73cd

1 file changed

Lines changed: 12 additions & 96 deletions

File tree

sentry_sdk/integrations/mcp.py

Lines changed: 12 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -475,55 +475,27 @@ async def _tool_handler_wrapper(
475475
return result
476476

477477

478-
async def _v2_tool_handler(
478+
async def _instrument_v2_tool_call(
479479
ctx: "ServerRequestContext[Any, Any]",
480480
call_next: "CallNext",
481481
) -> "HandlerResult":
482482
"""
483-
Wrapper for MCP tool handlers.
483+
Instrument a tool call as observed by the MCP Server middleware.
484484
Creates and manages the MCP span and attaches all attributes on the span.
485-
486-
Args:
487-
func: The handler function to wrap
488-
original_args: Original arguments passed to the handler
489-
original_kwargs: Original keyword arguments passed to the handler
490-
self: Optional instance for bound methods
491485
"""
492486
if ctx.params is None:
493487
return await call_next(ctx)
494488

495489
handler_name = ctx.params["name"]
496490
arguments = ctx.params["arguments"]
497491

498-
scopes = _get_active_http_scopes(ctx=ctx)
499-
500-
isolation_scope_context: "ContextManager[Any]"
501-
current_scope_context: "ContextManager[Any]"
502-
503-
if scopes is None:
504-
isolation_scope_context = nullcontext()
505-
current_scope_context = nullcontext()
506-
else:
507-
isolation_scope, current_scope = scopes
508-
509-
isolation_scope_context = (
510-
nullcontext()
511-
if isolation_scope is None
512-
else sentry_sdk.scope.use_isolation_scope(isolation_scope)
513-
)
514-
current_scope_context = (
515-
nullcontext()
516-
if current_scope is None
517-
else sentry_sdk.scope.use_scope(current_scope)
518-
)
519-
520492
# Get request ID, session ID, and transport from context
521493
request_id, session_id, mcp_transport = _get_request_context_data(ctx=ctx)
522494

523495
span_streaming = has_span_streaming_enabled(sentry_sdk.get_client().options)
524496

525497
# Start span and execute
526-
with isolation_scope_context, current_scope_context:
498+
with _with_active_http_scopes(ctx=ctx):
527499
span_mgr: "Union[Span, StreamedSpan]"
528500
if span_streaming:
529501
span_mgr = sentry_sdk.traces.start_span(
@@ -766,55 +738,27 @@ async def _prompt_handler_wrapper(
766738
return result
767739

768740

769-
async def _v2_prompt_handler(
741+
async def _instrument_v2_prompt_get(
770742
ctx: "ServerRequestContext[Any, Any]",
771743
call_next: "CallNext",
772744
) -> "HandlerResult":
773745
"""
774-
Wrapper for MCP prompt handlers.
746+
Instrument a prompt retrieval as observed by the MCP Server middleware.
775747
Creates and manages the MCP span and attaches all attributes on the span.
776-
777-
Args:
778-
func: The handler function to wrap
779-
original_args: Original arguments passed to the handler
780-
original_kwargs: Original keyword arguments passed to the handler
781-
self: Optional instance for bound methods
782748
"""
783749
if ctx.params is None:
784750
return await call_next(ctx)
785751

786752
handler_name = ctx.params["name"]
787753
arguments = {"name": handler_name, **ctx.params["arguments"]}
788754

789-
scopes = _get_active_http_scopes(ctx=ctx)
790-
791-
isolation_scope_context: "ContextManager[Any]"
792-
current_scope_context: "ContextManager[Any]"
793-
794-
if scopes is None:
795-
isolation_scope_context = nullcontext()
796-
current_scope_context = nullcontext()
797-
else:
798-
isolation_scope, current_scope = scopes
799-
800-
isolation_scope_context = (
801-
nullcontext()
802-
if isolation_scope is None
803-
else sentry_sdk.scope.use_isolation_scope(isolation_scope)
804-
)
805-
current_scope_context = (
806-
nullcontext()
807-
if current_scope is None
808-
else sentry_sdk.scope.use_scope(current_scope)
809-
)
810-
811755
# Get request ID, session ID, and transport from context
812756
request_id, session_id, mcp_transport = _get_request_context_data(ctx=ctx)
813757

814758
span_streaming = has_span_streaming_enabled(sentry_sdk.get_client().options)
815759

816760
# Start span and execute
817-
with isolation_scope_context, current_scope_context:
761+
with _with_active_http_scopes(ctx=ctx):
818762
span_mgr: "Union[Span, StreamedSpan]"
819763
if span_streaming:
820764
span_mgr = sentry_sdk.traces.start_span(
@@ -1042,54 +986,26 @@ async def _resource_handler_wrapper(
1042986
return result
1043987

1044988

1045-
async def _v2_resource_handler(
989+
async def _instrument_v2_resource_read(
1046990
ctx: "ServerRequestContext[Any, Any]",
1047991
call_next: "CallNext",
1048992
) -> "HandlerResult":
1049993
"""
1050-
Wrapper for MCP resource handlers.
994+
Instrument getting a resource as observed by the MCP Server middleware.
1051995
Creates and manages the MCP span and attaches all attributes on the span.
1052-
1053-
Args:
1054-
func: The handler function to wrap
1055-
original_args: Original arguments passed to the handler
1056-
original_kwargs: Original keyword arguments passed to the handler
1057-
self: Optional instance for bound methods
1058996
"""
1059997
if ctx.params is None:
1060998
return await call_next(ctx)
1061999

10621000
handler_name = ctx.params["uri"]
10631001

1064-
scopes = _get_active_http_scopes(ctx=ctx)
1065-
1066-
isolation_scope_context: "ContextManager[Any]"
1067-
current_scope_context: "ContextManager[Any]"
1068-
1069-
if scopes is None:
1070-
isolation_scope_context = nullcontext()
1071-
current_scope_context = nullcontext()
1072-
else:
1073-
isolation_scope, current_scope = scopes
1074-
1075-
isolation_scope_context = (
1076-
nullcontext()
1077-
if isolation_scope is None
1078-
else sentry_sdk.scope.use_isolation_scope(isolation_scope)
1079-
)
1080-
current_scope_context = (
1081-
nullcontext()
1082-
if current_scope is None
1083-
else sentry_sdk.scope.use_scope(current_scope)
1084-
)
1085-
10861002
# Get request ID, session ID, and transport from context
10871003
request_id, session_id, mcp_transport = _get_request_context_data(ctx=ctx)
10881004

10891005
span_streaming = has_span_streaming_enabled(sentry_sdk.get_client().options)
10901006

10911007
# Start span and execute
1092-
with isolation_scope_context, current_scope_context:
1008+
with _with_active_http_scopes(ctx=ctx):
10931009
span_mgr: "Union[Span, StreamedSpan]"
10941010
if span_streaming:
10951011
span_mgr = sentry_sdk.traces.start_span(
@@ -1218,13 +1134,13 @@ async def _sentry_middleware(
12181134
ctx: "ServerRequestContext[Any, Any]", call_next: "CallNext"
12191135
) -> "HandlerResult":
12201136
if ctx.method == "tools/call":
1221-
return await _v2_tool_handler(ctx, call_next)
1137+
return await _instrument_v2_tool_call(ctx, call_next)
12221138

12231139
if ctx.method == "prompts/get":
1224-
return await _v2_prompt_handler(ctx, call_next)
1140+
return await _instrument_v2_prompt_get(ctx, call_next)
12251141

12261142
if ctx.method == "resources/read":
1227-
return await _v2_resource_handler(ctx, call_next)
1143+
return await _instrument_v2_resource_read(ctx, call_next)
12281144

12291145
return await call_next(ctx)
12301146

0 commit comments

Comments
 (0)