Title: Fix: Refresh auth context per Streamable HTTP request by bgaidioz · Pull Request #1998 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: Fix: Refresh auth context per Streamable HTTP request by bgaidioz · Pull Request #1998 · modelcontextprotocol/python-sdk
X Title: Fix: Refresh auth context per Streamable HTTP request by bgaidioz · Pull Request #1998 · modelcontextprotocol/python-sdk
Description: This changeset addresses issue #1250: after the MCP client refreshes its token and starts using the new one, server‑side tools still receive the old (expired) token from get_access_token(). CI failed on coverage for the new branch in _handle_request. I added a small, low‑level unit test to cover it, but it’s fairly close to internals and I’m not sure this is the preferred approach. If there’s a better way to cover this path, please let me know what you recommend. Motivation and Context We've hit the bug and found this matching GitHub issue. I provided test code to reproduce the bug. Eventually I noticed project fastmcp hit the same problem and a patch was committed. How Has This Been Tested? The changes include a regression test. Without the patch, the #1250 bug is hit (AssertionError: assert 'token-a' == 'token-b'). The changes also include a unit-test. Which fails without the patch. Verified the test code provided to reproduce the bug, isn't showing tokens with negative validity. Ran our OAuth MCP against the patched version and confirm token renewal now works. Breaking Changes No. Types of changes 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 change) Documentation update Checklist I have read the MCP Documentation My code follows the repository's style guidelines New and existing tests pass locally I have added appropriate error handling I have added or updated documentation as needed Additional context My understanding: The context var is correct inside the ASGI request task where AuthContextMiddleware runs. The problem is that tool execution happens later in a different task. The context var value isn’t visible. StreamableHTTPSessionManager only wraps the request in a ServerMessageMetadata and writes it to a MemoryObjectSendStream. When that message is processed later, unless it's re-set, the context var isn’t the correct one. The fastmcp fix patches get_access_token() to read the token from the current request (available via request metadata in the tool execution context). Which permits to avoid reading the stale context var. This change instead updates auth_context_var from the current request’s scope["user"] inside _handle_request, so each message sees the latest token in the context var.
Open Graph Description: This changeset addresses issue #1250: after the MCP client refreshes its token and starts using the new one, server‑side tools still receive the old (expired) token from get_access_token(). CI fail...
X Description: This changeset addresses issue #1250: after the MCP client refreshes its token and starts using the new one, server‑side tools still receive the old (expired) token from get_access_token(). CI fail...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/pull/1998
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:013108e4-73e6-8da2-b501-5e6ca8e2d2ad |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | 8A7C:3A26D0:9D918B:D51293:6A60118B |
| html-safe-nonce | d2cf0d0155bd0cf8eeefcfda4f59c268fa11c30c8402d55c3e3aaa97ecede8bf |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4QTdDOjNBMjZEMDo5RDkxOEI6RDUxMjkzOjZBNjAxMThCIiwidmlzaXRvcl9pZCI6IjcwMzMyNDQ2NzgyNjQ3MjE4MDQiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 2b3d2ecbf136901668de27be8664d15e25d35e43f96a887079ba762a9f6650e0 |
| hovercard-subject-tag | pull_request:3250653123 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/modelcontextprotocol/python-sdk/pull/1998/files |
| twitter:image | https://avatars.githubusercontent.com/u/10529136?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/10529136?s=400&v=4 |
| og:image:alt | This changeset addresses issue #1250: after the MCP client refreshes its token and starts using the new one, server‑side tools still receive the old (expired) token from get_access_token(). CI fail... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 48cb2ed2304f8ae5a4a05d6327faf70466c4c0d9dcbf7b9df76251ca9c669a90 |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 862584018 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/python-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 862584018 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/python-sdk |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | cb0f10a384099e0765239a7cc220992cae52bdba |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width