8
8
from opentelemetry import trace
9
9
from opentelemetry .instrumentation .instrumentor import BaseInstrumentor
10
10
from opentelemetry .instrumentation .utils import unwrap
11
-
11
+ from . semconv import MCPAttributes , MCPSpanNames , MCPOperations , MCPTraceContext , MCPEnvironmentVariables
12
12
_instruments = ("mcp >= 1.6.0" ,)
13
13
14
14
class MCPInstrumentor (BaseInstrumentor ):
@@ -27,9 +27,9 @@ def instrumentation_dependencies() -> Collection[str]:
27
27
def _instrument (self , ** kwargs : Any ) -> None :
28
28
tracer_provider = kwargs .get ("tracer_provider" )
29
29
if tracer_provider :
30
- self .tracer = tracer_provider .get_tracer ("mcp" )
30
+ self .tracer = tracer_provider .get_tracer ("instrumentation. mcp" )
31
31
else :
32
- self .tracer = trace .get_tracer ("mcp" )
32
+ self .tracer = trace .get_tracer ("instrumentation. mcp" )
33
33
register_post_import_hook (
34
34
lambda _ : wrap_function_wrapper (
35
35
"mcp.shared.session" ,
@@ -65,7 +65,7 @@ def _wrap_send_request(
65
65
"""
66
66
67
67
async def async_wrapper ():
68
- with self .tracer .start_as_current_span ("client.send_request" , kind = trace .SpanKind .CLIENT ) as span :
68
+ with self .tracer .start_as_current_span (MCPSpanNames . CLIENT_SEND_REQUEST , kind = trace .SpanKind .CLIENT ) as span :
69
69
span_ctx = span .get_span_context ()
70
70
request = args [0 ] if len (args ) > 0 else kwargs .get ("request" )
71
71
if request :
@@ -107,7 +107,7 @@ async def _wrap_handle_request(
107
107
traceparent = None
108
108
109
109
if req and hasattr (req , "params" ) and req .params and hasattr (req .params , "meta" ) and req .params .meta :
110
- traceparent = getattr (req .params .meta , "traceparent" , None )
110
+ traceparent = getattr (req .params .meta , MCPTraceContext . TRACEPARENT_HEADER , None )
111
111
span_context = self ._extract_span_context_from_traceparent (traceparent ) if traceparent else None
112
112
if span_context :
113
113
span_name = self ._get_mcp_operation (req )
@@ -125,16 +125,24 @@ async def _wrap_handle_request(
125
125
def _generate_mcp_attributes (self , span : trace .Span , request : ClientRequest , is_client : bool ) -> None :
126
126
import mcp .types as types # pylint: disable=import-outside-toplevel,consider-using-from-import
127
127
128
- operation = "UnknownOperation"
128
+ operation = MCPOperations .UNKNOWN_OPERATION
129
+
129
130
if isinstance (request , types .ListToolsRequest ):
130
- operation = "ListTool"
131
- span .set_attribute ("mcp.list_tools" , True )
131
+ operation = MCPOperations .LIST_TOOL
132
+ span .set_attribute (MCPAttributes .MCP_LIST_TOOLS , True )
133
+ if is_client :
134
+ span .update_name (MCPSpanNames .CLIENT_LIST_TOOLS )
132
135
elif isinstance (request , types .CallToolRequest ):
133
136
operation = request .params .name
134
- span .set_attribute ("mcp.call_tool" , True )
137
+ span .set_attribute (MCPAttributes .MCP_CALL_TOOL , True )
138
+ if is_client :
139
+ span .update_name (MCPSpanNames .client_call_tool (request .params .name ))
135
140
elif isinstance (request , types .InitializeRequest ):
136
- operation = "Initialize"
137
- span .set_attribute ("mcp.initialize" , True )
141
+ operation = MCPOperations .INITIALIZE
142
+ span .set_attribute (MCPAttributes .MCP_INITIALIZE , True )
143
+ if is_client :
144
+ span .update_name (MCPSpanNames .CLIENT_INITIALIZE )
145
+
138
146
if is_client :
139
147
self ._add_client_attributes (span , operation , request )
140
148
else :
@@ -148,9 +156,9 @@ def _inject_trace_context(request_data: Dict[str, Any], span_ctx) -> None:
148
156
request_data ["params" ]["_meta" ] = {}
149
157
trace_id_hex = f"{ span_ctx .trace_id :032x} "
150
158
span_id_hex = f"{ span_ctx .span_id :016x} "
151
- trace_flags = "01"
152
- traceparent = f"00 -{ trace_id_hex } -{ span_id_hex } -{ trace_flags } "
153
- request_data ["params" ]["_meta" ]["traceparent" ] = traceparent
159
+ trace_flags = MCPTraceContext . TRACE_FLAGS_SAMPLED
160
+ traceparent = f"{ MCPTraceContext . TRACEPARENT_VERSION } -{ trace_id_hex } -{ span_id_hex } -{ trace_flags } "
161
+ request_data ["params" ]["_meta" ][MCPTraceContext . TRACEPARENT_HEADER ] = traceparent
154
162
155
163
@staticmethod
156
164
def _extract_span_context_from_traceparent (traceparent : str ):
@@ -177,24 +185,24 @@ def _get_mcp_operation(req: ClientRequest) -> str:
177
185
span_name = "unknown"
178
186
179
187
if isinstance (req , types .ListToolsRequest ):
180
- span_name = "tools/list"
188
+ span_name = MCPSpanNames . TOOLS_LIST
181
189
elif isinstance (req , types .CallToolRequest ):
182
- span_name = f"tools/ { req .params .name } "
190
+ span_name = MCPSpanNames . tools_call ( req .params .name )
183
191
elif isinstance (req , types .InitializeRequest ):
184
- span_name = "tools/initialize"
192
+ span_name = MCPSpanNames . TOOLS_INITIALIZE
185
193
return span_name
186
194
187
195
@staticmethod
188
196
def _add_client_attributes (span : trace .Span , operation : str , request : ClientRequest ) -> None :
189
197
import os # pylint: disable=import-outside-toplevel
190
198
191
- service_name = os .environ .get ("MCP_INSTRUMENTATION_SERVER_NAME" , "mcp server" )
192
- span .set_attribute ("aws.remote.service" , service_name )
193
- span .set_attribute ("aws.remote.operation" , operation )
199
+ service_name = os .environ .get (MCPEnvironmentVariables . SERVER_NAME , "mcp server" )
200
+ span .set_attribute (MCPAttributes . AWS_REMOTE_SERVICE , service_name )
201
+ span .set_attribute (MCPAttributes . AWS_REMOTE_OPERATION , operation )
194
202
if hasattr (request , "params" ) and request .params and hasattr (request .params , "name" ):
195
- span .set_attribute ("tool.name" , request .params .name )
203
+ span .set_attribute (MCPAttributes . MCP_TOOL_NAME , request .params .name )
196
204
197
205
@staticmethod
198
206
def _add_server_attributes (span : trace .Span , operation : str , request : ClientRequest ) -> None :
199
207
if hasattr (request , "params" ) and request .params and hasattr (request .params , "name" ):
200
- span .set_attribute ("tool.name" , request .params .name )
208
+ span .set_attribute (MCPAttributes . MCP_TOOL_NAME , request .params .name )
0 commit comments