Add MCP OAuth callback URL command

This commit is contained in:
Steven Lee
2026-06-17 17:38:10 +00:00
parent 33d50234a8
commit 18b3cfcb60
6 changed files with 508 additions and 30 deletions
+52
View File
@@ -3,6 +3,8 @@ use std::path::Path;
use anyhow::Result;
use codex_config::types::McpServerTransportConfig;
use codex_core::config::load_global_mcp_servers;
use codex_rmcp_client::resolve_mcp_oauth_callback_url;
use predicates::prelude::PredicateBooleanExt;
use predicates::str::contains;
use pretty_assertions::assert_eq;
use tempfile::TempDir;
@@ -234,6 +236,56 @@ async fn add_streamable_http_with_oauth_options() -> Result<()> {
Ok(())
}
#[tokio::test]
async fn add_streamable_http_prints_configured_oauth_callback_url() -> Result<()> {
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join("config.toml"),
r#"mcp_oauth_callback_url = "https://callbacks.example.com/oauth/callback"
"#,
)?;
let expected = resolve_mcp_oauth_callback_url(
"https://example.com/mcp",
/*callback_port*/ None,
Some("https://callbacks.example.com/oauth/callback"),
)?;
let mut add_cmd = codex_command(codex_home.path())?;
add_cmd
.args([
"mcp",
"add",
"oauth-server",
"--url",
"https://example.com/mcp",
])
.assert()
.success()
.stdout(contains(format!("OAuth callback URL: {expected}")));
Ok(())
}
#[tokio::test]
async fn add_streamable_http_does_not_print_ephemeral_callback_port_hint() -> Result<()> {
let codex_home = TempDir::new()?;
let mut add_cmd = codex_command(codex_home.path())?;
add_cmd
.args([
"mcp",
"add",
"oauth-server",
"--url",
"https://example.com/mcp",
])
.assert()
.success()
.stdout(contains("OAuth callback URL: unavailable").not());
Ok(())
}
#[tokio::test]
async fn add_streamable_http_rejects_removed_flag() -> Result<()> {
let codex_home = TempDir::new()?;
+65
View File
@@ -0,0 +1,65 @@
use std::path::Path;
use anyhow::Result;
use codex_rmcp_client::resolve_mcp_oauth_callback_url;
use pretty_assertions::assert_eq;
use tempfile::TempDir;
fn codex_command(codex_home: &Path) -> Result<assert_cmd::Command> {
let mut cmd = assert_cmd::Command::new(codex_utils_cargo_bin::cargo_bin("codex")?);
cmd.env("CODEX_HOME", codex_home);
Ok(cmd)
}
#[test]
fn callback_url_prints_configured_final_url() -> Result<()> {
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join("config.toml"),
r#"mcp_oauth_callback_url = "https://callbacks.example.com/oauth/callback"
[mcp_servers.github]
url = "https://example.com/mcp"
"#,
)?;
let expected = resolve_mcp_oauth_callback_url(
"https://example.com/mcp",
/*callback_port*/ None,
Some("https://callbacks.example.com/oauth/callback"),
)?;
let mut cmd = codex_command(codex_home.path())?;
let output = cmd.args(["mcp", "callback-url", "github"]).output()?;
assert!(output.status.success());
assert_eq!(String::from_utf8(output.stdout)?, format!("{expected}\n"));
assert_eq!(String::from_utf8(output.stderr)?, "");
assert!(!codex_home.path().join(".credentials.json").exists());
Ok(())
}
#[test]
fn callback_url_errors_when_default_port_is_ephemeral() -> Result<()> {
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join("config.toml"),
r#"[mcp_servers.github]
url = "https://example.com/mcp"
"#,
)?;
let mut cmd = codex_command(codex_home.path())?;
let output = cmd.args(["mcp", "callback-url", "github"]).output()?;
assert!(!output.status.success());
assert_eq!(String::from_utf8(output.stdout)?, "");
assert!(
String::from_utf8(output.stderr)?
.contains("set `mcp_oauth_callback_port` or `mcp_oauth_callback_url`")
);
assert!(!codex_home.path().join(".credentials.json").exists());
Ok(())
}