File tree Expand file tree Collapse file tree
packages/server/src/server
test/integration/test/server Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -47,6 +47,12 @@ import { getCompleter, isCompletable } from './completable.js';
4747import type { ServerOptions } from './server.js' ;
4848import { Server } from './server.js' ;
4949
50+ const DEFAULT_DEBOUNCED_NOTIFICATION_METHODS = [
51+ 'notifications/resources/list_changed' ,
52+ 'notifications/tools/list_changed' ,
53+ 'notifications/prompts/list_changed'
54+ ] ;
55+
5056/**
5157 * High-level MCP server that provides a simpler API for working with resources, tools, and prompts.
5258 * For advanced usage (like sending notifications or setting custom request handlers), use the underlying
@@ -75,7 +81,12 @@ export class McpServer {
7581 private _experimental ?: { tasks : ExperimentalMcpServerTasks } ;
7682
7783 constructor ( serverInfo : Implementation , options ?: ServerOptions ) {
78- this . server = new Server ( serverInfo , options ) ;
84+ this . server = new Server ( serverInfo , {
85+ ...options ,
86+ debouncedNotificationMethods : [
87+ ...new Set ( [ ...DEFAULT_DEBOUNCED_NOTIFICATION_METHODS , ...( options ?. debouncedNotificationMethods ?? [ ] ) ] )
88+ ]
89+ } ) ;
7990 }
8091
8192 /**
Original file line number Diff line number Diff line change @@ -809,6 +809,38 @@ describe('Zod v4', () => {
809809 ] ) ;
810810 } ) ;
811811
812+ test ( 'should debounce synchronous tool list changed notifications' , async ( ) => {
813+ const mcpServer = new McpServer ( {
814+ name : 'test server' ,
815+ version : '1.0'
816+ } ) ;
817+ const notifications : Notification [ ] = [ ] ;
818+ const client = new Client ( {
819+ name : 'test client' ,
820+ version : '1.0'
821+ } ) ;
822+ client . fallbackNotificationHandler = async notification => {
823+ notifications . push ( notification ) ;
824+ } ;
825+
826+ mcpServer . registerTool ( 'initial' , { } , async ( ) => ( {
827+ content : [ { type : 'text' , text : 'Initial response' } ]
828+ } ) ) ;
829+
830+ const [ clientTransport , serverTransport ] = InMemoryTransport . createLinkedPair ( ) ;
831+ await Promise . all ( [ client . connect ( clientTransport ) , mcpServer . connect ( serverTransport ) ] ) ;
832+
833+ for ( let i = 0 ; i < 20 ; i ++ ) {
834+ mcpServer . registerTool ( `tool-${ i } ` , { } , async ( ) => ( {
835+ content : [ { type : 'text' , text : `Tool ${ i } response` } ]
836+ } ) ) ;
837+ }
838+
839+ await new Promise ( process . nextTick ) ;
840+
841+ expect ( notifications ) . toMatchObject ( [ { method : 'notifications/tools/list_changed' } ] ) ;
842+ } ) ;
843+
812844 /***
813845 * Test: listChanged capability should default to true when not specified
814846 */
You can’t perform that action at this time.
0 commit comments