99import java .util .Map ;
1010
1111import io .modelcontextprotocol .common .McpTransportContext ;
12+ import io .modelcontextprotocol .json .McpJsonDefaults ;
1213import io .modelcontextprotocol .modern .JsonRpc .JSONRPCNotification ;
1314import io .modelcontextprotocol .modern .JsonRpc .JSONRPCRequest ;
1415import io .modelcontextprotocol .modern .JsonRpc .JSONRPCResponse ;
1718import io .modelcontextprotocol .modern .McpSchema .MetaKeys ;
1819import io .modelcontextprotocol .modern .McpSchema .ReadResourceOutcome ;
1920import io .modelcontextprotocol .modern .McpSchema .ReadResourceRequest ;
21+ import io .modelcontextprotocol .modern .McpSchema .SubscriptionFilter ;
22+ import io .modelcontextprotocol .modern .McpSchema .SubscriptionsAcknowledgedParams ;
2023import io .modelcontextprotocol .modern .server .feature .McpAsyncResourceRepository ;
2124import io .modelcontextprotocol .modern .server .feature .McpChangeFeed ;
2225import io .modelcontextprotocol .modern .server .feature .McpChangePublisher ;
2326import io .modelcontextprotocol .modern .server .feature .ResourcesFeature ;
2427import io .modelcontextprotocol .modern .server .feature .ResourcesPage ;
2528import io .modelcontextprotocol .modern .server .feature .ServerChange ;
2629import io .modelcontextprotocol .modern .server .feature .ToolsFeature ;
27- import io .modelcontextprotocol .spec .json .gson .GsonMcpJsonMapper ;
2830import org .junit .jupiter .api .Test ;
2931import reactor .core .publisher .Mono ;
3032import reactor .test .StepVerifier ;
@@ -43,8 +45,7 @@ void ackIsFirstAndReflectsHonouredSubset() {
4345 McpChangeFeed feed = new McpChangeFeed ();
4446 McpServer server = McpServer .builder ()
4547 .serverInfo (SERVER_INFO )
46- .jsonMapper (new GsonMcpJsonMapper ())
47- .feature (ToolsFeature .ofAsync (emptyTools (), new GsonMcpJsonMapper (), PERMISSIVE_VALIDATOR , 0L ,
48+ .feature (ToolsFeature .ofAsync (emptyTools (), McpJsonDefaults .getMapper (), PERMISSIVE_VALIDATOR , 0L ,
4849 CacheScope .PRIVATE ))
4950 .subscriptions (feed )
5051 .build ();
@@ -62,13 +63,9 @@ void ackIsFirstAndReflectsHonouredSubset() {
6263 StepVerifier .create (invocation .messages ()).assertNext (msg -> {
6364 JSONRPCNotification ack = (JSONRPCNotification ) msg ;
6465 assertThat (ack .method ()).isEqualTo (McpSchema .METHOD_NOTIFICATION_SUBSCRIPTIONS_ACKNOWLEDGED );
65- @ SuppressWarnings ("unchecked" )
66- Map <String , Object > ackParams = (Map <String , Object >) new GsonMcpJsonMapper ().convertValue (ack .params (),
67- Map .class );
68- @ SuppressWarnings ("unchecked" )
69- Map <String , Object > notifications = (Map <String , Object >) ackParams .get ("notifications" );
70- assertThat (notifications .get ("toolsListChanged" )).isEqualTo (true );
71- assertThat (notifications .get ("promptsListChanged" )).isNull ();
66+ SubscriptionFilter notifications = ((SubscriptionsAcknowledgedParams ) ack .params ()).notifications ();
67+ assertThat (notifications .toolsListChanged ()).isTrue ();
68+ assertThat (notifications .promptsListChanged ()).isNull ();
7269 })
7370 .then (() -> feed .broadcast (new ServerChange .ToolsListChanged ()))
7471 .assertNext (msg -> assertThat (((JSONRPCNotification ) msg ).method ())
@@ -84,8 +81,7 @@ void unrequestedTypeIsNeverEmitted() {
8481 McpChangeFeed feed = new McpChangeFeed ();
8582 McpServer server = McpServer .builder ()
8683 .serverInfo (SERVER_INFO )
87- .jsonMapper (new GsonMcpJsonMapper ())
88- .feature (ToolsFeature .ofAsync (emptyTools (), new GsonMcpJsonMapper (), PERMISSIVE_VALIDATOR , 0L ,
84+ .feature (ToolsFeature .ofAsync (emptyTools (), McpJsonDefaults .getMapper (), PERMISSIVE_VALIDATOR , 0L ,
8985 CacheScope .PRIVATE ))
9086 .subscriptions (feed )
9187 .build ();
@@ -115,8 +111,7 @@ void subscriptionIdMatchesRequestId() {
115111 McpChangeFeed feed = new McpChangeFeed ();
116112 McpServer server = McpServer .builder ()
117113 .serverInfo (SERVER_INFO )
118- .jsonMapper (new GsonMcpJsonMapper ())
119- .feature (ToolsFeature .ofAsync (emptyTools (), new GsonMcpJsonMapper (), PERMISSIVE_VALIDATOR , 0L ,
114+ .feature (ToolsFeature .ofAsync (emptyTools (), McpJsonDefaults .getMapper (), PERMISSIVE_VALIDATOR , 0L ,
120115 CacheScope .PRIVATE ))
121116 .subscriptions (feed )
122117 .build ();
@@ -131,7 +126,7 @@ void subscriptionIdMatchesRequestId() {
131126
132127 StepVerifier .create (invocation .messages ()).assertNext (msg -> {
133128 JSONRPCNotification ack = (JSONRPCNotification ) msg ;
134- assertThat (subscriptionIdOf (ack )).isEqualTo (42L );
129+ assertThat (subscriptionIdOf (ack )).isEqualTo (42 );
135130 }).assertNext (msg -> assertThat (msg ).isInstanceOf (JSONRPCResponse .class )).verifyComplete ();
136131 }
137132
@@ -183,8 +178,8 @@ void resourceSubscribeIsAdvertisedAndHonouredWhenRepositorySupportsIt() {
183178
184179 assertThat (resourcesCapability (server )).containsEntry ("subscribe" , true ).containsEntry ("listChanged" , true );
185180 StepVerifier .create (listenToResource (server ).messages ())
186- .assertNext (msg -> assertThat (acknowledgedNotifications ((JSONRPCNotification ) msg ))
187- .containsEntry ( "resourceSubscriptions" , List . of ( " test://a") ))
181+ .assertNext (msg -> assertThat (acknowledgedNotifications ((JSONRPCNotification ) msg ). resourceSubscriptions () )
182+ .containsExactly ( " test://a" ))
188183 .then (server ::closeGracefully )
189184 .expectNextMatches (msg -> msg instanceof JSONRPCResponse )
190185 .verifyComplete ();
@@ -196,8 +191,7 @@ void resourceSubscribeIsNeitherAdvertisedNorHonouredByDefault() {
196191
197192 assertThat (resourcesCapability (server )).containsEntry ("subscribe" , false ).containsEntry ("listChanged" , true );
198193 StepVerifier .create (listenToResource (server ).messages ())
199- .assertNext (msg -> assertThat (acknowledgedNotifications ((JSONRPCNotification ) msg ))
200- .extractingByKey ("resourceSubscriptions" )
194+ .assertNext (msg -> assertThat (acknowledgedNotifications ((JSONRPCNotification ) msg ).resourceSubscriptions ())
201195 .isNull ())
202196 .then (server ::closeGracefully )
203197 .expectNextMatches (msg -> msg instanceof JSONRPCResponse )
@@ -231,8 +225,7 @@ public boolean supportsSubscribe() {
231225 };
232226 McpServer .Builder builder = McpServer .builder ()
233227 .serverInfo (SERVER_INFO )
234- .jsonMapper (new GsonMcpJsonMapper ())
235- .feature (ResourcesFeature .ofAsync (repository , new GsonMcpJsonMapper (), 0L , CacheScope .PRIVATE ));
228+ .feature (ResourcesFeature .ofAsync (repository , McpJsonDefaults .getMapper (), 0L , CacheScope .PRIVATE ));
236229 if (publisher != null ) {
237230 builder .subscriptions (publisher );
238231 }
@@ -255,19 +248,15 @@ private static McpTransportResponse.Streaming listenToResource(McpServer server)
255248 return (McpTransportResponse .Streaming ) server .handle (McpTransportContext .EMPTY , request ).block ();
256249 }
257250
258- @ SuppressWarnings ("unchecked" )
259- private static Map <String , Object > acknowledgedNotifications (JSONRPCNotification ack ) {
251+ private static SubscriptionFilter acknowledgedNotifications (JSONRPCNotification ack ) {
260252 assertThat (ack .method ()).isEqualTo (McpSchema .METHOD_NOTIFICATION_SUBSCRIPTIONS_ACKNOWLEDGED );
261- Map <String , Object > params = (Map <String , Object >) new GsonMcpJsonMapper ().convertValue (ack .params (),
262- Map .class );
263- return (Map <String , Object >) params .get ("notifications" );
253+ return ((SubscriptionsAcknowledgedParams ) ack .params ()).notifications ();
264254 }
265255
266256 private static McpServer toolsServer (McpChangePublisher publisher ) {
267257 return McpServer .builder ()
268258 .serverInfo (SERVER_INFO )
269- .jsonMapper (new GsonMcpJsonMapper ())
270- .feature (ToolsFeature .ofAsync (emptyTools (), new GsonMcpJsonMapper (), PERMISSIVE_VALIDATOR , 0L ,
259+ .feature (ToolsFeature .ofAsync (emptyTools (), McpJsonDefaults .getMapper (), PERMISSIVE_VALIDATOR , 0L ,
271260 CacheScope .PRIVATE ))
272261 .subscriptions (publisher )
273262 .build ();
@@ -281,12 +270,8 @@ private static McpTransportResponse.Streaming listen(McpServer server, int id) {
281270 return (McpTransportResponse .Streaming ) server .handle (McpTransportContext .EMPTY , request ).block ();
282271 }
283272
284- @ SuppressWarnings ("unchecked" )
285273 private static Object subscriptionIdOf (JSONRPCNotification notification ) {
286- Map <String , Object > params = (Map <String , Object >) new GsonMcpJsonMapper ().convertValue (notification .params (),
287- Map .class );
288- Map <String , Object > meta = (Map <String , Object >) params .get ("meta" );
289- return meta .get (MetaKeys .SUBSCRIPTION_ID );
274+ return ((SubscriptionsAcknowledgedParams ) notification .params ()).meta ().get (MetaKeys .SUBSCRIPTION_ID );
290275 }
291276
292277}
0 commit comments