-
Notifications
You must be signed in to change notification settings - Fork 489
feat(contrib/mcp-go): Initial mcp-go tracer implementation
#4100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
mcp-go tracer implementation
|
✅ Tests 🎉 All green!❄️ No new flaky tests detected 🔗 Commit SHA: 38e2a00 | Docs | Datadog PR Page | Was this helpful? Give us feedback! |
contrib/mark3labs/mcp-go/hooks.go
Outdated
| // Hooks provides Datadog tracing for MCP servers. | ||
| type Hooks struct { | ||
| // Stores data between start and end of tool calls. In-memory works because it must be on the same instance. | ||
| toolCache *ttlcache.Cache[any, *llmobs.ToolSpan] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The in-memory cache just stores data between the start and end hooks. Creating a middleware would have avoided this, but would have been harder to automatically add to all tools. We'll also use hooks for session initialization spans (another PR on this stack).
Unfortunately this cache implementation does need to be shut down manually.
I experimented with but decided against cache customization options (max size, ttl).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another downside I see from this hooks option is that it does not allow to pass down the newly created context with the span to the handler, so if the user starts spans in the handler they won't be children of the spans we are creating here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, especially since users may want to add tags to the existing span in the handler. Just know that there will be asymmetry/inconsistency between tools and initialization because I don't see any initialization middleware.
mcp-go tracer implementationmcp-go tracer implementation
rarguelloF
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly looking good! just a few nits / comments
contrib/mark3labs/mcp-go/hooks.go
Outdated
|
|
||
| // onBeforeCallTool is called before a tool is executed. | ||
| func (h *Hooks) onBeforeCallTool(ctx context.Context, id any, request *mcp.CallToolRequest) { | ||
| toolSpan, _ := llmobs.StartToolSpan(ctx, request.Params.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if other tracers are providing any kind of info about these spans coming from the contrib package (in APM we would set tag component: "mark3labs/mcp-go").
Since this call also creates an APM span, we should do it at least for the APM part (we might need to change the llmobs package a little bit or add a new option).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sabrenner says that's just for APM spans. But LLMObs does set an integration tag so I'll add that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, @rarguelloF I see integration as a private field on the Span struct but no actual way to set it. I'll add that to llmobs.
rarguelloF
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly looking good! just a few nits / comments
95af4d3 to
4def1e6
Compare
genesor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, two nits
cd3a995 to
0a4f2bf
Compare
| "DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED": {}, | ||
| "DD_TRACE_ABANDONED_SPAN_TIMEOUT": {}, | ||
| "DD_TRACE_AGENT_PORT": {}, | ||
| "DD_TRACE_V1_PAYLOAD_FORMAT_ENABLED": {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should also not get deleted (see below)! probably a rebase issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now reset these files to main and rebased the branch and the tests are failing. The tests tell me to run go run ./scripts/configinverter/main.go generate and when I do it deletes this line.
See here: https://github.com/DataDog/dd-trace-go/runs/55310947575
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've put the changes back in order to pass tests.
It's not deleted, it's just moved below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch @jboolean I think the env var was actually manually added to both files without thinking this would break some stuff down the road.
sabrenner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mainly looked at mcpgo.go and double-checked the sdk changes to add the integration tag, looks good to me content-wise!
rarguelloF
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
3531efd to
c177b06
Compare
jboolean
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/merge
|
/merge |
|
View all feedbacks in Devflow UI.
This pull request is not mergeable according to GitHub. Common reasons include pending required checks, missing approvals, or merge conflicts — but it could also be blocked by other repository rules or settings.
The expected merge time in
|
c177b06 to
38e2a00
Compare

What does this PR do?
Adds contrib library for
mcp-go. Uses it to record LLMObs Tool spans for tool calls.This is the base of a Graphite stack.
Motivation
Tech spec for this project
Closes MLOB-4372
Reviewer's Checklist
./scripts/lint.shlocally.Testing
In addition to automated tests, this was tested locally with Datadog MCP Server
Unsure? Have a question? Request a review!