Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use codex_core::mcp::auth::McpOAuthLoginSupport;
use codex_core::mcp::auth::oauth_login_support;
use codex_core::mcp::auth::resolve_oauth_scopes;
use codex_core::mcp::auth::should_retry_without_scopes;
use codex_rmcp_client::perform_oauth_login;
use codex_rmcp_client::perform_oauth_login_silent;
use tracing::warn;

use super::CodexMessageProcessor;
Expand Down Expand Up @@ -45,7 +45,7 @@ impl CodexMessageProcessor {
let notification_name = name.clone();

tokio::spawn(async move {
let first_attempt = perform_oauth_login(
let first_attempt = perform_oauth_login_silent(
&name,
&oauth_config.url,
store_mode,
Expand All @@ -60,7 +60,7 @@ impl CodexMessageProcessor {

let final_result = match first_attempt {
Err(err) if should_retry_without_scopes(&resolved_scopes, &err) => {
perform_oauth_login(
perform_oauth_login_silent(
&name,
&oauth_config.url,
store_mode,
Expand Down
1 change: 1 addition & 0 deletions codex-rs/rmcp-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub use perform_oauth_login::OAuthProviderError;
pub use perform_oauth_login::OauthLoginHandle;
pub use perform_oauth_login::perform_oauth_login;
pub use perform_oauth_login::perform_oauth_login_return_url;
pub use perform_oauth_login::perform_oauth_login_silent;
pub use rmcp::model::ElicitationAction;
pub use rmcp_client::Elicitation;
pub use rmcp_client::ElicitationResponse;
Expand Down
76 changes: 69 additions & 7 deletions codex-rs/rmcp-client/src/perform_oauth_login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,61 @@ pub async fn perform_oauth_login(
oauth_resource: Option<&str>,
callback_port: Option<u16>,
callback_url: Option<&str>,
) -> Result<()> {
perform_oauth_login_with_browser_output(
server_name,
server_url,
store_mode,
http_headers,
env_http_headers,
scopes,
oauth_resource,
callback_port,
callback_url,
/*emit_browser_url*/ true,
)
.await
}

#[allow(clippy::too_many_arguments)]
pub async fn perform_oauth_login_silent(
server_name: &str,
server_url: &str,
store_mode: OAuthCredentialsStoreMode,
http_headers: Option<HashMap<String, String>>,
env_http_headers: Option<HashMap<String, String>>,
scopes: &[String],
oauth_resource: Option<&str>,
callback_port: Option<u16>,
callback_url: Option<&str>,
) -> Result<()> {
perform_oauth_login_with_browser_output(
server_name,
server_url,
store_mode,
http_headers,
env_http_headers,
scopes,
oauth_resource,
callback_port,
callback_url,
/*emit_browser_url*/ false,
)
.await
}

#[allow(clippy::too_many_arguments)]
async fn perform_oauth_login_with_browser_output(
server_name: &str,
server_url: &str,
store_mode: OAuthCredentialsStoreMode,
http_headers: Option<HashMap<String, String>>,
env_http_headers: Option<HashMap<String, String>>,
scopes: &[String],
oauth_resource: Option<&str>,
callback_port: Option<u16>,
callback_url: Option<&str>,
emit_browser_url: bool,
) -> Result<()> {
let headers = OauthHeaders {
http_headers,
Expand All @@ -98,7 +153,7 @@ pub async fn perform_oauth_login(
/*timeout_secs*/ None,
)
.await?
.finish()
.finish(emit_browser_url)
.await
}

Expand Down Expand Up @@ -415,16 +470,23 @@ impl OauthLoginFlow {
self.auth_url.clone()
}

async fn finish(mut self) -> Result<()> {
async fn finish(mut self, emit_browser_url: bool) -> Result<()> {
if self.launch_browser {
let server_name = &self.server_name;
let auth_url = &self.auth_url;
println!(
"Authorize `{server_name}` by opening this URL in your browser:\n{auth_url}\n"
);
if emit_browser_url {
println!(
"Authorize `{server_name}` by opening this URL in your browser:\n{auth_url}\n"
);
}

if webbrowser::open(auth_url).is_err() {
println!("(Browser launch failed; please copy the URL above manually.)");
if !emit_browser_url {
eprintln!(
"Authorize `{server_name}` by opening this URL in your browser:\n{auth_url}\n"
);
}
eprintln!("(Browser launch failed; please copy the URL above manually.)");
}
}

Expand Down Expand Up @@ -477,7 +539,7 @@ impl OauthLoginFlow {
let (tx, rx) = oneshot::channel();

tokio::spawn(async move {
let result = self.finish().await;
let result = self.finish(/*emit_browser_url*/ false).await;

if let Err(err) = &result {
eprintln!(
Expand Down
Loading