feat: per-request OAuth token injection with mid-session refresh for HTTP MCP servers
Replace the spawn-time static Authorization header for OAuth-managed HTTP MCP servers with McpOAuthClient, a custom implementation of rmcp's StreamableHttpClient trait that resolves the bearer token on every request via load_or_refresh_mcp_token. Tokens that expire mid-session now refresh transparently instead of failing tool calls until restart. On a 401 for an injected token, the wrapper force-refreshes (identity- aware: a still-unexpired copy of the rejected token is not trusted) and retries exactly once, matching Claude Code / official SDK semantics. Both *_with_max_sse_event_size trait methods are overridden to preserve the inner client's SSE size enforcement, and the inner reqwest client mirrors rmcp's default (pool_max_idle_per_host(0), no redirects). SSE, stdio, and static-header HTTP paths are unchanged; startup warning semantics (McpAuthRequired reasons) are preserved. Verified live: mid-session backdated token refreshed transparently during an active atlassian session.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
use crate::mcp::oauth::McpTokenStatus;
|
||||
use crate::mcp::{
|
||||
ConnectedServer, JsonField, McpAuthReason, McpAuthRequired, McpServer, McpTransportType,
|
||||
is_auth_required_error, oauth, spawn_mcp_server,
|
||||
ConnectedServer, JsonField, McpAuthRequired, McpServer, McpTransportType,
|
||||
is_auth_required_error, resolve_http_auth, spawn_mcp_server,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
@@ -103,13 +102,8 @@ impl McpFactory {
|
||||
return Ok(existing);
|
||||
}
|
||||
|
||||
let token_status = if spec.is_remote() {
|
||||
oauth::load_or_refresh_mcp_token(name).await
|
||||
} else {
|
||||
McpTokenStatus::NotAuthenticated
|
||||
};
|
||||
let auth_reason = McpAuthReason::from_token_status(&token_status);
|
||||
let handle = spawn_mcp_server(spec, log_path, token_status.into_token())
|
||||
let (auth, auth_reason) = resolve_http_auth(name, spec).await;
|
||||
let handle = spawn_mcp_server(spec, log_path, auth)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if is_auth_required_error(&e) {
|
||||
|
||||
Reference in New Issue
Block a user