Skip to content
Merged

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions codex-rs/app-server-protocol/schema/typescript/index.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions codex-rs/app-server-protocol/src/protocol/v2/mcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::shared::v2_enum_from_core;
use codex_protocol::approvals::ElicitationRequest as CoreElicitationRequest;
use codex_protocol::items::McpToolCallError as CoreMcpToolCallError;
use codex_protocol::mcp::CallToolResult as CoreMcpCallToolResult;
use codex_protocol::mcp::McpServerInfo;
use codex_protocol::mcp::Resource as McpResource;
pub use codex_protocol::mcp::ResourceContent as McpResourceContent;
use codex_protocol::mcp::ResourceTemplate as McpResourceTemplate;
Expand Down Expand Up @@ -53,6 +54,7 @@ pub enum McpServerStatusDetail {
#[ts(export_to = "v2/")]
pub struct McpServerStatus {
pub name: String,
pub server_info: Option<McpServerInfo>,
Comment thread
gpeal marked this conversation as resolved.
pub tools: std::collections::HashMap<String, McpTool>,
pub resources: Vec<McpResource>,
pub resource_templates: Vec<McpResourceTemplate>,
Expand Down
75 changes: 75 additions & 0 deletions codex-rs/app-server-protocol/src/protocol/v2/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use codex_protocol::items::TurnItem;
use codex_protocol::items::UserMessageItem;
use codex_protocol::items::WebSearchItem;
use codex_protocol::mcp::CallToolResult;
use codex_protocol::mcp::McpServerInfo;
use codex_protocol::memory_citation::MemoryCitation as CoreMemoryCitation;
use codex_protocol::memory_citation::MemoryCitationEntry as CoreMemoryCitationEntry;
use codex_protocol::models::AdditionalPermissionProfile as CoreAdditionalPermissionProfile;
Expand Down Expand Up @@ -1924,6 +1925,80 @@ fn mcp_server_elicitation_response_serializes_nullable_content() {
);
}

#[test]
fn mcp_server_status_serializes_absent_server_info_as_null() {
let response = ListMcpServerStatusResponse {
data: vec![McpServerStatus {
name: "not-ready".to_string(),
server_info: None,
tools: HashMap::new(),
resources: Vec::new(),
resource_templates: Vec::new(),
auth_status: McpAuthStatus::Unsupported,
}],
next_cursor: None,
};

assert_eq!(
serde_json::to_value(response).expect("response should serialize"),
json!({
"data": [{
"name": "not-ready",
"serverInfo": null,
"tools": {},
"resources": [],
"resourceTemplates": [],
"authStatus": "unsupported",
}],
"nextCursor": null,
})
);
}

#[test]
fn mcp_server_status_serializes_absent_server_info_metadata_as_null() {
let response = ListMcpServerStatusResponse {
data: vec![McpServerStatus {
name: "initialized".to_string(),
server_info: Some(McpServerInfo {
name: "lookup-server".to_string(),
title: None,
version: "1.0.0".to_string(),
description: None,
icons: None,
website_url: None,
}),
tools: HashMap::new(),
resources: Vec::new(),
resource_templates: Vec::new(),
auth_status: McpAuthStatus::Unsupported,
}],
next_cursor: None,
};

assert_eq!(
serde_json::to_value(response).expect("response should serialize"),
json!({
"data": [{
"name": "initialized",
"serverInfo": {
"name": "lookup-server",
"title": null,
"version": "1.0.0",
"description": null,
"icons": null,
"websiteUrl": null,
},
"tools": {},
"resources": [],
"resourceTemplates": [],
"authStatus": "unsupported",
}],
"nextCursor": null,
})
);
}

#[test]
fn sandbox_policy_round_trips_workspace_write_access() {
let v2_policy = SandboxPolicy::WorkspaceWrite {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ Example with notification opt-out:
- `mcpServer/oauth/login` — start an OAuth login for a configured MCP server; returns an `authorization_url` and later emits `mcpServer/oauthLogin/completed` once the browser flow finishes.
- `tool/requestUserInput` — prompt the user with 1–3 short questions for a tool call and return their answers (experimental).
- `config/mcpServer/reload` — reload MCP server config from disk and queue a refresh for loaded threads (applied on each thread's next active turn); returns `{}`. Use this after editing `config.toml` without restarting the server.
- `mcpServerStatus/list` — enumerate configured MCP servers with their tools and auth status, plus resources/resource templates for `full` detail; supports optional `threadId` and cursor+limit pagination. If `threadId` is omitted, the server reads from the latest global config directly. If `detail` is omitted, the server defaults to `full`.
- `mcpServerStatus/list` — enumerate configured MCP servers with their tools, auth status, server info, plus resources/resource templates for `full` detail; supports optional `threadId` and cursor+limit pagination. If `threadId` is omitted, the server reads from the latest global config directly. If `detail` is omitted, the server defaults to `full`.
- `mcpServer/resource/read` — read a resource from a configured MCP server by optional `threadId`, `server`, and `uri`, returning text/blob resource `contents`. If `threadId` is omitted, the server reads from the latest MCP config directly.
- `mcpServer/tool/call` — call a tool on a thread's configured MCP server by `threadId`, `server`, `tool`, optional `arguments`, and optional `_meta`, returning the MCP tool result.
- `windowsSandbox/setupStart` — start Windows sandbox setup for the selected mode (`elevated` or `unelevated`); accepts an optional absolute `cwd` to target setup for a specific workspace, returns `{ started: true }` immediately, and later emits `windowsSandbox/setupCompleted`.
Expand Down
2 changes: 2 additions & 0 deletions codex-rs/app-server/src/request_processors/mcp_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ impl McpRequestProcessor {
.await;

let McpServerStatusSnapshot {
server_infos,
tools_by_server,
resources,
resource_templates,
Expand Down Expand Up @@ -315,6 +316,7 @@ impl McpRequestProcessor {
.iter()
.map(|name| McpServerStatus {
name: name.clone(),
server_info: server_infos.get(name).cloned(),
tools: tools_by_server.get(name).cloned().unwrap_or_default(),
resources: resources.get(name).cloned().unwrap_or_default(),
resource_templates: resource_templates.get(name).cloned().unwrap_or_default(),
Expand Down
12 changes: 11 additions & 1 deletion codex-rs/app-server/tests/suite/v2/mcp_server_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use codex_core::config::set_project_trust_level;
use codex_protocol::config_types::TrustLevel;
use pretty_assertions::assert_eq;
use rmcp::handler::server::ServerHandler;
use rmcp::model::Implementation;
use rmcp::model::JsonObject;
use rmcp::model::ListResourceTemplatesResult;
use rmcp::model::ListResourcesResult;
Expand Down Expand Up @@ -99,6 +100,13 @@ url = "{mcp_server_url}/mcp"
.map(|tool| tool.name.as_str()),
Some("look-up.raw")
);
assert_eq!(
status
.server_info
.as_ref()
.and_then(|info| info.title.as_deref()),
Some("Lookup Server")
);

mcp_server_handle.abort();
let _ = mcp_server_handle.await;
Expand Down Expand Up @@ -205,7 +213,9 @@ struct McpStatusServer {

impl ServerHandler for McpStatusServer {
fn get_info(&self) -> ServerInfo {
ServerInfo::new(ServerCapabilities::builder().enable_tools().build())
ServerInfo::new(ServerCapabilities::builder().enable_tools().build()).with_server_info(
Implementation::new("lookup-server", "1.0.0").with_title("Lookup Server"),
)
}

async fn list_tools(
Expand Down
Loading
Loading