Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/rmcp/src/handler/server/router/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ where
}

pub fn list_all(&self) -> Vec<crate::model::Prompt> {
self.map.values().map(|item| item.attr.clone()).collect()
let mut prompts: Vec<_> = self.map.values().map(|item| item.attr.clone()).collect();
prompts.sort_by(|a, b| a.name.cmp(&b.name));
prompts
}
}

Expand Down
4 changes: 3 additions & 1 deletion crates/rmcp/src/handler/server/router/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,9 @@ where
}

pub fn list_all(&self) -> Vec<crate::model::Tool> {
self.map.values().map(|item| item.attr.clone()).collect()
let mut tools: Vec<_> = self.map.values().map(|item| item.attr.clone()).collect();
tools.sort_by(|a, b| a.name.cmp(&b.name));
tools
}

/// Get a tool definition by name.
Expand Down
36 changes: 36 additions & 0 deletions crates/rmcp/tests/test_prompt_routers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,39 @@ fn test_prompt_router() {
let prompts = test_prompt_router.list_all();
assert_eq!(prompts.len(), 4);
}

#[test]
fn test_prompt_router_list_all_is_sorted() {
let router = TestHandler::<()>::test_router()
.with_route(rmcp::handler::server::router::prompt::PromptRoute::new_dyn(
async_function_prompt_attr(),
|mut context| {
Box::pin(async move {
use rmcp::handler::server::{
common::FromContextPart, prompt::IntoGetPromptResult,
};
let params = Parameters::<Request>::from_context_part(&mut context)?;
let result = async_function(params).await;
result.into_get_prompt_result()
})
},
))
.with_route(rmcp::handler::server::router::prompt::PromptRoute::new_dyn(
async_function2_prompt_attr(),
|context| {
Box::pin(async move {
use rmcp::handler::server::prompt::IntoGetPromptResult;
let result = async_function2(context.server).await;
result.into_get_prompt_result()
})
},
));
let prompts = router.list_all();
let names: Vec<&str> = prompts.iter().map(|p| p.name.as_ref()).collect();
let mut sorted = names.clone();
sorted.sort();
assert_eq!(
names, sorted,
"list_all() should return prompts sorted alphabetically by name"
);
}
17 changes: 17 additions & 0 deletions crates/rmcp/tests/test_tool_routers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,20 @@ where
H: CallToolHandler<S, A>,
{
}

#[test]
fn test_tool_router_list_all_is_sorted() {
let router: ToolRouter<TestHandler<()>> = ToolRouter::<TestHandler<()>>::new()
.with_route((async_function_tool_attr(), async_function))
.with_route((async_function2_tool_attr(), async_function2))
+ TestHandler::<()>::test_router_1()
+ TestHandler::<()>::test_router_2();
let tools = router.list_all();
let names: Vec<&str> = tools.iter().map(|t| t.name.as_ref()).collect();
let mut sorted = names.clone();
sorted.sort();
assert_eq!(
names, sorted,
"list_all() should return tools sorted alphabetically by name"
);
}