Skip to content

Commit fea22f7

Browse files
nirgaclaude
andcommitted
refactor(mcp): match Python MCP client instrumentation exactly
Reverted enhancements to match the Python MCP client implementation precisely. The Python client instrumentation does NOT set: - TRACELOOP_WORKFLOW_NAME on any spans - TRACELOOP_SPAN_KIND on generic method spans (only on tool calls) - TRACELOOP_ENTITY_NAME on generic method spans (only on tool calls) Changes: 1. Session span: - Use "session" string literal instead of enum - Remove TRACELOOP_WORKFLOW_NAME 2. Tool call spans: - Use "tool" string literal instead of enum - Keep TRACELOOP_ENTITY_NAME (tool name) - Remove TRACELOOP_WORKFLOW_NAME 3. Generic method spans (tools/list, resources/read, etc): - Remove TRACELOOP_SPAN_KIND - Remove TRACELOOP_ENTITY_NAME - Keep TRACELOOP_ENTITY_INPUT/OUTPUT All 6 tests passing ✓ Sample app verified ✓ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 9b9ea4b commit fea22f7

File tree

2 files changed

+10
-51
lines changed

2 files changed

+10
-51
lines changed

packages/instrumentation-mcp/src/instrumentation.ts

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import {
2828
} from "@opentelemetry/instrumentation";
2929
import {
3030
SpanAttributes,
31-
TraceloopSpanKindValues,
3231
CONTEXT_KEY_ALLOW_TRACE_CONTENT,
3332
} from "@traceloop/ai-semantic-conventions";
3433
import { McpInstrumentationConfig } from "./types";
@@ -247,23 +246,13 @@ export class McpInstrumentation extends InstrumentationBase {
247246

248247
span.setAttribute(
249248
SpanAttributes.TRACELOOP_SPAN_KIND,
250-
TraceloopSpanKindValues.SESSION,
249+
"session",
251250
);
252251
span.setAttribute(
253252
SpanAttributes.TRACELOOP_ENTITY_NAME,
254253
"mcp.client.session",
255254
);
256255

257-
// Add client/server name as workflow name
258-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
259-
const clientInfo = (this as any)._clientInfo;
260-
if (clientInfo && clientInfo.name) {
261-
span.setAttribute(
262-
SpanAttributes.TRACELOOP_WORKFLOW_NAME,
263-
`${clientInfo.name}.mcp`,
264-
);
265-
}
266-
267256
// Create a context with this session span
268257
const sessionContext = trace.setSpan(context.active(), span);
269258

@@ -332,20 +321,13 @@ export class McpInstrumentation extends InstrumentationBase {
332321
const method = request.method;
333322
const params = request.params;
334323

335-
// Determine span name and kind based on method
324+
// Determine span name based on method
336325
let spanName: string;
337-
let spanKind: string;
338-
let entityName: string;
339-
340326
if (method === "tools/call") {
341327
const toolName = (params as MCPToolCallParams)?.name || "unknown";
342328
spanName = `${toolName}.tool`;
343-
entityName = toolName;
344-
spanKind = TraceloopSpanKindValues.TOOL;
345329
} else {
346330
spanName = `${method}.mcp`;
347-
entityName = method;
348-
spanKind = TraceloopSpanKindValues.UNKNOWN;
349331
}
350332

351333
// Use the stored session context as parent if available
@@ -360,21 +342,11 @@ export class McpInstrumentation extends InstrumentationBase {
360342
parentContext,
361343
);
362344

363-
span.setAttribute(SpanAttributes.TRACELOOP_SPAN_KIND, spanKind);
364-
span.setAttribute(SpanAttributes.TRACELOOP_ENTITY_NAME, entityName);
365-
366-
// Add workflow name from client/server info (similar to Python implementation)
367-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
368-
const clientInfo = (this as any)._clientInfo;
369-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
370-
const serverInfo = (this as any).server?._serverInfo;
371-
372-
const info = clientInfo || serverInfo;
373-
if (info && info.name) {
374-
span.setAttribute(
375-
SpanAttributes.TRACELOOP_WORKFLOW_NAME,
376-
`${info.name}.mcp`,
377-
);
345+
// Only set span kind and entity name for tool calls (matching Python implementation)
346+
if (method === "tools/call") {
347+
const toolName = (params as MCPToolCallParams)?.name || "unknown";
348+
span.setAttribute(SpanAttributes.TRACELOOP_SPAN_KIND, "tool");
349+
span.setAttribute(SpanAttributes.TRACELOOP_ENTITY_NAME, toolName);
378350
}
379351

380352
// Add input attributes if traceContent is enabled

packages/instrumentation-mcp/test/instrumentation.test.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,12 @@ describe("Test MCP instrumentation", function () {
248248
const sessionSpan = sessionSpans[0];
249249
assert.strictEqual(
250250
sessionSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND],
251-
TraceloopSpanKindValues.SESSION,
251+
"session",
252252
);
253253
assert.strictEqual(
254254
sessionSpan.attributes[SpanAttributes.TRACELOOP_ENTITY_NAME],
255255
"mcp.client.session",
256256
);
257-
assert.strictEqual(
258-
sessionSpan.attributes[SpanAttributes.TRACELOOP_WORKFLOW_NAME],
259-
"test-client.mcp",
260-
);
261257
});
262258

263259
it("should create tool call spans with correct attributes", async () => {
@@ -331,29 +327,20 @@ describe("Test MCP instrumentation", function () {
331327
const sessionSpan = sessionSpans[0];
332328
assert.strictEqual(
333329
sessionSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND],
334-
TraceloopSpanKindValues.SESSION,
335-
);
336-
assert.strictEqual(
337-
sessionSpan.attributes[SpanAttributes.TRACELOOP_WORKFLOW_NAME],
338-
"test-client.mcp",
330+
"session",
339331
);
340332

341333
// Verify tool span
342334
assert.ok(toolSpans.length > 0, "Should create tool span");
343335
const toolSpan = toolSpans[0];
344336
assert.strictEqual(
345337
toolSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND],
346-
TraceloopSpanKindValues.TOOL,
338+
"tool",
347339
);
348340
assert.strictEqual(
349341
toolSpan.attributes[SpanAttributes.TRACELOOP_ENTITY_NAME],
350342
"test_tool",
351343
);
352-
// Verify workflow name is also set on tool spans (matching Python implementation)
353-
assert.strictEqual(
354-
toolSpan.attributes[SpanAttributes.TRACELOOP_WORKFLOW_NAME],
355-
"test-client.mcp",
356-
);
357344

358345
// Verify tool span has input/output (since traceContent is enabled by default)
359346
const input = JSON.parse(

0 commit comments

Comments
 (0)