Add pluggable instrumentation interface and request_id logging by dgenio · Pull Request #1693 · modelcontextprotocol/python-sdk · GitHub
https://github.com/modelcontextprotocol/python-sdk/pull/1693 • 341 KB fetched Open original page
Add pluggable instrumentation interface and request_id logging by dgenio · Pull Request #1693 · modelcontextprotocol/python-sdk · GitHub
Skip to content
Navigation Menu
Sign in Appearance settings
* Platform
* AI CODE CREATION
* GitHub Copilot Write better code with AI
* GitHub Copilot app Direct agents from issue to merge
* MCP Registry Integrate external tools
* DEVELOPER WORKFLOWS
* Actions Automate any workflow
* Codespaces Instant dev environments
* Issues Plan and track work
* Code Review Manage code changes
* Code Quality Enforce quality at merge
* APPLICATION SECURITY
* GitHub Advanced Security Find and fix vulnerabilities
* Code security Secure your code as you build
* Secret protection Stop leaks before they start
* EXPLORE
* Why GitHub
* Documentation
* Blog
* Changelog
* Marketplace
View all features
* Solutions
* BY COMPANY SIZE
* Enterprises
* Small and medium teams
* Startups
* Nonprofits
* BY USE CASE
* App Modernization
* DevSecOps
* DevOps
* CI/CD
* View all use cases
* BY INDUSTRY
* Healthcare
* Financial services
* Manufacturing
* Government
* View all industries
View all solutions
* Resources
* EXPLORE BY TOPIC
* AI
* Software Development
* DevOps
* Security
* View all topics
* EXPLORE BY TYPE
* Customer stories
* Events & webinars
* Ebooks & reports
* Business insights
* GitHub Skills
* SUPPORT & SERVICES
* Documentation
* Customer support
* Community forum
* Trust center
* Partners
View all resources
* Open Source
* COMMUNITY
* GitHub Sponsors Fund open source developers
* PROGRAMS
* Security Lab
* Maintainer Community
* GitHub Stars
* Archive Program
* REPOSITORIES
* Topics
* Trending
* Collections
* Enterprise
* ENTERPRISE SOLUTIONS
* Enterprise platform AI-powered developer platform
* AVAILABLE ADD-ONS
* GitHub Advanced Security Enterprise-grade security features
* Copilot for Business Enterprise-grade AI features
* Premium Support Enterprise-grade 24/7 support
* Pricing
Search /
Sign in
Sign up Appearance settings
You signed in with another tab or window. Reload to refresh your session.
You signed out in another tab or window. Reload to refresh your session.
You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
Uh oh!
There was an error while loading. Please reload this page .
modelcontextprotocol
/
python-sdk
Public
*
Notifications
You must be signed in to change notification settings
*
Fork
3.9k
*
Star
24.3k
*
Code
*
Issues
226
*
Pull requests
184
*
Actions
*
Projects
*
Security and quality
6
*
Insights
Additional navigation options
*
Code
*
Issues
*
Pull requests
*
Actions
*
Projects
*
Security and quality
*
Insights
Add pluggable instrumentation interface and request_id logging - # 1693
# 1693
Closed
dgenio wants to merge 7 commits into modelcontextprotocol:main modelcontextprotocol/python-sdk:main from dgenio:feature/instrumentation-interface dgenio/python-sdk:feature/instrumentation-interface Copy head branch name to clipboard
Conversation Commits 7 ( 7 ) Checks Files changed
Closed
Add pluggable instrumentation interface and request_id logging # 1693 dgenio wants to merge 7 commits into modelcontextprotocol:main modelcontextprotocol/python-sdk:main from dgenio:feature/instrumentation-interface dgenio/python-sdk:feature/instrumentation-interface Copy head branch name to clipboard
Conversation
dgenio
commented
Nov 28, 2025
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page .
Copy link
Copy Markdown
Summary
This PR introduces a pluggable instrumentation interface with a token-based API for the MCP Python SDK, enabling OpenTelemetry and other observability integrations as requested in #421 .
Key Innovation: Token-Based API
The instrumentation interface uses a token-based approach that solves a critical design problem:
class Instrumenter ( Protocol ):
def on_request_start (...) -> Any : # Returns a token
"""Start instrumentation, return state token (e.g., OTel span)"""
def on_request_end ( token : Any , ...) -> None : # Receives the token
"""End instrumentation using the token"""
def on_error ( token : Any , ...) -> None : # Receives the token
"""Handle errors using the token"""
This design enables instrumenters to maintain state (like OpenTelemetry spans) without external storage or side-channels , addressing feedback from the community on API design best practices.
Changes
Core Interface
* Defined Instrumenter protocol with token-based hooks
* Created NoOpInstrumenter as default implementation with minimal overhead
* Token can be any value (span object, dict, etc.)
Integration
* Added instrumenter parameter to ServerSession and ClientSession constructors
* Wired instrumentation into Server._handle_request() to track:
* Request start/end with duration tracking
* Success/failure status
* Error occurrences with token propagation
* Added request_id to logging extra fields for correlation
OpenTelemetry Example
* NEW : Complete OpenTelemetryInstrumenter implementation in examples/opentelemetry_instrumentation.py
* Demonstrates span management using tokens
* Includes setup code and runnable example
* Shows proper error recording and status codes
Testing
* Comprehensive tests verifying:
* Token flow from start → end/error
* Hooks are invoked for successful and failed requests
* request_id is consistent across lifecycle
* Metadata is passed correctly
* Default no-op behavior works
Documentation
* Added docs/instrumentation.md with:
* Token-based API explanation with "Why Tokens?" section
* Complete OpenTelemetry integration guide
* Usage examples for server and client
* Custom metrics example
* Best practices and migration guide
Benefits
* No External Storage : Instrumenters don't need spans = {} dictionaries
* OpenTelemetry Compatible : Spans can be returned and passed directly
* Thread-Safe : Each request gets its own token
* Automatic Cleanup : Tokens are garbage collected
* Flexible : Token can be any value
Follow-up Work
* Package OpenTelemetry instrumenter as installable extra ( pip install mcp[opentelemetry] )
* Additional built-in instrumenters (Prometheus, StatsD, Datadog)
* Distributed tracing via params._meta.traceparent propagation
* Client-side instrumentation (server-side is complete)
Fixes #421
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page .
👍
1
SecretiveShell reacted with thumbs up emoji
All reactions
*
👍
1 reaction
dgenio
added 4 commits
November 28, 2025 12:56
feat: add instrumentation interface for observability
...
c846086
Add a pluggable instrumentation interface for monitoring MCP request/response lifecycle. This lays groundwork for OpenTelemetry and other observability integrations.
Changes:
- Define Instrumenter protocol with on_request_start, on_request_end, and on_error hooks
- Add NoOpInstrumenter as default implementation with minimal overhead
- Wire instrumenter into ServerSession and ClientSession constructors
- Add instrumentation calls in Server._handle_request for server-side monitoring
- Add request_id to log records via extra field for correlation
- Add comprehensive tests for instrumentation protocol
- Add documentation with examples and best practices
Addresses modelcontextprotocol#421
fix: correct import order in server.py
a01b2ae
style: apply ruff formatting to instrumentation files
8d79aa0
refactor: use token-based instrumentation API for OpenTelemetry support
...
c6bcdb5
This change addresses feedback on the instrumentation interface design. The updated API now uses a token-based approach where on_request_start() returns a token that is passed to on_request_end() and on_error(). This enables instrumenters to maintain state (like OpenTelemetry spans) without external storage or side-channels.
Changes:
- Updated Instrumenter protocol to return token from on_request_start()
- Modified on_request_end() and on_error() to accept token as first parameter
- Updated server.py to capture and pass instrumentation tokens
- Updated all tests to match new API
- Added complete OpenTelemetry example implementation
- Updated documentation with token-based examples
Fixes modelcontextprotocol#421
dgenio
commented
Nov 28, 2025
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page .
Copy link
Copy Markdown
Author
Updated the instrumentation interface to use a token-based API based on community feedback . This enables proper OpenTelemetry integration without external storage. See updated PR description for details.
All reactions
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page .
dgenio
added 3 commits
November 28, 2025 14:34
fix: rename TestInstrumenter to MockInstrumenter to avoid pytest coll…
...
c0c6833
…ection
Pytest was trying to collect TestInstrumenter as a test class because it starts with 'Test', but it's actually a helper class with an __init__ constructor. Renaming to MockInstrumenter resolves the PytestCollectionWarning.
fix: resolve CI failures for coverage and formatting
00a63c8
fix: add type annotations to MockInstrumenter for pyright
...
f631cd4
Added full type hints to MockInstrumenter class to resolve pyright type checking errors. This ensures the test helper class properly implements the Instrumenter protocol with correct types.
dgenio
marked this pull request as ready for review
November 28, 2025 14:50
maxisbey
added
enhancement
Request for a new feature that's not currently supported
P2
Moderate issues affecting some users, edge cases, potentially valuable feature
v2
Affects the v2 line (2.x on main)
labels
Dec 31, 2025
dgenio
mentioned this pull request
Feb 28, 2026
Adding Opentelemetry to MCP SDK
#421
Closed
dgenio
commented
Feb 28, 2026
Copy link
Copy Markdown
Author
This PR is stale due to significant upstream changes since it was opened:
* _handle_request was refactored with a new ServerRequestContext pattern and method-based handler dispatch
* ServerSession and ClientSession constructors have changed (new parameters for experimental features, tasks, etc.)
* Server.run() signature has evolved
The merge conflicts make this un-mergeable as-is, and the diff would be entirely different if rewritten.
I've commented on the original issue ( #421 ) to check with the assigned maintainer ( @Kludex ) before investing time in a rewrite. Leaving this open pending that discussion — will either close and open a fresh PR, or close if the maintainer has their own plans.
All reactions
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page .
maxisbey
commented
Mar 6, 2026
Copy link
Copy Markdown
Contributor
Let's keep discussions on the issue ( #421 ) and close stale PRs — easier to track direction there. Feel free to open a fresh PR once the approach is settled.
AI Disclaimer
All reactions
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page .
maxisbey
closed this
Mar 6, 2026
Sign up for free
to join this conversation on GitHub .
Already have an account?
Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
enhancement
Request for a new feature that's not currently supported
P2
Moderate issues affecting some users, edge cases, potentially valuable feature
v2
Affects the v2 line (2.x on main)
Projects
None yet
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Adding Opentelemetry to MCP SDK
Uh oh!
There was an error while loading. Please reload this page .
2 participants
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Footer
(c) 2026 GitHub, Inc.
Footer navigation
*
Terms
*
Privacy
*
Security
*
Status
*
Community
*
Docs
*
Contact
*
Manage cookies
*
Do not share my personal information
You can’t perform that action at this time.
Links found on this page
- Skip to content [direct]
- Sign in [direct]
- GitHub Copilot Write better code with AI [direct]
- GitHub Copilot app Direct agents from issue to merge [direct]
- MCP Registry Integrate external tools [direct]
- Actions Automate any workflow [direct]
- Codespaces Instant dev environments [direct]
- Issues Plan and track work [direct]
- Code Review Manage code changes [direct]
- Code Quality Enforce quality at merge [direct]
- GitHub Advanced Security Find and fix vulnerabilities [direct]
- Code security Secure your code as you build [direct]
- Secret protection Stop leaks before they start [direct]
- Why GitHub [direct]
- Documentation [direct]
- Blog [direct]
- Changelog [direct]
- Marketplace [direct]
- View all features [direct]
- Enterprises [direct]
- Small and medium teams [direct]
- Startups [direct]
- Nonprofits [direct]
- App Modernization [direct]
- DevSecOps [direct]
- DevOps [direct]
- CI/CD [direct]
- View all use cases [direct]
- Healthcare [direct]
- Financial services [direct]
- Manufacturing [direct]
- Government [direct]
- View all industries [direct]
- View all solutions [direct]
- AI [direct]
- Software Development [direct]
- DevOps [direct]
- Security [direct]
- View all topics [direct]
- Customer stories [direct]
- Events & webinars [direct]
- Ebooks & reports [direct]
- Business insights [direct]
- GitHub Skills [direct]
- Customer support [direct]
- Community forum [direct]
- Trust center [direct]
- Partners [direct]
- View all resources [direct]
- GitHub Sponsors Fund open source developers [direct]
- Security Lab [direct]
- Maintainer Community [direct]
- GitHub Stars [direct]
- Archive Program [direct]
- Topics [direct]
- Trending [direct]
- Collections [direct]
- Copilot for Business Enterprise-grade AI features [direct]
- Premium Support Enterprise-grade 24/7 support [direct]
- Pricing [direct]
- Sign up [direct]
- modelcontextprotocol [direct]
- python-sdk [direct]
- Notifications [direct]
- Issues
226 [direct]
- Pull requests
184 [direct]
- Actions [direct]
- Projects [direct]
- Security and quality
6 [direct]
- Insights [direct]
- dgenio [direct]
- modelcontextprotocol:main [direct]
- dgenio:feature/instrumentation-interface [direct]
- Commits 7 ( 7 ) [direct]
- Checks [direct]
- Files changed [direct]
- #421 [direct]
- feat: add instrumentation interface for observability [direct]
- fix: correct import order in server.py [direct]
- style: apply ruff formatting to instrumentation files [direct]
|
|