mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Support ui visibility meta for tools (#24700)
## Summary Adds support for the same ui.visibility metadata as resources [spec](https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/draft/apps.mdx#resource-discovery)
This commit is contained in:
committed by
GitHub
Unverified
parent
2264fdd4a2
commit
577ec03bf8
@@ -3,6 +3,7 @@ use std::collections::HashSet;
|
||||
use codex_features::Feature;
|
||||
use codex_mcp::CODEX_APPS_MCP_SERVER_NAME;
|
||||
use codex_mcp::ToolInfo as McpToolInfo;
|
||||
use codex_mcp::tool_is_model_visible;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::connectors;
|
||||
@@ -51,7 +52,9 @@ pub(crate) fn build_mcp_tool_exposure(
|
||||
fn filter_non_codex_apps_mcp_tools_only(mcp_tools: &[McpToolInfo]) -> Vec<McpToolInfo> {
|
||||
mcp_tools
|
||||
.iter()
|
||||
.filter(|tool| tool.server_name != CODEX_APPS_MCP_SERVER_NAME)
|
||||
.filter(|tool| {
|
||||
tool.server_name != CODEX_APPS_MCP_SERVER_NAME && tool_is_model_visible(tool)
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
@@ -72,6 +75,9 @@ fn filter_codex_apps_mcp_tools(
|
||||
if tool.server_name != CODEX_APPS_MCP_SERVER_NAME {
|
||||
return false;
|
||||
}
|
||||
if !tool_is_model_visible(tool) {
|
||||
return false;
|
||||
}
|
||||
let Some(connector_id) = tool.connector_id.as_deref() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ use codex_mcp::ToolInfo;
|
||||
use codex_tools::ToolName;
|
||||
use pretty_assertions::assert_eq;
|
||||
use rmcp::model::JsonObject;
|
||||
use rmcp::model::Meta;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
use super::*;
|
||||
@@ -80,6 +81,16 @@ fn tool_names(tools: &[ToolInfo]) -> HashSet<ToolName> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn with_visibility(mut tool: ToolInfo, visibility: &[&str]) -> ToolInfo {
|
||||
tool.tool.meta = Some(Meta(
|
||||
serde_json::json!({ "ui": { "visibility": visibility } })
|
||||
.as_object()
|
||||
.expect("metadata object")
|
||||
.clone(),
|
||||
));
|
||||
tool
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn directly_exposes_small_effective_tool_sets() {
|
||||
let config = test_config().await;
|
||||
@@ -93,6 +104,84 @@ async fn directly_exposes_small_effective_tool_sets() {
|
||||
assert!(exposure.deferred_tools.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn excludes_tools_hidden_from_model_exposure() {
|
||||
let config = test_config().await;
|
||||
let visible_tool = make_mcp_tool(
|
||||
"rmcp",
|
||||
"visible_tool",
|
||||
"mcp__rmcp",
|
||||
"visible_tool",
|
||||
/*connector_id*/ None,
|
||||
/*connector_name*/ None,
|
||||
);
|
||||
let hidden_tool = with_visibility(
|
||||
make_mcp_tool(
|
||||
"rmcp",
|
||||
"hidden_tool",
|
||||
"mcp__rmcp",
|
||||
"hidden_tool",
|
||||
/*connector_id*/ None,
|
||||
/*connector_name*/ None,
|
||||
),
|
||||
&["app"],
|
||||
);
|
||||
let empty_visibility_tool = with_visibility(
|
||||
make_mcp_tool(
|
||||
"rmcp",
|
||||
"empty_visibility_tool",
|
||||
"mcp__rmcp",
|
||||
"empty_visibility_tool",
|
||||
/*connector_id*/ None,
|
||||
/*connector_name*/ None,
|
||||
),
|
||||
&[],
|
||||
);
|
||||
let visible_app_tool = with_visibility(
|
||||
make_mcp_tool(
|
||||
CODEX_APPS_MCP_SERVER_NAME,
|
||||
"calendar_read",
|
||||
"mcp__codex_apps__calendar",
|
||||
"read",
|
||||
Some("calendar"),
|
||||
Some("Calendar"),
|
||||
),
|
||||
&["app", "model"],
|
||||
);
|
||||
let hidden_app_tool = with_visibility(
|
||||
make_mcp_tool(
|
||||
CODEX_APPS_MCP_SERVER_NAME,
|
||||
"calendar_open",
|
||||
"mcp__codex_apps__calendar",
|
||||
"open",
|
||||
Some("calendar"),
|
||||
Some("Calendar"),
|
||||
),
|
||||
&["app"],
|
||||
);
|
||||
let mcp_tools = vec![
|
||||
visible_tool.clone(),
|
||||
hidden_tool,
|
||||
empty_visibility_tool,
|
||||
visible_app_tool.clone(),
|
||||
hidden_app_tool,
|
||||
];
|
||||
let connectors = vec![make_connector("calendar", "Calendar")];
|
||||
|
||||
let exposure = build_mcp_tool_exposure(
|
||||
&mcp_tools,
|
||||
Some(connectors.as_slice()),
|
||||
&config,
|
||||
/*search_tool_enabled*/ false,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
tool_names(&exposure.direct_tools),
|
||||
tool_names(&[visible_tool, visible_app_tool])
|
||||
);
|
||||
assert!(exposure.deferred_tools.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn searches_large_effective_tool_sets() {
|
||||
let config = test_config().await;
|
||||
|
||||
Reference in New Issue
Block a user