Skip to content

Conversation

lukeina2z
Copy link
Contributor

@lukeina2z lukeina2z commented Oct 9, 2025

Description

This commit introduces a new instrumentation package for the Model Context
Protocol (MCP), enabling automatic distributed tracing for MCP client-server
interactions.

Key Features:

  • Automatic instrumentation of MCP client sessions and server handlers
  • Support for both stdio and HTTP/SSE transports
  • W3C trace context propagation across MCP messages
  • Comprehensive span attributes following semantic conventions
  • Tool calls, resource reads, prompt handling, and session lifecycle tracing

Package Structure:

  • Core instrumentation: McpInstrumentor with automatic wrapping
  • Semantic attributes: MCP-specific span attributes and conventions
  • Test coverage: Unit tests for instrumentor, server, and session wrappers
  • Examples: stdio (simple-client-server) and HTTP/SSE transport demos
  • Documentation: README, CHANGELOG, and example-specific guides

Technical Implementation:

  • Wraps mcp.ClientSession and mcp.server.Server classes
  • Injects trace context into message metadata
  • Extracts and propagates context across transport boundaries
  • Records exceptions and sets span status appropriately
  • Requires Python >=3.10 (MCP SDK requirement)

CI/CD Updates:

  • Added MCP instrumentation to test workflows
  • Updated lint configuration for new package
  • Disabled pypy3 tests (Python 3.10+ requirement)
  • Integrated into eachdist.ini and bootstrap generation

Examples:

  • simple-client-server: stdio transport with tool calls and resources
  • http-transport: HTTP/SSE transport with distributed tracing
  • Both include Jaeger trace visualizations and setup instructions"

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Unit tests added.
    tox -e py310-test-instrumentation-mcp-oldest
    tox -e py310-test-instrumentation-mcp-latest
    tox -e py311-test-instrumentation-mcp-oldest
    tox -e py311-test-instrumentation-mcp-latest
    tox -e py312-test-instrumentation-mcp-oldest
    tox -e py312-test-instrumentation-mcp-latest
    tox -e py313-test-instrumentation-mcp-oldest
    tox -e py313-test-instrumentation-mcp-latest
    tox -e pypy3-test-instrumentation-mcp-oldest
    tox -e pypy3-test-instrumentation-mcp-latest

    tox -e lint-instrumentation-mcp
    tox -e spellcheck
    tox -e ruff

  • End to end testing with two applications in the examples folder.

Does This PR Require a Core Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@lukeina2z lukeina2z requested a review from a team as a code owner October 9, 2025 16:10
@lukeina2z lukeina2z changed the title Add OpenTelemetry instrumentation for MCP (Model Context Protocol) [WIP] Add OpenTelemetry instrumentation for MCP (Model Context Protocol) Oct 13, 2025
@lukeina2z lukeina2z marked this pull request as draft October 13, 2025 01:49
@lukeina2z lukeina2z force-pushed the mcp-prfoo branch 4 times, most recently from 0775d46 to ba43d31 Compare October 14, 2025 05:59
@lukeina2z lukeina2z changed the title [WIP] Add OpenTelemetry instrumentation for MCP (Model Context Protocol) Add OpenTelemetry instrumentation for Model Context Protocol (MCP) Oct 14, 2025
@lukeina2z lukeina2z force-pushed the mcp-prfoo branch 3 times, most recently from bba04fc to 36a82f4 Compare October 14, 2025 17:30
@lukeina2z lukeina2z marked this pull request as ready for review October 14, 2025 17:30
@lukeina2z lukeina2z force-pushed the mcp-prfoo branch 3 times, most recently from 4bcb845 to 10f1f8f Compare October 14, 2025 21:44
This commit introduces a new instrumentation package for the Model Context
Protocol (MCP), enabling automatic distributed tracing for MCP client-server
interactions.

Key Features:
- Automatic instrumentation of MCP client sessions and server handlers
- Support for both stdio and HTTP/SSE transports
- W3C trace context propagation across MCP messages
- Comprehensive span attributes following semantic conventions
- Tool calls, resource reads, prompt handling, and session lifecycle tracing

Package Structure:
- Core instrumentation: McpInstrumentor with automatic wrapping
- Semantic attributes: MCP-specific span attributes and conventions
- Test coverage: Unit tests for instrumentor, server, and session wrappers
- Examples: stdio (simple-client-server) and HTTP/SSE transport demos
- Documentation: README, CHANGELOG, and example-specific guides

Technical Implementation:
- Wraps mcp.ClientSession and mcp.server.Server classes
- Injects trace context into message metadata
- Extracts and propagates context across transport boundaries
- Records exceptions and sets span status appropriately
- Requires Python >=3.10 (MCP SDK requirement)

CI/CD Updates:
- Added MCP instrumentation to test workflows
- Updated lint configuration for new package
- Disabled pypy3 tests (Python 3.10+ requirement)
- Integrated into eachdist.ini and bootstrap generation

Examples:
- simple-client-server: stdio transport with tool calls and resources
- http-transport: HTTP/SSE transport with distributed tracing
- Both include Jaeger trace visualizations and setup instructions"
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We drop python version 6 months after they have been EOL'ed. So Python 3.9 should be there.

Copy link
Contributor

@xrmx xrmx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you in touch with the genai WG people? From a quick look it looks like this needs semantic conventions attributes that are not spec'ed it.


from wrapt import register_post_import_hook # type: ignore[import-untyped]

from opentelemetry import trace
Copy link
Member

@mxiamxia mxiamxia Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the name of this file be instrumentor.py to stay consistent with the naming pattern and sementically better?

Comment on lines +46 to +47
_CLIENT_SPAN_NAME = "mcp.client"
_SERVER_SPAN_NAME = "mcp.server"
Copy link
Member

@mxiamxia mxiamxia Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these defined by MCP semconv? shoud these be moved to attributes.py as well?

tracer_provider: Optional tracer provider to use
propagators: Optional propagators for context injection/extraction
"""
_LOG.info("Initializing MCP instrumentor xyxyxy")
Copy link
Member

@mxiamxia mxiamxia Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this info logging needed? if yes, need to fix logging message content


def instrumentation_dependencies(self) -> Collection[str]:
"""Return the dependencies required for this instrumentation."""
return ("mcp >= 1.8.1",)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason why the support starts from this version

Comment on lines +167 to +169
message_json = message.model_dump(
by_alias=True, mode="json", exclude_none=True
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is a try/catch error handling required to not interupt the original request?

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.

8 participants