mcp: handle list changed notifications

This commit is contained in:
2026-06-20 19:24:59 +09:00
parent d31b89072d
commit e33dee192c
4 changed files with 459 additions and 9 deletions
+32 -2
View File
@@ -1,8 +1,8 @@
use std::time::Duration;
use mcp::stdio::{
CallToolRequest, McpErrorKind, McpPhase, McpStdioClient, McpStdioLimits, McpStdioServerSpec,
McpToolListLimits,
CallToolRequest, McpErrorKind, McpListChangedKind, McpPhase, McpStdioClient, McpStdioLimits,
McpStdioServerSpec, McpToolListLimits,
};
fn mock_server(mode: &str) -> McpStdioServerSpec {
@@ -239,6 +239,36 @@ async fn shutdown_terminates_or_kills_uncooperative_server() {
assert!(shutdown.terminated || shutdown.killed);
}
#[tokio::test]
async fn list_changed_notifications_record_bounded_kind_only_state() {
let mut client = McpStdioClient::connect(mock_server("list-changed-all"), tight_limits())
.await
.expect("initialize succeeds");
tokio::time::sleep(Duration::from_millis(50)).await;
let snapshot = client.snapshot_list_changes().await;
assert_eq!(snapshot.server_name, "mock");
assert!(snapshot.contains(McpListChangedKind::Tools));
assert!(snapshot.contains(McpListChangedKind::Resources));
assert!(snapshot.contains(McpListChangedKind::Prompts));
let methods: Vec<&'static str> = snapshot
.kinds()
.map(McpListChangedKind::notification_method)
.collect();
assert_eq!(
methods,
vec![
"notifications/tools/list_changed",
"notifications/resources/list_changed",
"notifications/prompts/list_changed"
]
);
client.clear_list_changes().await;
assert!(client.snapshot_list_changes().await.is_empty());
client.shutdown().await.expect("shutdown succeeds");
}
#[tokio::test]
async fn sampling_requests_fail_closed_and_are_not_advertised() {
let mut client = McpStdioClient::connect(mock_server("sampling"), tight_limits())