context_server: Add OAuth support to HTTP transport#44638
context_server: Add OAuth support to HTTP transport#44638erenatas wants to merge 2 commits intozed-industries:mainfrom
Conversation
|
We require contributors to sign our Contributor License Agreement, and we don't have @erenatas on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
@cla-bot check |
|
We require contributors to sign our Contributor License Agreement, and we don't have @erenatas on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
@cla-bot check |
|
We require contributors to sign our Contributor License Agreement, and we don't have @erenatas on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
33c59e8 to
f824271
Compare
9f2d708 to
2136852
Compare
|
It seems the tool call timeout setting not working with http transport support. |
Can you open an issue for this? It sounds like a different issue compared to what this PR tries to address to. |
|
@erenatas Thanks for the contribution! I haven’t had a chance to dig into this deeply yet, but here are some initial thoughts:
|
Thanks a lot for comments! Would you prefer getting them done in this PR or as a follow up considering the size of the change? I can work on it this week. |
|
@erenatas Awesome! We could split this, but I don’t want to merge before addressing points 3 and 4. |
This change implements RFC 6749 OAuth 2.0 Authorization Code flow with PKCE ([RFC 7636](https://oauth.net/2/pkce/)) and enables OAuth support including re-authentication and session handling for Streamable HTTP transport MCP servers. 1. Client sends request without Authorization header 2. Server returns 401 with WWW-Authenticate header containing: - resource_metadata URL for OAuth discovery - requested scopes 3. Client discovers OAuth endpoints via .well-known/oauth-authorization-server 4. Client performs dynamic client registration (if supported) 5. Client opens browser for user authorization with PKCE challenge 6. Local callback server receives authorization code 7. Client exchanges code for access_token + refresh_token 8. Tokens are persisted to ~/.config/zed/oauth_tokens.json 9. Original request is retried with Bearer token 1. OAuthManager.access_token() returns cached token 2. If token is expired/expiring (within 30s), refresh is attempted 3. If refresh fails, request proceeds without auth → 401 triggers re-login 1. Request with expired token returns 401 + WWW-Authenticate 2. handle_unauthorized() parses header and calls OAuthManager 3. OAuthManager performs full login flow (browser auth) 4. Session is proactively re-initialized (new Mcp-Session-Id) 5. Original request is retried with new token - OAuth is ONLY triggered by 401 response, never proactively - Manual `Authorization: Bearer <token>` headers bypass OAuth entirely - Token refresh happens transparently before requests - Session re-initialization after re-auth avoids 422 errors - Tokens are scoped per server URL for multi-server support Signed-off-by: Eren Atas <eren_atas@hotmail.com>
2136852 to
7634561
Compare
|
|
Hey @agu-z can you approve workflow so I can fix if any check fails? |
|
Done! Excited about your changes. Sorry, I couldn't review today, I was too busy. I'll take a look tomorrow. |
No worries :) Thanks for having a look! |
|
@erenatas I tried this with a few servers earlier today, and none of them were able to connect. I also think the UI needs significant work. While reviewing the code, I realized there are several architectural choices I’d approach differently, so I started working on an alternative implementation and I’m already fairly far along. Given that, I don’t think it makes sense to continue with this PR. Thanks for the effort regardless, and sorry it didn’t pan out. |
No problem. I would be glad If you have some time to provide feedback regarding what would be your architectural choices instead of my PR, so I would learn. Thanks for looking into it nonetheless. Also would be happy if you share the PR you are working on, would be happy to examine. Thanks in advance! |
|
Would it not have been better to guide the contributor in this case on what a better approach would look like? Something to consider, as it may lead to recurring contributions. |
|
Hey @agu-z , it's been a while. Did you have any chance to look into this? If not, if you can provide me your feedback about how this work should be handled (or what I should not do), I can update it. |

This change implements RFC 6749 OAuth 2.0 Authorization Code flow with PKCE
(RFC 7636) and enables OAuth support including
re-authentication and session handling for Streamable HTTP transport MCP servers.
Authentication Flow
Initial Connection (no token)
Subsequent Requests (cached token)
Re-authentication (token expired during session)
Notes
Authorization: Bearer <token>headers bypass OAuth entirelyImplementation Details
Typed Error System
ContextServerErrorenum with variants:AuthRequired,Connection,Protocol,OtherContextServerStatus::Errorto use typedContextServerErrortransport_error()in Client, Protocol, and ContextServerExplicit Authentication Flow
authenticate()method for explicit user-triggered authneeds_authentication()to check if auth is requiredlogout()to clear tokens and disable serverallow_auto_reauthenticationsetting for opt-in silent token refreshUI Changes on agent_ui
Settings
allow_auto_reauthenticationtoContextServerSettingsTested against a real OAuth enabled MCP server
Closes #43162
Release Notes: