The [official Rust
SDK](57fc428c57)
has come a long way since we first started our mcp client implementation
5 months ago and, today, it is much more complete than our own
stdio-only implementation.
This PR introduces a new config flag `experimental_use_rmcp_client`
which will use a new mcp client powered by the sdk instead of our own.
To keep this PR simple, I've only implemented the same stdio MCP
functionality that we had but will expand on it with future PRs.
---------
Co-authored-by: pakrym-oai <pakrym@openai.com>
135 lines
4.0 KiB
Rust
135 lines
4.0 KiB
Rust
use rmcp::ClientHandler;
|
|
use rmcp::RoleClient;
|
|
use rmcp::model::CancelledNotificationParam;
|
|
use rmcp::model::ClientInfo;
|
|
use rmcp::model::CreateElicitationRequestParam;
|
|
use rmcp::model::CreateElicitationResult;
|
|
use rmcp::model::ElicitationAction;
|
|
use rmcp::model::LoggingLevel;
|
|
use rmcp::model::LoggingMessageNotificationParam;
|
|
use rmcp::model::ProgressNotificationParam;
|
|
use rmcp::model::ResourceUpdatedNotificationParam;
|
|
use rmcp::service::NotificationContext;
|
|
use rmcp::service::RequestContext;
|
|
use tracing::debug;
|
|
use tracing::error;
|
|
use tracing::info;
|
|
use tracing::warn;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub(crate) struct LoggingClientHandler {
|
|
client_info: ClientInfo,
|
|
}
|
|
|
|
impl LoggingClientHandler {
|
|
pub(crate) fn new(client_info: ClientInfo) -> Self {
|
|
Self { client_info }
|
|
}
|
|
}
|
|
|
|
impl ClientHandler for LoggingClientHandler {
|
|
// TODO (CODEX-3571): support elicitations.
|
|
async fn create_elicitation(
|
|
&self,
|
|
request: CreateElicitationRequestParam,
|
|
_context: RequestContext<RoleClient>,
|
|
) -> Result<CreateElicitationResult, rmcp::ErrorData> {
|
|
info!(
|
|
"MCP server requested elicitation ({}). Elicitations are not supported yet. Declining.",
|
|
request.message
|
|
);
|
|
Ok(CreateElicitationResult {
|
|
action: ElicitationAction::Decline,
|
|
content: None,
|
|
})
|
|
}
|
|
|
|
async fn on_cancelled(
|
|
&self,
|
|
params: CancelledNotificationParam,
|
|
_context: NotificationContext<RoleClient>,
|
|
) {
|
|
info!(
|
|
"MCP server cancelled request (request_id: {}, reason: {:?})",
|
|
params.request_id, params.reason
|
|
);
|
|
}
|
|
|
|
async fn on_progress(
|
|
&self,
|
|
params: ProgressNotificationParam,
|
|
_context: NotificationContext<RoleClient>,
|
|
) {
|
|
info!(
|
|
"MCP server progress notification (token: {:?}, progress: {}, total: {:?}, message: {:?})",
|
|
params.progress_token, params.progress, params.total, params.message
|
|
);
|
|
}
|
|
|
|
async fn on_resource_updated(
|
|
&self,
|
|
params: ResourceUpdatedNotificationParam,
|
|
_context: NotificationContext<RoleClient>,
|
|
) {
|
|
info!("MCP server resource updated (uri: {})", params.uri);
|
|
}
|
|
|
|
async fn on_resource_list_changed(&self, _context: NotificationContext<RoleClient>) {
|
|
info!("MCP server resource list changed");
|
|
}
|
|
|
|
async fn on_tool_list_changed(&self, _context: NotificationContext<RoleClient>) {
|
|
info!("MCP server tool list changed");
|
|
}
|
|
|
|
async fn on_prompt_list_changed(&self, _context: NotificationContext<RoleClient>) {
|
|
info!("MCP server prompt list changed");
|
|
}
|
|
|
|
fn get_info(&self) -> ClientInfo {
|
|
self.client_info.clone()
|
|
}
|
|
|
|
async fn on_logging_message(
|
|
&self,
|
|
params: LoggingMessageNotificationParam,
|
|
_context: NotificationContext<RoleClient>,
|
|
) {
|
|
let LoggingMessageNotificationParam {
|
|
level,
|
|
logger,
|
|
data,
|
|
} = params;
|
|
let logger = logger.as_deref();
|
|
match level {
|
|
LoggingLevel::Emergency
|
|
| LoggingLevel::Alert
|
|
| LoggingLevel::Critical
|
|
| LoggingLevel::Error => {
|
|
error!(
|
|
"MCP server log message (level: {:?}, logger: {:?}, data: {})",
|
|
level, logger, data
|
|
);
|
|
}
|
|
LoggingLevel::Warning => {
|
|
warn!(
|
|
"MCP server log message (level: {:?}, logger: {:?}, data: {})",
|
|
level, logger, data
|
|
);
|
|
}
|
|
LoggingLevel::Notice | LoggingLevel::Info => {
|
|
info!(
|
|
"MCP server log message (level: {:?}, logger: {:?}, data: {})",
|
|
level, logger, data
|
|
);
|
|
}
|
|
LoggingLevel::Debug => {
|
|
debug!(
|
|
"MCP server log message (level: {:?}, logger: {:?}, data: {})",
|
|
level, logger, data
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|