@@ -54,14 +54,8 @@ class Registry
5454
5555 private bool $ discoveredElementsLoaded = false ;
5656
57- /** @var callable|null */
58- private $ notifyToolsChanged = null ;
57+ private bool $ notificationsEnabled = true ;
5958
60- /** @var callable|null */
61- private $ notifyResourcesChanged = null ;
62-
63- /** @var callable|null */
64- private $ notifyPromptsChanged = null ;
6559
6660 public function __construct (
6761 LoggerInterface $ logger ,
@@ -73,7 +67,6 @@ public function __construct(
7367 $ this ->clientStateManager = $ clientStateManager ;
7468
7569 $ this ->initializeCollections ();
76- $ this ->initializeDefaultNotifiers ();
7770
7871 if ($ this ->cache ) {
7972 $ this ->loadDiscoveredElementsFromCache ();
@@ -115,54 +108,93 @@ private function initializeCollections(): void
115108 $ this ->manualTemplateUris = [];
116109 }
117110
118- private function initializeDefaultNotifiers (): void
111+ public function enableNotifications (): void
119112 {
120- $ this ->notifyToolsChanged = function () {
121- if ($ this ->clientStateManager ) {
122- $ notification = Notification::make ('notifications/tools/list_changed ' );
123- $ framedMessage = json_encode ($ notification ->toArray (), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n" ;
124- if ($ framedMessage !== false ) {
125- $ this ->clientStateManager ->queueMessageForAll ($ framedMessage );
126- }
127- }
128- };
129-
130- $ this ->notifyResourcesChanged = function () {
131- if ($ this ->clientStateManager ) {
132- $ notification = Notification::make ('notifications/resources/list_changed ' );
133- $ framedMessage = json_encode ($ notification ->toArray (), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n" ;
134- if ($ framedMessage !== false ) {
135- $ this ->clientStateManager ->queueMessageForAll ($ framedMessage );
136- }
137- }
138- };
139-
140- $ this ->notifyPromptsChanged = function () {
141- if ($ this ->clientStateManager ) {
142- $ notification = Notification::make ('notifications/prompts/list_changed ' );
143- $ framedMessage = json_encode ($ notification ->toArray (), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n" ;
144- if ($ framedMessage !== false ) {
145- $ this ->clientStateManager ->queueMessageForAll ($ framedMessage );
146- }
147- }
148- };
113+ $ this ->notificationsEnabled = true ;
149114 }
150115
151- public function setToolsChangedNotifier (? callable $ notifier ): void
116+ public function disableNotifications ( ): void
152117 {
153- $ this ->notifyToolsChanged = $ notifier ;
118+ $ this ->notificationsEnabled = false ;
154119 }
155120
156- public function setResourcesChangedNotifier (? callable $ notifier ): void
121+ public function notifyToolsChanged ( ): void
157122 {
158- $ this ->notifyResourcesChanged = $ notifier ;
123+ if (!$ this ->notificationsEnabled || !$ this ->clientStateManager ) {
124+ return ;
125+ }
126+ $ notification = Notification::make ('notifications/tools/list_changed ' );
127+
128+ $ framedMessage = json_encode ($ notification , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n" ;
129+ if ($ framedMessage === false || $ framedMessage === "\n" ) {
130+ $ this ->logger ->error ('Failed to encode notification for queuing. ' , ['method ' => $ notification ->method ]);
131+ return ;
132+ }
133+ $ this ->clientStateManager ->queueMessageForAll ($ framedMessage );
159134 }
160135
161- public function setPromptsChangedNotifier (? callable $ notifier ): void
136+ public function notifyResourcesChanged ( ): void
162137 {
163- $ this ->notifyPromptsChanged = $ notifier ;
138+ if (!$ this ->notificationsEnabled || !$ this ->clientStateManager ) {
139+ return ;
140+ }
141+ $ notification = Notification::make ('notifications/resources/list_changed ' );
142+
143+ $ framedMessage = json_encode ($ notification , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n" ;
144+ if ($ framedMessage === false || $ framedMessage === "\n" ) {
145+ $ this ->logger ->error ('Failed to encode notification for queuing. ' , ['method ' => $ notification ->method ]);
146+ return ;
147+ }
148+ $ this ->clientStateManager ->queueMessageForAll ($ framedMessage );
164149 }
165150
151+ public function notifyPromptsChanged (): void
152+ {
153+ if (!$ this ->notificationsEnabled || !$ this ->clientStateManager ) {
154+ return ;
155+ }
156+ $ notification = Notification::make ('notifications/prompts/list_changed ' );
157+
158+ $ framedMessage = json_encode ($ notification , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n" ;
159+ if ($ framedMessage === false || $ framedMessage === "\n" ) {
160+ $ this ->logger ->error ('Failed to encode notification for queuing. ' , ['method ' => $ notification ->method ]);
161+ return ;
162+ }
163+ $ this ->clientStateManager ->queueMessageForAll ($ framedMessage );
164+ }
165+
166+ public function notifyResourceUpdated (string $ uri ): void
167+ {
168+ if (!$ this ->notificationsEnabled || !$ this ->clientStateManager ) {
169+ return ;
170+ }
171+
172+ $ subscribers = $ this ->clientStateManager ->getResourceSubscribers ($ uri );
173+ if (empty ($ subscribers )) {
174+ return ;
175+ }
176+ $ notification = Notification::make ('notifications/resources/updated ' , ['uri ' => $ uri ]);
177+
178+ $ framedMessage = json_encode ($ notification , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n" ;
179+ if ($ framedMessage === false || $ framedMessage === "\n" ) {
180+ $ this ->logger ->error ('Failed to encode resource/updated notification. ' , ['uri ' => $ uri ]);
181+ return ;
182+ }
183+
184+ foreach ($ subscribers as $ clientId ) {
185+ $ this ->clientStateManager ->queueMessage ($ clientId , $ framedMessage );
186+ }
187+ }
188+
189+ /** @deprecated */
190+ public function setToolsChangedNotifier (?callable $ notifier ): void {}
191+
192+ /** @deprecated */
193+ public function setResourcesChangedNotifier (?callable $ notifier ): void {}
194+
195+ /** @deprecated */
196+ public function setPromptsChangedNotifier (?callable $ notifier ): void {}
197+
166198 public function registerTool (ToolDefinition $ tool , bool $ isManual = false ): void
167199 {
168200 $ toolName = $ tool ->getName ();
@@ -187,8 +219,8 @@ public function registerTool(ToolDefinition $tool, bool $isManual = false): void
187219 unset($ this ->manualToolNames [$ toolName ]);
188220 }
189221
190- if (! $ exists && $ this -> notifyToolsChanged ) {
191- ( $ this ->notifyToolsChanged )( $ tool );
222+ if (! $ exists ) {
223+ $ this ->notifyToolsChanged ( );
192224 }
193225 }
194226
@@ -214,8 +246,8 @@ public function registerResource(ResourceDefinition $resource, bool $isManual =
214246 unset($ this ->manualResourceUris [$ uri ]);
215247 }
216248
217- if (! $ exists && $ this -> notifyResourcesChanged ) {
218- ( $ this ->notifyResourcesChanged ) ();
249+ if (! $ exists ) {
250+ $ this ->notifyResourcesChanged ();
219251 }
220252 }
221253
@@ -265,8 +297,8 @@ public function registerPrompt(PromptDefinition $prompt, bool $isManual = false)
265297 unset($ this ->manualPromptNames [$ promptName ]);
266298 }
267299
268- if (! $ exists && $ this -> notifyPromptsChanged ) {
269- ( $ this ->notifyPromptsChanged ) ();
300+ if (! $ exists ) {
301+ $ this ->notifyPromptsChanged ();
270302 }
271303 }
272304
0 commit comments