Rename Codex Apps MCP fixtures

This commit is contained in:
Meta Vens 2026-05-14 05:24:54 +01:00
commit 034ea8dfaa
10 changed files with 103 additions and 95 deletions

View file

@ -947,6 +947,12 @@ MCP names. MCP itself remains valid JSON-RPC protocol edge machinery; the cut is
only the deleted Codex Apps product identity leaking into tests and prompt
snapshots.
The test-support type names were then cleaned to match: `apps_test_server.rs`
became `mcp_test_server.rs`, `AppsTestServer` became `McpTestServer`, and
app-server MCP resource/elicitation/tool tests now use demo/resource MCP server
names instead of `Apps*` wrappers. This is naming purification only, not a
protocol rewrite.
That husk has now been cut from `codex-core`. The root core crate no longer
exports `plugins`, no longer depends on `codex-core-plugins` or `codex-plugin`,
and the core plugin manager / marketplace add-remove-sync modules and tests

Binary file not shown.

View file

@ -306,6 +306,9 @@ current_status:
constants/snapshot handling are gone, and old `codex_apps` MCP fixtures now
use neutral MCP server names so tests do not launder deleted Codex Apps
branding back into the harness.
The follow-up test-support rename moved `apps_test_server.rs` to
`mcp_test_server.rs` and renamed `Apps*` MCP fixture wrappers to neutral
`Mcp*` / demo-resource names without changing MCP behavior.
surfaces; those are compatibility stumps to classify next, not keeper
auth/model-spine machinery.
next_action: Continue starving coordinator/runtime execution and operator surfaces off app-server JSON-RPC and out of `codex_message_processor.rs`; keep the vestigial Codex organ narrowed to subscription auth/model transport.

View file

