This product is not supported for your selected Datadog site. ().
Cette page n'est pas encore disponible en français, sa traduction est en cours. Si vous avez des questions ou des retours sur notre projet de traduction actuel, n'hésitez pas à nous contacter.
You can monitor your MCP clients with Datadog LLM Observability in two ways:
Manual instrumentation: If you are not using the official MCP Python SDK, or your MCP clients are written in Node.js or Java
Automatically instrument your MCP client
If you are using the official MCP Python SDK to connect to an MCP server with an MCP client session, use the following steps to automatically instrument your MCP client application:
Run your application with the ddtrace-run command:
ddtrace-run <YOUR_APP_STARTUP_COMMAND>
Manually instrument your MCP client
You can also manually instrument your MCP client by using Datadog’s LLM Observability SDKs for Python, Node.js, and Java. Use the following steps to add the required tags and spans:
Import the LLM Observability SDK:
fromddtrace.llmobsimportLLMObs
const{llmobs}=require('dd-trace');
importdatadog.trace.api.llmobs.LLMObs;
Start a workflow span around your MCP client session:
Within your client session, start a task span around your MCP client session initialization call. Annotate the parent client session span with the server information returned from the initialization call.
Start a task span around your call to the MCP server for getting the list of available tools within your client session.
withLLMObs.task(name="MCP Client Session List Tool"):tools=list_tools()LLMObs.annotate(output_data=tools,)
consttools=awaitllmobs.trace({kind:'task',name:'MCP Client Session List Tool'},async()=>{consttools=awaitlistTools();llmobs.annotate({outputData:tools,});returntools;});
LLMObsSpantoolsListTaskSpan=LLMObs.startTaskSpan("MCP Client Session List Tool");List<Object>tools=listTools();toolsListTaskSpan.annotateIO(null,tools);toolsListTaskSpan.finish();
Within your client session, start a tool span around your tool calls to the MCP server. Annotate the tool span with:
The server name from the information returned from the initialization call
The MCP tool type (client; for server-side monitoring, use server)
If the tool call returns an error from the MCP server (even if it would not normally raise or throw an error) mark the tool span with an error.
At this point, your instrumentation is complete. Your code should resemble the following:
withLLMObs.workflow(name="MCP Client Session")asclient_session_span:withLLMObs.task(name="MCP Client Session Initialization"):server_info=initialize_mcp_client()LLMObs.annotate(client_session_span,tags={"mcp_server_name":server_info.name,"mcp_server_version":server_info.version,"mcp_server_title":server_info.title,})withLLMObs.task(name="MCP Client Session List Tool"):tools=list_tools()LLMObs.annotate(output_data=tools,)# tool calls as part of a user feedback loop or user interactionname,arguments=get_next_tool_call()withLLMObs.tool(name=f"MCP Client Tool: {name}")astool_span:result=call_tool(name,arguments)ifresult.isError:tool_span.error=1tool_span.set_tag("error.message",result.content[0].text)LLMObs.annotate(input_data=arguments,output_data=result,tags={"mcp_server_name":server_info.name,"mcp_tool_kind":"client",})
llmobs.trace({kind:'workflow',name:'MCP Client Session'},async(clientSessionSpan)=>{llmobs.trace({kind:'task',name:'MCP Client Session Initialization'},async()=>{constserverInfo=awaitinitializeMcpClient();llmobs.annotate(clientSessionSpan,{tags:{mcp_server_name:serverInfo.name,mcp_server_version:serverInfo.version,mcp_server_title:serverInfo.title,}});});consttools=awaitllmobs.trace({kind:'task',name:'MCP Client Session List Tool'},async()=>{consttools=awaitlistTools();llmobs.annotate({outputData:tools,});returntools;});// tool calls as part of a user feedback loop or user interaction
const{name,arguments}=awaitgetNextToolCall();llmobs.trace({kind:'tool',name:`MCP Client Tool: ${name}`},async()=>{constresult=awaitcallTool(name,arguments);if(result.isError){toolSpan.setTag("error",true);toolSpan.setTag("error.message",result.content[0].text);}llmobs.annotate({inputData:arguments,outputData:result,tags:{mcp_server_name:serverInfo.name,mcp_tool_kind:"client"}});});})
LLMObsSpanclientSessionSpan=LLMObs.startWorkflowSpan("MCP Client Session");LLMObsSpaninitializationTaskSpan=LLMObs.startTaskSpan("MCP Client Session Initialization");ObjectserverInfo=initializeMcpClient();clientSessionSpan.setTags(Map.of("mcp_server_name",serverInfo.name(),"mcp_server_version",serverInfo.version(),"mcp_server_title",serverInfo.title(),));initializationTaskSpan.finish();LLMObsSpantoolsListTaskSpan=LLMObs.startTaskSpan("MCP Client Session List Tool");List<Object>tools=listTools();toolsListTaskSpan.annotateIO(null,tools);toolsListTaskSpan.finish();// tool calls as part of a user feedback loop or user interactionObjecttool=getNextToolCall();LLMObsSpantoolSpan=LLMObs.startToolSpan("MCP Client Tool: "+tool.name());Objectresult=callTool(tool.name(),tool.arguments());if(result.isError){toolSpan.setTag("error",true);toolSpan.setTag("error.message",result.content[0].text);}toolSpan.annotateIO(tool.arguments(),result);toolSpan.setTag("mcp_tool_kind","client");toolSpan.setTag("mcp_server_name",serverInfo.name());toolSpan.finish();// ... more tool calls, tasks, or user interactionsclientSessionSpan.finish();//finishattheendoftheclientsessionscope