fix: resolve clippy warnings across workspace (#1195)

* fix: resolve clippy warnings across workspace

* ci: also run clippy on rmcp with all features except local

--all-features enables the local feature, which cfg-gates out
tower.rs and most of the test suite, so the existing clippy step
never actually lints them.
This commit is contained in:
Dale Seo 2026-09-08 19:05:29 -04:00 • committed by GitHub
commit 6fa40536de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 277 additions and 289 deletions

View file

@ -100,10 +100,10 @@ impl ProgressAwareClient {
}
fn stop_tracking(&self) {
if let Ok(mut tracker_opt) = self.tracker.lock() {
if let Some(tracker) = tracker_opt.take() {
tracker.print_summary();
}
if let Ok(mut tracker_opt) = self.tracker.lock()
&& let Some(tracker) = tracker_opt.take()
{
tracker.print_summary();
}
}
}
@ -114,10 +114,10 @@ impl ClientHandler for ProgressAwareClient {
params: ProgressNotificationParam,
_context: NotificationContext<RoleClient>,
) {
if let Ok(tracker_opt) = self.tracker.lock() {
if let Some(tracker) = tracker_opt.as_ref() {
tracker.handle_progress(&params);
}
if let Ok(tracker_opt) = self.tracker.lock()
&& let Some(tracker) = tracker_opt.as_ref()
{
tracker.handle_progress(&params);
}
}
@ -182,10 +182,10 @@ async fn test_stdio_transport(records: u32) -> Result<()> {
.call_tool(CallToolRequestParams::new("stream_processor"))
.await?;
if let Some(content) = tool_result.content.first() {
if let Some(text) = content.as_text() {
tracing::info!("Processing completed: {}", text.text);
}
if let Some(content) = tool_result.content.first()
&& let Some(text) = content.as_text()
{
tracing::info!("Processing completed: {}", text.text);
}
service.cancel().await?;
@ -236,10 +236,10 @@ async fn test_http_transport(http_url: &str, records: u32) -> Result<()> {
.call_tool(CallToolRequestParams::new("stream_processor"))
.await?;
if let Some(content) = tool_result.content.first() {
if let Some(text) = content.as_text() {
tracing::info!("processing completed: {}", text.text);
}
if let Some(content) = tool_result.content.first()
&& let Some(text) = content.as_text()
{
tracing::info!("processing completed: {}", text.text);
}
client.cancel().await?;

View file

@ -1,3 +1,8 @@
#![expect(
deprecated,
reason = "This example demonstrates the deprecated MCP sampling API"
)]
use anyhow::Result;
use rmcp::{
ClientHandler, ServiceExt,

View file

@ -151,16 +151,16 @@ async fn fetch_and_validate_client_metadata(client_id_url: &str) -> Result<Value
}
// token_endpoint_auth_method MUST NOT be any shared secret based method
if let Some(method) = json.get("token_endpoint_auth_method") {
if let Some(method_str) = method.as_str() {
let forbidden = [
"client_secret_post",
"client_secret_basic",
"client_secret_jwt",
];
if forbidden.contains(&method_str) || method_str.starts_with("client_secret_") {
return Err("invalid_client: token_endpoint_auth_method MUST NOT be a shared secret based method".to_string());
}
if let Some(method) = json.get("token_endpoint_auth_method")
&& let Some(method_str) = method.as_str()
{
let forbidden = [
"client_secret_post",
"client_secret_basic",
"client_secret_jwt",
];
if forbidden.contains(&method_str) || method_str.starts_with("client_secret_") {
return Err("invalid_client: token_endpoint_auth_method MUST NOT be a shared secret based method".to_string());
}
}

View file

@ -75,13 +75,13 @@ impl ProgressDemo {
ctx.meta.get_key_value("progressToken")
);
let Some((_, progress_token)) = ctx.meta.get_key_value("progressToken") else {
return Err(McpError::internal_error(format!("No progress token"), None));
return Err(McpError::internal_error("No progress token", None));
};
let Ok(progress_token) = serde_json::from_value::<NumberOrString>(progress_token.clone())
else {
return Err(McpError::internal_error(
format!("Invalid format of the progress token"),
"Invalid format of the progress token",
None,
));
};

View file

@ -123,23 +123,23 @@ impl SqlQueryServer {
.collect();
// If no uppercase letters found, just use first letter
if first_chars.is_empty() && !candidate.is_empty() {
if let Some(first) = candidate.chars().next() {
first_chars.push(first.to_lowercase().next().unwrap_or('\0'));
}
if first_chars.is_empty()
&& let Some(first) = candidate.chars().next()
{
first_chars.push(first.to_lowercase().next().unwrap_or('\0'));
}
}
// Special case: if query is 2 chars and we only got 1 char, try matching first 2 letters
if query_chars.len() == 2 && first_chars.len() == 1 {
if let Some(first) = candidate.chars().nth(0) {
if let Some(second) = candidate.chars().nth(1) {
first_chars = vec![
first.to_lowercase().next().unwrap_or('\0'),
second.to_lowercase().next().unwrap_or('\0'),
];
}
}
if query_chars.len() == 2
&& first_chars.len() == 1
&& let Some(first) = candidate.chars().next()
&& let Some(second) = candidate.chars().nth(1)
{
first_chars = vec![
first.to_lowercase().next().unwrap_or('\0'),
second.to_lowercase().next().unwrap_or('\0'),
];
}
if query_chars.len() != first_chars.len() {
@ -193,7 +193,7 @@ impl SqlQueryServer {
}
}
#[prompt_router]
#[prompt_router(router = "prompt_router")]
impl SqlQueryServer {
#[prompt(name = "sql_query", description = "Smart SQL query builder")]
async fn sql_query(
@ -308,7 +308,7 @@ impl SqlQueryServer {
}
}
#[prompt_handler]
#[prompt_handler(router = self.prompt_router)]
impl ServerHandler for SqlQueryServer {
fn get_info(&self) -> ServerInfo {
ServerInfo::new(

View file

@ -69,10 +69,10 @@ impl McpOAuthStore {
redirect_uri: &str,
) -> Option<OAuthClientConfig> {
let clients = self.clients.read().await;
if let Some(client) = clients.get(client_id) {
if client.redirect_uri.contains(&redirect_uri.to_string()) {
return Some(client.clone());
}
if let Some(client) = clients.get(client_id)
&& client.redirect_uri == redirect_uri
{
return Some(client.clone());
}
None
}

View file

@ -97,7 +97,7 @@ struct ElicitationEnumFormServer {
tool_router: ToolRouter<ElicitationEnumFormServer>,
}
#[tool_router]
#[tool_router(router = tool_router)]
impl ElicitationEnumFormServer {
pub fn new() -> Self {
Self {
@ -153,7 +153,7 @@ impl ElicitationEnumFormServer {
}
}
#[tool_handler]
#[tool_handler(router = self.tool_router)]
impl ServerHandler for ElicitationEnumFormServer {
fn get_info(&self) -> ServerInfo {
ServerInfo::new(ServerCapabilities::builder().enable_tools().build())

View file

@ -64,7 +64,7 @@ impl Default for ElicitationServer {
}
}
#[tool_router]
#[tool_router(router = tool_router)]
impl ElicitationServer {
#[tool(description = "Greet user with name collection")]
async fn greet_user(
@ -145,7 +145,7 @@ impl ElicitationServer {
}
}
#[tool_handler]
#[tool_handler(router = self.tool_router)]
impl ServerHandler for ElicitationServer {
fn get_info(&self) -> ServerInfo {
ServerInfo::new(ServerCapabilities::builder().enable_tools().build())

View file

@ -112,7 +112,7 @@ impl Default for PromptServer {
}
}
#[prompt_router]
#[prompt_router(router = "prompt_router")]
impl PromptServer {
/// Simple greeting prompt without parameters
#[prompt(
@ -305,17 +305,17 @@ impl PromptServer {
];
// Add tried solutions if any
if let Some(tried) = args.tried_solutions {
if !tried.is_empty() {
messages.push(PromptMessage::new_text(
Role::User,
format!("I've already tried: {}", tried.join(", ")),
));
messages.push(PromptMessage::new_text(
Role::Assistant,
"I see you've already attempted some solutions. Let me suggest different approaches.",
));
}
if let Some(tried) = args.tried_solutions
&& !tried.is_empty()
{
messages.push(PromptMessage::new_text(
Role::User,
format!("I've already tried: {}", tried.join(", ")),
));
messages.push(PromptMessage::new_text(
Role::Assistant,
"I see you've already attempted some solutions. Let me suggest different approaches.",
));
}
messages.push(PromptMessage::new_text(
@ -361,7 +361,7 @@ impl PromptServer {
}
}
#[prompt_handler]
#[prompt_handler(router = self.prompt_router)]
impl ServerHandler for PromptServer {
fn get_info(&self) -> ServerInfo {
ServerInfo::new(ServerCapabilities::builder().enable_prompts().build()).with_instructions(

View file

@ -1,4 +1,7 @@
#![allow(deprecated)]
#![expect(
deprecated,
reason = "This example demonstrates the deprecated MCP sampling API"
)]
use std::sync::Arc;
use anyhow::Result;