@ -55,7 +55,7 @@ const TEST_RESOURCE_TEXT: &str = "Resource body from the MCP server.";
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn mcp_resource_read_returns_resource_contents() -> Result<()> {
let responses_server = responses::start_mock_server().await;
let (apps_server_url, apps_server_handle) = start_resource_apps_mcp_server().await?;
let (mcp_server_url, mcp_server_handle) = start_resource_demo_mcp_server().await?;
let codex_home = TempDir::new()?;
let responses_server_uri = responses_server.uri();
@ -68,11 +68,11 @@ approval_policy = "untrusted"
sandbox_mode = "read-only"
model_provider = "mock_provider"
chatgpt_base_url = "{apps_server_url}"
chatgpt_base_url = "{mcp_server_url}"
mcp_oauth_credentials_store = "file"
[features]
apps = true
[model_providers.mock_provider]
name = "Mock provider for test"
@ -126,25 +126,25 @@ stream_max_retries = 0
expected_resource_read_response()
);
apps_server_handle.abort();
let _ = apps_server_handle.await;
mcp_server_handle.abort();
let _ = mcp_server_handle.await;
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn mcp_resource_read_returns_resource_contents_without_thread() -> Result<()> {
let (apps_server_url, apps_server_handle) = start_resource_apps_mcp_server().await?;
let (mcp_server_url, mcp_server_handle) = start_resource_demo_mcp_server().await?;
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join("config.toml"),
format!(
r#"
chatgpt_base_url = "{apps_server_url}"
chatgpt_base_url = "{mcp_server_url}"
mcp_oauth_credentials_store = "file"
[features]
apps = true
"#
),
)?;
@ -178,8 +178,8 @@ apps = true
expected_resource_read_response()
);
apps_server_handle.abort();
let _ = apps_server_handle.await;
mcp_server_handle.abort();
let _ = mcp_server_handle.await;
Ok(())
}
@ -244,22 +244,22 @@ async fn mcp_resource_read_returns_error_for_unknown_thread() -> Result<()> {
Ok(())
}
async fn start_resource_apps_mcp_server() -> Result<(String, JoinHandle<()>)> {
async fn start_resource_demo_mcp_server() -> Result<(String, JoinHandle<()>)> {
let listener = TcpListener::bind("127.0.0.1:0").await?;
let addr = listener.local_addr()?;
let apps_server_url = format!("http://{addr}");
let mcp_server_url = format!("http://{addr}");
let mcp_service = StreamableHttpService::new(
move || Ok(ResourceAppsMcpServer),
move || Ok(ResourceDemoMcpServer),
Arc::new(LocalSessionManager::default()),
StreamableHttpServerConfig::default(),
);
let router = Router::new().nest_service("/api/mcp/demo", mcp_service);
let apps_server_handle = tokio::spawn(async move {
let mcp_server_handle = tokio::spawn(async move {
let _ = axum::serve(listener, router).await;
});
Ok((apps_server_url, apps_server_handle))
Ok((mcp_server_url, mcp_server_handle))
}
fn expected_resource_read_response() -> McpResourceReadResponse {
@ -282,9 +282,9 @@ fn expected_resource_read_response() -> McpResourceReadResponse {
}
#[derive(Clone, Default)]
struct ResourceAppsMcpServer;
struct ResourceDemoMcpServer;
impl ServerHandler for ResourceAppsMcpServer {
impl ServerHandler for ResourceDemoMcpServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
protocol_version: ProtocolVersion::V_2025_06_18,

View file

@ -103,10 +103,10 @@ async fn mcp_server_elicitation_round_trip() -> Result<()> {
)
.await;
let (apps_server_url, apps_server_handle) = start_apps_server().await?;
let (mcp_server_url, mcp_server_handle) = start_demo_mcp_server().await?;
let codex_home = TempDir::new()?;
write_config_toml(codex_home.path(), &responses_server.uri(), &apps_server_url)?;
write_config_toml(codex_home.path(), &responses_server.uri(), &mcp_server_url)?;
write_chatgpt_auth(
codex_home.path(),
ChatGptAuthFixture::new("chatgpt-token")
@ -292,21 +292,21 @@ async fn mcp_server_elicitation_round_trip() -> Result<()> {
}])
);
apps_server_handle.abort();
let _ = apps_server_handle.await;
mcp_server_handle.abort();
let _ = mcp_server_handle.await;
Ok(())
}
#[derive(Clone)]
struct AppsServerState {
struct McpServerState {
expected_bearer: String,
expected_account_id: String,
}
#[derive(Clone, Default)]
struct ElicitationAppsMcpServer;
struct ElicitationDemoMcpServer;
impl ServerHandler for ElicitationAppsMcpServer {
impl ServerHandler for ElicitationDemoMcpServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
protocol_version: rmcp::model::ProtocolVersion::V_2025_06_18,
@ -385,8 +385,8 @@ impl ServerHandler for ElicitationAppsMcpServer {
}
}
async fn start_apps_server() -> Result<(String, JoinHandle<()>)> {
let state = Arc::new(AppsServerState {
async fn start_demo_mcp_server() -> Result<(String, JoinHandle<()>)> {
let state = Arc::new(McpServerState {
expected_bearer: "Bearer chatgpt-token".to_string(),
expected_account_id: "account-123".to_string(),
});
@ -395,7 +395,7 @@ async fn start_apps_server() -> Result<(String, JoinHandle<()>)> {
let addr = listener.local_addr()?;
let mcp_service = StreamableHttpService::new(
move || Ok(ElicitationAppsMcpServer),
move || Ok(ElicitationDemoMcpServer),
Arc::new(LocalSessionManager::default()),
StreamableHttpServerConfig::default(),
);
@ -417,7 +417,7 @@ async fn start_apps_server() -> Result<(String, JoinHandle<()>)> {
}
async fn list_directory_connectors(
State(state): State<Arc<AppsServerState>>,
State(state): State<Arc<McpServerState>>,
headers: HeaderMap,
uri: Uri,
) -> Result<Json<serde_json::Value>, StatusCode> {
@ -461,7 +461,7 @@ async fn list_directory_connectors(
fn write_config_toml(
codex_home: &std::path::Path,
responses_server_uri: &str,
apps_server_url: &str,
mcp_server_url: &str,
) -> std::io::Result<()> {
std::fs::write(
codex_home.join("config.toml"),
@ -472,11 +472,11 @@ approval_policy = "untrusted"
sandbox_mode = "read-only"
model_provider = "mock_provider"
chatgpt_base_url = "{apps_server_url}"
chatgpt_base_url = "{mcp_server_url}"
mcp_oauth_credentials_store = "file"
[features]
apps = true
[model_providers.mock_provider]
name = "Mock provider for test"

View file

@ -162,9 +162,9 @@ async fn mcp_server_tool_call_returns_error_for_unknown_thread() -> Result<()> {
}
#[derive(Clone, Default)]
struct ToolAppsMcpServer;
struct ToolDemoMcpServer;
impl ServerHandler for ToolAppsMcpServer {
impl ServerHandler for ToolDemoMcpServer {
fn get_info(&self) -> ServerInfo {
ServerInfo {
capabilities: ServerCapabilities::builder().enable_tools().build(),
@ -238,7 +238,7 @@ async fn start_mcp_server() -> Result<(String, JoinHandle<()>)> {
let listener = TcpListener::bind("127.0.0.1:0").await?;
let addr = listener.local_addr()?;
let mcp_service = StreamableHttpService::new(
|| Ok(ToolAppsMcpServer),
|| Ok(ToolDemoMcpServer),
Arc::new(LocalSessionManager::default()),
StreamableHttpServerConfig::default(),
);

View file

@ -18,7 +18,7 @@ pub use codex_utils_absolute_path::test_support::PathExt;
use regex_lite::Regex;
use std::path::PathBuf;
pub mod apps_test_server;
pub mod mcp_test_server;
pub mod context_snapshot;
pub mod process;
pub mod responses;

View file

@ -16,23 +16,23 @@ const DISCOVERABLE_CALENDAR_ID: &str = "connector_2128aebfecb84f64a069897515042a
const DISCOVERABLE_GMAIL_ID: &str = "connector_68df038e0ba48191908c8434991bbac2";
const CONNECTOR_DESCRIPTION: &str = "Plan events and manage your calendar.";
const PROTOCOL_VERSION: &str = "2025-11-25";
const SERVER_NAME: &str = "codex-apps-test";
const SERVER_NAME: &str = "demo-mcp-test";
const SERVER_VERSION: &str = "1.0.0";
const SEARCHABLE_TOOL_COUNT: usize = 100;
pub const CALENDAR_CREATE_EVENT_RESOURCE_URI: &str =
"connector://calendar/tools/calendar_create_event";
pub const CALENDAR_CREATE_EVENT_MCP_APP_RESOURCE_URI: &str =
pub const CALENDAR_CREATE_EVENT_MCP_RESOURCE_URI: &str =
"ui://widget/calendar-create-event.html";
const CALENDAR_LIST_EVENTS_RESOURCE_URI: &str = "connector://calendar/tools/calendar_list_events";
pub const DOCUMENT_EXTRACT_TEXT_RESOURCE_URI: &str =
"connector://calendar/tools/calendar_extract_text";
#[derive(Clone)]
pub struct AppsTestServer {
pub chatgpt_base_url: String,
pub struct McpTestServer {
pub mcp_base_url: String,
}
impl AppsTestServer {
impl McpTestServer {
pub async fn mount(server: &MockServer) -> Result<Self> {
Self::mount_with_connector_name(server, CONNECTOR_NAME).await
}
@ -48,7 +48,7 @@ impl AppsTestServer {
)
.await;
Ok(Self {
chatgpt_base_url: server.uri(),
mcp_base_url: server.uri(),
})
}
@ -66,7 +66,7 @@ impl AppsTestServer {
)
.await;
Ok(Self {
chatgpt_base_url: server.uri(),
mcp_base_url: server.uri(),
})
}
}
@ -122,7 +122,7 @@ async fn mount_streamable_http_json_rpc(
) {
Mock::given(method("POST"))
.and(path_regex("^/api/mcp/demo/?$"))
.respond_with(CodexAppsJsonRpcResponder {
.respond_with(DemoMcpJsonRpcResponder {
connector_name,
connector_description,
searchable,
@ -131,13 +131,13 @@ async fn mount_streamable_http_json_rpc(
.await;
}
struct CodexAppsJsonRpcResponder {
struct DemoMcpJsonRpcResponder {
connector_name: String,
connector_description: String,
searchable: bool,
}
impl Respond for CodexAppsJsonRpcResponder {
impl Respond for DemoMcpJsonRpcResponder {
fn respond(&self, request: &Request) -> ResponseTemplate {
let body: Value = match serde_json::from_slice(&request.body) {
Ok(body) => body,
@ -208,7 +208,7 @@ impl Respond for CodexAppsJsonRpcResponder {
"connector_id": CONNECTOR_ID,
"connector_name": self.connector_name.clone(),
"connector_description": self.connector_description.clone(),
"openai/outputTemplate": CALENDAR_CREATE_EVENT_MCP_APP_RESOURCE_URI,
"openai/outputTemplate": CALENDAR_CREATE_EVENT_MCP_RESOURCE_URI,
"_mcp_bridge": {
"resource_uri": CALENDAR_CREATE_EVENT_RESOURCE_URI,
"contains_mcp_source": true,

View file

@ -16,8 +16,8 @@ use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::Op;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::user_input::UserInput;
use core_test_support::apps_test_server::AppsTestServer;
use core_test_support::assert_regex_match;
use core_test_support::mcp_test_server::McpTestServer;
use core_test_support::responses;
use core_test_support::responses::ResponseMock;
use core_test_support::responses::ResponsesRequest;
@ -356,7 +356,7 @@ async fn code_mode_only_guides_all_tools_search_and_calls_deferred_app_tools() -
skip_if_no_network!(Ok(()));
let server = responses::start_mock_server().await;
let apps_server = AppsTestServer::mount_searchable(&server).await?;
let mcp_server = McpTestServer::mount_searchable(&server).await?;
let resp_mock = responses::mount_sse_once(
&server,
sse(vec![
@ -393,7 +393,7 @@ if (!tool) {
)
.await;
let apps_base_url = apps_server.chatgpt_base_url.clone();
let mcp_base_url = mcp_server.mcp_base_url.clone();
let mut builder = test_codex()
.with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing())
.with_config(move |config| {
@ -416,7 +416,7 @@ if (!tool) {
.iter_mut()
.find(|model| model.slug == "gpt-5.4")
.expect("gpt-5.4 exists in bundled models.json");
config.chatgpt_base_url = apps_base_url;
config.chatgpt_base_url = mcp_base_url;
config.model = Some("gpt-5.4".to_string());
model.supports_search_tool = true;
config.model_catalog = Some(model_catalog);

View file

@ -18,9 +18,9 @@ use codex_protocol::protocol::McpInvocation;
use codex_protocol::protocol::Op;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::user_input::UserInput;
use core_test_support::apps_test_server::AppsTestServer;
use core_test_support::apps_test_server::CALENDAR_CREATE_EVENT_MCP_APP_RESOURCE_URI;
use core_test_support::apps_test_server::CALENDAR_CREATE_EVENT_RESOURCE_URI;
use core_test_support::mcp_test_server::CALENDAR_CREATE_EVENT_MCP_RESOURCE_URI;
use core_test_support::mcp_test_server::CALENDAR_CREATE_EVENT_RESOURCE_URI;
use core_test_support::mcp_test_server::McpTestServer;
use core_test_support::responses::ResponsesRequest;
use core_test_support::responses::ev_assistant_message;
use core_test_support::responses::ev_completed;
@ -111,27 +111,27 @@ fn configure_search_capable_model(config: &mut Config) {
config.model_catalog = Some(model_catalog);
}
fn configure_search_capable_apps(config: &mut Config, apps_base_url: &str) {
config.chatgpt_base_url = apps_base_url.to_string();
fn configure_search_capable_mcp(config: &mut Config, mcp_base_url: &str) {
config.chatgpt_base_url = mcp_base_url.to_string();
configure_search_capable_model(config);
}
fn configure_apps_without_tool_search(config: &mut Config, apps_base_url: &str) {
configure_search_capable_apps(config, apps_base_url);
fn configure_mcp_without_tool_search(config: &mut Config, mcp_base_url: &str) {
configure_search_capable_mcp(config, mcp_base_url);
config
.features
.disable(Feature::ToolSearch)
.expect("test config should allow feature update");
}
fn configure_apps(config: &mut Config, apps_base_url: &str) {
configure_search_capable_apps(config, apps_base_url);
fn configure_mcp(config: &mut Config, mcp_base_url: &str) {
configure_search_capable_mcp(config, mcp_base_url);
}
fn configured_builder(apps_base_url: String) -> TestCodexBuilder {
fn configured_builder(mcp_base_url: String) -> TestCodexBuilder {
test_codex()
.with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing())
.with_config(move |config| configure_apps(config, apps_base_url.as_str()))
.with_config(move |config| configure_mcp(config, mcp_base_url.as_str()))
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
@ -139,7 +139,7 @@ async fn search_tool_enabled_by_default_adds_tool_search() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount_searchable(&server).await?;
let mcp_server = McpTestServer::mount_searchable(&server).await?;
let mock = mount_sse_once(
&server,
sse(vec![
@ -150,7 +150,7 @@ async fn search_tool_enabled_by_default_adds_tool_search() -> Result<()> {
)
.await;
let mut builder = configured_builder(apps_server.chatgpt_base_url.clone());
let mut builder = configured_builder(mcp_server.mcp_base_url.clone());
let test = builder.build(&server).await?;
test.submit_turn_with_policies(
@ -197,7 +197,7 @@ async fn always_defer_feature_hides_small_app_tool_sets() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount(&server).await?;
let mcp_server = McpTestServer::mount(&server).await?;
let mock = mount_sse_once(
&server,
sse(vec![
@ -208,13 +208,12 @@ async fn always_defer_feature_hides_small_app_tool_sets() -> Result<()> {
)
.await;
let mut builder =
configured_builder(apps_server.chatgpt_base_url.clone()).with_config(|config| {
config
.features
.enable(Feature::ToolSearchAlwaysDeferMcpTools)
.expect("test config should allow feature update");
});
let mut builder = configured_builder(mcp_server.mcp_base_url.clone()).with_config(|config| {
config
.features
.enable(Feature::ToolSearchAlwaysDeferMcpTools)
.expect("test config should allow feature update");
});
let test = builder.build(&server).await?;
test.submit_turn_with_policies(
@ -239,11 +238,11 @@ async fn always_defer_feature_hides_small_app_tool_sets() -> Result<()> {
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn tool_search_disabled_exposes_apps_tools_directly() -> Result<()> {
async fn tool_search_disabled_exposes_mcp_tools_directly() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount_searchable(&server).await?;
let mcp_server = McpTestServer::mount_searchable(&server).await?;
let mock = mount_sse_once(
&server,
sse(vec![
@ -257,7 +256,7 @@ async fn tool_search_disabled_exposes_apps_tools_directly() -> Result<()> {
let mut builder = test_codex()
.with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing())
.with_config(move |config| {
configure_apps_without_tool_search(config, apps_server.chatgpt_base_url.as_str())
configure_mcp_without_tool_search(config, mcp_server.mcp_base_url.as_str())
});
let test = builder.build(&server).await?;
@ -291,7 +290,7 @@ async fn search_tool_is_hidden_for_api_key_auth() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount(&server).await?;
let mcp_server = McpTestServer::mount(&server).await?;
let mock = mount_sse_once(
&server,
sse(vec![
@ -304,7 +303,7 @@ async fn search_tool_is_hidden_for_api_key_auth() -> Result<()> {
let mut builder = test_codex()
.with_auth(CodexAuth::from_api_key("Test API Key"))
.with_config(move |config| configure_apps(config, apps_server.chatgpt_base_url.as_str()));
.with_config(move |config| configure_mcp(config, mcp_server.mcp_base_url.as_str()));
let test = builder.build(&server).await?;
test.submit_turn_with_policies(
@ -329,7 +328,7 @@ async fn search_tool_adds_discovery_instructions_to_tool_description() -> Result
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount_searchable(&server).await?;
let mcp_server = McpTestServer::mount_searchable(&server).await?;
let mock = mount_sse_once(
&server,
sse(vec![
@ -340,7 +339,7 @@ async fn search_tool_adds_discovery_instructions_to_tool_description() -> Result
)
.await;
let mut builder = configured_builder(apps_server.chatgpt_base_url.clone());
let mut builder = configured_builder(mcp_server.mcp_base_url.clone());
let test = builder.build(&server).await?;
test.submit_turn_with_policies(
@ -367,11 +366,11 @@ async fn search_tool_adds_discovery_instructions_to_tool_description() -> Result
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn search_tool_hides_apps_tools_without_search() -> Result<()> {
async fn search_tool_hides_mcp_tools_without_search() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount_searchable(&server).await?;
let mcp_server = McpTestServer::mount_searchable(&server).await?;
let mock = mount_sse_once(
&server,
sse(vec![
@ -382,7 +381,7 @@ async fn search_tool_hides_apps_tools_without_search() -> Result<()> {
)
.await;
let mut builder = configured_builder(apps_server.chatgpt_base_url.clone());
let mut builder = configured_builder(mcp_server.mcp_base_url.clone());
let test = builder.build(&server).await?;
test.submit_turn_with_policies(
@ -407,7 +406,7 @@ async fn explicit_mcp_mentions_expose_mcp_tools_without_search() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount(&server).await?;
let mcp_server = McpTestServer::mount(&server).await?;
let mock = mount_sse_once(
&server,
sse(vec![
@ -418,7 +417,7 @@ async fn explicit_mcp_mentions_expose_mcp_tools_without_search() -> Result<()> {
)
.await;
let mut builder = configured_builder(apps_server.chatgpt_base_url.clone());
let mut builder = configured_builder(mcp_server.mcp_base_url.clone());
let test = builder.build(&server).await?;
test.submit_turn_with_policies(
@ -452,7 +451,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount_searchable(&server).await?;
let mcp_server = McpTestServer::mount_searchable(&server).await?;
let call_id = "tool-search-1";
let mock = mount_sse_sequence(
&server,
@ -494,7 +493,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
)
.await;
let mut builder = configured_builder(apps_server.chatgpt_base_url.clone());
let mut builder = configured_builder(mcp_server.mcp_base_url.clone());
let test = builder.build(&server).await?;
test.codex
.submit(Op::UserInput {
@ -518,7 +517,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
assert_eq!(begin.call_id, "calendar-call-1");
assert_eq!(
begin.mcp_app_resource_uri.as_deref(),
Some(CALENDAR_CREATE_EVENT_MCP_APP_RESOURCE_URI)
Some(CALENDAR_CREATE_EVENT_MCP_RESOURCE_URI)
);
let EventMsg::McpToolCallEnd(end) = wait_for_event(&test.codex, |event| {
@ -531,7 +530,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
assert_eq!(end.call_id, "calendar-call-1");
assert_eq!(
end.mcp_app_resource_uri.as_deref(),
Some(CALENDAR_CREATE_EVENT_MCP_APP_RESOURCE_URI)
Some(CALENDAR_CREATE_EVENT_MCP_RESOURCE_URI)
);
assert_eq!(
end.invocation,
@ -566,7 +565,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
let requests = mock.requests();
assert_eq!(requests.len(), 3);
let apps_tool_call = server
let mcp_tool_call = server
.received_requests()
.await
.unwrap_or_default()
@ -577,10 +576,10 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
&& body.get("method").and_then(Value::as_str) == Some("tools/call"))
.then_some(body)
})
.expect("apps tools/call request should be recorded");
.expect("MCP tools/call request should be recorded");
assert_eq!(
apps_tool_call.pointer("/params/_meta/_mcp_bridge"),
mcp_tool_call.pointer("/params/_meta/_mcp_bridge"),
Some(&json!({
"resource_uri": CALENDAR_CREATE_EVENT_RESOURCE_URI,
"contains_mcp_source": true,
@ -588,15 +587,15 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
}))
);
assert_eq!(
apps_tool_call.pointer("/params/_meta/x-codex-turn-metadata/session_id"),
mcp_tool_call.pointer("/params/_meta/x-codex-turn-metadata/session_id"),
Some(&json!(test.session_configured.session_id.to_string()))
);
assert!(
apps_tool_call
mcp_tool_call
.pointer("/params/_meta/x-codex-turn-metadata/turn_id")
.and_then(Value::as_str)
.is_some_and(|turn_id| !turn_id.is_empty()),
"apps tools/call should include turn metadata turn_id: {apps_tool_call:?}"
"MCP tools/call should include turn metadata turn_id: {mcp_tool_call:?}"
);
let first_request_tools = tool_names(&requests[0].body_json());
@ -878,7 +877,7 @@ async fn tool_search_indexes_only_enabled_non_app_mcp_tools() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount_searchable(&server).await?;
let mcp_server = McpTestServer::mount_searchable(&server).await?;
let echo_call_id = "tool-search-echo";
let image_call_id = "tool-search-image";
let mock = mount_sse_sequence(
@ -913,7 +912,7 @@ async fn tool_search_indexes_only_enabled_non_app_mcp_tools() -> Result<()> {
let rmcp_test_server_bin = stdio_server_bin()?;
let mut builder =
configured_builder(apps_server.chatgpt_base_url.clone()).with_config(move |config| {
configured_builder(mcp_server.mcp_base_url.clone()).with_config(move |config| {
let mut servers = config.mcp_servers.get().clone();
servers.insert(
"rmcp".to_string(),