Skip to content

feat(contrib/mark3labs/mcp-go): expose captured intent to tool handlers via context#4941

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 1 commit into
mainfrom
jb/mcp-intent-from-context
Jul 2, 2026
Merged

feat(contrib/mark3labs/mcp-go): expose captured intent to tool handlers via context#4941
gh-worker-dd-mergequeue-cf854d[bot] merged 1 commit into
mainfrom
jb/mcp-intent-from-context

Conversation

@jboolean

@jboolean jboolean commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

This PR stack ports functionality added in the clone of this contrib in dd-source back to dd-trace-go so that the clone can be removed.

Summary

The intent-capture middleware annotates the LLMObs span with the client-supplied telemetry.intent, but tool handlers had no way to read it without re-parsing the telemetry blob — which the same middleware strips before the handler runs.

This change:

  • Stashes the captured intent on context.Context alongside the existing LLMObs annotation.
  • Exports IntentFromContext(ctx) (string, bool) and ContextWithIntent(ctx, intent) context.Context so tool handlers can forward the intent downstream (e.g. to a search API for retrieval/ranking experiments).
  • Refactors the previous processTelemetry into extractIntent + annotateIntentOnSpan for clarity; behavior is otherwise unchanged.

Ported from internal dd-source PR #443664.

Test plan

  • TestIntentFromContext — round-trip + empty-intent + missing-key behavior.
  • TestIntentCaptureStashesIntentOnContext — end-to-end: a tools/call with telemetry.intent makes the value visible to the handler via IntentFromContext.
  • Existing intent-capture tests still pass.

Stacked on #4940.

@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jun 24, 2026

Copy link
Copy Markdown

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 57.89%
Overall Coverage: 62.80%

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 2de53a9 | Docs | Datadog PR Page | Give us feedback!

@pr-commenter

pr-commenter Bot commented Jun 24, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-07-01 16:38:39

Comparing candidate commit 2de53a9 in PR branch jb/mcp-intent-from-context with baseline commit e46fd46 in branch jb/mcp-preserve-raw-schema-fields.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 321 metrics, 2 unstable metrics, 1 flaky benchmarks without significant changes.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

Known flaky benchmarks

These benchmarks are marked as flaky and will not trigger a failure. Modify FLAKY_BENCHMARKS_REGEX to control which benchmarks are marked as flaky.

Known flaky benchmarks without significant changes:

  • scenario:BenchmarkOTLPTraceWriterFlush

Comment thread contrib/mark3labs/mcp-go/intent_capture_test.go
@jboolean jboolean force-pushed the jb/mcp-intent-from-context branch from 0f308e2 to 301b597 Compare June 24, 2026 14:43
@jboolean jboolean requested a review from thollander June 24, 2026 14:45
@jboolean jboolean marked this pull request as ready for review June 24, 2026 14:50
@jboolean jboolean requested review from a team as code owners June 24, 2026 14:50
@jboolean jboolean requested review from rarguelloF and removed request for a team June 24, 2026 14:50
@jboolean jboolean changed the base branch from jb/mcp-raw-input-schema-race-fix to graphite-base/4941 June 24, 2026 15:08
@jboolean jboolean force-pushed the jb/mcp-intent-from-context branch from 301b597 to ce524bf Compare June 24, 2026 15:08
@jboolean jboolean changed the base branch from graphite-base/4941 to jb/mcp-preserve-raw-schema-fields June 24, 2026 15:09
@jboolean jboolean force-pushed the jb/mcp-intent-from-context branch from ce524bf to ec14544 Compare June 24, 2026 15:28
@jboolean jboolean force-pushed the jb/mcp-preserve-raw-schema-fields branch 2 times, most recently from a2b4f0a to 13679e8 Compare June 24, 2026 16:48
@jboolean jboolean force-pushed the jb/mcp-intent-from-context branch from ec14544 to 0c444d5 Compare June 24, 2026 16:48
@jboolean jboolean requested a review from sabrenner June 25, 2026 14:55
…rs via context

The intent-capture middleware annotates the LLMObs span with the client-
supplied telemetry.intent, but tool handlers had no way to read it without
re-parsing the telemetry blob (which the same middleware strips before the
handler runs).

Stash the intent on context.Context alongside the existing LLMObs annotation
and export IntentFromContext / ContextWithIntent helpers so handlers can
forward the intent downstream (e.g. to a search API for retrieval/ranking
experiments).

Ported from internal dd-source PR #443664.
@jboolean jboolean force-pushed the jb/mcp-preserve-raw-schema-fields branch from e46fd46 to b88a735 Compare July 1, 2026 15:00
@jboolean jboolean requested review from a team as code owners July 1, 2026 15:00
@jboolean jboolean force-pushed the jb/mcp-intent-from-context branch from 08d7e54 to 13679e8 Compare July 1, 2026 15:00
@jboolean jboolean changed the base branch from jb/mcp-preserve-raw-schema-fields to graphite-base/4941 July 1, 2026 16:06
@jboolean jboolean force-pushed the graphite-base/4941 branch from b88a735 to e46fd46 Compare July 1, 2026 16:06
@jboolean jboolean force-pushed the jb/mcp-intent-from-context branch from 13679e8 to 2de53a9 Compare July 1, 2026 16:06
@jboolean jboolean changed the base branch from graphite-base/4941 to jb/mcp-preserve-raw-schema-fields July 1, 2026 16:06
@jboolean jboolean removed request for a team July 1, 2026 18:26
Base automatically changed from jb/mcp-preserve-raw-schema-fields to main July 2, 2026 20:36
@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d Bot merged commit 4b636a7 into main Jul 2, 2026
897 of 928 checks passed
@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d Bot deleted the jb/mcp-intent-from-context branch July 2, 2026 20:52
gh-worker-dd-mergequeue-cf854d Bot added a commit that referenced this pull request Jul 3, 2026
…tools (#4942)

This PR stack ports functionality added in the clone of this contrib in dd-source back to dd-trace-go.

## Summary

The intent-capture `ListTools` hook unconditionally adds `telemetry` as a required field to every tool's input schema. That breaks tools annotated as UI-only (`_meta.ui.visibility` excluding `"model"`): they are invoked by the app UI, not by the model, so the UI caller has no `intent` to supply. OpenAI's MCP client strictly validates tool arguments against the advertised schema and rejects every UI-driven call as a result.

This change adds an `isModelCallable` helper that inspects `*mcp.Meta.AdditionalFields["ui"]["visibility"]` (handling both `[]string` and `[]any` shapes from JSON round-trips) and short-circuits the injection when the model is not in the visibility list. Tools with no `_meta.ui.visibility` continue to default to model-callable per the MCP Apps spec.

Ported from internal dd-source PR [#420911](DataDog/dd-source#420911).

## Test plan

- [x] `TestIntentCaptureSkipsUIOnlyTools` — three tools (model-only, UI-only `[app]`, dual `[app, model]`); asserts `telemetry` is injected for model and dual but not for UI-only.
- [x] Existing intent-capture tests still pass.

Stacked on #4941.

## MCP standard reference

The `_meta.ui.visibility` field is part of the official [MCP Apps extension](https://modelcontextprotocol.io/extensions/apps/overview). Values: `["model", "app"]` (default), `["model"]`, or `["app"]` — they control which actor may invoke the tool. UI-only tools (`["app"]`) are invoked by the host shell, never by the model. This PR's skip logic respects that standard.

---

Parallel port in the modelcontextprotocol/go-sdk contrib: #4949


Co-authored-by: jboolean <julian.boilen@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apm:ecosystem contrib/* related feature requests or bugs mergequeue-status: done

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants