From add270dd3ccfac5dc6dbb71905ea9543fadeaba4 Mon Sep 17 00:00:00 2001 From: Julian Boilen Date: Thu, 25 Jun 2026 16:59:24 -0400 Subject: [PATCH] Document MCP intent capture feature and expand MCP server instrumentation details --- .../instrumentation/auto_instrumentation.md | 27 ++++++++++++-- .../llm_observability/instrumentation/sdk.md | 37 ++++++++++++++++++- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/content/en/llm_observability/instrumentation/auto_instrumentation.md b/content/en/llm_observability/instrumentation/auto_instrumentation.md index bb17fe2f0de..11aeea66e03 100644 --- a/content/en/llm_observability/instrumentation/auto_instrumentation.md +++ b/content/en/llm_observability/instrumentation/auto_instrumentation.md @@ -537,17 +537,36 @@ The Model Context Protocol (MCP) integration instruments client and server tool ### Traced methods -The MCP integration instruments the following methods: +The MCP integration instruments both MCP clients and servers. + +#### MCP clients + +The MCP client-side instrumentation records client tool calls. - [Client Tool Calls][2]: - `mcp.client.session.ClientSession.call_tool` -- [Server Tool Calls][3]: - - `mcp.server.fastmcp.tools.tool_manager.ToolManager.call_tool` +#### MCP servers + +The MCP server-side integration instruments [`initialize`][3] and [`tools/call`][4] MCP methods. [`tools/list`][5] calls are optionally intercepted when intent capture is enabled. + +The following tags are recorded on server spans: +- `mcp_method`: The MCP method called. +- `mcp_session_id`: The MCP [session ID][6], recorded when available in the request. +- `client_name`: The name of the client as provided to `initialize`. +- `client_version`: The version of the client as provided to `initialize`. + +- Server methods instrumented: + - `mcp.server.shared.session.RequestResponder.__enter__` + - `mcp.server.shared.session.RequestResponder.__exit__` + - `mcp.server.shared.session.RequestResponder.respond` [1]: https://modelcontextprotocol.io/docs/getting-started/intro [2]: https://github.com/modelcontextprotocol/python-sdk?tab=readme-ov-file#writing-mcp-clients -[3]: https://github.com/modelcontextprotocol/python-sdk?tab=readme-ov-file#tools +[3]: https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#initialization +[4]: https://modelcontextprotocol.io/specification/2025-11-25/server/tools#calling-tools +[5]: https://modelcontextprotocol.io/specification/2025-11-25/server/tools#listing-tools +[6]: https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#session-management {{% /tab %}} {{% tab "Node.js" %}} diff --git a/content/en/llm_observability/instrumentation/sdk.md b/content/en/llm_observability/instrumentation/sdk.md index 87d2a67e0d7..6b9e00dea03 100644 --- a/content/en/llm_observability/instrumentation/sdk.md +++ b/content/en/llm_observability/instrumentation/sdk.md @@ -92,9 +92,13 @@ DD_LLMOBS_ML_APP= ddtrace-run : optional - _string_
Your Datadog API key. Only required if you are not using the Datadog Agent. -[1]: /getting_started/tagging/unified_service_tagging?tab=kubernetes#non-containerized-environment +`DD_MCP_CAPTURE_INTENT` +: optional - _integer or string_ - **default**: `false` +
When set to `1` or `true`, adds an argument to every MCP tool requesting that the calling model describe why it chose to call the tool. The intent is recorded on the tool span. {{% /tab %}} +[1]: /getting_started/tagging/unified_service_tagging?tab=kubernetes#non-containerized-environment + {{% tab "Node.js" %}} Enable Agent Observability by running your application with `NODE_OPTIONS="--import dd-trace/initialize.mjs"` and specifying the required environment variables. @@ -224,6 +228,10 @@ LLMObs.enable( : optional - _string_
The name of the service used for your application. If not provided, this defaults to the value of `DD_SERVICE`. +`capture_intent` +: optional - _boolean_ - **default**: `false` +
When set to `True`, adds an argument to every MCP server tool requesting that the calling model describe why it chose to call the tool. The intent is recorded on the tool span. If not provided, this defaults to the value of `DD_MCP_CAPTURE_INTENT`. + [1]: /llm_observability/instrumentation/auto_instrumentation/ {{% /tab %}} @@ -1957,6 +1965,33 @@ The versioning system works as follows: This gives you the flexibility to either rely on automatic version management based on template content changes, or maintain full control over versioning with your own version labels. +## MCP intent capture + +To gain insight into why your MCP tools were called, enable intent capture on your MCP server. When enabled, the SDK adds an argument to every MCP tool requesting that the calling model describe why it chose to call the tool. The intent is recorded on the tool span, helping you improve your tool definitions and descriptions. + +{{< tabs >}} +{{% tab "Python" %}} + +Enable MCP intent capture with the `DD_MCP_CAPTURE_INTENT` environment variable: + +{{< code-block lang="shell" >}} +DD_MCP_CAPTURE_INTENT=1 DD_SITE= DD_API_KEY= DD_LLMOBS_ENABLED=1 \ +DD_LLMOBS_ML_APP= ddtrace-run +{{< /code-block >}} + +Or, enable it programmatically with the `capture_intent` parameter on `LLMObs.enable()`: + +{{< code-block lang="python" >}} +from ddtrace.llmobs import LLMObs +LLMObs.enable( + ml_app="", + capture_intent=True, +) +{{< /code-block >}} + +{{% /tab %}} +{{< /tabs >}} + ## Cost monitoring Attach token metrics (for automatic cost tracking) or cost metrics (for manual cost tracking) to your LLM/embedding spans. Token metrics allow Datadog to calculate costs using provider pricing, while cost metrics let you supply your own pricing when using custom or unsupported models. For more details, see [Costs][14].