Skip to content

feat: Add native MCP Instrumentation support#655

Merged
liustve merged 148 commits intomainfrom
mcp-instrumentor
Mar 17, 2026
Merged

feat: Add native MCP Instrumentation support#655
liustve merged 148 commits intomainfrom
mcp-instrumentor

Conversation

@liustve
Copy link
Copy Markdown
Contributor

@liustve liustve commented Feb 12, 2026

Description of changes:

Adds native OTel instrumentation for mcp following OTel's Gen's MCP semantic conventions 1.39

Instruments and wraps MCP client and server transports to capture spans for tool calls, prompts, resources, and session lifecycle.

Add auto-wiring using OTel's entry points system, so applications using ADOT Python auto-instrumentation will automatically trace mcp workflows without any code changes.

Testing

Unit tests added
Contract tests added
Manual E2E test with a FastMCP sample app, example spans shown below:

image
{
    "resource": {
        "attributes": {
            "aws.local.service": "test-agent",
            "aws.service.type": "gen_ai_agent",
            "telemetry.sdk.language": "python",
            "service.name": "test-agent",
            "telemetry.sdk.version": "1.39.1",
            "telemetry.auto.version": "0.14.2.dev0-aws",
            "telemetry.sdk.name": "opentelemetry"
        }
    },
    "scope": {
        "name": "amazon.opentelemetry.distro.instrumentation.mcp",
        "version": "0.14.2.dev0"
    },
    "traceId": "698d966cb0e4ac2c4add6a8dd4287515",
    "spanId": "cdc5be689ece0a0c",
    "parentSpanId": "ff36ddd067423294",
    "flags": 256,
    "name": "tools/call add",
    "kind": "CLIENT",
    "startTimeUnixNano": 1770886764840135000,
    "endTimeUnixNano": 1770886764847511000,
    "durationNano": 7376000,
    "attributes": {
        "aws.local.service": "test-agent",
        "telemetry.extended": "true",
        "aws.remote.service": "localhost:8000",
        "network.transport": "tcp",
        "aws.local.environment": "generic:default",
        "aws.remote.operation": "UnknownRemoteOperation",
        "server.address": "localhost",
        "mcp.session.id": "3c16664f7b0d484d81bf9ad78295213a",
        "aws.local.operation": "UnmappedOperation",
        "aws.span.kind": "CLIENT",
        "gen_ai.operation.name": "execute_tool",
        "gen_ai.tool.name": "add",
        "mcp.protocol.version": "2025-11-25",
        "server.port": 8000,
        "PlatformType": "Generic",
        "gen_ai.tool.call.arguments": "{\"a\": 5, \"b\": 3}",
        "mcp.method.name": "tools/call",
        "jsonrpc.request.id": "3",
        "gen_ai.tool.call.result": "meta=None content=[TextContent(type='text', text='Result: 8', annotations=None, meta=None)] structuredContent={'result': 'Result: 8'} isError=False"
    },
    "status": {
        "code": "OK"
    }
}
{
    "resource": {
        "attributes": {
            "aws.local.service": "test-mcp",
            "aws.service.type": "gen_ai_agent",
            "telemetry.sdk.language": "python",
            "service.name": "test-mcp",
            "telemetry.sdk.version": "1.39.1",
            "telemetry.auto.version": "0.14.2.dev0-aws",
            "telemetry.sdk.name": "opentelemetry"
        }
    },
    "scope": {
        "name": "amazon.opentelemetry.distro.instrumentation.mcp",
        "version": "0.14.2.dev0"
    },
    "traceId": "698d966cb0e4ac2c4add6a8dd4287515",
    "spanId": "7c0713d9a2d04672",
    "parentSpanId": "cdc5be689ece0a0c",
    "flags": 768,
    "name": "tools/call add",
    "kind": "SERVER",
    "startTimeUnixNano": 1770886764844750000,
    "endTimeUnixNano": 1770886764846329000,
    "durationNano": 1579000,
    "attributes": {
        "aws.local.service": "test-mcp",
        "telemetry.extended": "true",
        "network.transport": "tcp",
        "aws.local.environment": "generic:default",
        "mcp.session.id": "3c16664f7b0d484d81bf9ad78295213a",
        "client.address": "127.0.0.1",
        "aws.local.operation": "tools/call add",
        "aws.span.kind": "SERVER",
        "client.port": 50052,
        "gen_ai.operation.name": "execute_tool",
        "gen_ai.tool.name": "add",
        "mcp.protocol.version": "2025-11-25",
        "PlatformType": "Generic",
        "gen_ai.tool.call.arguments": "{\"a\": 5, \"b\": 3}",
        "mcp.method.name": "tools/call",
        "jsonrpc.request.id": "3"
    },
    "status": {
        "code": "OK"
    }
}

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

liustve and others added 30 commits November 12, 2025 13:25
wangzlei
wangzlei previously approved these changes Mar 17, 2026
@liustve
Copy link
Copy Markdown
Contributor Author

liustve commented Mar 17, 2026

Code is a bit complicated. Did review together with @wangzlei offline

@liustve liustve merged commit 29d3678 into main Mar 17, 2026
17 checks passed
@liustve liustve deleted the mcp-instrumentor branch March 17, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants