File size: 2,191 Bytes
17f328f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | //! Routes device verification directly to the app, outside automated approval policy.
use super::*;
pub(super) async fn route(
router: ElicitationRequestRouter,
events: Option<Sender<Event>>,
authority: Arc<StdMutex<Option<ElicitationAuthority>>>,
server_name: String,
request: ElicitationRequest,
) -> Result<ElicitationResponse> {
let authority = authority
.lock()
.ok()
.and_then(|authority| authority.clone());
let plugin_service = authority.as_ref().is_some_and(|authority| {
authority
.config
.mcp_server_catalog
.server(&server_name)
.is_some_and(|server| {
server
.source()
.is_host_owned_apps(&server_name, server.config())
})
});
let Some(events) = events.filter(|_| plugin_service && !router.auto_deny()) else {
return Ok(ElicitationResponse {
action: ElicitationAction::Cancel,
content: None,
meta: None,
});
};
let id = format!(
"codex-mcp-elicitation-{}",
NEXT_ELICITATION_REQUEST_ID.fetch_add(1, Ordering::Relaxed)
);
let key = (server_name.clone(), RequestId::String(id.clone().into()));
let (response, receiver) = oneshot::channel();
router
.requests
.lock()
.map_err(|_| anyhow!("elicitation request router unavailable"))?
.insert(key.clone(), response);
let _pending = PendingElicitationRequest { router, key };
let _active = authority
.as_ref()
.and_then(|authority| authority.lifecycle.as_ref())
.map(ElicitationLifecycle::start);
events
.send(Event {
id: "mcp_elicitation_request".to_string(),
msg: EventMsg::ElicitationRequest(ElicitationRequestEvent {
turn_id: None,
server_name,
id: ProtocolRequestId::String(id),
request,
}),
})
.await
.context("failed to deliver user-verification request")?;
receiver
.await
.context("user-verification response channel closed")
}
|