mirror of
https://github.com/openai/codex.git
synced 2026-11-11 21:10:39 +00:00
Add explicit app and account targets to MCP resource reads (#47248)
## What changed
Allow `mcpServer/resource/read` to specify `target: {connectorId, linkId}` for direct hosted app reads without tool discovery, when supported by the backend. Require an explicit `linkId`: a string selects an account, while `null` requests no-auth access subject to backend policy.
Restrict direct targets to `codex_apps` and reject empty connector IDs, empty link IDs, and synthetic link IDs. Preserve originating app/account scope when `originCallId` and `threadId` are supplied, and retain discovery when `target` is omitted.
Update protocol schemas and TypeScript and Python models, preserving required-but-nullable `linkId` semantics in Python code generation.
## Testing
Extend resource-read tests to check target metadata with and without a thread, including explicit no-auth targets and omitted targets. Add Python model tests for string and null `linkId` values and rejection of a missing `linkId`.
GitOrigin-RevId: 8cf5595fbdd937193aeb529901fc95299f6e18ad
This commit is contained in:
@@ -450,21 +450,41 @@ impl McpRequestProcessor {
|
||||
server,
|
||||
uri,
|
||||
connector_id,
|
||||
target,
|
||||
} = params;
|
||||
let mut resource_params = ReadResourceRequestParams::new(uri);
|
||||
let mut meta = serde_json::Map::new();
|
||||
if let Some(connector_id) = connector_id {
|
||||
resource_params.meta = Some(
|
||||
serde_json::Map::from_iter([(
|
||||
"x-codex-turn-metadata".to_string(),
|
||||
serde_json::json!({
|
||||
"mcp_request_meta": {
|
||||
"selected_connector_ids": [connector_id],
|
||||
},
|
||||
}),
|
||||
)])
|
||||
.into(),
|
||||
meta.insert(
|
||||
"x-codex-turn-metadata".to_string(),
|
||||
serde_json::json!({
|
||||
"mcp_request_meta": {"selected_connector_ids": [connector_id]},
|
||||
}),
|
||||
);
|
||||
}
|
||||
if origin_call_id.is_none()
|
||||
&& let Some(target) = target
|
||||
{
|
||||
if server != codex_mcp::CODEX_APPS_MCP_SERVER_NAME
|
||||
|| target.connector_id.trim().is_empty()
|
||||
|| target
|
||||
.link_id
|
||||
.as_ref()
|
||||
.is_some_and(|id| id.trim().is_empty() || id.starts_with("synthetic_link::"))
|
||||
{
|
||||
return Err(invalid_request(
|
||||
"target requires codex_apps, a connectorId, and a real linkId or null",
|
||||
));
|
||||
}
|
||||
meta.insert(
|
||||
"connector_id".to_string(),
|
||||
serde_json::json!(target.connector_id),
|
||||
);
|
||||
meta.insert("link_id".to_string(), serde_json::json!(target.link_id));
|
||||
}
|
||||
if !meta.is_empty() {
|
||||
resource_params.meta = Some(meta.into());
|
||||
}
|
||||
|
||||
if let Some(thread_id) = thread_id {
|
||||
let (_, thread) = self.load_thread(&thread_id).await?;
|
||||
|
||||
Reference in New Issue
Block a user